95 lines
2.5 KiB
Vue
95 lines
2.5 KiB
Vue
<template>
|
||
<view
|
||
class="login-advertisement"
|
||
:class="{ 'login-advertisement--linked': advertisement.targetUrl }"
|
||
:role="advertisement.targetUrl ? 'button' : 'img'"
|
||
:aria-label="advertisement.targetUrl
|
||
? `${advertisement.title},查看详情`
|
||
: advertisement.title"
|
||
@click="openAdvertisement"
|
||
>
|
||
<image :src="advertisement.image" mode="aspectFill" />
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { onBeforeUnmount, onMounted, ref } from "vue";
|
||
import {
|
||
createRequestController,
|
||
isRequestCancelled,
|
||
} from "@/services/api/request-controller.js";
|
||
import { siteContentApi } from "@/services/api/site-content-service.js";
|
||
import { openSiteContentTarget } from "@/utils/navigation/gateway.js";
|
||
|
||
const fallbackAdvertisement = Object.freeze({
|
||
title: "寻根问祖",
|
||
image: "/static/assets/modules/genealogy/opaque/home-ad-heritage-hall.png",
|
||
targetUrl: "",
|
||
});
|
||
|
||
const advertisement = ref(fallbackAdvertisement);
|
||
const promotionRequestController = createRequestController();
|
||
let isMounted = true;
|
||
|
||
const loadAdvertisement = async () => {
|
||
try {
|
||
const promotions = await siteContentApi.getPromotions({
|
||
placement: "home_banner",
|
||
requestController: promotionRequestController,
|
||
});
|
||
if (!isMounted) return;
|
||
const promotion = promotions.find((entry) => entry.coverFile?.accessUrl);
|
||
if (!promotion) return;
|
||
advertisement.value = {
|
||
title: promotion.title,
|
||
image: promotion.coverFile.accessUrl,
|
||
targetUrl: promotion.targetUrl,
|
||
};
|
||
} catch (error) {
|
||
if (!isMounted || isRequestCancelled(error)) return;
|
||
advertisement.value = fallbackAdvertisement;
|
||
}
|
||
};
|
||
|
||
const openAdvertisement = async () => {
|
||
if (!advertisement.value.targetUrl) return;
|
||
try {
|
||
await openSiteContentTarget(advertisement.value.targetUrl, () => {
|
||
uni.showToast({ title: "广告内容暂时打不开", icon: "none" });
|
||
});
|
||
} catch {
|
||
uni.showToast({ title: "广告内容暂时打不开", icon: "none" });
|
||
}
|
||
};
|
||
|
||
onMounted(loadAdvertisement);
|
||
onBeforeUnmount(() => {
|
||
isMounted = false;
|
||
promotionRequestController.abort();
|
||
});
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.login-advertisement {
|
||
width: 100%;
|
||
height: 128rpx;
|
||
flex: 0 0 auto;
|
||
overflow: hidden;
|
||
box-sizing: border-box;
|
||
margin-top: 22rpx;
|
||
border: 1rpx solid rgba(142, 96, 44, 0.38);
|
||
border-radius: 12rpx;
|
||
background: #f1ece2;
|
||
}
|
||
|
||
.login-advertisement--linked:active {
|
||
opacity: 0.78;
|
||
}
|
||
|
||
.login-advertisement image {
|
||
display: block;
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
</style>
|