Files
SmartCulturalTourismManageU…/pages/info/info.vue

711 lines
26 KiB
Vue
Raw Normal View History

2025-08-26 16:17:24 +08:00
<template>
<view class="waper">
<u-navbar :autoBack="true" :placeholder="true" bgColor="#03AE80" leftIconColor="#fff">
<view slot='center' style="font-size: 36rpx; font-weight: bold; color: #fff;">核销</view>
</u-navbar>
<view class="colorLump"></view>
<view class="con-box" v-if="detData">
<view class="info">
<image class="bgm" src="../../static/img/hxxq.png" mode=""></image>
<view class="top">
<view class="img">
<image :src="$utils.getJointImg(detData.image11)" mode=""></image>
</view>
<view class="text-box">
<view class="title">
<view class="label">{{detData.ticketName}}</view>
<view class="status" v-if="detData.historyList && detData.historyList.length > 0">已核销</view>
</view>
<view class="price">{{detData.price}}</view>
</view>
</view>
<view class="bottom" v-if="detailList">
<view class="row">
<view class="key">订单编号</view>
<view class="value">{{detData.orderCodeZdd}}</view>
</view>
<view class="row">
<view class="key">下单时间</view>
<view class="value">{{detData.paymentTime}}</view>
</view>
<view class="row" v-if="detailList.availableStartTime && detailList.availableEndTime">
<view class="key">有效期</view>
<view class="value">{{detailList.availableStartTime.split(' ')[0]}}{{detailList.availableEndTime.split(' ')[0]}}</view>
</view>
<view class="row">
<view class="key">联系人</view>
<view class="value">{{!detailList.userName ? '窗口售票' : (detailList.userName + ' ' + (detailList.mobilePhone ? detailList.mobilePhone : ''))}}</view>
</view>
<view class="row">
<view class="key">出行人</view>
<view class="value">{{!detailList.userName ? '不实名' : (detailList.userName + ' ' + (detailList.identityCard ? detailList.identityCard : ''))}}</view>
</view>
<view class="row">
<view class="key">适用时间段</view>
<view class="value">{{detData.weekLabel + ((detData.weekLabel && detData.classify == '4') ? '不可用' : '')}}</view>
</view>
</view>
</view>
<!-- 可核销 -->
<template v-if="!detData.historyList || detData.historyList.length == 0">
<!-- 普通票 -->
<template v-if="detData.classify == '1'">
<!-- 一票一码 -->
<template v-if="detData.qrcodeRule == '1'">
<view class="information" v-if="detailList">
<view class="item">
<view class="num">{{detailList.canVerificationMun}}</view>
<view class="label">总次数</view>
</view>
<view class="item">
<view class="num">{{detailList.verificationMun}}</view>
<view class="label">已核销</view>
</view>
<view class="item">
<view class="num">{{detailList.canVerificationMun - detailList.verificationMun}}</view>
<view class="label">未核销</view>
</view>
</view>
<view class="quantity" v-if="detailList">
<view class="title">本次核销次数</view>
<view class="card-box">
<view class="card" :class="{'active': activeCard == item}" v-for="(item,index) in getNumbers(0, (detailList.canVerificationMun - detailList.verificationMun - 1))" :key="index" @click="selectCard(item, '1')">{{(detailList.canVerificationMun - detailList.verificationMun) - item}}</view>
</view>
</view>
</template>
<!-- 多票一码 -->
<template v-else>
<view class="information">
<view class="item">
<view class="num">{{detData.buyQuantity}}</view>
<view class="label">总张数</view>
</view>
<view class="item">
<view class="num">{{detData.buyQuantity - detData.verificationMunTotal}}</view>
<view class="label">已核销</view>
</view>
<view class="item">
<view class="num">{{detData.verificationMunTotal}}</view>
<view class="label">未核销</view>
</view>
</view>
<view class="quantity">
<view class="title">本次核销张数</view>
<view class="card-box">
<!-- #ifdef APP-PLUS -->
<view class="card" :class="{'active': activeCard == item}" v-for="(item,index) in detData.verificationMunTotal" :key="index" @click="selectCard((item - 1), '2')">
{{detData.verificationMunTotal - (item - 1)}}
</view>
<!-- #endif -->
<!-- #ifndef APP-PLUS -->
<view class="card" :class="{'active': activeCard == item}" v-for="(item,index) in detData.verificationMunTotal" :key="index" @click="selectCard(item, '2')">
{{detData.verificationMunTotal - item}}
</view>
<!-- #endif -->
</view>
</view>
</template>
</template>
<template v-else>
<view class="classify" v-if="detailList">
<view class="classify_title">选择核销门票</view>
<view class="classify_waper">
<view v-for="(i, index) in detailList.orderDetailChildList" :key="index" :class="'classify_list' + (i.active ? ' active' : '')" @click="tabActive(i, index)">
<view class="top">{{i.ticketName}}</view>
<view class="bottom">
<view>
<text>出行人</text>
<text>{{detailList.userName ? detailList.userName : '不实名'}} {{detailList.identityCard ? detailList.identityCard : ''}}</text>
</view>
<view>
<text>总核销次数</text>
<text>{{i.canVerificationNum > 0 ? i.canVerificationNum : '不限次数'}}</text>
</view>
<view>
<text>已核销次数</text>
<text>{{i.verificationNum}}</text>
</view>
<view v-if="detData.classify == '4' || detData.classify == '5'">
<text>当日核销次数</text>
<text>{{i.dayCount}}</text>
</view>
<view v-if="detData.classify == '4' || detData.classify == '5'">
<text>当月核销次数</text>
<text>{{i.monthCount}}</text>
</view>
</view>
<image src="../../static/img/active.png" mode="" v-if="i.active"></image>
</view>
</view>
</view>
<view class="classify_btn" @click="submitClassify">确认核销</view>
</template>
</template>
<!-- 不可核销 -->
<template v-else>
<view class="log_waper">
<view class="title">
<view>核销记录</view>
<view>剩余次数{{detData.verificationMunTotal}}</view>
</view>
<view class="cont">
<view class="list" v-for="(i, index) in detData.historyList" :key="index">
<view class="left">
<view v-if="detData.classify == '1'">已核销</view>
<view v-else>{{i.childTicketName}} - 已核销</view>
<view>{{i.createTime}}</view>
</view>
<view class="right">{{i.verificationNum}}</view>
</view>
</view>
</view>
</template>
</view>
<u-popup :show="show" round="10" mode="center">
<view class="popup_waper" v-if="detData">
<u-icon name="close" color="#333" size="42rpx" @click="closePopup"></u-icon>
<view v-if="result && result.code == 200">
<view class="status">
<image class="icon" src="../../static/img/hx11.png" mode=""></image>
</view>
<view class="text">核销成功</view>
<view class="msg" v-if="detData.classify == '1'">
{{detData.ticketName}}
{{num}}
<text v-if="detData.qrcodeRule == '1'"></text>
<text v-if="detData.qrcodeRule == '2'"></text>
({{detData.price}}/)
</view>
<view class="msg" v-if="detailList && activeCard">
{{activeCard.ticketName}}
{{num}}
<text></text>
</view>
<view class="popup_btn" @click="closePopup">确认</view>
</view>
<view v-if="result && result.code != 200">
<view class="status">
<image class="icon" src="../../static/img/hx12.png" mode=""></image>
</view>
<view class="text">核销失败</view>
<view class="msg">{{result.msg}}</view>
<view class="popup_btn" @click="closePopup">确认</view>
</view>
</view>
</u-popup>
<u-popup :show="show1" round="10" mode="center">
<view class="popup_waper1" v-if="detData">
<view class="title">确认核销</view>
<view class="msg" v-if="detData.qrcodeRule == '1'">确认是否核销{{num}}次门票</view>
<view class="msg" v-if="detData.qrcodeRule == '2'">确认是否核销{{num}}张门票</view>
<view class="btn-box">
<view class="default" @click="closePopup1">取消</view>
<view class="active" @click="submit">确定</view>
</view>
</view>
</u-popup>
</view>
</template>
<script>
export default {
data () {
return {
id: '',
code: '',
activeCard: null,
detData: null,
show: false,
show1: false,
result: null,
num: 0,
detailList: null
}
},
onLoad(options) {
this.code = options.code
this.getVerificationDetail()
},
methods: {
getNumbers(start, end) {
return Array.from({ length: end - start + 1 }, (_, i) => start + i);
},
tabActive (info, index) {
if (info.canVerificationNum == 0) {
this.detailList.orderDetailChildList.forEach((i, ind) => {
this.detailList.orderDetailChildList[ind].active = false;
})
this.detailList.orderDetailChildList[index].active = true;
this.$forceUpdate();
} else {
if (this.detData.classify == '4') {// 年卡
if (info.dayCount < info.dayVerificationNum && info.monthCount < info.monthVerificationNum) {
this.detData.orderChildList.forEach((i, ind) => {
this.detData.orderChildList[ind].active = false;
})
this.detData.orderChildList[index].active = true;
this.$forceUpdate();
} else uni.showToast({ mask: true, title: '当前门票当日/当月已无核销次数', icon: 'none' });
} else {
if (info.canVerificationNum - info.verificationNum > 0) {
this.detailList.orderDetailChildList.forEach((i, ind) => {
this.detailList.orderDetailChildList[ind].active = false;
})
this.detailList.orderDetailChildList[index].active = true;
this.$forceUpdate();
} else uni.showToast({ mask: true, title: '当前门票已无核销次数', icon: 'none' })
}
}
},
submitClassify () {
let info = this.detailList.orderDetailChildList.find((item) => {
return item.active
})
if (!info) {
uni.showToast({ mask: true, title: '请选择核销门票', icon: 'none' })
return false;
}
this.show1 = true;
this.num = 1;
this.activeCard = info;
},
async getVerificationDetail() {
let info = await this.$http.getVerificationDetail({ verificationCode: this.code, serialNo: this.$AppSerialNumber })
if (info.code == 200) {
this.detData = info.data
if (info.data.classify == '2') {
info.data.ticketOrderDetailList[0].orderDetailChildList.forEach((item, index) => {
info.data.ticketOrderDetailList[0].orderDetailChildList[index].active = false;
})
}
this.detailList = info.data.ticketOrderDetailList[0];
if (new Date().getTime() / 1000 > new Date(this.detData.availableEndTime + ' 23:59:59').getTime() / 1000) {
this.detData.timeActive = true;
} else this.detData.timeActive = false;
let time = [];
let weekLabel = '';
if (this.detData.applicablePeriod) {
this.detData.applicablePeriod.split(",").forEach((item) => {
time.push(Number(item));
})
if (this.detData.classify == '4') {
let arr = [];
time.forEach((item) => {
if (item > 0) arr.push(this.getDay(item))
})
weekLabel = arr.join(',');
} else {
if (time.length > 0) {
if (this.isContinuous(time)) {// 数组连续
weekLabel = this.getWeek(time[0]) + '至' + this.getWeek(time[time.length - 1]);
} else {
let arr = [];
time.forEach((item) => {
arr.push(this.getWeek(item))
})
weekLabel = arr.join(',');
}
} else weekLabel = '周一至周日';
}
}
this.detData.weekLabel = weekLabel ? weekLabel : '不限';
} else {
uni.$u.toast(info.msg);
setTimeout(() => {
uni.navigateBack()
}, 1500)
}
},
getDay (key) {
let str = '';
switch (key) {
case 1:
str = '周末';
break;
case 2:
str = '元旦';
break;
case 3:
str = '春节';
break;
case 4:
str = '清明';
break;
case 5:
str = '劳动';
break;
case 6:
str = '端午';
break;
case 7:
str = '中秋';
break;
case 8:
str = '国庆';
break;
}
return str;
},
isContinuous (nums) {
nums.sort((a, b) => a - b);
for (let i = 1; i < nums.length; i++) {
if (nums[i] !== nums[i - 1] + 1) {
return false;
}
}
return true;
},
getWeek (key) {
let str = '';
switch (key) {
case 1:
str = '周一';
break;
case 2:
str = '周二';
break;
case 3:
str = '周三';
break;
case 4:
str = '周四';
break;
case 5:
str = '周五';
break;
case 6:
str = '周六';
break;
case 7:
str = '周日';
break;
}
return str;
},
selectCard(e, type) {
if (type == '1') {
this.num = (this.detailList.canVerificationMun - this.detailList.verificationMun) - e;
} else {
this.num = this.detData.verificationMunTotal - e;
}
this.activeCard = e;
this.show1 = true;
},
closePopup () {
this.show = false;
this.activeCard = null;
uni.reLaunch({ url: '/pages/index/index' })
},
closePopup1() {
this.activeCard = null;
this.show1 = false;
},
async submit () {
let params = {}
if (this.detData.classify == '1') {// 普通票
if (this.detData.qrcodeRule == '1') {// 一票一码
params = { qrcodeRule: '1', detailId: this.detailList.id, num: this.num, ticketClassify: this.detData.classify, orderItemId: this.detData.id };
} else params = { qrcodeRule: '2', detailId: this.detailList.id, num: this.num, ticketClassify: this.detData.classify, orderItemId: this.detData.id };
} else {// 套票
params = { qrcodeRule: '1', childId: this.activeCard.id, num: 1, ticketClassify: this.detData.classify, orderItemId: this.detData.id };
}
// if (this.detData.classify == '1') {
// params = {
// qrcodeRule: this.detData.qrcodeRule,
// num: this.num,
// ticketClassify: this.detData.classify
// }
// if (this.detData.qrcodeRule == '1') {
// params.id = this.detData.id
// } else if (this.detData.qrcodeRule == '2') {
// params.orderId = this.detData.orderId
// }
// } else {
// params = { qrcodeRule: '1', id: this.activeCard.id, num: 1, ticketClassify: this.detData.classify };
// }
let info = null;
// #ifdef APP-PLUS
params.serialNo = this.$AppSerialNumber;
params.ticketId = this.detData.classify == '1' ? this.detData.ticketId : this.activeCard.ticketId;
// params.ticketId = this.detData.orderChildList.length == 0 ? this.detData.ticketId : this.activeCard.ticketId;
info = await this.$http.handheldVerification(params)
// #endif
// #ifndef APP-PLUS
info = await this.$http.toVerification(params)
// #endif
this.result = info;
if (this.detData.classify == '1') {
this.closePopup1()
} else this.show1 = false;
this.show = true;
},
}
}
</script>
<style lang="scss">
.waper{
width: 100%; box-sizing: border-box;
.colorLump {
width: 750rpx;
height: 228rpx;
background: #03AE80;
}
.con-box {
margin-top: -196rpx;
padding: 0 32rpx 32rpx;
}
.info{
width: 686rpx; height: 644rpx; box-sizing: border-box; padding: 24rpx 24rpx 32rpx; position: relative;
.bgm {
position: absolute;
left: 0;
top: 0;
}
.top{
width: 638rpx;
margin: 24rpx 24rpx 0;
padding-bottom: 32rpx;
position: absolute;
left: 0;
top: 0;
border-bottom: 1rpx dashed rgba(0,0,0,0.2);
display: flex;
.img{
width: 140rpx; height: 140rpx; margin-right: 20rpx;
image{ border-radius: 10rpx; }
}
.text-box{
flex: 1;
.title {
display: flex;
align-items: center;
justify-content: space-between;
.label {
font-weight: 500;
font-size: 28rpx;
color: #333333;
}
.status {
font-weight: 400;
font-size: 28rpx;
color: #FF5833;
}
}
.price {
margin-top: 20rpx;
font-weight: 500;
font-size: 28rpx;
color: #333333;
}
}
}
.bottom{
width: 638rpx;
margin: 32rpx 24rpx;
position: absolute;
left: 0;
bottom: 0;
.row {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 30rpx;
&:first-child {
margin-top: 0;
}
.key {
font-weight: 400;
font-size: 28rpx;
color: #666666;
}
.value {
font-weight: 400;
font-size: 28rpx;
color: #333333;
}
}
}
}
.information {
margin-top: 20rpx;
width: 686rpx;
height: 222rpx;
background: #FFFFFF;
border-radius: 10rpx;
padding: 32rpx 24rpx;
box-sizing: border-box;
display: flex;
align-items: center;
.item {
width: 200rpx;
height: 159rpx;
background: #FBFBFB;
border-radius: 10rpx;
text-align: center;
margin-right: 19rpx;
&:last-child {
margin-right: 0;
}
.num {
margin-top: 24rpx;
font-weight: bold;
font-size: 48rpx;
color: #333333;
}
.label {
margin-top: 8rpx;
font-weight: 400;
font-size: 28rpx;
color: #666666;
}
}
}
.quantity {
margin-top: 20rpx;
width: 686rpx;
background: #FFFFFF;
border-radius: 10rpx;
padding: 32rpx 24rpx;
box-sizing: border-box;
.title {
font-weight: 500;
font-size: 32rpx;
color: #333333;
}
.card-box {
padding-top: 8rpx;
.card {
display: inline-block;
width: 142rpx;
height: 100rpx;
background: #FBFBFB;
border-radius: 10rpx;
line-height: 100rpx;
text-align: center;
font-weight: 500;
font-size: 32rpx;
color: #333333;
margin: 16rpx 23rpx 0 0;
&:nth-child(4n) {
margin-right: 0;
}
}
.active {
background: #03AE80;
color: #fff;
}
}
}
.classify{
width: 100%; margin-top: 20rpx; background: #fff; border-radius: 10rpx; box-sizing: border-box; padding: 32rpx 24rpx;
.classify_title{ line-height: 46rpx; color: #333; font-size: 32rpx; color: #333; font-weight: 500; }
.classify_waper{
width: 100%; margin-top: 24rpx;
.classify_list{
width: 100%; background: #FBFBFB; box-sizing: border-box; border: 2rpx solid #FBFBFB; border-radius: 10rpx; padding: 24rpx; margin-bottom: 16rpx;
&:last-child{ margin-bottom: 0; }
.top{ line-height: 40rpx; color: #333; font-size: 28rpx; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bottom{
width: 100%; margin-top: 20rpx;
view{
font-size: 0; height: 40rpx; line-height: 40rpx; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-bottom: 16rpx;
&:last-child{ margin-bottom: 0; }
text{
color: #666; font-size: 28rpx;
&:last-child{ color: #333; }
}
}
}
&.active{
border-color: #03AE80; position: relative;
image{ width: 90rpx; height: 90rpx; position: absolute; right: 0; bottom: 0; }
}
}
}
}
.classify_btn{ width: 100%; margin-top: 36rpx; border-radius: 100rpx; background: #03AE80; color: #fff; font-size: 32rpx; font-weight: 500; text-align: center; line-height: 90rpx; height: 90rpx; }
}
/deep/.u-safe-bottom {
display: none;
}
.popup_waper1 {
width: 638rpx;
height: 350rpx;
background: linear-gradient( 180deg, #E8F8F4 0%, rgba(232,248,244,0) 100%);
border-radius: 20rpx;
padding: 64rpx 32rpx 39rpx;
box-sizing: border-box;
text-align: center;
.title {
font-weight: 500;
font-size: 40rpx;
color: #000000;
}
.msg {
margin-top: 24rpx;
font-weight: 400;
font-size: 28rpx;
color: #333333;
}
.btn-box {
margin-top: 48rpx;
display: flex;
align-items: center;
justify-content: space-between;
.default {
width: 274rpx;
height: 78rpx;
border-radius: 80rpx;
border: 1rpx solid #999999;
line-height: 78rpx;
text-align: center;
font-weight: 400;
font-size: 30rpx;
color: #666666;
}
.active {
width: 276rpx;
height: 80rpx;
background: #03AE80;
border-radius: 80rpx;
line-height: 80rpx;
text-align: center;
font-weight: 500;
font-size: 30rpx;
color: #FFFFFF;
}
}
}
.log_waper{
width: 100%; margin-top: 20rpx; background: #fff; box-sizing: border-box; padding: 32rpx 24rpx 20rpx; border-radius: 10rpx;
.title{
height: 46rpx; display: flex; justify-content: space-between; align-items: center;
view{
&:nth-child(1){ color: #333; font-size: 32rpx; font-weight: 500; }
&:nth-child(2){ color: #999; font-size: 24rpx; }
}
}
.cont{
width: 100%; margin-top: 4rpx;
.list{
width: 100%; padding: 20rpx 0; display: flex; justify-content: space-between; align-items: center; border-bottom: 2rpx solid #E8E8E8;
&:last-child{ border-bottom: 0; }
.left{
view{
&:nth-child(1){ color: #333; font-size: 28rpx; font-weight: 500; line-height: 40rpx; }
&:nth-child(2){ color: #999; font-size: 24rpx; line-height: 34rpx; margin-top: 8rpx; }
}
}
.right{ line-height: 50rpx; color: #FF3333; font-size: 36rpx; font-weight: 600; }
}
}
}
</style>