<template> <view class="pages"> <view class="" :style="{height: navHeight+'px' }"></view> <view class="navbar-box"> <u-navbar title="订单详情" :safeAreaInsetTop="true" @leftClick="leftClick" :titleStyle="{color:'#fff'}" leftIconColor="#fff" bgColor="transparent"></u-navbar> </view> <view class="page-wrap"> <view class="base-info"> <view class="up u-flex"> <image class="img" :src="pageContent.performImg" mode="aspectFill" alt="" /> <view class="text"> <view class="name text-item">{{pageContent.performName}}</view> <view class="time text-item">日期 {{pageContent.timeDate}}({{pageContent.timeWeek}})</view> <view class="time text-item">场次 {{pageContent.performTimeStart}} - {{pageContent.performTimeEnd}}</view> <!-- <view class="num text-item">{{pageContent.goodsName}} / {{pageContent.seatTypeName}}</view> --> <view class=" text-item">{{pageContent.auditoriumName}}</view> <!-- <view class="position text-item">{{performInfo.name}}</view> --> <!-- <view class="addr u-flex u-row-between"> <view class="u-line-1">地址:遵义市《伟大转折》演艺中心</view> <u-icon name="arrow-right" color="#2D2D2D" size="36rpx"></u-icon> </view> --> </view> </view> <view class="down"> <view class="num-wrap u-flex u-row-between"> <view class="title">选购数量</view> <view class="num">{{totalVisitor}}</view> </view> </view> </view> <view class="block-wrap purchaser"> <view class="block-title u-flex"> <view class="name">购票人信息</view> <!-- <text>用于入园身份验证</text> --> </view> <view class="" v-if="vuex_member_info.isAuth"> <view class="item">姓名:{{pageContent.purchaser.name}}</view> <view class="item">手机号:{{pageContent.purchaser.mobile|hidePhoneNumber}}</view> <view class="item">身份证:{{pageContent.purchaser.idcard|maskID}}</view> </view> <view class="un-auth" v-else @click="$u.route('center/factorauth',{from:'bookticket'})"> 请先<text style="color: #ED0000;">实名认证</text> </view> </view> <view class="block-wrap visitors" v-for="(goods, goodsIndex) in pageContent.goodsList" :key="goodsIndex"> <view class="block-title u-flex"> <view class="name">{{goods.goodsName}}({{goods.saleNum}}张)</view> <text v-if="goods.realList && goods.realList[0]">需要{{goods.realList[0].realNum}}张身份证</text> <!-- <text v-else>不需要身份证</text> --> </view> <view class="people-list u-flex u-flex-wrap"> <!-- 已选择的观影人 --> <view class="people btn" v-for="(visitor,index) in goods.visitors" :key="index"> {{visitor.name}} </view> <!-- 添加观影人按钮 --> <view v-if="goods.realList && goods.realList[0]" class="btn u-flex u-row-center" @click="showVisitorSelect(goodsIndex)"> <u-icon name="plus-circle" color="#2D2D2D" size="32rpx"></u-icon> <text class="text">新增/更换</text> </view> </view> <!-- 观影人列表 --> <view class="peoples" v-if="goods.visitors && goods.visitors.length>0"> <view class="peoples-item u-flex u-row-between" v-for="(visitor,index) in goods.visitors" :key="index"> <view class="left u-flex u-row-center u-flex-col"> <view style="margin-bottom: 5px;">观影人{{ index + 1 }}</view> <u-icon @click="delVisitor(goodsIndex, visitor)" name="close-circle" color="#2D2D2D" size="32rpx"></u-icon> </view> <view class="center"> <view class="center-item name">{{visitor.name}}</view> <view class="center-item mobile">手机号 {{visitor.mobile}}</view> <view class="center-item idcard">身份证 {{visitor.idcard}}</view> </view> <view class="right" @click="editVisitor(visitor)">编辑</view> </view> </view> </view> <view class="coupon u-flex u-row-between block-wrap" @click="selectCoupon"> <view class="left">优惠券</view> <view class="right u-flex"> <text v-if="couponList.length<1||Number(this.salePrice)<=0">暂无可用</text> <text v-if="coupon.quota" style="color: #EF2929;">已选1张优惠券</text> <text v-if="couponList.length>0&&!coupon.quota&&Number(this.salePrice)>0">未选择优惠券</text> <u-icon name="arrow-right" color="#7F7F7F" size="24rpx"></u-icon> </view> </view> <view class="notice"> <view class="title u-flex u-row-between u-border-bottom"> <text>购票须知</text> </view> <view class="notice-item parse-content"> <u-parse :content="pageContent.ticketNotice"></u-parse> </view> <!-- <view class="notice-item"> 1.由于设备故障等不可抗力因素,存在少量场次取消的情况,会 进行退票退款 </view> <view class="notice-item"> 2.由于影院系统不稳定等因素,存在出票失败的情况,会进行退款 </view> <view class="notice-item"> 3.取票码可以在"我的-订单页"中查看 </view> --> </view> </view> <u-popup :show="visitorShow"> <view class="people-show-content"> <view class="title"> <view class="cancel" @click="visitorShow=false">取消</view> 选择观影人 </view> <view class="add-btn u-flex u-row-center" @click="addVisitor"> <!-- <image class="img" :src="staticUrl+'/img/car.png'" ></image> --> 添加观影人信息 </view> <view class="list"> <u-checkbox-group v-model="selectedVisitor[currentGoodsIndex]" iconPlacement="left"> <view class="people u-flex u-row-between" v-for="(item,index) in visitorList" :key="index" :class="{'disabled': selectedVisitors.includes(item.idcard) && !selectedVisitor[currentGoodsIndex].includes(item.idcard)}"> <u-checkbox activeColor="#ED0303" :label="item.name" :name="item.idcard" :disabled="selectedVisitors.includes(item.idcard) && !selectedVisitor[currentGoodsIndex].includes(item.idcard)" ></u-checkbox> <u-icon name="edit-pen-fill" color="#7F7F7F" size="32rpx" @click="editVisitor(item)" ></u-icon> </view> </u-checkbox-group> </view> <view class="full-btn" @click="confirmVisitor">确定</view> </view> </u-popup> <view class="page-bottom"> <view class="inner u-flex u-row-between"> <view class="left u-flex u-col-top"> <text>实付金额:</text> <view class="total-price"> ¥{{pageContent.salePrice}} <view class="original-price"> 划线价¥{{pageContent.originalPrice}} </view> <view class="bottom-coupon" v-if="pageContent.preferentialPrice"> 优惠共减¥{{pageContent.preferentialPrice}} </view> </view> </view> <view class="right"> <view class="btn active" v-if="pageContent.salePrice>=0&&cansubmit&&vuex_member_info.isAuth" @click="setTemplate">立即支付</view> <!-- <u-button @click="setTemplate" class="btn active" v-if="totalPrice>0&&cansubmit&&vuex_member_info.isAuth">立即支付</u-button> --> <view class="btn" v-else>立即支付</view> </view> </view> </view> <u-modal :show="umodal.show" :title="umodal.title" :content='umodal.content' confirmColor="#ED0303" @confirm="modalConfirm" ></u-modal> </view> </template> <script> import { locale } from "moment/moment"; import { systemInfo } from "@/mixin.js"; // #ifdef H5 import wxH5 from "weixin-jsapi"; // #endif export default { mixins: [systemInfo], data() { return { performId: '', performInfo: {}, pageData: {}, //上个页面传过来的数据 pageContent: { performName: '', goodsName: '', timeDate: '', timeWeek: '', seatTypeName: '', auditoriumName: '', performTimeEnd: '', performTimeStart: '', purchaser: { mobile: '', idcard: '' }, ticketNotice: '', viewerList: [], goodsList:[], }, //页面信息 ticketNotice: '', cansubmit: true, staticUrl: this.$commonConfig.staticUrl, visitors: [], // 改为数组对象,每个对象包含goodsId和对应的游客列表 visitorShow: false, //游客弹层 visitorList: [], //游客列表 selectedVisitor: {}, // 改为对象,key为goodsId params: {}, //要提交的数据 orderId: '', //订单提交获取 payResult: {}, //gotoPay结果 paysuccess: false, //支付结果 templateIdList: [], //微信小程序订阅消息 umodal:{ show:false, title:'温馨提示', content:'' }, scene:null, retailId:null,//分销码 label:null,//scene解析出来的 retailId:null, couponList:[], latitude:null, longitude:null, selectGoodsList:[], currentGoodsIndex: '', // 当前选择的商品ID selectedVisitors: [], // 所有已选择的观影人idcard列表 salePrice:undefined,//获取第一次的销售价格 } }, watch: { visitors: { handler: function(newValue, oldValue) { this.findOrderCoupons(); console.log(`The value changed to ${newValue.length}`); }, immediate: false } }, computed: { // finalPrice(){ // let discount = 0; // let price = this.pageContent.salePrice||0; // if(this.coupon.type==1){ // discount = this.coupon.quota || 0; // 如果没有优惠券,默认为0 // price = Math.max(this.pageContent.salePrice - discount,0); // }else if(this.coupon.type==2){ // price = this.pageContent.salePrice*(this.coupon.quota/100); // } // // console.log('price',price); // // console.log('price',typeof price); // if(typeof price=='string'){ // price = Number(price) // } // return price.toFixed(2) // }, // totalPrice() { // // 计算所有商品的总价 // return this.pageContent.goodsList.reduce((total, goods) => { // return total + (Number(goods.salePrice) * goods.saleNum); // }, 0).toFixed(2); // }, totalVisitor() { // 计算所需的总游客数 return this.pageContent.goodsList.reduce((total, goods) => { return total + goods.saleNum; }, 0); }, couponAmount() { let amount = 0; if (this.coupon.type == 1) { amount = this.coupon.quota || 0; // 如果没有优惠券,默认为0 } else if (this.coupon.type == 2) { // 将总价和折扣转化为整数 const totalPrice = Math.round(this.pageContent.salePrice * 100); // 以分为单位 const discountRate = this.coupon.quota; // 折扣百分比 const discountAmount = totalPrice * (discountRate / 100); const finalAmount = totalPrice - discountAmount; amount = finalAmount / 100; // 结果转换回以元为单位 // console.log('this.pageContent.salePrice',this.pageContent.salePrice); // console.log('this.coupon.quota',this.coupon.quota); // console.log('amount',amount); } return amount.toFixed(2); }, }, onShow() { this.getSettlement(); if(this.salePrice>0){ this.findOrderCoupons() } }, onLoad(page) { console.log('bookticket page', page); this.pageData = page; this.performId = page.performId; this.pageData.performTimeId = page.performTimeId; this.pageData.seatTypeId = page.seatTypeId; const selectGoodsList = uni.getStorageSync('selectGoodsList'); if(selectGoodsList.length>0){ this.selectGoodsList = JSON.parse(selectGoodsList); uni.removeStorage({ key:'selectGoodsList' }) } console.log('selectGoodsList',this.selectGoodsList); this.getSystemInfo(); // this.getSettlement(); this.getTemplateIdList(); //获取模板列表 }, onUnload() { this.$u.vuex('coupon', {}); }, methods: { leftClick(e) { let pages = getCurrentPages(); if (pages.length == 1) { uni.$u.route('/pages/index/index') } else { uni.navigateBack() }; }, getSettlement() { this.pageData.goodsList = this.selectGoodsList; // console.log('coupon',this.coupon.quota) let params = { ...this.pageData, } if(this.coupon.quota){ params.coupon = { memberCouponId :this.coupon.id } } this.$u.api.getSettlementV2(params).then(res => { // console.log('getSettlement',res.data); this.pageContent = res.data; if(!this.salePrice){ this.salePrice = this.pageContent.salePrice; } this.getMemberAll(); }).catch(err => { console.log('getSettlement', err); }) }, getMemberAll() { let that = this; // const userId = this.vuex_member_info.id; const userId = this.pageContent.viewerList[0]?.id; this.$u.api.selectMemberAll({ userid: userId }).then(res => { // console.log('getMemberAll',res.data); this.visitorList = res.data.list; // this.visitors = this.visitorList.filter(obj => obj.memberId==userId); this.selectedVisitor = []; this.visitorList.forEach(visitor => { if (this.visitors.find(item => item.idcard === visitor.idcard)) { this.selectedVisitor.push(visitor.idcard); } }); this.visitors = this.visitorList.filter(obj => that.selectedVisitor.includes(obj.idcard)); console.log('this.visitorList',this.visitorList); console.log('this.selectedVisitor',this.selectedVisitor); console.log('this.visitors',this.visitors); }).catch(err => { console.log('getMemberAll', err); }) }, showVisitorSelect(goodsIndex) { this.currentGoodsIndex = goodsIndex; this.visitorShow = true; // 初始化当前商品的已选游客 if(!this.selectedVisitor[goodsIndex]) { this.selectedVisitor[goodsIndex] = []; } // 设置checkbox的选中状态 const currentGoods = this.pageContent.goodsList[goodsIndex]; if(currentGoods.visitors) { this.selectedVisitor[goodsIndex] = currentGoods.visitors.map(v => v.idcard); } // 获取其他商品已选的观影人列表(排除当前商品) this.selectedVisitors = this.pageContent.goodsList.reduce((acc, goods, index) => { if(index !== goodsIndex && goods.visitors) { acc.push(...goods.visitors.map(v => v.idcard)); } return acc; }, []); }, delVisitor(goodsIndex, visitor) { console.log('goodsIndex', goodsIndex); console.log('visitor', visitor); // 从对应商品的游客列表中删除 const goods = this.pageContent.goodsList[goodsIndex]; if(goods) { // 使用 Vue.set 或 this.$set 来确保视图更新 this.$set(goods, 'visitors', (goods.visitors || []).filter(v => v.idcard !== visitor.idcard)); } // 从选中列表中删除 if(this.selectedVisitor[goodsIndex]) { // 同样使用 this.$set 来更新数组 this.$set(this.selectedVisitor, goodsIndex, this.selectedVisitor[goodsIndex].filter(id => id !== visitor.idcard) ); } // 更新其他商品的 selectedVisitors this.selectedVisitors = this.pageContent.goodsList.reduce((acc, goods, index) => { if(index !== goodsIndex && goods.visitors) { acc.push(...goods.visitors.map(v => v.idcard)); } return acc; }, []); }, addVisitor() { uni.$u.route('/center/people', { type: 'addVisitor', fromPage: 'bookticket' }); }, editVisitor(item) { uni.$u.route('/center/people', { type: 'editVisitor', fromPage: 'bookticket', id: item.id, name: item.name, mobile: item.mobile, idcard: item.idcard, }); }, getTemplateIdList() { this.$u.api.templateIdList({ templateLabel: 'order_pay' }).then(res => { // console.log('getTemplateIdList', res.data); this.templateIdList = res.data.list.map(item => { return item.templateId }); // if(this.templateIdList.length>0){ // this.templateEven(); // } }).catch(err => { console.log('getTemplateIdList', err); }) }, async submitorder() { let _this = this; let retailId = null; try { retailId = await new Promise((resolve, reject) => { uni.getStorage({ key: 'retailId', success: function (res) { console.log('getPositionData retailId====', res.data); resolve(res.data); }, fail: function (error) { reject(error); } }); }); console.log('getPositionData retailId', retailId); } catch (error) { console.error('获取retailId失败', error); // 在这里可以添加处理失败的逻辑 } this.retailId = retailId; console.log('submitorder retailId',this.retailId); console.log('this.pageContent',this.pageContent); // 构建订单参数 let params = { performId: this.pageContent.performId, goodsList: this.pageContent.goodsList.map(goods => { return { goodsId: goods.goodsId, saleNum: goods.saleNum, tourists: (goods.visitors ?? []).map(visitor => { return { realType: goods.realList[0].realType, name: visitor.name, mobile: visitor.mobile, idcard: visitor.idcard } }) } }), auditoriumId: this.pageContent.auditoriumId, performTimeId: this.pageContent.performTimeId, seatTypeId: this.pageContent.seatTypeId, purchaser: { name: this.pageContent.purchaser.name, mobile: this.pageContent.purchaser.mobile, idcard: this.pageContent.purchaser.idcard }, label: this.label, retailId: this.retailId, coupon: { memberCouponId: this.coupon.quota ? this.coupon.id : null }, longitude: this.longitude, latitude: this.latitude } // 发起提交订单请求 this.$u.api.submitOrderV2(params, {custom:{toast:false}}) .then(res => { this.orderId = res.data.orderId; this.gotoPay(); }) .catch(err => { this.cansubmit = true; this.umodal.title = ''; this.umodal.content = err.msg; this.umodal.show = true; }).finally(()=>{ uni.hideLoading() }) }, modalConfirm(){ this.umodal.show = false; }, // 订阅消息 templateEven() { let that = this wx.showModal({ title: '温馨提示', content: '为更好的促进与您的交流,服务号需要实时向您发送消息', confirmText: "同意", cancelText: "拒绝", success: function(res) { if (res.confirm) { //调用订阅消息 // console.log('用户点击确定'); //调用订阅 that.setTemplate(); } else if (res.cancel) { // console.log('用户点击取消'); ///显示第二个弹说明一下 wx.showModal({ title: '温馨提示', content: '拒绝后您将无法获取实时的消息', confirmText: "知道了", showCancel: false, success: function(res) { that.gotoPay(); ///点击知道了的后续操作 ///如跳转首页面 } }); } } }); }, showOpenLocationSettings() { uni.showModal({ title: '提示', content: '需要获取您的地理位置,请前往设置中开启', confirmText: '去设置', success: (res) => { if (res.confirm) { uni.openSetting({ success: (res) => { if (res.authSetting['scope.userLocation']) { this.setTemplate(); } } }); } } }); }, getUserLocation() { return new Promise((resolve, reject) => { uni.getLocation({ type: 'gcj02', success: (res) => { resolve(res); }, fail: (err) => { reject(err); } }); }); }, // 设置小程序订阅消息 async setTemplate() { if(this.needIdcardNumber&&this.needIdcardNumber!==this.visitors.length){ uni.showToast({ title:'观影人信息不正确', icon:'none' }) return false } try { const location = await this.getUserLocation(); this.longitude = location.longitude; this.latitude = location.latitude; if (!this.longitude || !this.latitude) { uni.showToast({ title: '无法获取地理位置', icon: 'none' }); return; } console.log('location', location); } catch (err) { if (err.errMsg === 'getLocation:fail auth deny') { // 用户拒绝授权,提示用户打开位置权限 this.showOpenLocationSettings(); } else { uni.showToast({ title: '获取地理位置失败', icon: 'none' }); } return } let that = this; // console.log('templateIdList', this.templateIdList); // #ifdef MP uni.requestSubscribeMessage({ tmplIds: that.templateIdList, success(res) { // that.gotoPay(); console.log("设置小程序订阅消息 success:", res); }, fail(res) { console.log("设置小程序订阅消息 fail:", res); }, complete(res) { // that.gotoPay(); that.submitorder(); console.log("设置小程序订阅消息 complete:", res); } }) // #endif // #ifdef H5 that.gotoPay() // #endif }, gotoPay() { this.$u.api.gotoPayV2({ orderId: this.orderId, openid: '' }).then(res => { // this.payResult = res.data.payInfo; // this.payResult.package = res.data.payInfo.packageValue; // ygh if(!res.data.needPay){ //this.payQuery(); uni.$u.route('/center/orderdetails', { type:'redirectTo', id: this.orderId }); }else { this.payResult = res.data.payInfo; this.payResult.package = res.data.payInfo.packageValue; // #ifdef H5 this.initConfig(this.payResult) // #endif // #ifdef MP this.wxPay() // #endif } // if(this.params.paymentMode==1||this.params.paymentMode==4){ // this.wxPay() // }else{ // uni.$u.route('/shopping/paysuccess'); // } // console.log('gotoPayres', res.data); }).catch(err => { this.cansubmit = true; // this.paypass = ''; // this.checkPassShow = false; console.log('gotoPay', err); }) }, wxPay() { let that = this; uni.requestPayment({ ...this.payResult, "provider": "wxpay", "orderInfo": { // "appid": "wx499********7c70e", // 微信开放平台 - 应用 - AppId,注意和微信小程序、公众号 AppId 可能不一致 // "noncestr": "c5sEwbaNPiXAF3iv", // 随机字符串 // "package": "Sign=WXPay", // 固定值 // "partnerid": "148*****52", // 微信支付商户号 // "prepayid": "wx202254********************fbe90000", // 统一下单订单号 // "timestamp": 1597935292, // 时间戳(单位:秒) // "sign": "A842B45937F6EFF60DEC7A2EAA52D5A0" // 签名,这里用的 MD5/RSA 签名 }, success(res) { that.payQuery(); }, fail(e) { uni.$u.route('/center/order', { status: 0 }); console.log('wxPayfail', e); }, complete() { this.cansubmit = true; } }) }, payQuery() { let that = this; let retryCount = 0; let maxRetryCount = 5; // 设置最大重试次数 let interval = 2000; // 设置间隔时间为2秒 let timeout = 10000; // 设置超时时间为10秒 let timer; uni.showLoading({ title: '支付结果查询中' }) timer = setInterval(() => { retryCount++; if (retryCount > maxRetryCount || retryCount * interval > timeout) { clearInterval(timer); uni.hideLoading(); console.log("支付查询超时或达到最大重试次数"); // 在这里添加超时或达到最大重试次数的处理逻辑 uni.redirectTo({ url: '/center/order' }); } else { console.log("第" + retryCount + "次查询"); // 调用查询支付状态的方法 // 如果支付状态为成功,则清除定时器并处理成功的逻辑 // 如果支付状态为失败,则清除定时器并处理失败的逻辑 this.$u.api.payQueryV2({ orderId: this.orderId }).then(res => { // 0-未支付 1-已支付 2-支付中 3-支付失败 4-支付退款 let payStatus = res.data.payStatus; if (payStatus === 1) { // uni.$u.route('/center/orderdetails', { // type:'redirectTo', // id: res.data.orderId // }); uni.redirectTo({ url: '/center/order?status=3' }); // uni.$u.route('/center/paysuccess'); } else if (payStatus === 0 || payStatus === 2) { this.payQuery() } else if (payStatus === 3) { uni.toast('支付失败') } clearInterval(timer); }).catch(err => { console.log('payQuery', err); }).finally(() => { uni.hideLoading() this.cansubmit = true; }) } }, interval); }, /** * 公众号微信支付 */ initConfig() { // #ifdef H5 let that = this wxH5.config({ debug: false, // 这里一般在测试阶段先用ture,等打包给后台的时候就改回false, appId: that.payResult.appId, // 必填,公众号的唯一标识 timestamp: that.payResult.timeStamp, // 必填,生成签名的时间戳 nonceStr: that.payResult.nonceStr, // 必填,生成签名的随机串 signature: that.payResult.paySign, // 必填,签名 jsApiList: ['chooseWXPay', 'checkJsApi'] // 必填,需要使用的JS接口列表 }) wxH5.ready(() => { wxH5.chooseWXPay({ timestamp: that.payResult.timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符 nonceStr: that.payResult.nonceStr, // 支付签名随机串,不长于 32 位 package: that.payResult.packageValue, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*) signType: 'SHA1', // 签名方式,默认为'SHA1',使用新版支付需传入'MD5' paySign: that.payResult.paySign, // 支付签名 success: () => { that.payQuery(); }, fail: (e) => { uni.$u.route('/center/order', { status: 0 }); console.log('wxPayfail', e); }, cancel: () => { uni.$u.route('/center/order', { status: 0 }); that.cansubmit = true; } }) }) // #endif }, selectCoupon(){ if(Number(this.salePrice)<=0){ return } let goodsId = this.pageContent.goodsList[0].goodsId; this.$u.route('/center/couponselect',{ salePrice:this.salePrice, performId:this.performId, goodsId: goodsId }) }, findOrderCoupons() { let goodsId = this.pageContent.goodsList[0].goodsId; // console.log('findOrderCoupons-goodsId',goodsId) console.log('this.salePrice',this.salePrice) let param = { salePrice: this.salePrice, performId: this.performId, goodsId: goodsId }; this.$u.api.findOrderCoupons(param) .then(res => { this.couponList = res.data.list || []; console.log('this.couponList',this.couponList); console.log('this.coupon.id',this.coupon.id); if (this.couponList.length < 1 || !this.couponList.some(obj => obj.id === this.coupon.id)) { this.$u.vuex('coupon', {}); } }) .catch(err => { // console.log('findOrderCoupons',err.data); }); }, // 确认选择观影人 confirmVisitor() { const goods = this.pageContent.goodsList[this.currentGoodsIndex]; // 验证身份证数量是否符合要求 if(goods.realList[0] && this.selectedVisitor[this.currentGoodsIndex].length !== goods.realList[0].realNum) { uni.showToast({ title: `请选择${goods.realList[0].realNum}位观影人`, icon: 'none' }) return false; } // 更新选中的观影人 goods.visitors = this.visitorList .filter(obj => this.selectedVisitor[this.currentGoodsIndex].includes(obj.idcard)) .map(item => ({ name: item.name, mobile: item.mobile, idcard: item.idcard })); this.visitorShow = false; }, // 修改支付按钮点击方法 setTemplate() { // 检查是否所有商品都选择了足够的观影人 const isValid = this.pageContent.goodsList.every(goods => { // 如果没有realList或realList[0]为空,则不需要验证观影人数量 if(!goods.realList || !goods.realList[0]) return true; // 如果需要观影人但没有选择任何观影人 if(!goods.visitors) return false; // 验证观影人数量是否符合要求 return goods.visitors.length === goods.realList[0].realNum; }); if(!isValid) { uni.showToast({ title: '请为需要实名认证的票种选择足够的观影人', icon: 'none' }); return; } // 继续原有的支付逻辑 this.submitorder(); } } } </script> <style> page { background: linear-gradient(180deg, #ED0000 0%, #F9FBFD 50%, #fff 100%); background-repeat: no-repeat; } </style> <style lang="scss" scoped> .base-info { border-radius: 30rpx; overflow: hidden; background: radial-gradient(circle at -26rpx 294rpx, transparent 8%, #fff 4%) left, radial-gradient(circle at calc(100% + 26rpx) 294rpx, transparent 8%, #fff 4%) right; background-size: 50% 100%; background-repeat: no-repeat; padding: 34rpx 36rpx; box-sizing: border-box; margin: 30rpx 0 40rpx; .up { margin-bottom: 36rpx; .img { display: block; width: 172rpx; height: 230rpx; border-radius: 20rpx; margin-right: 32rpx; } .text { flex: 1; font-size: 22rpx; font-weight: 400; color: #606060; line-height: 1; } .text-item { margin-bottom: 18rpx; } .name { font-size: 32rpx; line-height: 1.5; font-weight: bold; color: #2D2D2D; } .addr { font-size: 24rpx; font-weight: 500; color: #2D2D2D; } } .down { position: relative; &:before { content: ''; width: calc(100% + 26rpx); height: 1px; position: absolute; left: -13rpx; top: -2rpx; border-top: 4rpx dashed #F39FA0; } .num-wrap { padding-top: 36rpx; .title { font-size: 14px; color: #4E4E4E; } } } } .block-wrap { background: #FFFFFF; box-shadow: 0rpx 0rpx 20rpx 2rpx rgba(221, 221, 221, 0.5); border-radius: 20rpx; margin-bottom: 28rpx; padding: 32rpx 30rpx 34rpx; .block-title { // padding-left: 16rpx; position: relative; margin-bottom: 22rpx; font-size: 24rpx; font-weight: 500; color: #CACACA; // &:before{ // content: ''; // width: 6rpx; // height: 32rpx; // background: #1677FF; // border-radius: 4rpx; // position: absolute; // left: 0; // top: 50%; // margin-top: -16rpx; // } .name { font-size: 32rpx; font-weight: bold; color: #2D2D2D; margin-right: 20rpx; } } .no-people { font-size: 28rpx; font-weight: 400; color: #7F7F7F; .right { margin-left: 20rpx; color: #1677FF; } } .peoples { font-size: 28rpx; font-weight: 400; color: #7F7F7F; margin-bottom: 24rpx; .left{ text-align: center; } .center{ .center-item{ & ~ .center-item{ margin-top: 3px; } } } .peoples-item { margin-bottom: 10rpx; } // .name { // margin-left: 20rpx; // margin-right: 28rpx; // font-size: 28rpx; // font-weight: bold; // color: #363636; // } .people-id { font-size: 20rpx; font-weight: 400; color: #606060; } .right { font-size: 28rpx; font-weight: 400; color: #ED0303; } } } .people-list { margin-bottom: 20rpx; .btn { width: 185rpx; height: 60rpx; line-height: 60rpx; font-size: 24rpx; font-weight: 500; color: #2D2D2D; background-color: #F1F1F1; border: 1px solid #F1F1F1; border-radius: 8rpx; margin-bottom: 12rpx; .text { margin-left: 16rpx; } &.people { margin-right: 16rpx; text-align: center; background-color: #FFF2F2; border-color: #ED0303; } } } .visitors { margin-bottom: 20rpx; } .people-show-content { background: #FFFFFF; border-radius: 40rpx 40rpx 0rpx 0rpx; padding: 30rpx 40rpx; .title { position: relative; font-size: 32rpx; font-weight: 500; color: #606060; margin-bottom: 46rpx; text-align: center; .cancel { position: absolute; left: 0; top: 0; } } .add-btn { margin-bottom: 28rpx; background: #ffdee1; border-radius: 44rpx; padding: 26rpx; font-size: 24rpx; font-weight: 400; color: #ff1616; .img { width: 28rpx; height: 36rpx; margin-right: 36rpx; } } .list { /deep/ .u-radio-group { flex-wrap: wrap; } /deep/ .u-checkbox-group { flex-wrap: wrap; } overflow-y: auto; height: 40vh; .people { width: 100%; margin-bottom: 24rpx; } } .btn {} } .coupon { .left{ font-weight: bold; font-size: 28rpx; color: #2D2D2D; } .right{ font-weight: 400; font-size: 24rpx; color: #606060; } /deep/ .u-icon{ top: 1px; margin-left: 5px; position: relative; } } .notice { background: #FFFFFF; box-shadow: 0rpx 0rpx 16rpx 2rpx rgba(232, 232, 232, 0.5); border-radius: 16rpx; padding: 44rpx 36rpx; margin-bottom: 24rpx; .title { font-size: 28rpx; font-weight: bold; color: #2D2D2D; padding-bottom: 20rpx; margin-bottom: 26rpx; border-bottom-style: dashed; } .notice-item { font-size: 24rpx; font-weight: 400; color: #7F7F7F; line-height: 36rpx; margin-bottom: 8rpx; } } .page-bottom { position: relative; z-index: 1001; height: 98rpx; padding: 24rpx 20rpx 50rpx; .inner { position: fixed; background-color: #fff; height: 98rpx; left: 0; right: 0; bottom: 0; padding: 24rpx 20rpx 50rpx; box-shadow: 0rpx -4rpx 12rpx 0rpx rgba(215, 215, 215, 0.5); .total-price { font-size: 40rpx; font-weight: bold; color: #ED0000; .bottom-coupon{ font-size: 24rpx; } .original-price{ font-size: 24rpx; color: #7F7F7F; text-decoration: line-through; } } .btn { font-size: 28rpx; height: 80rpx; line-height: 80rpx; border-radius: 50rpx; padding: 0 50rpx; background-color: #eee; color: #333; text-align: center; &.active { background: linear-gradient(90deg, #FF7979 0%, #ED0000 100%); color: #fff; } } } } .purchaser { .item { margin-bottom: 10rpx; font-size: 26rpx; color: #333; } .un-auth { padding: 26rpx; background-color: #eee; color: #333; text-align: center; border-radius: 8rpx; } } .list { .people { &.disabled { opacity: 0.5; } } } </style>