HaniBlindBox/honey_box/components/float-ball/FloatBall.vue
2026-02-02 21:09:46 +08:00

184 lines
4.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view>
<!-- 悬浮球 -->
<template v-if="floatBall">
<view v-for="(item, index) in displayFloatBalls" :style="[getBallStyle(item)]" :key="index" class="group-fixed1"
@click="BallClick(item)">
<image :src="item.image"></image>
</view>
</template>
<!-- 悬浮球弹窗 -->
<uni-popup ref="floatBall_popup" type="center" maskBackgroundColor="rgba(0,0,0,0.8)">
<view class="pop-ball" v-if="ballItem"
:style="{ backgroundImage: 'url(' + ballItem.image_bj + ')', backgroundSize: '100% 99.5%', backgroundRepeat: 'no-repeat' }">
<image show-menu-by-longpress v-if="ballItem != null" :src="ballItem.image_details" mode="aspectFit"
:style="[getPopupStyle(ballItem)]">
</image>
</view>
<view class="pop-ball-close flex" @click="$refs.floatBall_popup.close()">
<view style="width: 48rpx;height: 48rpx;border-radius: 50%;opacity: 0.5;">
<image show-menu-by-longpress :src="$img1('common/close.png')" class="img100" />
</view>
</view>
</uni-popup>
</view>
</template>
<script>
export default {
name: 'FloatBall',
props: {
// 是否显示优惠券悬浮球
showCouponBall: {
type: Boolean,
default: true
}
},
data() {
return {
floatBall: [],
ballItem: null
}
},
computed: {
// 过滤后的悬浮球列表根据showCouponBall控制优惠券悬浮球显示
displayFloatBalls() {
if (!this.floatBall) {
console.log('[FloatBall] floatBall为空');
return [];
}
console.log('[FloatBall] 计算displayFloatBalls, showCouponBall=', this.showCouponBall, ', floatBall数量=', this.floatBall.length);
const result = this.floatBall.filter(item => {
// 如果是优惠券悬浮球根据showCouponBall决定是否显示
const isCouponBall = item.link_url && item.link_url.toLowerCase().includes('coupon');
if (isCouponBall) {
console.log('[FloatBall] 发现优惠券悬浮球, showCouponBall=', this.showCouponBall, ', 是否显示=', this.showCouponBall);
return this.showCouponBall;
}
return true;
});
console.log('[FloatBall] 过滤后悬浮球数量=', result.length);
return result;
},
getBallStyle() {
return (item) => {
let s = {
width: item.width,
height: item.height,
top: item.position_y,
};
if (item.position_x.indexOf('-') > -1) {
let position_x = item.position_x.split('-')[1];
s.right = position_x;
} else {
s.left = item.position_x;
}
if (item.effect == 1) {
s.animation = "m-zoom 1.2s ease-in-out infinite";
}
return s;
}
},
getPopupStyle() {
return (item) => {
if (item == null) {
return {};
}
let s = {
width: item.image_details_w,
height: item.image_details_h,
position: 'relative',
};
if (item.image_details_x != "0") {
s.left = item.image_details_x;
}
if (item.image_details_y != "0") {
s.top = item.image_details_y;
}
return s;
};
}
},
methods: {
BallClick(item) {
// 优惠券悬浮球特殊处理 - 触发自定义事件
if (item.link_url && item.link_url.toLowerCase().includes('coupon')) {
this.$emit('coupon-click', item);
return;
}
if (item.type == 2) {
this.$c.nav(item.link_url);
return;
}
if (item.type == 1) {
this.ballItem = item;
this.$refs.floatBall_popup.open();
}
},
async getFloatBall() {
const { status, data, msg } = await this.$request.get("getFloatBall");
console.log('[FloatBall] getFloatBall响应: status=', status, ', data=', JSON.stringify(data));
if (status == 1) {
this.floatBall = data;
console.log('[FloatBall] 设置floatBall, 数量=', data ? data.length : 0);
// 通知父组件悬浮球数据已加载
this.$emit('loaded', data);
}
}
},
mounted() {
this.getFloatBall();
}
}
</script>
<style lang="scss" scoped>
.group-fixed1 {
width: 52rpx;
height: 120rpx;
position: fixed;
z-index: 10;
right: 0;
top: 21vh;
image {
width: 100%;
height: 100%;
}
}
.pop-ball {
width: 85vw;
// height: 400px;
position: relative;
border-radius: 25rpx;
display: flex;
align-items: center;
justify-content: center;
}
.pop-ball-close {
margin-top: 20rpx;
width: 100%;
height: 50rpx;
display: flex;
align-items: center;
justify-content: center;
}
@keyframes m-zoom {
0% {
transform: scale(1);
}
50% {
transform: scale(0.9);
}
100% {
transform: scale(1);
}
}
</style>