HaniBlindBox/honey_box/components/float-ball/FloatBall.vue
2026-02-02 20:41:41 +08:00

174 lines
4.1 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) return [];
return this.floatBall.filter(item => {
// 如果是优惠券悬浮球根据showCouponBall决定是否显示
if (item.link_url && item.link_url.toLowerCase().includes('coupon')) {
return this.showCouponBall;
}
return true;
});
},
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");
if (status == 1) {
this.floatBall = data;
// 通知父组件悬浮球数据已加载
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>