347 lines
16 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 class="group-purchase-container">
<!-- 商品列表 -->
<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: [],
idVal: '',
};
},
onLoad(options) {
this.idVal = Number(options.id)
// 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() {
if (!uni.getStorageSync('userId')) {
uni.showToast({
title: '请先登录',
icon: 'none'
})
return
}
const params = {
adver_id: this.idVal,
}
return request(shopApi.adverGoodsList, 'POST', params).then(res => {
const list = res.data.adver_goods_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() {
const params = {
is_group_buy: 1,
}
return request(shopApi.getCar, "POST", params).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(itemObj) {
const item = {
...itemObj,
groupById: itemObj.group_buy_activity_info.id
};
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 {
if (this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].quantity == this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].total_stock) {
uni.showToast({
title: '库存不足',
icon: 'none'
});
return
}
if (this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].quantity == this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].max_limit_quantity) {
uni.showToast({
title: '一次最多购买' + this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].max_limit_quantity + '件',
icon: 'none'
});
return
}
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() {
const item = {
is_group_buy: 1,
}
NavgateTo("../shopCar/index?item=" + JSON.stringify(item));
},
// 计算距离结束日期的剩余时间
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>