|
|
@@ -0,0 +1,94 @@
|
|
|
+<template>
|
|
|
+ <div v-if="banners.length > 0" class="banner-container">
|
|
|
+ <a
|
|
|
+ v-for="banner in banners"
|
|
|
+ :key="banner.id"
|
|
|
+ :href="banner.link"
|
|
|
+ @click="(event) => handleClick(event, banner)"
|
|
|
+ class="banner-item block w-full rounded-2xl overflow-hidden bg-white/5 border border-white/10 hover:bg-white/10 transition cursor-pointer"
|
|
|
+ >
|
|
|
+ <img
|
|
|
+ :src="banner.image"
|
|
|
+ :alt="banner.title"
|
|
|
+ class="w-full h-auto object-cover"
|
|
|
+ />
|
|
|
+ </a>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+import { ref, onMounted } from "vue";
|
|
|
+import { getBannersByPosition, recordBannerClick } from "@/services/api";
|
|
|
+
|
|
|
+interface Banner {
|
|
|
+ id: number;
|
|
|
+ image: string;
|
|
|
+ title: string;
|
|
|
+ link: string;
|
|
|
+ position: "top" | "middle" | "bottom";
|
|
|
+ enabled: boolean;
|
|
|
+ clickCount: number;
|
|
|
+ todayClickCount: number;
|
|
|
+}
|
|
|
+
|
|
|
+const props = defineProps<{
|
|
|
+ position: "top" | "middle" | "bottom";
|
|
|
+}>();
|
|
|
+
|
|
|
+const banners = ref<Banner[]>([]);
|
|
|
+
|
|
|
+// 加载广告
|
|
|
+const loadBanners = async () => {
|
|
|
+ try {
|
|
|
+ const data = await getBannersByPosition(props.position);
|
|
|
+ // 接口已经只返回启用的广告,直接使用
|
|
|
+ banners.value = Array.isArray(data) ? data : [];
|
|
|
+ } catch (error) {
|
|
|
+ console.error(`获取${props.position}位置广告失败:`, error);
|
|
|
+ banners.value = [];
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// 处理广告点击
|
|
|
+const handleClick = async (event: Event, banner: Banner) => {
|
|
|
+ // 阻止默认跳转,先记录点击
|
|
|
+ event.preventDefault();
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 异步记录点击,不等待完成,避免阻塞跳转
|
|
|
+ recordBannerClick(banner.id).catch((error) => {
|
|
|
+ console.error("记录广告点击失败:", error);
|
|
|
+ });
|
|
|
+
|
|
|
+ // 记录请求发送后立即跳转
|
|
|
+ if (banner.link) {
|
|
|
+ window.open(banner.link, "_blank", "noopener,noreferrer");
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error("处理广告点击失败:", error);
|
|
|
+ // 即使出错也允许跳转
|
|
|
+ if (banner.link) {
|
|
|
+ window.open(banner.link, "_blank", "noopener,noreferrer");
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ loadBanners();
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.banner-container {
|
|
|
+ @apply w-full;
|
|
|
+}
|
|
|
+
|
|
|
+.banner-item {
|
|
|
+ @apply mb-3;
|
|
|
+}
|
|
|
+
|
|
|
+.banner-item:last-child {
|
|
|
+ @apply mb-0;
|
|
|
+}
|
|
|
+</style>
|
|
|
+
|