Commit 0319e33e5d678e0972c59e1d7a1a75dbea422244

Authored by pengye
1 parent 330fb60e

排菜套餐页面

// pack-cookbook/pages/comboBuy.js
import util from '../../utils/util';
import App from '../../utils/api';
Page({
/**
* 页面的初始数据
*/
data: {
sid: '',
details: {}, //上页面传入的套餐信息
seller: {}, //商家信息
couponArr: [], //本套餐可用的优惠券列表
finalList: [], //勾选的券列表
planPrice: '', //套餐价格
memberPrice: '', //菜品原价
discountPrice: '', //优惠金额
actualPrice: '', //抵扣后价格
couponSwitch: true, //本单使用优惠券开关
dataStr: Date.now() * 1 / 1000,
},
couponModal: '',
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
console.log('comboBuy options----', options);
this.couponModal = this.selectComponent("#couponModal");
let details = {};
if (options.details) {
details = JSON.parse(options.details);
}
let planPrice = details.plan_price || '';
let memberPrice = details.member_price || details.menu_price || '';
if (planPrice !== '') {
planPrice = parseFloat(planPrice).toFixed(2);
}
if (memberPrice !== '') {
memberPrice = parseFloat(memberPrice).toFixed(2);
}
this.setData({
details,
planPrice,
memberPrice,
actualPrice: planPrice || '0.00',
})
let sid = (details.seller && details.seller.sid) || options.sid || '';
if (sid) {
this.setData({
sid
})
if (details.seller) {
this.setData({
seller: details.seller
})
}
this.getSellerDetailFun(sid)
}
},
// 获取商家名称、照片
getSellerDetailFun(sid) {
App.Customer.GetSellerDetail({
sid
}).then(res => {
let data = res.data;
this.setData({
seller: {
seller_image: data.seller_image,
sellername: data.sellername,
sid: data.id
}
})
this.getCoupon()
})
},
// 获取所有优惠券,只展示本套餐可用的
getCoupon() {
if (!this.data.sid) return;
App.Activity.ActivityListByOpenid({
sellerid: this.data.sid
}).then(res => {
if (res.ret == 200 && res.data && res.data.length > 0) {
let list = res.data;
list.forEach(detail => {
detail.exp_date = detail.exp_date ? util.determine(detail.exp_date) : '';
detail.arule = detail.arule ? util.determine(detail.arule) : '';
detail.expiration_date = detail.expiration_date ? util.determine(detail.expiration_date) : '';
detail.aexpiration = detail.aexpiration ? util.determine(detail.aexpiration) : '';
if (detail.arule) {
detail.accumulationShow = detail.arule.is_accumulation
}
if (detail.exp_date && detail.exp_date.week_data) {
let mor = this.hasConsecutiveSelect(detail.exp_date.week_data, '1').rArr.join('、')
let noon = this.hasConsecutiveSelect(detail.exp_date.week_data, '2').rArr.join('、')
let nig = this.hasConsecutiveSelect(detail.exp_date.week_data, '3').rArr.join('、')
if (mor) mor = '早餐:' + mor
if (noon) noon = '午餐:' + noon
if (nig) nig = '晚餐:' + nig
detail.morText = mor;
detail.noonText = noon;
detail.nigText = nig;
}
detail.checked = false;
detail.showCpupon = '0';
detail.cdate = detail.cdate * 1;
detail.useStime = '';
detail.useEtime = '';
let condition = detail.aexpiration || {};
if (condition.valid_forever === '0' && condition.stime && condition.etime) {
detail.useStime = condition.stime;
detail.useEtime = condition.etime;
}
if (condition.valid_forever === '1') {
detail.foreverText = '永久有效';
}
if (condition.valid_forever === '0' && condition.today) {
let obj = this.setTimeRange(detail.cdate, 0, parseInt(condition.today) - 1);
detail.useStime = obj.useStime;
detail.useEtime = obj.useEtime;
}
if (condition.valid_forever === '0' && condition.tomorrow) {
let obj = this.setTimeRange(detail.cdate, 1, condition.tomorrow * 1);
detail.useStime = obj.useStime;
detail.useEtime = obj.useEtime;
}
if (condition.valid_forever === '0' && condition.sday && condition.eday) {
let obj = this.setTimeRange(detail.cdate, parseInt(condition.sday) - 1, parseInt(condition.eday) - 1);
detail.useStime = obj.useStime;
detail.useEtime = obj.useEtime;
}
if ((detail.useStime > 0 && detail.useEtime > 0) || condition.valid_forever === '1') {
detail.endDateStr = condition.valid_forever == '1' ? '永久有效' : (util.unixtoTime(detail.useStime, 'YYYY-MM-DD') + '至' + util.unixtoTime(detail.useEtime, 'YYYY-MM-DD'));
}
})
// 过滤已过期的券
list = list.filter(item => {
return (this.data.dataStr < (item.useEtime * 1) || item.aexpiration.valid_forever == '1');
})
// 判断券是否可用:满足套餐价格门槛的才显示
let planPrice = parseFloat(this.data.planPrice) || 0;
list = list.filter(item => {
let desc = parseFloat(item.desc) || 0;
return desc == 0 || planPrice >= desc;
})
// 相同aid的券合并成一张,用加减号选择张数
let couponGroup = {};
let couponList = [];
list.forEach(item => {
let key = item.aid ? item.aid : item.activity_id
if (couponGroup[key]) {
couponGroup[key].num = (couponGroup[key].num * 1) + 1
couponGroup[key].activityIds.push(item.activity_id)
} else {
item.num = 1
item.checkedNum = 0
item.groupKey = key
item.activityIds = [item.activity_id]
couponGroup[key] = item
couponList.push(item)
}
})
list = couponList
// 单次使用数量限制,0表示不限制,默认0
list.forEach(item => {
let useLimit = item.single_use_limit ? (item.single_use_limit * 1) : 0
item.maxNum = (useLimit > 0 && useLimit < item.num) ? useLimit : item.num
item.showCpupon = '1'
item.canCheck = '1'
item.isOk = '1'
})
// 面额大的排在前面
list.sort((a, b) => (parseFloat(b.price) || 0) - (parseFloat(a.price) || 0))
console.log('comboBuy couponArr----', list);
this.setData({
couponArr: list
})
if (this.data.couponSwitch) {
this.colationData()
}
} else {
this.setData({
couponArr: [],
discountPrice: '',
actualPrice: this.data.planPrice || '0.00',
})
}
})
},
// 打开优惠券弹框
showCouponModal() {
this.couponModal.showModal()
},
// 关闭优惠券弹框
closeCouponModal() {
this.couponModal.closeModal()
},
// 使用券开关
switchChange(event) {
this.setData({
couponSwitch: event.detail.value,
})
if (this.data.couponSwitch) {
this.colationData()
} else {
let list = this.data.couponArr;
list.forEach(i => {
i.checkedNum = 0;
i.showCpupon = '1';
i.canAdd = '1';
})
this.setData({
couponArr: list,
finalList: [],
discountPrice: '',
actualPrice: this.data.planPrice || '0.00',
})
}
},
// 加减号选择券的张数
changeCouponNum(e) {
let type = e.currentTarget.dataset.type;
let aid = e.currentTarget.dataset.aid;
const list = this.data.couponArr
let item = list.find(i => i.aid == aid)
if (!item) return
if (type == 'plus') {
if (item.canAdd != '1') return
item.checkedNum = (item.checkedNum * 1) + 1
}
if (type == 'minus') {
if (item.checkedNum <= 0) return
item.checkedNum = (item.checkedNum * 1) - 1
}
this.refreshCouponState()
},
// 加减号中间输入框
numInputChange(e) {
let aid = e.currentTarget.dataset.aid;
let val = (e.detail.value || '').replace(/[^\d]/g, '');
const list = this.data.couponArr
let item = list.find(i => i.aid == aid)
if (!item) return
let maxSelect = this.getMaxSelectNum(item)
let num = val === '' ? 0 : parseInt(val, 10)
if (isNaN(num)) num = 0
if (num > maxSelect) num = maxSelect
item.checkedNum = num
this.refreshCouponState()
},
// 计算某张券当前最多可以选到的张数
getMaxSelectNum(item) {
const list = this.data.couponArr
let inputValue = parseFloat(this.data.planPrice)
let descStr = 0
let val = 0
list.forEach(i => {
if (i.checkedNum > 0 && i.aid != item.aid) {
let d = parseFloat(i.desc) || 0
if (d > 0) descStr += d * i.checkedNum
val += parseFloat(i.price) * i.checkedNum
}
})
let itemDesc = parseFloat(item.desc) || 0
let itemPrice = parseFloat(item.price)
let maxSelect = item.maxNum
if (item.accumulationShow != '1' && maxSelect > 1) maxSelect = 1
if (inputValue > 0) {
if (itemDesc > 0) {
let byDesc = Math.floor((inputValue - descStr) / itemDesc)
if (byDesc < maxSelect) maxSelect = byDesc
} else {
if (descStr >= inputValue) {
maxSelect = 0
} else {
let byPrice = Math.floor((inputValue - val) / itemPrice)
if (byPrice < maxSelect) maxSelect = byPrice
}
}
}
if (maxSelect < 0) maxSelect = 0
return maxSelect
},
// 根据选择的券张数刷新券的可选状态
refreshCouponState() {
const list = this.data.couponArr
let currentCoupon = '0';
let inputValue = parseFloat(this.data.planPrice)
let val = 0;
let descStr = 0;
list.forEach(item => {
if (item.checkedNum > 0) {
val += parseFloat(item.price) * item.checkedNum
let itemDesc = parseFloat(item.desc) || 0
if (itemDesc > 0) {
descStr += itemDesc * item.checkedNum
}
if (item.accumulationShow != '1') {
currentCoupon = '2'
} else {
currentCoupon = '1'
}
}
})
if (currentCoupon == '0') {
list.forEach(item => {
if (item.canCheck == "1") {
item.showCpupon = '1';
}
})
}
if (currentCoupon == '2') {
list.map((item) => {
if (item.checkedNum > 0) {
item.showCpupon = '1'
} else {
item.showCpupon = '0'
}
})
}
if (currentCoupon == '1') {
list.forEach(item => {
if (item.checkedNum > 0 || (item.accumulationShow == "1" && parseFloat(item.price) <= (inputValue - val) && (((parseFloat(item.desc) || 0) > 0 && (inputValue - descStr) >= parseFloat(item.desc)) || ((parseFloat(item.desc) || 0) === 0 && descStr < inputValue)))) {
item.showCpupon = '1';
} else {
item.showCpupon = '0';
}
})
}
let finalList = []
list.forEach(item => {
if (item.checkedNum > 0) {
for (let k = 0; k < item.checkedNum; k++) {
finalList.push({
...item,
activity_id: item.activityIds[k]
})
}
}
})
this.updateCanAdd()
let discountPrice = 0;
finalList.forEach(i => {
discountPrice += parseFloat(i.price)
})
discountPrice = discountPrice.toFixed(2)
let actualPrice = (inputValue - discountPrice).toFixed(2)
if (parseFloat(actualPrice) < 0) actualPrice = '0.00'
this.setData({
couponArr: list,
finalList,
discountPrice: discountPrice == '0.00' ? '' : discountPrice,
actualPrice,
})
},
// 计算每张券还能不能继续加
updateCanAdd() {
const list = this.data.couponArr
let inputValue = parseFloat(this.data.planPrice)
let descStr = 0
let val = 0
list.forEach(item => {
if (item.checkedNum > 0) {
let itemDesc = parseFloat(item.desc) || 0
let itemPrice = parseFloat(item.price)
if (itemDesc > 0) descStr += itemDesc * item.checkedNum
val += itemPrice * item.checkedNum
}
})
list.forEach(item => {
item.canAdd = '0'
let maxSelect = item.accumulationShow == '1' ? item.maxNum : 1
if (item.showCpupon == '1' && item.checkedNum < maxSelect) {
let itemDesc = parseFloat(item.desc) || 0
let itemPrice = parseFloat(item.price)
if (itemDesc > 0) {
if (descStr + itemDesc <= inputValue) item.canAdd = '1'
} else {
if (descStr < inputValue && val + itemPrice <= inputValue) item.canAdd = '1'
}
}
})
},
// 点确认选择
checkCertificate() {
this.closeCouponModal()
let list = this.data.couponArr;
let price = 0;
list.forEach(i => {
if (i.checkedNum > 0) {
price += parseFloat(i.price) * i.checkedNum
}
})
let planPrice = parseFloat(this.data.planPrice) || 0;
let actualPrice = (planPrice - price).toFixed(2)
if (parseFloat(actualPrice) < 0) actualPrice = '0.00'
price = price.toFixed(2)
this.setData({
couponSwitch: price != '0.00',
discountPrice: price == '0.00' ? '' : price,
actualPrice,
})
},
// 自动勾选最优惠券组合
colationData() {
let list = this.data.couponArr;
if (!list.length) {
this.setData({
discountPrice: '',
actualPrice: this.data.planPrice || '0.00',
})
return
}
let obj = this.findBestCoupons(list);
this.setData({
couponArr: obj.arr,
})
this.refreshCouponState()
},
// 最优惠的消费券组合
findBestCoupons(arr) {
const amount = parseFloat(this.data.planPrice) || 0;
const validCoupons = arr.filter(coupon => (coupon.isOk == '1' && parseFloat(coupon.desc) <= amount) && amount >= parseFloat(coupon.price));
validCoupons.sort((a, b) => parseFloat(b.price) - parseFloat(a.price));
arr.forEach(item => {
const isValid = validCoupons.some(validCoupon => validCoupon.activity_id == item.activity_id);
item.canCheck = isValid ? '1' : '0';
item.checkedNum = 0;
item.showCpupon = isValid ? '1' : '0';
});
let stackingCoupons = validCoupons.filter(i => i.accumulationShow == '1')
let list1 = [];
let list2 = [];
let finalList = [];
let selectCount = {};
stackingCoupons.sort((a, b) => {
if (a.desc === '0' || a.desc === '') return -1;
if (b.desc === '0' || b.desc === '') return 1;
if (parseFloat(b.price) !== parseFloat(a.price)) return parseFloat(b.price) - parseFloat(a.price);
return parseFloat(b.desc) - parseFloat(a.desc);
});
let thresholdDescSum = 0
let maxThresholdValue = 0
let thresholdCoupons = stackingCoupons.filter(coupon => (parseFloat(coupon.desc) || 0) > 0)
thresholdCoupons.sort((a, b) => {
if (parseFloat(b.desc) !== parseFloat(a.desc)) return parseFloat(b.desc) - parseFloat(a.desc)
return parseFloat(b.price) - parseFloat(a.price)
})
thresholdCoupons.forEach(coupon => {
let couponDesc = parseFloat(coupon.desc) || 0
let couponPrice = parseFloat(coupon.price)
let maxCopies = Math.floor((amount - thresholdDescSum) / couponDesc)
if (maxCopies > coupon.maxNum) maxCopies = coupon.maxNum
if (maxCopies > 0) {
selectCount[coupon.aid] = maxCopies
thresholdDescSum += couponDesc * maxCopies
maxThresholdValue += couponPrice * maxCopies
}
})
list1 = stackingCoupons.filter(i => (selectCount[i.aid] || 0) > 0)
let noDescValue = 0
let noDescCount = {}
stackingCoupons.forEach(coupon => {
let couponDesc = parseFloat(coupon.desc) || 0
let couponPrice = parseFloat(coupon.price)
if (couponDesc === 0 && couponPrice > 0) {
let num = Math.floor((amount - noDescValue) / couponPrice)
if (num > coupon.maxNum) num = coupon.maxNum
if (num > 0) {
noDescCount[coupon.aid] = num
noDescValue += couponPrice * num
}
}
})
let maxStackableValue = maxThresholdValue
if (thresholdDescSum < amount) {
stackingCoupons.forEach(coupon => {
let couponDesc = parseFloat(coupon.desc) || 0
let couponPrice = parseFloat(coupon.price)
if (couponDesc === 0 && couponPrice > 0) {
let num = Math.floor((amount - maxStackableValue) / couponPrice)
if (num > coupon.maxNum) num = coupon.maxNum
if (num > 0) {
selectCount[coupon.aid] = num
maxStackableValue += couponPrice * num
}
}
})
list1 = stackingCoupons.filter(i => (selectCount[i.aid] || 0) > 0)
} else if (noDescValue > maxThresholdValue) {
list1 = stackingCoupons.filter(i => (noDescCount[i.aid] || 0) > 0)
selectCount = noDescCount
maxStackableValue = noDescValue
} else if (noDescValue == maxThresholdValue && noDescValue > 0) {
let listThreshold = stackingCoupons.filter(i => (selectCount[i.aid] || 0) > 0)
let listNoDesc = stackingCoupons.filter(i => (noDescCount[i.aid] || 0) > 0)
let min1 = listThreshold.length > 0 ? Math.min(...listThreshold.map(item => item.useEtime)) : Infinity
let min2 = listNoDesc.length > 0 ? Math.min(...listNoDesc.map(item => item.useEtime)) : Infinity
if (min2 < min1) {
list1 = listNoDesc
selectCount = noDescCount
}
}
let stackList = list1
let stackCount = selectCount
let maxNonStackableValue = 0
validCoupons.forEach(coupon => {
if (coupon.accumulationShow != '1') {
const discountAmount = parseFloat(coupon.price);
const finalAmount = amount - discountAmount;
if (finalAmount > 0 || finalAmount == 0) {
if (maxNonStackableValue < discountAmount) {
maxNonStackableValue = discountAmount
list2 = [{ ...coupon }]
}
}
}
});
if (maxStackableValue > maxNonStackableValue) {
finalList = stackList
} else if (maxStackableValue < maxNonStackableValue) {
finalList = list2
stackCount = {}
if (list2[0]) stackCount[list2[0].aid] = 1
} else {
let copiedList1 = JSON.parse(JSON.stringify(stackList));
let copiedList2 = JSON.parse(JSON.stringify(list2));
let minList1 = copiedList1.length > 0 ? Math.min(...copiedList1.map(item => item.useEtime)) : Infinity;
let minList2 = copiedList2.length > 0 ? Math.min(...copiedList2.map(item => item.useEtime)) : Infinity;
if (minList1 <= minList2) {
finalList = stackList
} else {
finalList = list2
stackCount = {}
if (list2[0]) stackCount[list2[0].aid] = 1
}
}
let discountPrice = 0;
finalList.forEach(coupon => {
let target = arr.findIndex(obj => obj.aid === coupon.aid || obj.activity_id === coupon.activity_id);
if (target > -1) {
arr[target].showCpupon = '1';
arr[target].checkedNum = stackCount[coupon.aid] || 1;
discountPrice += parseFloat(coupon.price) * (stackCount[coupon.aid] || 1);
}
});
finalList = []
arr.forEach(item => {
if (item.checkedNum > 0) {
for (let k = 0; k < item.checkedNum; k++) {
finalList.push({
...item,
activity_id: item.activityIds[k]
})
}
}
})
discountPrice = discountPrice.toFixed(2)
return {
arr,
discountPrice,
finalList,
};
},
// 处理优惠券不可用日期数据
hasConsecutiveSelect(arr, type) {
let firstTitle = null;
let lastTitle = null;
let rArr = []
let num = 0
for (let i = 0; i < arr.length; i++) {
let str = type == '1' ? arr[i].selectMor : type == '2' ? arr[i].selectNoon : type == '3' ? arr[i].selectNig : '';
if (str) {
rArr.push(arr[i].title)
num++
if (num == 1) {
firstTitle = arr[i].title
}
if (num >= 5) {
lastTitle = arr[i].title
}
if (num >= 5 && i >= (arr.length - 1)) {
let fi = rArr.findIndex((item) => {
return item == firstTitle
})
rArr.splice(fi, num, firstTitle + '至' + lastTitle)
num = 0
}
} else {
if (num < 5) {
num = 0
firstTitle = null;
lastTitle = null;
} else {
let fi = rArr.findIndex((item) => {
return item == firstTitle
})
rArr.splice(fi, num, firstTitle + '至' + lastTitle)
num = 0
}
}
}
return {
rArr,
lastTitle,
firstTitle
};
},
// 计算免费券有效期的起始、结束日期
setTimeRange(cdate, startOffset, endOffset) {
const startDate = new Date((cdate + startOffset * 86400) * 1000);
startDate.setHours(0, 0, 0, 0);
let useStime = startDate.getTime() / 1000
const endDate = new Date((cdate + endOffset * 86400) * 1000);
endDate.setHours(23, 59, 59, 0);
let useEtime = endDate.getTime() / 1000
return { useStime, useEtime };
},
// 支付(暂未接入支付流程,先占位)
submitPay() {
wx.showToast({
title: '支付功能开发中',
icon: 'none',
})
},
onReady() {},
onShow() {},
onHide() {},
onUnload() {},
onPullDownRefresh() {},
onReachBottom() {},
onShareAppMessage() {}
})
... ...
{
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTextStyle": "black",
"usingComponents": {
"nav": "/components/nav/nav",
"my-modal": "/components/modal/modal"
}
}
... ...
<!--pack-cookbook/pages/comboBuy.wxml-->
<nav>套餐购买</nav>
<!-- 商家信息 -->
<view class="sellInfo">
<image src="{{seller.seller_image}}" mode="aspectFill" />
<view class="nameInfo font32r">{{seller.sellername}}</view>
</view>
<!-- 套餐信息 -->
<view class="comboCard">
<view class="priceRow">
<text class="label font28r">套餐名称</text>
<view class="valueText font28r">{{details.pname}}</view>
</view>
<view class="priceRow" wx:if="{{memberPrice}}">
<text class="label font28r">菜品原价</text>
<view class="memberPrice font28r">¥ {{memberPrice}}</view>
</view>
<view class="priceRow">
<text class="label font28r">套餐价格</text>
<view class="valueText font28r">¥ {{planPrice}}</view>
</view>
<view bindtap="showCouponModal" class="priceRow couponsBox colorOrange">
<view class="couponLeft font28r">选择优惠券</view>
<view class="couponRight">
<text wx:if="{{discountPrice && discountPrice!='0.00' && couponSwitch}}">- ¥ {{discountPrice}}</text>
<text class="noUse font28r" wx:if="{{couponArr.length == 0}}">暂无可用</text>
<view class="more"></view>
</view>
</view>
<view class="priceRow">
<text class="label font28r">抵扣后</text>
<view class="valueText font28r">¥ {{actualPrice}}</view>
</view>
</view>
<view class="bottomBox"></view>
<!-- 底部支付 -->
<view class="payBtnBox">
<view class="total">合计<text>¥ {{actualPrice}}</text></view>
<view class="payBtn font32r" bindtap="submitPay">支付</view>
</view>
<!-- 使用优惠券弹框 -->
<my-modal id="couponModal" fadeStyle="slideUp" height="{{couponArr.length > 3 ? '80%' : '60%'}}">
<view slot="modalName" class="titleModal">
<image bind:tap="closeCouponModal" src="https://qn.colorcun.com/closeImg1.png" mode="aspectFit" />
<view class="couponTotalText font28r">所有优惠券</view>
<view bindtap="checkCertificate" class="btn font32r">确认</view>
</view>
<view slot="modalContent">
<view class="infoBox">
<view class="infoTop">
<view class="info font28r">本单使用优惠券</view>
<switch checked="{{couponSwitch}}" bindchange="switchChange" color="#09BB07" class="infoSwitch" />
</view>
<view class="infoBottom font24r">选择优惠券后可抵扣套餐价格</view>
</view>
<scroll-view class="couponBox" scroll-y="true">
<view wx:for="{{couponArr}}" data-aid="{{item.aid}}" class="couponItems {{item.showCpupon == '0' ? 'couponNo' : ''}}" wx:key="groupKey">
<view class="itemLeft">
<view class="priceText" wx:if="{{item.price}}">
<view class="icons font24r">¥</view><text class="priceText">{{item.price}}</text>
</view>
<view class="icons font20r" wx:if="{{item.desc && item.desc != '0'}}">消费满{{item.desc}}元可用</view>
<view class="icons font20r" wx:else>无门槛</view>
</view>
<view class="itemRight">
<view class="anameText">
<view class="anameInfo">
<view class="names font40r">{{item.aname}}</view>
<view class="discountText1 font20r">{{item.accumulationShow == '1' ? '可' : '不可'}}叠加</view>
</view>
</view>
<view wx:if="{{item.endDateStr}}" class="font20r bottomTitle">有效日期:<view class="bottom font20r">{{item.endDateStr}}</view>
</view>
<view wx:if="{{item.morText || item.noonText || item.nigText}}" class="font20r bottomTitle"><text>不可使用:</text>
<view class="textBox">
<view wx:if="{{item.morText}}" class="bottom font20r">{{item.morText}}</view>
<view wx:if="{{item.noonText}}" class="bottom font20r">{{item.noonText}}</view>
<view wx:if="{{item.nigText}}" class="bottom font20r">{{item.nigText}}</view>
</view>
</view>
<view wx:if="{{item.exp_date.week_show=='无'}}" class="bottom font20r">无使用时间限制</view>
</view>
<view class="rightBox">
<view class="ownNum font20r">拥有{{item.num}}张</view>
<view class="numBox">
<view class="numBtn {{item.checkedNum == 0 ? 'numBtnDisabled' : ''}}" bindtap="changeCouponNum" data-aid="{{item.aid}}" data-type="minus">-</view>
<input class="numText" type="number" value="{{item.checkedNum}}" data-aid="{{item.aid}}" disabled="{{item.showCpupon == '0'}}" bindinput="numInputChange" />
<view class="numBtn {{item.canAdd != '1' ? 'numBtnDisabled' : ''}}" bindtap="changeCouponNum" data-aid="{{item.aid}}" data-type="plus">+</view>
</view>
</view>
</view>
</scroll-view>
</view>
</my-modal>
... ...
/* pack-cookbook/pages/comboBuy.wxss */
page {
background: #F5F5F5;
}
/* 商家信息 */
.sellInfo {
padding: 56rpx 0 40rpx 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: #fff;
}
.sellInfo image {
width: 200rpx;
height: 200rpx;
margin-bottom: 20rpx;
}
.sellInfo .nameInfo {
color: #000000;
font-family: "PingFang SC";
font-weight: 500;
}
/* 套餐信息 */
.comboCard {
margin: 20rpx;
padding: 40rpx;
background: #fff;
border-radius: 10rpx;
}
.priceRow {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 24rpx;
}
.priceRow:last-child {
margin-bottom: 0;
}
.priceRow .label {
color: #515151;
font-family: "PingFang SC";
}
.valueText {
color: #000;
font-family: "PingFang SC";
}
.memberPrice {
color: #999;
text-decoration: line-through;
font-family: "PingFang SC";
}
.couponsBox {
display: flex;
align-items: center;
justify-content: space-between;
color: #999;
margin-bottom: 24rpx;
padding: 0;
background: transparent;
border: none;
}
.colorOrange {
color: #ED7B2F;
}
.colorOrange .more {
background-image: url('https://qn.colorcun.com/chevronRight.png');
background-size: contain;
background-repeat: no-repeat;
width: 36rpx;
height: 32rpx;
margin-left: 0;
}
.couponsBox .couponRight {
display: flex;
align-items: center;
}
.noUse {
font-family: PingFang SC;
font-weight: 400;
color: #ED7B2F;
}
/* 底部支付 */
.bottomBox {
padding-bottom: 180rpx;
}
.payBtnBox {
position: fixed;
left: 0;
bottom: 0;
height: 160rpx;
padding: 0 40rpx;
box-sizing: border-box;
z-index: 10;
width: 100%;
background: #fff;
display: flex;
align-items: center;
justify-content: space-between;
}
.total {
display: flex;
align-items: center;
color: #000;
font-family: "PingFang SC";
}
.total text {
color: #FD4D59;
font-family: "PingFang SC";
font-weight: 600;
font-size: 44rpx;
margin-left: 8rpx;
}
.payBtn {
background: linear-gradient(90deg, #ff4d11 0%, #fe7600 100%);
color: #fff;
height: 72rpx;
border-radius: 198rpx;
font-family: "PingFang SC";
font-weight: 600;
padding: 0 80rpx;
display: flex;
align-items: center;
justify-content: center;
}
/* 优惠券弹框 */
.mymodal .mymodal-title {
padding: 0 !important;
}
.titleModal {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 32rpx;
}
.couponTotalText {
color: #000000;
font-family: PingFang SC;
font-weight: 400;
}
.titleModal image {
width: 60rpx;
height: 60rpx;
}
.btn {
background: #09BB07;
border-radius: 10rpx;
color: #fff;
text-align: center;
padding: 10rpx 42rpx;
height: 48rpx;
line-height: 48rpx;
}
.infoBox {
width: 100%;
position: absolute;
box-sizing: border-box;
left: 0;
top: 95rpx;
padding: 28rpx 40rpx 0 40rpx;
background: #fff;
z-index: 10;
}
.infoTop {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
}
.infoBottom {
border-bottom: 2rpx solid #dbdbdb;
color: #696969;
font-family: PingFang SC;
font-weight: 400;
padding: 10rpx 0 30rpx 0;
}
.info {
color: #fe6d03;
font-family: PingFang SC;
font-weight: 500;
}
.infoTop switch {
transform: scale(.9);
}
.couponBox {
position: relative;
}
.couponItems {
border: 2rpx solid #09bb07;
margin-bottom: 16rpx;
border-radius: 20rpx;
display: flex;
padding: 20rpx 10rpx;
}
.couponItems:nth-of-type(1) {
margin-top: 160rpx;
}
.itemLeft {
min-width: 21%;
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
border-right: 2rpx dashed #09BB07;
padding-right: 10rpx;
margin-right: 10rpx;
}
.priceText {
color: #FD4D59;
font-weight: 600;
font-size: 56rpx;
margin-top: 6rpx;
display: flex;
align-items: baseline;
justify-content: center;
font-family: PingFang SC;
}
.icons {
color: #FD4D59;
font-size: 20rpx;
font-weight: 500;
font-family: PingFang SC;
}
.anameText {
display: flex;
justify-content: space-between;
margin-bottom: 14rpx;
}
.anameText .names {
font-family: PingFang SC;
font-weight: 600;
line-height: 48rpx;
display: -webkit-box;
word-break: break-all;
word-wrap: break-word;
overflow: hidden;
text-align: left;
}
.discountText1 {
color: #fe6d03;
font-family: PingFang SC;
font-weight: 500;
margin: 0 20rpx;
}
.anameInfo {
display: flex;
align-items: center;
flex-wrap: wrap;
}
.ownNum {
text-align: center;
color: #fe6d03;
font-family: PingFang SC;
font-weight: 500;
flex-shrink: 0;
}
.textBox {
width: 90%;
display: flex;
flex-direction: column;
}
.bottomTitle {
color: #515151;
font-family: PingFang SC;
font-weight: 600;
}
.bottomTitle text {
flex-shrink: 0;
}
.bottom {
font-weight: normal;
}
.itemRight {
flex: 1;
}
.itemRight view {
display: flex;
line-height: 36rpx;
flex-shrink: 0;
}
.rightBox {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.numBox {
display: flex;
align-items: center;
justify-content: center;
margin: 30rpx 10rpx 0 10rpx;
flex-shrink: 0;
align-self: center;
}
.numBtn {
width: 44rpx;
height: 44rpx;
border-radius: 50%;
background: linear-gradient(90deg, #ff4d11 0%, #fe7600 100%);
color: #ffffff;
font-size: 48rpx;
font-weight: 600;
line-height: 44rpx;
text-align: center;
}
.numBox .numBtn:first-child {
line-height: 40rpx;
}
.numBtnDisabled {
background: #cccccc;
}
.numText {
min-width: 48rpx;
width: 64rpx;
height: 44rpx;
border: 2rpx solid #c8c8c8;
margin: 0 10rpx;
text-align: center;
font-size: 28rpx;
font-weight: 600;
color: #333333;
}
.mymodal .mymodal-content {
height: 80% !important;
}
.couponNo {
border: 2rpx solid #999;
}
.couponNo .itemLeft {
border-right: 2rpx dashed #999;
}
.couponNo .numText {
border: 2rpx solid #999;
color: #999;
}
.couponNo .priceText,
.couponNo .icons,
.couponNo .itemRight,
.couponNo .discountText1,
.couponNo .bottomTitle,
.couponNo .ownNum,
.couponNo .bottom {
color: #999;
}
... ...
import util from '../../utils/util';
import App from '../../utils/api';
Page({
/**
* 页面的初始数据
*/
data: {
details:{}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
if(options.item){
let details =JSON.parse(options.item);
if(details && details.cook_list){
details.cook_list = JSON.parse(details.cook_list)
let list = [];
details.cook_list.forEach(i=>{
if(i.cookbooklist.length>0){
i.cookbooklist.forEach(j=>{
if(j.amountHasOrderList && j.amountHasOrderList.length>0){
j.amountHasOrderList.forEach(m=>{
console.log('mmmmmmm-------',m);
console.log('jjjjjj-------',j);
list.push({
image:j.image,
dishName:j.name,
amount:m.amount,
name:m.practiceModel && m.practiceModel.name?m.practiceModel.name:'',
specs:m.specModel && m.specModel.specs?m.specModel.specs:'',
price:m.specModel && m.specModel.price?m.specModel.price:'',
})
})
}
})
}
})
details.list = list
}
console.log('options---',details);
this.setData({
details
})
}
},
// 跳转到购买页
submitOrder(){
let details = this.data.details;
console.log('details-------',details);
let url = util.http_build_query({
details:JSON.stringify(details)
}, './comboBuy')
wx.navigateTo({
url
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})
\ No newline at end of file
... ...
{
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTextStyle": "white",
"usingComponents": {
"nav": "/components/nav/nav"
}
}
\ No newline at end of file
... ...
<!--pack-cookbook/pages/comboDetails.wxml-->
<nav>套餐详情</nav>
<view class="titleBox">
<view class="leftInfo font32r">{{details.pname}}</view>
<view class="rightInfo font32r">¥{{details.plan_price}}/{{details.pnum}}人</view>
</view>
<view class="centerMain">
<view class="title">
<image src="https://qn.colorcun.com/voucherUnion_6.png" mode="" />
<text class="font32r">菜品</text>
</view>
<view class="items" wx:for="{{details.list}}" wx:key="index">
<view class="news">
<view class="font24r">{{item.dishName}}</view>
<view class="font24r">{{item.amount}}{{item.specs}} {{item.name}}<text>原价¥{{item.price}}</text></view>
</view>
<image wx:if="{{item.image}}" src="{{item.image}}" mode="widthFix" />
</view>
</view>
<view class="fixed_box">
<view class="leftPrice">
<view wx:if="{{details.menu_price}}" class="font24r originalPrice">原价<text>¥{{details.menu_price}}</text></view>
<view wx:if="{{details.plan_price}}" class="font24r comboPrice">套餐价<text>¥{{details.plan_price}}</text></view>
</view>
<button class="font32r btns" bindtap="submitOrder">购买</button>
</view>
\ No newline at end of file
... ...
/* pack-cookbook/pages/comboDetails.wxss */
page {
background: #F5F5F5;
}
.titleBox {
padding: 40rpx;
display: flex;
align-items: center;
justify-content: space-between;
background: #fff;
}
.leftInfo {
color: #000000;
font-family: "PingFang SC";
font-weight: 600;
}
.rightInfo {
font-family: "PingFang SC";
font-weight: 500;
font-size: 32rpx;
color: #ff4d11;
}
.centerMain {
margin: 14rpx 12rpx;
background: #fff;
border-radius: 10rpx;
padding: 32rpx 32rpx 150rpx 32rpx;
}
.title {
display: flex;
align-items: center;
}
.title image {
width: 28rpx;
height: 28rpx;
}
.news {
color: #696969;
margin: 40rpx 0 12rpx;
display: flex;
align-items: center;
justify-content: space-between;
}
.news text {
margin-left: 12rpx;
}
.items image {
width: 100%;
}
.fixed_box {
position: fixed;
bottom: 0;
left: 0;
height: 160rpx;
background: #fafafa;
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 40rpx 30rpx 40rpx;
box-sizing: border-box;
}
.leftPrice {
display: flex;
flex-direction: column;
}
.leftPrice text{
margin-left: 8rpx;
}
.comboPrice text{
font-size: 32rpx;
}
.originalPrice {
text-decoration: line-through;
color: #696969;
font-family: "PingFang SC";
font-weight: 400;
}
.comboPrice {
color: #fd4d59;
font-family: "PingFang SC";
font-weight: 600;
}
.comboPrice text {
font-size: 32rpx;
}
.btns {
margin: 0;
width: 30%;
border-radius: 42rpx;
color: #fff;
background: linear-gradient(90deg, #ff4d11 0%, #fe7600 100%);
}
\ No newline at end of file
... ...
// pack-cookbook/pages/comboList.js
import util from '../../utils/util';
import App from '../../utils/api';
Page({
/**
* 页面的初始数据
*/
data: {
sid: '',
uid: '',
seller: {},
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
this.setData({
sid: options.sid,
uid: options.uid
})
if (options.sid) {
this.getSellerDetailFun(options.sid)
}
},
// 排菜/套餐列表
grtPlanCookListFun() {
App.PlanCook.GetPlanCookList({
sellerid: this.data.sid,
uid: this.data.uid,
}).then(res => {
let data = res.data.package_list;
this.setData({
comboList: data
})
})
},
// 获取店铺名称
getSellerDetailFun(sid) {
App.Customer.GetSellerDetail({
sid
}).then(res => {
let data = res.data;
this.setData({
seller: {
seller_image: data.seller_image,
sellername: data.sellername,
sid: data.id
}
})
})
},
// 跳转到详情
gotoComboDetails(e) {
let items = e.currentTarget.dataset['item'];
console.log('item-------', items);
items.seller = this.data.seller;
let url = util.http_build_query({
item: JSON.stringify(items)
}, './comboDetails')
wx.navigateTo({
url
})
},
// 分享
sharesetting() {
console.log(111);
return {
title: '点击查看' + this.data.seller.sellername + '套餐排菜',
path: util.http_build_query({
sid: this.data.sid
}, '/pack-cookbook/pages/comboList'),
imageUrl: this.data.seller.seller_image || 'http://nosqn.colorcun.com/reserve/images/3x/%E6%9A%82%E6%97%A0.png',
}
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
this.grtPlanCookListFun()
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
return this.sharesetting();
},
/**
* 监听用户点击分享到朋友圈按钮的操作
*/
onShareTimeline() {
return this.sharesetting();
},
})
\ No newline at end of file
... ...
{
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTextStyle": "white",
"usingComponents": {
"nav": "/components/nav/nav"
}
}
\ No newline at end of file
... ...
<!--pack-cookbook/pages/comboList.wxml-->
<nav>店铺套餐</nav>
<view class="titleBox">
<image src="{{seller.seller_image}}" mode="" />
<view class="nameInfo font32r">{{seller.sellername}}</view>
</view>
<view class="comboBox">
<view class="items" bind:tap="gotoComboDetails" data-item="{{item}}" wx:for="{{comboList}}" wx:key="{{item.id}}">
<view class="leftBox">
<view class="names font32r">{{item.pname}}</view>
<view class="priceBox font32r">¥{{item.plan_price}}/{{item.pnum}}人</view>
</view>
<view class="btn font24r">详情</view>
</view>
</view>
<view class="fixed_box">
<button class="font32r btns btns1" open-type="share">分享</button>
<button class="font32r btns" bindtap="submitOrder">已购套餐</button>
</view>
\ No newline at end of file
... ...
/* pack-cookbook/pages/comboList.wxss */
page {
background: #F5F5F5;
}
.titleBox {
background: #fff;
display: flex;
align-items: center;
padding: 32rpx 0 20rpx 32rpx;
border-bottom: 2rpx solid #ededed;
margin: 0 20rpx;
}
.titleBox image {
width: 60rpx;
height: 60rpx;
border-radius: 10rpx;
}
.nameInfo {
margin-left: 20rpx;
color: #000000;
font-family: "PingFang SC";
font-weight: 500;
}
.comboBox {
display: flex;
flex-direction: column;
align-items: center;
background: #fff;
padding: 0 20rpx;
}
.items {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
padding: 50rpx 32rpx 50rpx 32rpx;
border-bottom: 2rpx solid #ededed;
}
.leftBox .names {
color: #000000;
font-family: "PingFang SC";
font-weight: 600;
}
.priceBox {
color: #ff4d11;
font-family: "PingFang SC";
font-weight: 500;
margin: 10rpx 0 0 -4rpx;
}
.btn {
color: #ffffff;
font-family: "PingFang SC";
font-weight: 600;
background: linear-gradient(90deg, #ff4d11 0%, #fe7600 100%);
padding: 4rpx 32rpx;
border-radius: 198rpx;
}
.fixed_box {
position: fixed;
bottom: 0;
left: 0;
height: 160rpx;
background: #fafafa;
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 40rpx 30rpx 40rpx;
box-sizing: border-box;
}
.btns {
margin: 0;
width: 45%;
border-radius: 42rpx;
color: #fff;
background: linear-gradient(90deg, #ff4d11 0%, #fe7600 100%);
}
.btns1{
background:#fff;
color: #ff4d11;
border: 2rpx solid #ff4d11;
}
\ No newline at end of file
... ...