You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1328 lines
34 KiB
1328 lines
34 KiB
<template>
|
|
<!-- 拼团单一商家 -->
|
|
<view class="page1">
|
|
<!-- 固定顶部导航栏(悬浮在背景图之上) -->
|
|
<view class="nav-bar" :style="{'padding-top': menuButtonInfo.top +'px','background':lastScrollTop>200?'#fff':''}">
|
|
<view class="back-btn" @tap="back">
|
|
<uni-icons type="left" size="28"></uni-icons>
|
|
</view>
|
|
<view class="title-search">
|
|
<uni-icons type="search" size="18" style="margin: 9rpx;"></uni-icons>
|
|
<input type="text" placeholder="搜索" />
|
|
</view>
|
|
</view>
|
|
<!-- 背景头图(随页面滚动) -->
|
|
<view class="title"></view>
|
|
<view class="content">
|
|
<view class="pintuan">
|
|
<view class="shop-top">
|
|
<view class="shop-img">
|
|
<img :src="shopItem.shopIcon" alt="">
|
|
<img src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/6c4ab92a43c842d8bb22035bce1f65cc.png"
|
|
alt=""
|
|
style="width:30rpx;height:30rpx;position: absolute;top: 0;left: 0;background-size: 100%;" />
|
|
</view>
|
|
<view class="shop-content" @tap="goDetail('shopDetail')">
|
|
<view class="shop-name">
|
|
{{shopItem.shopName}}
|
|
</view>
|
|
<view class="shop-content-center">
|
|
<view class="shop-rate">
|
|
<view class="shop-rate-num">{{shopItem.shopScore}}</view>
|
|
<view>
|
|
<uni-rate :disabled="true" size="20" disabledColor="rgba(255, 184, 84, 1)"
|
|
:value="shopItem.shopScore" />
|
|
</view>
|
|
</view>
|
|
<view class="shop-tag">
|
|
<text
|
|
style="padding: 4rpx 10rpx;background: rgba(223, 255, 176, 1);color: #777;border-radius: 6rpx;">
|
|
{{shopItem.shopTypeTitle}}
|
|
</text>
|
|
</view>
|
|
</view>
|
|
<view class="shop-content-bottom">
|
|
<view class="shop-deal" @tap.stop="goDetail('shopEvaluate')" style="color: #777;">
|
|
店铺评价<uni-icons type="right" size="12"></uni-icons>
|
|
</view>
|
|
<view class="shop-deal1">
|
|
销量 <text> {{shopItem.saleCount != null ? shopItem.saleCount : 0}}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="shop-bottom">
|
|
公告:{{shopItem.remark}}
|
|
</view>
|
|
</view>
|
|
<view class="pintuan" style="padding: 0;margin-top:20rpx;display: flex;">
|
|
<view class="pintuan-left">
|
|
<view class="pintuan-left-img">
|
|
<img src="/static/images/img/shangpintu.png" alt="">
|
|
</view>
|
|
<view class="pintuan-left-box">
|
|
<view class="pintuan-left-name">
|
|
无骨双拼|招牌炸鸡套餐
|
|
</view>
|
|
<view class="pintuan-left-price">
|
|
拼团<text style="color: red;">¥59.90</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="pintuan-right">
|
|
<view class="pintuan-right-img">
|
|
<img src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/94f91382e76c4f289d53fbf858e8732b.png"
|
|
alt="" />
|
|
<view class="weipincheng">+</view>
|
|
</view>
|
|
<view class="pintuan-right-cha">
|
|
差<text style="color: red;">1人</text>拼成
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<!-- 分类栏:移到goods-list外层,position:sticky才能生效 -->
|
|
<view class="menu-list" id="menuList" :style="{'top': navBarHeight + 'px','background':lastScrollTop>200?'#fff':''}">
|
|
<view class="menu1" @tap="checkTab(index)" v-for="(item,index) in menuList" :key="index" :style="{'font-size':item.checked?'40rpx':'30rpx','color':item.checked?'rgba(0, 35, 28, 1)':'#777'}">
|
|
<view style="width: 90px;">{{item.categoryName}}</view>
|
|
<img v-if="item.checked" class="checked-img" src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/4bb5fc7725cb4a7a84d1d3a15f05b39c.png" alt="" />
|
|
</view>
|
|
</view>
|
|
<view class="goods-list">
|
|
<view class="goods-member" v-for="(item,index) in productItem" :key="index" @tap="goDetail('product',item)">
|
|
<view class="goods-top">
|
|
<view class="goods-img">
|
|
<img :src="item.productPicture" alt="" style="border-radius: 10px;">
|
|
<img src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/6c4ab92a43c842d8bb22035bce1f65cc.png"
|
|
alt=""
|
|
style="width:30rpx;height:30rpx;position: absolute;top: 0;left: 0;background-size: 100%;" />
|
|
</view>
|
|
<view class="goods-content" @tap="goDetail('goodsDetail')">
|
|
<view class="goods-name">
|
|
{{item.productName}}
|
|
</view>
|
|
<view class="goods-content-center">
|
|
<view class="goods-deal1">
|
|
月售 <text> 100+</text>
|
|
</view>
|
|
<view class="goods-tag">
|
|
<view class="pintuan-right-img">
|
|
<img src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/94f91382e76c4f289d53fbf858e8732b.png"
|
|
alt="" />
|
|
<view class="weipincheng">+</view>
|
|
</view>
|
|
<view class="pintuan-right-cha">
|
|
差<text style="color: red;">1人</text>拼成
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="shop-tag1">
|
|
<text
|
|
style="padding: 4rpx 10rpx;background: rgba(223, 255, 176, 1);color: #777;border-radius: 6rpx;">
|
|
{{item.attributeListPrice | sliceMsg1}}
|
|
</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="goods-bottom">
|
|
<view class="goods-btn" @tap="openPopup('xiadan','dandu',item)"
|
|
style="background: rgba(166, 255, 234, 0.3);margin-right: 6%;border: 1px solid rgba(166, 255, 234, 0.5);">
|
|
直接购买¥{{item.attributeListPrice | sliceMsg}}
|
|
</view>
|
|
<view class="goods-btn" @tap="openPopup('xiadan','pintuan',item)">
|
|
拼团购买¥{{item.productGroupBuyPrices | slicePrice}}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<uni-load-more :status="loadStatus" @change="onChange" />
|
|
</view>
|
|
<view style="width: 100%;height: 160rpx;"></view>
|
|
<view class="bottom">
|
|
<view class="bottom-left">
|
|
<view style="position: relative;width: 60rpx;height: 80rpx;margin-top: 20rpx;" @tap="openPopup('car','','')">
|
|
<img src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/60db52398a65459e9541881c926986a4.png" alt="" />
|
|
<view class="bottom-dot" v-if="cartTotalCount > 0">{{cartTotalCount}}</view>
|
|
</view>
|
|
<view class="bottom-price">¥{{cartTotalPrice}}</view>
|
|
</view>
|
|
<view class="bottom-right" @tap="submitCartCheckout">
|
|
<img src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/d93d893296ed46ea99cfd0e8e2835eaa.png" alt="" />
|
|
</view>
|
|
</view>
|
|
|
|
|
|
<!-- 购物车弹窗 -->
|
|
<uni-popup ref="carPopup" background-color="#fff">
|
|
<view class="car-content">
|
|
<view class="car-close" @tap="$refs.carPopup.close()">
|
|
<uni-icons type="close" size="30" color="#fff"></uni-icons>
|
|
</view>
|
|
<view class="car-title">
|
|
已加购商品({{cartTotalCount}})
|
|
</view>
|
|
|
|
<scroll-view scroll-y style="max-height: 400rpx;">
|
|
<view class="goods-top" style="padding: 10px 0;" v-for="(cartItem, index) in cartItems" :key="index">
|
|
<view class="goods-img" style="width: 120rpx;height: 120rpx;">
|
|
<img :src="cartItem.item.productPicture" alt="" style="border-radius: 10px;width:100%;height:100%;">
|
|
</view>
|
|
<view class="goods-content" style="padding-left: 20rpx;">
|
|
<view class="goods-name">
|
|
{{cartItem.item.productName}}
|
|
</view>
|
|
<view class="goods-content-center">
|
|
<view class="goods-deal1" v-if="cartItem.specs">
|
|
<text style="color: #999; font-size: 20rpx;">已选规格: {{getSpecDisplayString(cartItem.specs)}}</text>
|
|
</view>
|
|
</view>
|
|
<view class="goods-content-bottom" style="margin-top: 10rpx;">
|
|
<view style="font-size: 28rpx;line-height: 54rpx;margin-right: 20rpx;flex: 1;color: red;">
|
|
¥{{cartItem.price}}
|
|
</view>
|
|
<view class="goods-num">
|
|
<view class="num-plus" style="background: #999;color: #fff;" @tap="adjustCart(cartItem.cartId, -1)">
|
|
-
|
|
</view>
|
|
<view class="num">
|
|
{{cartItem.quantity}}
|
|
</view>
|
|
<view class="num-plus" @tap="adjustCart(cartItem.cartId, 1)">
|
|
+
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</scroll-view>
|
|
|
|
<view style="width: 100%;height: 160rpx;"></view>
|
|
<view class="bottom" style="padding-bottom: 10px;">
|
|
<view class="bottom-left">
|
|
<view style="width: 60rpx;height: 80rpx;margin-top: 10rpx;" @tap="$refs.carPopup.close()">
|
|
<img src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/60db52398a65459e9541881c926986a4.png" alt="" />
|
|
</view>
|
|
<view class="bottom-price" style="line-height: 24px;">
|
|
<view>¥{{cartTotalPrice}}</view>
|
|
</view>
|
|
</view>
|
|
<view class="bottom-right" @tap="submitCartCheckout">
|
|
<img src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/d93d893296ed46ea99cfd0e8e2835eaa.png" alt="" />
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</uni-popup>
|
|
|
|
<!-- 警告弹出层 -->
|
|
<uni-popup ref="warnPopup" background-color="#fff">
|
|
<view class="warnImg">
|
|
<img @tap="$refs.warnPopup.close()" src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/4996043b3987401794b974d359429b8e.png" alt="购物车是空的" style="width:300px;height:370px;" />
|
|
</view>
|
|
</uni-popup>
|
|
<!-- 拼团和选规格弹窗 -->
|
|
<uni-popup ref="pintuanPopup" background-color="#fff">
|
|
<view class="car-content">
|
|
<view class="car-close" @tap="$refs.pintuanPopup.close()">
|
|
<uni-icons type="close" size="30" color="#fff"></uni-icons>
|
|
</view>
|
|
<view class="goods-top">
|
|
<view class="goods-img">
|
|
<img :src="currentItem.productPicture" alt="" style="border-radius: 10px;">
|
|
<img src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/6c4ab92a43c842d8bb22035bce1f65cc.png"
|
|
alt=""
|
|
style="width:30rpx;height:30rpx;position: absolute;top: 0;left: 0;background-size: 100%;" />
|
|
</view>
|
|
<view class="goods-content">
|
|
<view class="goods-name">
|
|
{{currentItem.productName}}
|
|
</view>
|
|
<view class="goods-content-center">
|
|
<view class="goods-deal1">
|
|
月售 <text> 100+</text>
|
|
</view>
|
|
</view>
|
|
<view class="goods-content-bottom">
|
|
<view style="font-size: 28rpx;line-height: 54rpx;margin-right: 20rpx;">
|
|
¥{{currentItem.attributeListPrice | sliceMsg}}
|
|
</view>
|
|
<view class="pintuan-left-price" v-if="currentItem.productGroupBuyPrices && currentItem.productGroupBuyPrices.length > 0">
|
|
拼团<text style="color: red;">¥{{currentItem.productGroupBuyPrices | slicePrice}}起</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<scroll-view scroll-y style="max-height: 50vh;">
|
|
<view class="goods-spec" v-if="parsedSpecs.length > 0">
|
|
<view class="spec1" v-for="(spec, sIndex) in parsedSpecs" :key="sIndex">
|
|
<view class="spec11">
|
|
选{{spec.name}}
|
|
</view>
|
|
<view class="spec22" >
|
|
<view :class="spec.selected === option ? 'spec-check' : 'spec222'"
|
|
v-for="(option, oIndex) in spec.options"
|
|
:key="oIndex"
|
|
@tap="selectSpec(sIndex, option)">
|
|
{{option}}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<template v-if="isPintuan && currentItem.productGroupBuyPrices && currentItem.productGroupBuyPrices.length > 0">
|
|
<view class="spec11">
|
|
成团选择
|
|
</view>
|
|
<view class="goods-team">
|
|
<view :class="selectedGroupRule && selectedGroupRule.groupCount === rule.groupCount ? 'team-check' : 'team1'"
|
|
v-for="(rule, rIndex) in currentItem.productGroupBuyPrices" :key="rIndex"
|
|
@tap="selectGroupRule(rule)">
|
|
<view class="team11">
|
|
¥{{parseFloat(rule.groupPrice).toFixed(2)}}
|
|
</view>
|
|
<view class="team11">
|
|
{{rule.groupCount}}人团
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="spec11">
|
|
他们都在拼
|
|
</view>
|
|
<!-- 占位假数据展示 -->
|
|
<view class="">
|
|
<view class="goods-center">
|
|
<view class="list-right">
|
|
<view class="list-right-img">
|
|
<img src="https://jewel-shop.oss-cn-beijing.aliyuncs.com/94f91382e76c4f289d53fbf858e8732b.png"
|
|
alt="" />
|
|
<view class="list-weipincheng">+</view>
|
|
</view>
|
|
<view class="list-right-cha">
|
|
<view class="cha11">
|
|
不限拼
|
|
</view>
|
|
<view class="">
|
|
差<text style="color: red;">1人</text>拼成
|
|
</view>
|
|
</view>
|
|
<view class="list-right-price">
|
|
去凑单
|
|
</view>
|
|
</view>
|
|
<view class="list-btn" @tap="submitPintuan">
|
|
去拼单
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
<view style="width: 100%;height: 160rpx;"></view>
|
|
</scroll-view>
|
|
<view class="bottom" style="padding-bottom: 20px;height: 80px;z-index: 10;">
|
|
<view v-if="isPintuan" class="pintuan1">
|
|
<view class="pintuan2" style="border-bottom-left-radius: 50px;border-top-left-radius: 50px;" @tap="submitPintuan(true)">
|
|
面对面团
|
|
</view>
|
|
<view class="pintuan2" style="background: rgba(0, 35, 28, 1);border-bottom-right-radius: 50px;border-top-right-radius: 50px;color: rgba(166, 255, 234, 1);" @tap="submitPintuan(false)">
|
|
拼团购买¥{{selectedGroupRule && selectedGroupRule.groupPrice ? parseFloat(selectedGroupRule.groupPrice).toFixed(2) : '0.00'}}
|
|
</view>
|
|
</view>
|
|
<view v-else class="pintuan0" @tap="submitAddToCart">
|
|
加入购物车
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</uni-popup>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
data() {
|
|
return {
|
|
loadStatus: 'more',
|
|
type:'',
|
|
shopId:'',
|
|
shopItem:{},
|
|
productId:'',
|
|
productItem:[],
|
|
cartItems: [],
|
|
currentItem: {},
|
|
parsedSpecs: [],
|
|
selectedGroupRule: {},
|
|
pageNum:1,
|
|
total:1,
|
|
// 导航栏高度(用于sticky top偏移)
|
|
navBarHeight: 0,
|
|
// 分类栏距离页面顶部的距离(用于上滑检测)
|
|
menuListOffsetTop: 0,
|
|
lastScrollTop: 0,
|
|
// 防止切换分类之后onPageScroll闪回的标志
|
|
isSwitching: false,
|
|
searchForm:{
|
|
shopId:'',
|
|
delFlag: 1,
|
|
pageNum: 1,
|
|
pageSize: '10',
|
|
categoryId:''
|
|
},
|
|
menuButtonInfo: {},
|
|
isPintuan:true,
|
|
menuList:[{
|
|
categoryName:'猜你喜欢',
|
|
id:'',
|
|
checked:true
|
|
}]
|
|
}
|
|
},
|
|
components: {
|
|
|
|
},
|
|
computed: {
|
|
cartTotalCount() {
|
|
return this.cartItems.reduce((acc, curr) => acc + curr.quantity, 0);
|
|
},
|
|
cartTotalPrice() {
|
|
return this.cartItems.reduce((acc, curr) => acc + (curr.quantity * curr.price), 0).toFixed(2);
|
|
}
|
|
},
|
|
filters: {
|
|
sliceMsg(val) {
|
|
var name = ''
|
|
if (typeof(val) == 'string') {
|
|
let newObj = JSON.parse(val)
|
|
for (let as in newObj) {
|
|
name = newObj[as].specPrice
|
|
}
|
|
}
|
|
return name;
|
|
},
|
|
sliceMsg1(val) {
|
|
var name = '正在有'
|
|
let aa = Math.floor(Math.random() * (15 - 5 + 1)) + 1;
|
|
name+=aa+'人下单'
|
|
return name;
|
|
},
|
|
slicePrice(val){
|
|
let begin = ''
|
|
if(val != null){
|
|
begin = val[0].groupPrice
|
|
for(let i = 0;i < val.length;i++){
|
|
if(val[i].groupPrice < begin){
|
|
begin = val[i].groupPrice
|
|
}
|
|
}
|
|
}
|
|
return begin;
|
|
}
|
|
},
|
|
onPageScroll(e) {
|
|
const scrollTop = e.scrollTop;
|
|
const isScrollingUp = scrollTop < this.lastScrollTop;
|
|
// 向上滑到靠近页面顶部时(背景头图区域),切换到上一个分类
|
|
// 门槛用 80px:用户需要明确地滑回头部较大区域,避免误触发
|
|
if (isScrollingUp && scrollTop < 80 && !this.isSwitching) {
|
|
const currIdx = this.menuList.findIndex(m => m.checked);
|
|
if (currIdx > 0) {
|
|
this._switchCategory(currIdx - 1);
|
|
}
|
|
}
|
|
this.lastScrollTop = scrollTop;
|
|
},
|
|
onReachBottom() {
|
|
// 当前分类还有更多页时,继续加载
|
|
if (this.searchForm.pageNum < this.total) {
|
|
this.searchForm.pageNum++;
|
|
this.getProduct(this.searchForm.categoryId);
|
|
return;
|
|
}
|
|
// 当前分类已是最后一页,自动切换到下一分类
|
|
const currIdx = this.menuList.findIndex(m => m.checked);
|
|
if (currIdx !== -1 && currIdx < this.menuList.length - 1) {
|
|
this._switchCategory(currIdx + 1);
|
|
}
|
|
},
|
|
onLoad(option) {
|
|
this.type = option.type;
|
|
if (this.type == 'shop') {
|
|
this.shopItem = JSON.parse(option.item);
|
|
} else {
|
|
this.productItem = JSON.parse(option.item);
|
|
}
|
|
this.getCategory(this.shopItem.id);
|
|
this.getProduct('');
|
|
},
|
|
onShow() {
|
|
this.menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
|
// 计算导航栏高度用于sticky offset:statusBarHeight + 44px内容区
|
|
const info = uni.getSystemInfoSync();
|
|
this.navBarHeight = info.statusBarHeight + 40;
|
|
},
|
|
onReady() {
|
|
// 记录分类栏相对页面的偏移量,用于上滑检测
|
|
setTimeout(() => {
|
|
const query = uni.createSelectorQuery().in(this);
|
|
query.select('#menuList').boundingClientRect(rect => {
|
|
if (rect) this.menuListOffsetTop = rect.top + this.lastScrollTop;
|
|
}).exec();
|
|
}, 500);
|
|
},
|
|
methods: {
|
|
getProduct(categoryId) {
|
|
let that = this;
|
|
this.loadStatus = 'loading';
|
|
this.searchForm.shopId = this.shopItem.id;
|
|
this.searchForm.categoryId = categoryId;
|
|
that.tui.request("/app/product/getShareList", "POST", this.searchForm, false, false).then((res) => {
|
|
that.loadStatus = 'nomore';
|
|
if (res.code == 200) {
|
|
if (that.searchForm.pageNum == 1) {
|
|
that.productItem = res.result.records;
|
|
} else {
|
|
that.productItem = [...that.productItem, ...res.result.records];
|
|
}
|
|
console.log(res.result.records)
|
|
that.total = res.result.pages; // pages = 总页数
|
|
that.pageNum = that.searchForm.pageNum;
|
|
// 当前分类没有商品,自动跳过到下一个分类
|
|
// 注意:这里不能用isSwitching拦戚,因为_switchCategory本身已置 isSwitching=true
|
|
if (res.result.records.length === 0) {
|
|
const currIdx = that.menuList.findIndex(m => m.checked);
|
|
if (currIdx !== -1 && currIdx < that.menuList.length - 1) {
|
|
// 重置锁再跳过,防止连锁导致永远跳不过
|
|
that.isSwitching = false;
|
|
that._switchCategory(currIdx + 1);
|
|
}
|
|
}
|
|
that.$forceUpdate();
|
|
} else {
|
|
that.tui.toast(res.message);
|
|
return;
|
|
}
|
|
uni.hideLoading();
|
|
}).catch((res) => {});
|
|
},
|
|
getCategory(id){
|
|
let that = this
|
|
that.tui.request("/app/productCategory/list", "GET", {
|
|
shopId:id
|
|
}, false, true).then((res) => {
|
|
if (res.code == 200) {
|
|
if(res.result.length >0){
|
|
for(let i = 0;i<res.result.length;i++){
|
|
res.result[i].checked = false
|
|
that.menuList.push(res.result[i])
|
|
}
|
|
}
|
|
that.$forceUpdate()
|
|
} else {
|
|
that.tui.toast(res.message)
|
|
return
|
|
}
|
|
uni.hideLoading()
|
|
}).catch((res) => {})
|
|
},
|
|
// 内部切换方法:带isSwitching保护,防止程序化滚动期间闪回
|
|
_switchCategory(index) {
|
|
if (this.isSwitching) return;
|
|
this.isSwitching = true;
|
|
this.checkTab(index);
|
|
// 400ms后解除锁(动画200ms,预留200ms缓冲)
|
|
setTimeout(() => { this.isSwitching = false; }, 400);
|
|
},
|
|
checkTab(index) {
|
|
for (let i = 0; i < this.menuList.length; i++) {
|
|
this.menuList[i].checked = (i === index);
|
|
}
|
|
// 重置分页
|
|
this.searchForm.pageNum = 1;
|
|
this.pageNum = 1;
|
|
this.total = 1;
|
|
this.productItem = [];
|
|
this.getProduct(this.menuList[index].id);
|
|
// 滚动到正确位置:分类栏刚好吸顶在nav-bar下方
|
|
// menuListOffsetTop - navBarHeight 使分类栏正好在sticky位置,首条商品可见
|
|
const target = this.menuListOffsetTop - this.navBarHeight;
|
|
uni.pageScrollTo({ scrollTop: target > 0 ? target : 0, duration: 200 });
|
|
},
|
|
openPopup(type,index,item){
|
|
if(type == 'car'){
|
|
this.$refs.carPopup.open('bottom')
|
|
}else if(type == 'xiadan'){
|
|
this.currentItem = item;
|
|
// Parse specifications
|
|
this.parsedSpecs = [];
|
|
if(item.attributeList && item.attributeList !== '{}') {
|
|
try {
|
|
let attrs = typeof item.attributeList === 'string' ? JSON.parse(item.attributeList) : item.attributeList;
|
|
for(let key in attrs) {
|
|
if(attrs[key] && attrs[key].title && attrs[key].title.length > 0) {
|
|
this.parsedSpecs.push({
|
|
name: key,
|
|
options: attrs[key].title,
|
|
selected: attrs[key].title[0] // Default select first
|
|
});
|
|
}
|
|
}
|
|
} catch(e) {
|
|
console.error("Failed to parse specifications", e);
|
|
}
|
|
}
|
|
|
|
if(index == 'pintuan'){
|
|
this.isPintuan = true;
|
|
// Set default group rule
|
|
if(item.productGroupBuyPrices && item.productGroupBuyPrices.length > 0) {
|
|
this.selectedGroupRule = item.productGroupBuyPrices[0];
|
|
} else {
|
|
this.selectedGroupRule = {};
|
|
}
|
|
this.$refs.pintuanPopup.open('bottom');
|
|
} else {
|
|
this.isPintuan = false;
|
|
// If solo buy and NO specs, add immediately to cart
|
|
if(this.parsedSpecs.length === 0) {
|
|
this.addToCart(item, null);
|
|
uni.showToast({ title: '已加入购物车', icon: 'none' });
|
|
} else {
|
|
// Open popup to select specs
|
|
this.$refs.pintuanPopup.open('bottom');
|
|
}
|
|
}
|
|
}
|
|
},
|
|
selectSpec(sIndex, option) {
|
|
this.parsedSpecs[sIndex].selected = option;
|
|
this.$forceUpdate();
|
|
},
|
|
selectGroupRule(rule) {
|
|
this.selectedGroupRule = rule;
|
|
},
|
|
submitAddToCart() {
|
|
let specChoices = {};
|
|
for (let spec of this.parsedSpecs) {
|
|
specChoices[spec.name] = spec.selected;
|
|
}
|
|
this.addToCart(this.currentItem, specChoices);
|
|
uni.showToast({ title: '已加入购物车', icon: 'none' });
|
|
this.$refs.pintuanPopup.close();
|
|
},
|
|
submitPintuan(isFaceToFace) {
|
|
let specChoices = {};
|
|
for (let spec of this.parsedSpecs) {
|
|
specChoices[spec.name] = spec.selected;
|
|
}
|
|
let packageFee = parseFloat(this.currentItem.lunchBox || 0);
|
|
// Pack data for checkout
|
|
let goData = {
|
|
item: this.currentItem,
|
|
groupRule: this.selectedGroupRule,
|
|
specs: specChoices,
|
|
orderType: 2, // 2 indicates Group Buy
|
|
isFaceToFace: isFaceToFace || false
|
|
};
|
|
// Directly navigate to checkout
|
|
uni.navigateTo({
|
|
url: '/package1/buyFood/buyFood?item=' + encodeURIComponent(JSON.stringify(goData)) + '&shopItem=' + encodeURIComponent(JSON.stringify(this.shopItem)) + '&packageFee=' + packageFee
|
|
});
|
|
this.$refs.pintuanPopup.close();
|
|
},
|
|
addToCart(item, specs) {
|
|
let specStr = specs ? JSON.stringify(specs) : '';
|
|
let cartId = item.id + '_' + specStr;
|
|
let existingItem = this.cartItems.find(c => c.cartId === cartId);
|
|
if(existingItem) {
|
|
existingItem.quantity++;
|
|
} else {
|
|
let priceToUse = 0;
|
|
if(item.attributeListPrice) {
|
|
try {
|
|
let pObj = typeof item.attributeListPrice === 'string' ? JSON.parse(item.attributeListPrice) : item.attributeListPrice;
|
|
if(Array.isArray(pObj) && pObj.length > 0) {
|
|
priceToUse = parseFloat(pObj[0].specPrice);
|
|
} else {
|
|
for(let k in pObj) { priceToUse = parseFloat(pObj[k].specPrice); break; }
|
|
}
|
|
} catch(e){}
|
|
}
|
|
this.cartItems.push({
|
|
cartId: cartId,
|
|
item: item,
|
|
specs: specs,
|
|
quantity: 1,
|
|
price: priceToUse.toFixed(2)
|
|
});
|
|
}
|
|
},
|
|
adjustCart(cartId, delta) {
|
|
let index = this.cartItems.findIndex(c => c.cartId === cartId);
|
|
if(index !== -1) {
|
|
let newQty = this.cartItems[index].quantity + delta;
|
|
if(newQty <= 0) {
|
|
this.cartItems.splice(index, 1);
|
|
} else {
|
|
this.cartItems[index].quantity = newQty;
|
|
}
|
|
}
|
|
},
|
|
getSpecDisplayString(specs) {
|
|
if(!specs) return '';
|
|
let arr = [];
|
|
for(let k in specs) { arr.push(specs[k]); }
|
|
return arr.join(',');
|
|
},
|
|
submitCartCheckout() {
|
|
if(this.cartItems.length === 0) {
|
|
this.$refs.warnPopup.open()
|
|
return;
|
|
}
|
|
|
|
let totalPackageFee = 0;
|
|
for (let cartItem of this.cartItems) {
|
|
totalPackageFee += parseFloat(cartItem.item.lunchBox || 0) * cartItem.quantity;
|
|
}
|
|
|
|
// 类似普通订单结算逻辑
|
|
uni.navigateTo({
|
|
url: '/package1/buyFood/buyFood?cart=' + encodeURIComponent(JSON.stringify(this.cartItems)) + '&shopItem=' + encodeURIComponent(JSON.stringify(this.shopItem)) + '&packageFee=' + totalPackageFee
|
|
});
|
|
},
|
|
goDetail(type) {
|
|
if (type == 'goodsDetail') {
|
|
uni.navigateTo({
|
|
url: '/package1/goods/goodsDetail'
|
|
})
|
|
}else if(type == 'shopDetail'){
|
|
uni.navigateTo({
|
|
url: '/package1/group/groupBuyDetail?item=' + JSON.stringify(this.shopItem)
|
|
})
|
|
}else if(type == 'shopEvaluate'){
|
|
uni.navigateTo({
|
|
url: '/package1/group/shopEvaluate?item=' + JSON.stringify(this.shopItem)
|
|
})
|
|
}
|
|
},
|
|
back() {
|
|
uni.navigateBack()
|
|
}
|
|
}
|
|
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
page {
|
|
width: 100%;
|
|
height: 100%;
|
|
font-size: 24rpx;
|
|
background: #F5F8F5;
|
|
color: #00231C;
|
|
}
|
|
|
|
.page1 {
|
|
width: 100%;
|
|
height: 100%;
|
|
font-size: 24rpx;
|
|
position: relative;
|
|
}
|
|
|
|
/* 顶部背景图随页面滚动(不固定) */
|
|
.title {
|
|
background: url('https://jewel-shop.oss-cn-beijing.aliyuncs.com/8bc15960c2dc40268e295d6dd23aecce.png') no-repeat;
|
|
width: 100%;
|
|
height: 340rpx;
|
|
background-size: 100% 100%;
|
|
}
|
|
|
|
/* 固定在顶部的导航栏,覆盖在背景图上 */
|
|
.nav-bar {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
display: flex;
|
|
align-items: center;
|
|
z-index: 100;
|
|
padding: 8px 12px;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.title-search {
|
|
display: flex;
|
|
flex: 1;
|
|
background: rgba(255,255,255,0.9);
|
|
height: 54rpx;
|
|
margin-left: 20rpx;
|
|
border-radius: 54rpx;
|
|
|
|
input {
|
|
height: 54rpx;
|
|
line-height: 54rpx;
|
|
}
|
|
}
|
|
|
|
.back-btn {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 60rpx;
|
|
height: 60rpx;
|
|
border-radius: 50%;
|
|
}
|
|
|
|
/* content 上移,叠在背景图下方,减少头部空白 */
|
|
.content {
|
|
margin-top: -150rpx;
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
|
|
.shop-img {
|
|
width: 160rpx;
|
|
height: 160rpx;
|
|
position: relative;
|
|
|
|
img {
|
|
width: 100%;
|
|
background-size: 100%;
|
|
height: 100%;
|
|
border-radius: 10px;
|
|
}
|
|
}
|
|
|
|
.shop-top {
|
|
display: flex;
|
|
}
|
|
|
|
.shop-content {
|
|
flex: 1;
|
|
padding-left: 20rpx;
|
|
|
|
}
|
|
|
|
.shop-name {
|
|
font-size: 32rpx;
|
|
font-weight: 900;
|
|
}
|
|
|
|
.shop-content-center {
|
|
display: flex;
|
|
margin: 20rpx 0;
|
|
}
|
|
|
|
.shop-rate {
|
|
background: rgba(249, 212, 157, 0.34);
|
|
height: 40rpx;
|
|
display: flex;
|
|
border-radius: 20rpx;
|
|
padding: 0 5px 0 0;
|
|
}
|
|
|
|
.shop-rate-num {
|
|
width: 50rpx;
|
|
height: 100%;
|
|
text-align: center;
|
|
background: linear-gradient(90deg, rgba(255, 77, 0, 1), rgba(255, 184, 84, 1));
|
|
color: #fff;
|
|
line-height: 40rpx;
|
|
font-size: 22rpx;
|
|
border-bottom-left-radius: 20rpx;
|
|
border-top-left-radius: 20rpx;
|
|
border-bottom-right-radius: 10rpx;
|
|
border-top-right-radius: 10rpx;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.shop-tag {
|
|
flex: 1;
|
|
line-height: 40rpx;
|
|
text-align: right;
|
|
}
|
|
|
|
.shop-tag1 {
|
|
flex: 1;
|
|
line-height: 40rpx;
|
|
text-align: left;
|
|
}
|
|
|
|
.shop-content-bottom {
|
|
display: flex;
|
|
}
|
|
|
|
.shop-deal {
|
|
flex: 1;
|
|
}
|
|
|
|
.shop-bottom {
|
|
margin-top: 20rpx;
|
|
line-height: 40rpx;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.pintuan {
|
|
background: #fff;
|
|
padding: 20rpx;
|
|
width: 95%;
|
|
margin: 0 auto;
|
|
border-radius: 20rpx;
|
|
}
|
|
|
|
.pintuan-left {
|
|
display: flex;
|
|
padding: 20rpx;
|
|
flex: 1;
|
|
}
|
|
|
|
.pintuan-left-img {
|
|
width: 90rpx;
|
|
height: 90rpx;
|
|
|
|
img {
|
|
width: 100%;
|
|
height: 100%;
|
|
background-size: 100%;
|
|
border-radius: 10px;
|
|
}
|
|
}
|
|
|
|
.pintuan-left-box {
|
|
flex: 1;
|
|
padding-left: 20rpx;
|
|
}
|
|
|
|
.pintuan-right {
|
|
display: flex;
|
|
margin-top: 50rpx;
|
|
width: 30%;
|
|
}
|
|
|
|
.pintuan-right-img {
|
|
height: 40rpx;
|
|
display: flex;
|
|
|
|
img {
|
|
width: 40rpx;
|
|
height: 40rpx;
|
|
z-index: 98;
|
|
background-size: 100%;
|
|
}
|
|
}
|
|
|
|
.pintuan-left-name {
|
|
font-weight: 700;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
|
|
.pintuan-left-price {
|
|
display: inline;
|
|
padding: 10rpx;
|
|
background: rgba(255, 57, 57, 0.1);
|
|
border-radius: 10rpx;
|
|
}
|
|
|
|
.weipincheng {
|
|
width: 40rpx;
|
|
height: 40rpx;
|
|
background: rgba(166, 255, 234, 1);
|
|
border-radius: 40rpx;
|
|
text-align: center;
|
|
font-size: 28rpx;
|
|
font-weight: 700;
|
|
margin-left: -6rpx;
|
|
z-index: 97;
|
|
}
|
|
|
|
.pintuan-right-cha {}
|
|
|
|
.goods-member{
|
|
padding: 10px 0;
|
|
margin-top: 10px;
|
|
border-radius: 10px;
|
|
background: #fff;
|
|
}
|
|
|
|
.goods-list {
|
|
width: 95%;
|
|
height: auto;
|
|
border-radius: 20rpx;
|
|
margin: 0 auto 20rpx;
|
|
/* padding-top等于分类栏高度,防止商品内容被sticky栏遮住 */
|
|
padding-top: 10px;
|
|
}
|
|
|
|
.goods-top {
|
|
padding: 20rpx 0;
|
|
display: flex;
|
|
}
|
|
|
|
.goods-content {
|
|
flex: 1;
|
|
padding-left: 20rpx;
|
|
}
|
|
|
|
.goods-name {
|
|
font-size: 32rpx;
|
|
font-weight: 900;
|
|
}
|
|
|
|
.goods-content-center {
|
|
display: flex;
|
|
margin: 16rpx 0;
|
|
}
|
|
|
|
.goods-rate {
|
|
background: rgba(249, 212, 157, 0.34);
|
|
height: 40rpx;
|
|
display: flex;
|
|
border-radius: 20rpx;
|
|
}
|
|
|
|
.goods-rate-num {
|
|
width: 50rpx;
|
|
height: 100%;
|
|
text-align: center;
|
|
background: linear-gradient(90deg, rgba(255, 77, 0, 1), rgba(255, 184, 84, 1));
|
|
color: #fff;
|
|
line-height: 40rpx;
|
|
font-size: 22rpx;
|
|
border-bottom-left-radius: 20rpx;
|
|
border-top-left-radius: 20rpx;
|
|
border-bottom-right-radius: 10rpx;
|
|
border-top-right-radius: 10rpx;
|
|
}
|
|
|
|
.goods-deal1 {
|
|
width: 60%;
|
|
}
|
|
|
|
.goods-tag {
|
|
display: flex;
|
|
margin: 0;
|
|
width: 40%;
|
|
}
|
|
|
|
.goods-content-bottom {
|
|
display: flex;
|
|
}
|
|
|
|
.goods-deal {
|
|
flex: 1;
|
|
}
|
|
|
|
.goods-img {
|
|
width: 160rpx;
|
|
height: 160rpx;
|
|
position: relative;
|
|
|
|
img {
|
|
width: 100%;
|
|
background-size: 100%;
|
|
height: 100%;
|
|
}
|
|
}
|
|
|
|
.goods-bottom {
|
|
display: flex;
|
|
width: 95%;
|
|
margin: 20rpx auto;
|
|
height: 70rpx;
|
|
line-height: 70rpx;
|
|
}
|
|
|
|
.goods-btn {
|
|
background: linear-gradient(90deg, rgba(227, 255, 150, 1), rgba(166, 255, 234, 1));
|
|
width: 47%;
|
|
text-align: center;
|
|
font-size: 28rpx;
|
|
font-weight: 600;
|
|
border-radius: 20rpx;
|
|
}
|
|
|
|
.bottom {
|
|
position: fixed;
|
|
bottom: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
display: flex;
|
|
background: #fff;
|
|
z-index: 98;
|
|
box-shadow: 0 -5px 5px rgba(0, 0, 0, 0.3);
|
|
}
|
|
|
|
.bottom-left {
|
|
flex: 1;
|
|
display: flex;
|
|
padding: 20rpx;
|
|
|
|
img {
|
|
width: 60rpx;
|
|
height: 80rpx;
|
|
background-size: 100%;
|
|
}
|
|
}
|
|
|
|
.bottom-price{
|
|
margin-left: 40rpx;
|
|
font-size: 40rpx;
|
|
color: red;
|
|
font-weight: 700;
|
|
line-height: 110rpx;
|
|
}
|
|
|
|
.bottom-right {
|
|
padding-top: 20rpx;
|
|
flex: 1;
|
|
|
|
img {
|
|
width: 360rpx;
|
|
height: 100rpx;
|
|
background-size: 100%;
|
|
}
|
|
}
|
|
.bottom-dot{
|
|
position: absolute;
|
|
top: 0;
|
|
right: -20rpx;
|
|
background: red;
|
|
color: #fff;
|
|
width: 32rpx;
|
|
height: 32rpx;
|
|
border-radius: 32rpx;
|
|
text-align: center;
|
|
line-height: 32rpx;
|
|
}
|
|
|
|
.car-content{
|
|
position: relative;
|
|
height: 600px;
|
|
width: 100%;
|
|
border-top-left-radius: 10px;
|
|
border-top-right-radius: 10px;
|
|
padding: 10px;
|
|
overflow: scroll;
|
|
}
|
|
|
|
.car-close{
|
|
width: 30px;
|
|
height: 30px;
|
|
position: absolute;
|
|
top: -40px;
|
|
right: 10px;
|
|
}
|
|
|
|
.car-title{
|
|
height: 48px;
|
|
line-height: 30px;
|
|
margin: 0 auto;
|
|
font-size: 14px;
|
|
font-weight: 700;
|
|
}
|
|
.num-plus{
|
|
width: 28px;
|
|
height: 28px;
|
|
font-size: 18px;
|
|
text-align: center;
|
|
font-weight: 700;
|
|
line-height: 24px;
|
|
border-radius: 5px;
|
|
|
|
background: rgba(0, 35, 28, 1);
|
|
color: rgba(166, 255, 234, 1);
|
|
|
|
}
|
|
.num{
|
|
width: 40px;
|
|
height: 28px;
|
|
text-align: center;
|
|
line-height: 28px;
|
|
font-size: 14px;
|
|
}
|
|
.goods-num{
|
|
display: flex;
|
|
height: 28px;
|
|
flex: 1;
|
|
margin-left: 20px;
|
|
}
|
|
.pintuan0{
|
|
width: 90%;
|
|
height: 50px;
|
|
border-radius: 50px;
|
|
background: linear-gradient(90deg, rgba(227, 255, 150, 1), rgba(166, 255, 234, 1));
|
|
text-align: center;
|
|
font-size: 13px;
|
|
font-weight: 700;
|
|
line-height: 50px;
|
|
margin: auto;
|
|
}
|
|
.pintuan1{
|
|
width: 90%;
|
|
height: 50px;
|
|
line-height: 50px;
|
|
display: flex;
|
|
text-align: center;
|
|
margin: auto;
|
|
font-size: 13px;
|
|
font-weight: 700;
|
|
}
|
|
.pintuan2{
|
|
flex: 1;
|
|
background: linear-gradient(90deg, rgba(227, 255, 150, 1), rgba(166, 255, 234, 1));
|
|
}
|
|
.spec11{
|
|
height: 48px;
|
|
line-height: 48px;
|
|
font-size: 14px;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.spec222{
|
|
display: inline-block;
|
|
padding: 0 10px;
|
|
background: #eee;
|
|
color: #777;
|
|
height: 36px;
|
|
line-height: 36px;
|
|
text-align: center;
|
|
border-radius: 10px;
|
|
margin-right: 10px;
|
|
}
|
|
.spec-check{
|
|
display: inline-block;
|
|
padding: 0 10px;
|
|
background: rgba(166, 255, 234, 1);
|
|
height: 36px;
|
|
line-height: 36px;
|
|
text-align: center;
|
|
border-radius: 10px;
|
|
margin-right: 10px;
|
|
}
|
|
.team1{
|
|
width: 77px;
|
|
height: 83px;
|
|
background: #eee;
|
|
border-radius: 10px;
|
|
font-size: 13px;
|
|
text-align: center;
|
|
line-height: 30px;
|
|
float: left;
|
|
margin-right: 20px;
|
|
}
|
|
.team-check{
|
|
width: 77px;
|
|
height: 83px;
|
|
background: rgba(166, 255, 234, 1);
|
|
border-radius: 10px;
|
|
font-size: 13px;
|
|
text-align: center;
|
|
line-height: 30px;
|
|
float: left;
|
|
margin-right: 20px;
|
|
}
|
|
.team11{
|
|
margin-top: 10px;
|
|
}
|
|
.goods-team{
|
|
width: 100%;
|
|
min-height: 90px;
|
|
}
|
|
.list-right {
|
|
display: flex;
|
|
width: 100%;
|
|
padding: 15px 0 15px 15px;
|
|
flex: 1;
|
|
}
|
|
|
|
.list-right-img {
|
|
height: 40px;
|
|
display: flex;
|
|
|
|
img {
|
|
width: 40px;
|
|
height: 40px;
|
|
z-index: 98;
|
|
background-size: 100%;
|
|
}
|
|
}
|
|
|
|
.list-weipincheng {
|
|
width: 40px;
|
|
height: 40px;
|
|
background: #a6ffea;
|
|
border-radius: 40px;
|
|
text-align: center;
|
|
font-size: 28rpx;
|
|
font-weight: 700;
|
|
margin-left: -6rpx;
|
|
z-index: 97;
|
|
line-height: 40px;
|
|
}
|
|
|
|
.goods-center {
|
|
width: 100%;
|
|
margin: 0 auto 10px;
|
|
background: #f5f8f5;
|
|
height: 70px;
|
|
border-radius: 10px;
|
|
overflow: hidden;
|
|
display: flex;
|
|
}
|
|
|
|
.list-right-cha {
|
|
margin-left: 10px;
|
|
}
|
|
.list-right-price{
|
|
flex: 1;
|
|
text-align: right;
|
|
line-height: 40px;
|
|
color: red;
|
|
font-size: 14px;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.list-btn {
|
|
background: linear-gradient(90deg, #e3ff96, #a6ffea);
|
|
width: 130rpx;
|
|
text-align: center;
|
|
font-size: 28rpx;
|
|
font-weight: 600;
|
|
border-radius: 30px;
|
|
height: 30px;
|
|
line-height: 30px;
|
|
margin: 20px;
|
|
}
|
|
.cha11{
|
|
font-size: 11px;
|
|
background: rgba(255, 57, 57, 0.2);
|
|
color: red;
|
|
display: inline-block;
|
|
padding: 3px;
|
|
border-radius: 5px;
|
|
margin-bottom: 5px;
|
|
}
|
|
.menu-list{
|
|
height: 45px;
|
|
width: 100%;
|
|
overflow-x: scroll;
|
|
display: flex;
|
|
overflow-y: hidden;
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 90;
|
|
background: #F5F8F5;
|
|
align-items: center;
|
|
padding-bottom: 4px;
|
|
}
|
|
.checked-img{
|
|
width: 90px;
|
|
height: 10px;
|
|
position: absolute;
|
|
bottom: 0;
|
|
left: 0;
|
|
}
|
|
|
|
.menu1{
|
|
width: 90px;
|
|
height: 35px;
|
|
position: relative;
|
|
margin-right: 10px;
|
|
line-height: 35px;
|
|
}
|
|
</style>
|