320 lines
14 KiB
Vue
320 lines
14 KiB
Vue
m<template>
|
||
<view class="group-purchase-container">
|
||
<!-- 顶部横幅 -->
|
||
<view class="banner">
|
||
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/gp_index_top.png"></image>
|
||
</view>
|
||
|
||
<!-- 商品列表 -->
|
||
<view class="goods-list">
|
||
<!-- 商品项 -->
|
||
<view v-for="(item, index) in goodsList" :key="index">
|
||
<!-- 有多个货品 -->
|
||
<view class="goods-item" v-if="item.group_buy_goods_list.length > 1">
|
||
<view class="goods-image">
|
||
<image :src="item.commodity_pic" mode="aspectFill"></image>
|
||
</view>
|
||
<view class="goods-info">
|
||
<view class="goods-name">{{ item.commodity_name }}</view>
|
||
<view class="goods-desc">{{ item.commodity_intro }}</view>
|
||
<view class="goods-price"> {{ getPriceRange(item.group_buy_goods_list) }} </view>
|
||
|
||
<!-- 选择规格标签 -->
|
||
<view class="specification-tag" @click.stop="toggleSkuList(index)">
|
||
<text>{{ item.showSkuList ? '收起' : '选择规格' }}</text>
|
||
<u-icon name="arrow-down" size="26rpx" color="#FF370B" v-if="!item.showSkuList"></u-icon>
|
||
<u-icon name="arrow-up" size="26rpx" color="#FF370B" v-else></u-icon>
|
||
</view>
|
||
|
||
<!-- 货品列表 -->
|
||
<view class="sku-list" v-if="item.showSkuList">
|
||
<view v-for="(sku, skuIndex) in item.group_buy_goods_list" :key="skuIndex">
|
||
<view class="sku-item" @click="toDetail(sku)">
|
||
<view class="sku-info">
|
||
<view class="sku-image">
|
||
<image :src="sku.commodity_pic" mode="aspectFill"></image>
|
||
</view>
|
||
<view class="goods-info">
|
||
<view class="goods-name">{{ sku.goods_name }}</view>
|
||
<view class="goods-desc">{{ sku.goods_spec }}</view>
|
||
</view>
|
||
</view>
|
||
<view class="price-container">
|
||
<view class="sku-price">
|
||
<view class="sku-price1">团购价</view>
|
||
<view class="sku-price2">¥{{ sku.group_buy_price }}/{{ sku.goods_unit }}
|
||
</view>
|
||
</view>
|
||
<view class="sku-control">
|
||
<view class="decrease-btn" @tap.stop="decreaseQuantity(index, skuIndex)">-
|
||
</view>
|
||
<view class="quantity">{{ sku.quantity }}</view>
|
||
<view class="increase-btn" @tap.stop="increaseQuantity(index, skuIndex)">+
|
||
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="original-price">单买价 ¥{{ sku.sales_price }}/{{ sku.goods_unit }}</view>
|
||
<view class="sku-countdown">
|
||
{{
|
||
getEndTheCountdown(sku.group_buy_activity_info.end_time)
|
||
}}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<!-- 只有一个货品 -->
|
||
<view v-else>
|
||
<view class="goods-item2" @click="toDetail(item)">
|
||
<view class="goods-image">
|
||
<image :src="item.commodity_pic" mode="aspectFill"></image>
|
||
</view>
|
||
<view class="goods-info">
|
||
<view class="goods-name">{{ item.commodity_name }}</view>
|
||
<view class="goods-desc">{{ item.commodity_intro }}</view>
|
||
<view class="price-container">
|
||
<view class="group-price">
|
||
<view class="group-price1">团购价</view>
|
||
<view class="group-price2">¥{{ item.group_buy_goods_list[0].group_buy_price }}/{{
|
||
item.group_buy_goods_list[0].goods_unit }}</view>
|
||
</view>
|
||
<view class="quantity-control">
|
||
<view class="decrease-btn" @tap.stop="decreaseQuantity(index, 0)">-</view>
|
||
<view class="quantity">{{ item.group_buy_goods_list[0].quantity }}</view>
|
||
<view class="increase-btn" @tap.stop="increaseQuantity(index, 0)">+</view>
|
||
</view>
|
||
</view>
|
||
<view class="original-price">单买价 ¥{{ item.group_buy_goods_list[0].sales_price }}/{{
|
||
item.group_buy_goods_list[0].goods_unit }}</view>
|
||
<view class="countdown">
|
||
{{ getEndTheCountdown(item.group_buy_goods_list[0].group_buy_activity_info.end_time) }}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 购物车按钮 -->
|
||
<view class="shop_car" @click="shopCar">
|
||
<u-badge numberType="limit" type="error" max="99" :value="carNum"></u-badge>
|
||
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_car_num.png"></image>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import { picUrl, menuButtonInfo, request, NavgateTo } from "../../../utils";
|
||
import { apiArr } from '@/api/groupPurchase.js'
|
||
import { apiArr as shopApi } from "../../../api/shop.js";
|
||
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
goodsList: [],
|
||
carNum: 0,
|
||
quantity: 0,
|
||
timer: null, // 定时器ID
|
||
endTime: '', // 初始化结束时间
|
||
updateTime: Date.now(), // 用于触发倒计时更新的时间戳
|
||
goodsDetail: []
|
||
};
|
||
},
|
||
onLoad() {
|
||
// this.getGoodsList()
|
||
},
|
||
onShow() {
|
||
// 在页面显示时启动定时器
|
||
if (!this.timer) {
|
||
this.timer = setInterval(() => {
|
||
// 更新时间戳,触发页面重新渲染
|
||
this.updateTime = Date.now();
|
||
}, 1000);
|
||
}
|
||
|
||
// 确保getGoodsList和getShopdetail都执行完毕后再执行getGoodsNum
|
||
Promise.all([
|
||
// 确保getGoodsList已完成
|
||
this.goodsList.length > 0 ? Promise.resolve() : this.getGoodsList(),
|
||
// 调用getShopdetail并等待其完成
|
||
this.getShopdetail()
|
||
]).then(() => {
|
||
this.getGoodsNum();//获取货品在购物车中的数量
|
||
});
|
||
},
|
||
methods: {
|
||
getGoodsList() {
|
||
const params = {
|
||
user_id: uni.getStorageSync('userId')
|
||
}
|
||
return request(apiArr.groupBuyList, 'POST', params).then(res => {
|
||
const list = res.group_buy_list.map(item => {
|
||
// 为每个货品初始化quantity
|
||
const group_buy_goods_list = item.group_buy_goods_list.map(sku => ({
|
||
...sku,
|
||
commodity_pic: picUrl + sku.commodity_pic,
|
||
quantity: 0
|
||
}));
|
||
return {
|
||
...item,
|
||
commodity_pic: picUrl + item.commodity_pic,
|
||
showSkuList: false,
|
||
group_buy_goods_list
|
||
}
|
||
})
|
||
this.goodsList = list
|
||
return res;
|
||
})
|
||
},
|
||
getShopdetail() {
|
||
return request(shopApi.getCar, "POST").then((res) => {
|
||
this.carNum = res.total;
|
||
// 合并当日达和普通商品数据
|
||
this.goodsDetail = [].concat(res.same_day_cart_list, res.normal_cart_list)
|
||
.flatMap(supplier => supplier.commodity_cart_and_goods_model);
|
||
return res;
|
||
});
|
||
},
|
||
getGoodsNum() {
|
||
if (!this.goodsDetail || !this.goodsList || this.goodsList.length === 0) {
|
||
return;
|
||
}
|
||
// 遍历所有商品
|
||
this.goodsList.forEach(goods => {
|
||
// 遍历商品的所有货品
|
||
goods.group_buy_goods_list.forEach(sku => {
|
||
// 在购物车数据中查找对应的货品
|
||
const matchedItem = this.goodsDetail.find(item => item.goods_id === sku.goods_id);
|
||
|
||
// 如果找到匹配项,更新quantity
|
||
if (matchedItem) {
|
||
sku.quantity = matchedItem.count;
|
||
} else {
|
||
// 如果没有找到,设置为0
|
||
sku.quantity = 0;
|
||
}
|
||
});
|
||
});
|
||
},
|
||
toDetail(item) {
|
||
NavgateTo(`/packages/shop/groupPurchaseDetail/index?item=${JSON.stringify(item)}`)
|
||
},
|
||
// 获取商品价格范围
|
||
getPriceRange(goodsList) {
|
||
if (!goodsList || goodsList.length === 0) return '¥0';
|
||
const prices = goodsList.map(item => Number(item.sales_price));
|
||
const minPrice = Math.min(...prices);
|
||
const maxPrice = Math.max(...prices);
|
||
return minPrice === maxPrice ? `¥${minPrice}` : `¥${minPrice} ~ ¥${maxPrice}`;
|
||
},
|
||
// 展开/收起货品列表
|
||
toggleSkuList(index) {
|
||
this.goodsList[index].showSkuList = !this.goodsList[index].showSkuList;
|
||
},
|
||
// 增加货品数量
|
||
increaseQuantity(goodsIndex, skuIndex) {
|
||
if (this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].quantity == 0) {
|
||
this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].quantity += this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].min_order_quantity
|
||
this.carNum += this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].min_order_quantity
|
||
|
||
} else {
|
||
this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].quantity++;
|
||
this.carNum++;
|
||
}
|
||
const params = {
|
||
goods_id_and_count: [
|
||
{
|
||
goods_id: this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].id,
|
||
count: this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].quantity,
|
||
},
|
||
],
|
||
group_buy_id: this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].group_buy_activity_info.id
|
||
}
|
||
this.updateCar(params);
|
||
},
|
||
// 减少货品数量
|
||
decreaseQuantity(goodsIndex, skuIndex) {
|
||
if (this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].quantity > 0) {
|
||
if(this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].quantity == this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].min_order_quantity){
|
||
this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].quantity = 0
|
||
this.carNum = 0
|
||
}else{
|
||
this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].quantity--;
|
||
this.carNum--;
|
||
}
|
||
|
||
const params = {
|
||
goods_id_and_count: [
|
||
{
|
||
goods_id: this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].id,
|
||
count: this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].quantity,
|
||
},
|
||
],
|
||
group_buy_id: this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].group_buy_activity_info.id
|
||
}
|
||
this.updateCar(params);
|
||
} else {
|
||
uni.showToast({
|
||
title: '已经没有了...',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
},
|
||
// 请求更改购物车接口
|
||
async updateCar(params) {
|
||
return request(shopApi.updateCar, "POST", params).then((res) => {
|
||
this.getShopdetail();
|
||
uni.showToast({
|
||
title: "操作成功!",
|
||
success() { },
|
||
});
|
||
});
|
||
},
|
||
// 跳转到购物车
|
||
shopCar() {
|
||
NavgateTo("../shopCar/index");
|
||
},
|
||
// 计算距离结束日期的剩余时间
|
||
getEndTheCountdown(endTime) {
|
||
// 获取当前时间和结束时间的时间戳
|
||
const now = new Date().getTime();
|
||
const end = new Date(endTime).getTime();
|
||
|
||
// 计算时间差(毫秒)
|
||
let diff = end - now;
|
||
|
||
// 如果已经结束,返回提示
|
||
if (diff <= 0) {
|
||
return '团购已结束';
|
||
}
|
||
|
||
// 计算天、小时、分钟
|
||
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
|
||
diff -= days * (1000 * 60 * 60 * 24);
|
||
|
||
const hours = Math.floor(diff / (1000 * 60 * 60));
|
||
diff -= hours * (1000 * 60 * 60);
|
||
|
||
const minutes = Math.floor(diff / (1000 * 60));
|
||
diff -= minutes * (1000 * 60);
|
||
|
||
// 返回格式化的字符串
|
||
return `${days}天${hours}小时${minutes}分钟后结束`;
|
||
}
|
||
},
|
||
onHide() {
|
||
// 清除定时器
|
||
if (this.timer) {
|
||
clearInterval(this.timer)
|
||
this.timer = null
|
||
}
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style>
|
||
@import url("./index.css");
|
||
</style> |