312
This commit is contained in:
parent
93e75199c8
commit
d534aa8269
|
|
@ -1,13 +1,13 @@
|
|||
<template>
|
||||
<uni-popup ref="popup" type="center" maskBackgroundColor="rgba(0,0,0,0.9)">
|
||||
<view v-if="visible" class="preview-popup">
|
||||
<view v-if="visible" class="preview-popup" @touchmove.stop.prevent="moveHandle">
|
||||
<!-- 翻转卡片容器 -->
|
||||
<view class="flip-container" :class="{ 'flipped': showList }">
|
||||
<view class="flipper">
|
||||
<!-- 正面:商品图片 -->
|
||||
<view class="front">
|
||||
<view class="pic center relative">
|
||||
<image :src="innerImgUrl" @click="toggleList" lazy-load></image>
|
||||
<view class="pic center relative" @click="toggleList">
|
||||
<image :src="innerImgUrl" lazy-load mode="aspectFit"></image>
|
||||
<view class="type-tag justify-center"
|
||||
:style="{ backgroundColor: dataItem.shang_info ? dataItem.shang_info.color : '#000000' }"
|
||||
v-if="innerTipTitle">{{ innerTipTitle }}</view>
|
||||
|
|
@ -16,40 +16,51 @@
|
|||
|
||||
<!-- 背面:赏品列表 -->
|
||||
<view class="back">
|
||||
<scroll-view class="list" :scroll-y="true">
|
||||
<!-- 加载中状态 -->
|
||||
<view class="loading-container center" v-if="loading">
|
||||
<view class="loading-text">加载中...</view>
|
||||
</view>
|
||||
<!-- 赏品列表内容 -->
|
||||
<view class="res-list" v-else>
|
||||
<view class="res-item" v-for="(item, i) in children" :key="i" @click.stop="handleItemClick(item)">
|
||||
<view class="pic center">
|
||||
<image :src="item.imgurl" lazy-load></image>
|
||||
<view class="tag center"
|
||||
:style="{ backgroundColor: item.shang_info ? item.shang_info.color : '#000000' }">{{
|
||||
item.shang_info ?
|
||||
item.shang_info.title : "" }}</view>
|
||||
<view class="num center">{{ item.surplus_stock }}/{{ item.stock }}</view>
|
||||
<!-- 售罄遮罩 -->
|
||||
<view class="sold-out-mask center" v-if="item.surplus_stock <= 0">
|
||||
<text>售罄</text>
|
||||
</view>
|
||||
<view class="listt">
|
||||
<scroll-view class="list" :scroll-y="true">
|
||||
<!-- 加载中状态 -->
|
||||
<view class="loading-container center" v-if="loading">
|
||||
<view class="loading-icon">
|
||||
<image :src="$img('/static/img/loading.gif')" mode="aspectFit" v-if="hasLoadingGif"></image>
|
||||
<view class="loading-dot" v-else></view>
|
||||
</view>
|
||||
<view>
|
||||
<view class="item-title hang1" style="margin-top:5rpx;">
|
||||
<text> {{ item.title }}</text>
|
||||
<view class="loading-text">加载中...</view>
|
||||
</view>
|
||||
<!-- 空列表状态 -->
|
||||
<view class="empty-container center" v-else-if="children.length === 0 && !loading">
|
||||
<view class="empty-text">暂无商品</view>
|
||||
</view>
|
||||
<!-- 赏品列表内容 -->
|
||||
<view class="res-list" v-else>
|
||||
<view class="res-item" v-for="(item, i) in children" :key="item.id || i"
|
||||
@click.stop="handleItemClick(item)">
|
||||
<view class="pic center">
|
||||
<image :src="item.imgurl" lazy-load mode="aspectFill"></image>
|
||||
<view class="tag center"
|
||||
:style="{ backgroundColor: item.shang_info ? item.shang_info.color : '#000000' }">
|
||||
{{ item.shang_info ? item.shang_info.title : "" }}
|
||||
</view>
|
||||
<view class="num center">{{ item.surplus_stock }}/{{ item.stock }}</view>
|
||||
<!-- 售罄遮罩 -->
|
||||
<view class="sold-out-mask center" v-if="item.surplus_stock <= 0">
|
||||
<text>售罄</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item-title hang1">
|
||||
<text style="color: #f39205;"> {{ item.pro }}</text>
|
||||
</view>
|
||||
<view class="item-title hang1">
|
||||
<text>售价:{{ item.price }}</text>
|
||||
<view class="item-info">
|
||||
<view class="item-title hang1">
|
||||
<text>{{ item.title }}</text>
|
||||
</view>
|
||||
<view class="item-probability hang1">
|
||||
<text>{{ item.pro }}</text>
|
||||
</view>
|
||||
<view class="item-price hang1">
|
||||
<text>售价:{{ item.price }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
|
@ -62,9 +73,12 @@
|
|||
<!-- 商品信息列表 -->
|
||||
<view class="info-list">
|
||||
<view class="info-item" v-if="innerProbability">{{ innerProbability }}</view>
|
||||
<view class="info-item" v-if="isTips" @click="toggleList">{{ showList ? '收起' : '查看奖品' }}</view>
|
||||
<view class="info-item highlight" v-if="isTips" @click="toggleList">
|
||||
{{ showList ? '收起' : '查看奖品' }}
|
||||
<!-- <text class="arrow-icon">{{ showList ? '↑' : '↓' }}</text> -->
|
||||
</view>
|
||||
<view class="info-item" v-if="innerProductType">产品类型: {{ innerProductType }}</view>
|
||||
<view class="info-item" v-for="(item, index) in innerExtraInfo" :key="index">{{ item }}</view>
|
||||
<view class="info-item" v-for="(item, index) in innerExtraInfo" :key="'info-' + index">{{ item }}</view>
|
||||
</view>
|
||||
|
||||
<!-- 关闭按钮 -->
|
||||
|
|
@ -111,8 +125,8 @@ export default {
|
|||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
|
|
@ -128,9 +142,12 @@ export default {
|
|||
isTips: false,
|
||||
children: [],
|
||||
goods: null,
|
||||
loading: false
|
||||
loading: false,
|
||||
hasLoadingGif: false,
|
||||
loadError: false
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
// 监听props变化,更新内部数据
|
||||
title(val) {
|
||||
|
|
@ -152,6 +169,7 @@ export default {
|
|||
this.innerExtraInfo = val;
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
// 初始化内部数据
|
||||
this.innerTitle = this.title;
|
||||
|
|
@ -161,20 +179,46 @@ export default {
|
|||
this.innerProbability = this.probability;
|
||||
this.innerExtraInfo = this.extraInfo;
|
||||
|
||||
// 检查是否有loading图片资源
|
||||
this.checkLoadingResource();
|
||||
|
||||
// 监听全局预览事件
|
||||
uni.$on('global-preview-event', this.handleGlobalEvent);
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
// 组件销毁前移除事件监听
|
||||
uni.$off('global-preview-event', this.handleGlobalEvent);
|
||||
},
|
||||
|
||||
methods: {
|
||||
moveHandle(e) {
|
||||
return true;
|
||||
},
|
||||
// 检查loading图片资源是否存在
|
||||
checkLoadingResource() {
|
||||
try {
|
||||
const loadingPath = this.$img('/static/img/loading.gif');
|
||||
uni.getImageInfo({
|
||||
src: loadingPath,
|
||||
success: () => {
|
||||
this.hasLoadingGif = true;
|
||||
},
|
||||
fail: () => {
|
||||
this.hasLoadingGif = false;
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
this.hasLoadingGif = false;
|
||||
}
|
||||
},
|
||||
|
||||
// 处理列表项点击
|
||||
handleItemClick(item) {
|
||||
console.log('点击了', item);
|
||||
this.$emit('itemClick', item);
|
||||
|
||||
|
||||
},
|
||||
|
||||
// 处理全局预览事件
|
||||
handleGlobalEvent(options) {
|
||||
console.log('收到全局预览事件', options);
|
||||
|
|
@ -184,7 +228,7 @@ export default {
|
|||
// 切换列表显示状态,添加动画效果
|
||||
toggleList() {
|
||||
if (this.isTips) {
|
||||
if (this.children.length == 0) {
|
||||
if (this.children.length === 0 && !this.loading && !this.loadError) {
|
||||
this.loadChildren();
|
||||
}
|
||||
this.showList = !this.showList;
|
||||
|
|
@ -193,45 +237,47 @@ export default {
|
|||
|
||||
// 设置预览数据并打开弹窗
|
||||
setPreviewData(data) {
|
||||
console.log('设置预览数据', data);
|
||||
if (!data) return;
|
||||
|
||||
// 更新内部数据
|
||||
if (data.title !== undefined) this.innerTitle = data.title;
|
||||
if (data.imgUrl !== undefined) this.innerImgUrl = data.imgUrl;
|
||||
if (data.tipTitle !== undefined) this.innerTipTitle = data.tipTitle;
|
||||
if (data.productType !== undefined) this.innerProductType = data.productType;
|
||||
if (data.probability !== undefined) this.innerProbability = data.probability;
|
||||
if (data.extraInfo !== undefined) this.innerExtraInfo = data.extraInfo;
|
||||
// 重置数据状态
|
||||
this.loadError = false;
|
||||
this.showList = false;
|
||||
this.isTips = false;
|
||||
if (data.dataItem !== undefined && data.goods != null) {
|
||||
console.log(data.dataItem, data.goods);
|
||||
if (data.dataItem.goods_type == 4) {
|
||||
this.goods = data.goods;
|
||||
this.dataItem = data.dataItem;
|
||||
this.isTips = true;
|
||||
this.children.splice(0, this.children.length);
|
||||
}
|
||||
|
||||
// 更新商品基本信息
|
||||
if (data.dataItem) {
|
||||
const item = data.dataItem;
|
||||
this.innerTitle = item.title || '';
|
||||
this.innerImgUrl = item.imgurl || '';
|
||||
this.innerTipTitle = item.shang_info ? item.shang_info.title : '';
|
||||
this.innerProbability = item.pro || '';
|
||||
}
|
||||
|
||||
// 更新其他信息
|
||||
if (data.productType) this.innerProductType = data.productType;
|
||||
if (data.extraInfo) this.innerExtraInfo = data.extraInfo;
|
||||
|
||||
// 设置商品和数据项
|
||||
if (data.dataItem && data.goods && data.dataItem.goods_type == 4) {
|
||||
this.goods = data.goods;
|
||||
this.dataItem = data.dataItem;
|
||||
this.isTips = true;
|
||||
this.children = [];
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
this.open();
|
||||
},
|
||||
|
||||
// 打开弹窗
|
||||
open() {
|
||||
// console.log('尝试打开弹窗', this.$refs.popup);
|
||||
this.visible = true;
|
||||
// console.log('打开弹窗', this.dataItem);
|
||||
// 使用nextTick确保DOM更新后再打开弹窗
|
||||
|
||||
this.$nextTick(() => {
|
||||
console.log(' ');
|
||||
if (this.$refs.popup) {
|
||||
// 小程序环境下需要额外延迟
|
||||
setTimeout(() => {
|
||||
this.$refs.popup.open();
|
||||
console.log('弹窗已打开');
|
||||
}, 50);
|
||||
} else {
|
||||
console.error('popup ref不存在,请检查组件是否正确挂载');
|
||||
|
|
@ -239,12 +285,10 @@ export default {
|
|||
setTimeout(() => {
|
||||
if (this.$refs.popup) {
|
||||
this.$refs.popup.open();
|
||||
console.log('弹窗已打开(延迟尝试)');
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
// 关闭弹窗
|
||||
|
|
@ -255,24 +299,39 @@ export default {
|
|||
}
|
||||
this.$emit('close');
|
||||
},
|
||||
|
||||
// 加载子商品数据
|
||||
async loadChildren() {
|
||||
if (this.loading) return;
|
||||
|
||||
this.loading = true;
|
||||
var res = await this.req({
|
||||
url: "goods_children",
|
||||
method: "POST",
|
||||
Loading:true,
|
||||
data: {
|
||||
goods_id: this.goods.id,
|
||||
goods_num: this.goods.num,
|
||||
goods_list_id: this.dataItem.id
|
||||
this.loadError = false;
|
||||
|
||||
try {
|
||||
const res = await this.req({
|
||||
url: "goods_children",
|
||||
method: "POST",
|
||||
Loading: true, // 已经有自己的loading状态,不需要全局loading
|
||||
data: {
|
||||
goods_id: this.goods.id,
|
||||
goods_num: this.goods.num,
|
||||
goods_list_id: this.dataItem.id
|
||||
}
|
||||
});
|
||||
|
||||
if (res && res.status === 1) {
|
||||
this.children = res.data || [];
|
||||
} else {
|
||||
this.loadError = true;
|
||||
this.children = [];
|
||||
}
|
||||
});
|
||||
if (res == null || res.status !== 1) {
|
||||
} catch (error) {
|
||||
console.error('加载数据出错', error);
|
||||
this.loadError = true;
|
||||
this.children = [];
|
||||
} finally {
|
||||
this.loading = false;
|
||||
return;
|
||||
}
|
||||
this.children = res.data;
|
||||
this.loading = false;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -289,14 +348,14 @@ export default {
|
|||
.flip-container {
|
||||
perspective: 1000px;
|
||||
width: 100%;
|
||||
height: 598rpx;
|
||||
height: 620rpx;
|
||||
|
||||
&.flipped .flipper {
|
||||
transform: rotateY(180deg);
|
||||
}
|
||||
|
||||
.flipper {
|
||||
transition: 0.8s;
|
||||
transition: 0.6s;
|
||||
transform-style: preserve-3d;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
|
@ -312,7 +371,6 @@ export default {
|
|||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 16rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.front {
|
||||
|
|
@ -325,25 +383,39 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
.list {
|
||||
.listt {
|
||||
width: 100%;
|
||||
padding-top: 5rpx;
|
||||
height: 598rpx;
|
||||
height: 620rpx;
|
||||
background-color: #ffffff;
|
||||
border-radius: 16rpx;
|
||||
margin: 0rpx auto;
|
||||
}
|
||||
|
||||
.list {
|
||||
width: 100%;
|
||||
height: 610rpx;
|
||||
background-color: #ffffff;
|
||||
border-radius: 16rpx;
|
||||
margin: 0rpx auto;
|
||||
|
||||
.res-list {
|
||||
padding: 20rpx 10rpx;
|
||||
padding: 5rpx 15rpx;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 33%);
|
||||
gap: 20rpx 8rpx;
|
||||
justify-content: center;
|
||||
|
||||
.res-item {
|
||||
width: 180rpx;
|
||||
// height: 240rpx;
|
||||
background-color: #f8f8f8;
|
||||
border-radius: 16rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
transition: transform 0.2s ease;
|
||||
|
||||
&:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
.pic {
|
||||
width: 100%;
|
||||
|
|
@ -369,23 +441,51 @@ export default {
|
|||
font-weight: 400;
|
||||
font-size: 20rpx;
|
||||
color: #333333;
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
background-color: rgba(255, 255, 255, 0.7);
|
||||
border-radius: 18rpx;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
padding: 22rpx 10rpx 0;
|
||||
font-weight: 400;
|
||||
font-size: 16rpx;
|
||||
color: #333333;
|
||||
.item-info {
|
||||
padding: 5rpx 0;
|
||||
}
|
||||
|
||||
.exchange {
|
||||
padding: 10rpx 10rpx;
|
||||
font-weight: 400;
|
||||
.item-title {
|
||||
padding: 0 2%;
|
||||
margin: 1rpx 0;
|
||||
width: 100%;
|
||||
font-size: 20rpx;
|
||||
color: #ffffff;
|
||||
text-align: left;
|
||||
height: 28rpx;
|
||||
line-height: 28rpx;
|
||||
font-weight: 500;
|
||||
color: #333333;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.item-probability {
|
||||
padding: 0 2%;
|
||||
margin: 1rpx 0;
|
||||
width: 100%;
|
||||
font-size: 20rpx;
|
||||
text-align: left;
|
||||
height: 28rpx;
|
||||
line-height: 28rpx;
|
||||
color: #f39205;
|
||||
}
|
||||
|
||||
.item-price {
|
||||
padding: 0 2%;
|
||||
margin: 1rpx 0;
|
||||
width: 100%;
|
||||
font-size: 20rpx;
|
||||
text-align: left;
|
||||
height: 28rpx;
|
||||
line-height: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -394,7 +494,7 @@ export default {
|
|||
// 商品图片区域
|
||||
.pic {
|
||||
width: 100%;
|
||||
height: 598rpx;
|
||||
height: 620rpx;
|
||||
background: #FFFFFF;
|
||||
border-radius: 16rpx;
|
||||
|
||||
|
|
@ -440,6 +540,8 @@ export default {
|
|||
font-weight: 600;
|
||||
font-size: 24rpx;
|
||||
color: #333333;
|
||||
text-align: center;
|
||||
line-height: 1.4;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -457,6 +559,17 @@ export default {
|
|||
font-weight: 400;
|
||||
color: #ffffff;
|
||||
cursor: pointer;
|
||||
|
||||
&.highlight {
|
||||
color: #f39205;
|
||||
font-weight: 500;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.arrow-icon {
|
||||
margin-left: 4rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -511,19 +624,46 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
.item-title {
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
width: 100%;
|
||||
font-size: 20rpx;
|
||||
text-align: left;
|
||||
padding-left: 2%;
|
||||
height: 30rpx;
|
||||
line-height: 30rpx;
|
||||
}
|
||||
|
||||
// 加载中样式
|
||||
.loading-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #ffffff;
|
||||
border-radius: 16rpx;
|
||||
|
||||
.loading-icon {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.loading-dot {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
background-color: #f39205;
|
||||
border-radius: 50%;
|
||||
animation: bounce 1.5s infinite ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
padding: 10rpx 40rpx;
|
||||
border-radius: 40rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 空状态样式
|
||||
.empty-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
|
|
@ -531,14 +671,28 @@ export default {
|
|||
align-items: center;
|
||||
background-color: #ffffff;
|
||||
border-radius: 16rpx;
|
||||
|
||||
.loading-text {
|
||||
|
||||
.empty-text {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
color: #999999;
|
||||
padding: 20rpx 40rpx;
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
border-radius: 40rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes bounce {
|
||||
|
||||
0%,
|
||||
100% {
|
||||
transform: scale(0);
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -326,11 +326,7 @@
|
|||
console.log(item,this.pageData);
|
||||
// 使用全局方法调用预览弹窗
|
||||
this.$preview({
|
||||
title: item.title,
|
||||
imgUrl: item.imgurl,
|
||||
tipTitle: item.shang_info ? item.shang_info.title : '',
|
||||
productType: this.optData.type_text,
|
||||
probability: item.pro,
|
||||
dataItem: item,
|
||||
goods: this.pageData.goods
|
||||
}).then(() => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user