导游中台-游客端
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.

924 lines
22 KiB

11 months ago
<template>
<view class="bg">
<view class="top-box">
11 months ago
<view class="top-title">{{skuInfo.title}}</view>
<view class="top-subtitle">出行日期{{selectDay}}</view>
<view class="top-subtitle">已选{{skuInfo.title}}</view>
11 months ago
</view>
<!-- 出行人数 -->
<view class="num-box flex-column">
<view class="flex-between">
<view>出行人数 <span>请如实填写必填</span></view>
<view style="display: flex;align-items: center;">
<image src="https://static.ticket.sz-trip.com/tourist/daoyou/numDel.png" @click="changeNum(0)"></image>
<view class="num">{{buyNum}}</view>
<image src="https://static.ticket.sz-trip.com/tourist/daoyou/numAdd.png" @click="changeNum(1)"></image>
</view>
</view>
<view>若超过最大出行人数请预约多名导游</view>
</view>
<!-- 出行信息 -->
<view class="people-box">
10 months ago
<view>{{skuInfo.is_card == 1 ? (skuInfo.is_real_name ? '需填'+buyNum+'位出行人' : '需填1位出行人') : '无需填写出行人'}}</view>
11 months ago
<!-- is_card是否实名 -->
10 months ago
<view v-if="skuInfo.is_card == 1">
11 months ago
<!-- 已选中出行人 -->
<view v-if="seldPeople.length > 0">
<view class="people-seld">
<view class="people-seldItem" v-for="(item,index) in seldPeople" :key="index">
{{item.name}}
<image src="https://static.ticket.sz-trip.com/tourist/daoyou/dui.png"></image>
</view>
<view class="people-more" @click="changeContactAddPopup('open',{})">更多></view>
</view>
</view>
11 months ago
<view class="people-list">
<view class="people-item flex-between" v-for="(item,index) in seldPeople" :key="item.id">
<image src="https://static.ticket.sz-trip.com/tourist/daoyou/del.png" class="del-img" @click="removeSeldPeople(item, index)"></image>
<view class="item-peopleNum">
出行人{{index + 1}}
</view>
<view class="item-text">
<view class="name text-overflow">{{ item.name }}</view>
<view class="subtitle">手机号 {{ item.tel }}</view>
<view class="subtitle">{{ item.title }} {{ item.id_number }}</view>
</view>
11 months ago
<image src="https://static.ticket.sz-trip.com/tourist/daoyou/edit.png" class="edit-img" @click="changeContactAddPopup('open',item)"></image>
11 months ago
</view>
</view>
11 months ago
<view class="people-add" v-for="(item,index) in skuInfo.is_real_name ? buyNum : 1" :key="index" @click="changeContactAddPopup('open',{})"
11 months ago
v-if="!seldPeople[index]">
11 months ago
<image src="https://static.ticket.sz-trip.com/tourist/daoyou/add.png" class="add-img"></image>
<view>出行人{{index + 1}} 点击填写1位出行人信息</view>
<image src="https://static.ticket.sz-trip.com/tourist/daoyou/peopleRight.png" class="right-img"></image>
</view>
</view>
<view class="flex-between">
联系电话
<input type="number" maxlength="11" v-model="phone" placeholder="请填写联系手机号"/>
<image src="https://static.ticket.sz-trip.com/tourist/daoyou/phoneClear.png" v-if="phone.length > 0" @click="phone = ''"></image>
</view>
</view>
11 months ago
<footer class="flex-between">
<view class="footer-left">
<view>
10 months ago
合计<span>{{sku.money / 100}}</span>
11 months ago
</view>
<view style="margin-top: 10rpx;" @click="clickAgreement(0)">
10 months ago
<span><image src="https://static.ticket.sz-trip.com/tongli/images/user/dui.png" v-show="isAgreement"></image></span>阅读并同意{{xieyi.title}}
11 months ago
</view>
</view>
<view :class="['order-btn', {'order-disable': !isAgreement}]" @click="order">去支付</view>
</footer>
<!-- 选择出行人 -->
<uni-popup ref="contactPopup" type="bottom" backgroundColor="#F4F4F4" >
<view class="people-popup">
<view class="ptop-box">
<view class="top flex-between" style="padding-bottom: 14rpx;">
<text class="text-overflow" @click="$refs.contactPopup.close()">取消</text>
<text style="color: #96684F;" class="confirm" @click="$refs.contactPopup.close()">确定</text>
</view>
</view>
<view class="button" @click="$refs.contactAddPopup.open()">添加出行人</view>
<view class="popup-list" v-if="contactList.length > 0">
<view :class="['popup-item', item.isSeld ? 'active': '']"
v-for="(item, index) in contactList" :key="index" @click="seldThisContact(item,index)">
<view class="item-top flex flex-items-center">
<image src="https://static.ticket.sz-trip.com/tourist/daoyou/edit.png" class="edit-img" @click.stop="changeContactAddPopup('open',item)"></image>
<view class="name flex-shrink-0" style="padding-left: 32rpx;width: 180rpx;">{{item.name}}</view>
<view class="flex-1 w-1rpx" style="padding-left: 20rpx;">
<view class="name">
<text>手机号 {{ item.tel }}</text>
<text class="tag" v-if="item.is_default == 1">默认</text>
</view>
<view class="subtitle text-overflowRows">身份证 {{ item.id_number}}</view>
</view>
</view>
</view>
</view>
</view>
</uni-popup>
<!-- 新增编辑出行人弹窗 -->
<uni-popup ref="contactAddPopup" type="bottom" backgroundColor="#F4F4F4" style="border-radius: 13rpx 13rpx 0 0;">
<view class="people-popup" style="padding: 0;">
<view class="ptop-box">
<view class="top flex-between" style="height: fit-content;">
<text class="text-overflow" @click="changeContactAddPopup('close')">取消</text>
<text style="color: #96684F;" class="confirm" @click="saveContact">保存</text>
</view>
</view>
<view class="add-edit-content">
<contactAddVue ref="contactAddVueRef"></contactAddVue>
</view>
</view>
</uni-popup>
<!-- 协议弹框 -->
<uni-popup ref="agreementPopup" type="bottom" backgroundColor="#FFFFFF">
<view class="agreement-box">
<image src="https://static.ticket.sz-trip.com/tourist/daoyou/cha.png" class="agreement-cha" @click="$refs.agreementPopup.close()"></image>
<scroll-view class="agreement-content" scroll-y="true" @scrolltolower="lower" lower-threshold="20">
10 months ago
<view class="agreement-title">{{xieyi.title}}</view>
<view v-html="formateRichText(xieyi.content)"></view>
11 months ago
</scroll-view>
<view class="agreement-btn flex-center">
11 months ago
<view :class="['flex-center', {'agreement-disable': !isBottom}]" @click="clickAgreement(1)">
{{isBottom ? '同意本条款' : '请上滑看完本条款后同意'}}
</view>
11 months ago
</view>
</view>
</uni-popup>
11 months ago
</view>
</template>
<script>
11 months ago
import contactAddVue from '@/components/contactAdd.vue';
11 months ago
export default {
11 months ago
components: {contactAddVue},
11 months ago
data() {
return {
buyNum: 1,
11 months ago
sku: this.$store.state.user.touristInfo.sku,
skuInfo: this.$store.state.user.touristInfo.sku.sku_info,
selectDay: this.$store.state.user.touristInfo.selectDay,
11 months ago
phone: '',
11 months ago
seldPeople: [],
contactList: [],
isAgreement: false,
11 months ago
isBottom: false,
10 months ago
xieyi: ''
11 months ago
}
},
11 months ago
onLoad() {
10 months ago
console.log(this.skuInfo)
11 months ago
this.getContactList()
11 months ago
// 获取下单协议
this.Post({
id: 3
}, '/api/Article/getArticleById').then(res => {
10 months ago
this.xieyi = res.data
11 months ago
})
11 months ago
},
11 months ago
methods: {
11 months ago
// 下单
order() {
let seldUserIdArr = []
// is_card 是否实名 0否 1是
10 months ago
if(this.skuInfo.is_card == 1) {
11 months ago
for (let i = 0; i < this.seldPeople.length; i++) {
seldUserIdArr.push(this.seldPeople[i].id)
}
if (seldUserIdArr.length < 1) {
uni.showToast({
title:'请选择出行人',
icon:'none'
})
return;
}
}
if (!this.IsTel(this.phone)) {
uni.showToast({
title:'请输入正确格式的手机号',
icon:'none'
})
return;
}
// 阅读协议
if(this.isAgreement) {
let goods = []
let params = {
11 months ago
goods_id: this.skuInfo.goods_id,
specifications_id: this.skuInfo.id,
10 months ago
num: 1,
contact_num: this.buyNum,
11 months ago
contact_id: seldUserIdArr,
11 months ago
date: this.selectDay,
11 months ago
start_time: '',
11 months ago
end_time: ''
11 months ago
}
goods.push(params)
let data = {
goods: goods,
coupon: this.coupon ? this.coupon.id : "",
10 months ago
reserve_phone: this.phone,
guide_id: this.$store.state.user.touristInfo.guide_id
11 months ago
}
this.Post({
method: 'POST',
data: JSON.stringify(data)
}, '/api/order/place').then(res => {
10 months ago
let order_id = res.data.order_id
this.$store.commit("changeTouristInfo", null);
this.$store.commit("choseCoupon", "");
11 months ago
10 months ago
this.Post({
order_id: order_id,
type: "miniprogram",
platform: 'miniprogram'
}, '/api/pay/unify').then(res => {
if (res.data) {
let data = res.data
WeixinJSBridge.invoke('getBrandWCPayRequest', {
"appId": data.appId, //公众号ID,由商户传入
"timeStamp": data.timeStamp, //时间戳,自1970年以来的秒数
10 months ago
"nonceStr": data.nonceStr, //随机串
10 months ago
"package": data.package,
"signType": data.signType, //微信签名方式:
"paySign": data.paySign //微信签名
},
function(res) {
// if (res.err_msg == "get_brand_wcpay_request:ok") {
// // 使用以上方式判断前端返回,微信团队郑重提示:
// //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
// }
uni.navigateTo({
10 months ago
url: '/subPackages/order/trades'
10 months ago
})
});
}
})
11 months ago
})
}else {
this.isBottom = false
this.$refs.agreementPopup.open()
}
},
// 查看协议
clickAgreement(type) {
11 months ago
if(type && this.isBottom) {
11 months ago
this.isAgreement = true
this.$refs.agreementPopup.close()
}else {
if(this.isAgreement){
this.isAgreement = false
return;
}
this.isBottom = false
this.$refs.agreementPopup.open()
}
},
// 协议触底
lower() {
this.isBottom = true
},
// 出行人弹框
changeContactAddPopup(type, item) {
if(type == 'open') {
// 如果没有出行人或编辑 打开新增编辑弹窗
if (this.contactList.length<=0 || item.id) {
this.$refs.contactAddPopup.open()
if(item.id) {
this.$nextTick(()=>{
this.$refs.contactAddVueRef.init(item)
})
}
return;
}
this.$refs.contactPopup.open()
}else {
this.$refs.contactAddPopup.close()
}
},
// 选中出行人
seldThisContact(item,index) {
// 实名一证多票
11 months ago
if(!this.skuInfo.is_real_name) {
11 months ago
if(item.isSeld) {
this.contactList[index].isSeld = false
this.seldPeople = []
}else {
for (let i = 0; i < this.contactList.length; i++) {
this.contactList[i].isSeld = false
}
}
};
// 一证一票
11 months ago
if (this.skuInfo.is_real_name && item.isSeld) {
11 months ago
this.contactList[index].isSeld = false
this.seldPeople = []
for (let i = 0; i < this.contactList.length; i++) {
if (this.contactList[i].isSeld) {
this.seldPeople.push(this.contactList[i])
}
}
if (this.buyNum <= this.seldPeople.length + 1) {
this.buyNum = this.seldPeople.length || 1
}
return
}
let nowSeld = []
for (let i = 0; i < this.contactList.length; i++) {
if (this.contactList[i].isSeld) {
nowSeld.push(this.contactList[i])
}
}
// 根据出行数量更换出行人
if(this.buyNum == 1) {
for (let i = 0; i < this.contactList.length; i++) {
this.contactList[i].isSeld = false
}
nowSeld = []
11 months ago
}else if(this.skuInfo.is_real_name && this.seldPeople.length == this.buyNum && item.isSeld == false) {
11 months ago
this.$toast('您只需选择' + this.buyNum + '游客')
return;
}
item.isSeld = true
nowSeld.push(this.contactList[index])
this.seldPeople = nowSeld
},
11 months ago
// 取消选中出行人
removeSeldPeople(item,index) {
for (let i = 0; i < this.seldPeople.length; i++) {
if (this.seldPeople[i].id == item.id) {
this.seldPeople.splice(i, 1)
}
}
},
11 months ago
// 保存出行人
async saveContact () {
let res = await this.$refs.contactAddVueRef.submit()
if (res && res.code == 1) {
this.getContactList();
this.changeContactAddPopup('close')
}
},
// 获取出行人信息
getContactList() {
this.Post({},'/api/user/contactList').then(res => {
10 months ago
res.data.forEach((item, index) => {
11 months ago
item.isSeld = false
10 months ago
// 默认出行人选中
if(this.seldPeople.length == 0 && item.is_default == 1) {
item.isSeld = true
this.seldPeople.push(item)
}
11 months ago
})
this.contactList = res.data
10 months ago
// 如果是添加或者修改完出行人后需要默认选中已选择的出行人
if(this.seldPeople.length > 0){
for (let i = 0; i < this.seldPeople.length; i++) {
for (let j = 0; j < this.contactList.length; j++) {
if(this.contactList[j].id == this.seldPeople[i].id){
this.seldPeople[i] = this.contactList[j]
this.contactList[j].isSeld = true
}
}
}
this.$forceUpdate()
}
11 months ago
})
},
11 months ago
// 选择数量
changeNum(type) {
if(type) {
// 增加数量
this.buyNum += 1
10 months ago
if(this.buyNum > this.skuInfo.contact_num){
this.buyNum = this.skuInfo.contact_num
uni.showToast({
title:"最大出行人数为"+this.skuInfo.contact_num,
icon:'none'
})
}
11 months ago
}else {
// 减少数量
if (this.buyNum <= 1) {
return
}
11 months ago
if(this.buyNum == this.seldPeople.length) {
this.contactList.forEach(item => {
if(item.id == this.seldPeople[this.seldPeople.length -1].id) {
item.isSeld = false
}
})
this.seldPeople.pop()
}
11 months ago
this.buyNum -= 1
}
}
}
}
</script>
<style lang="scss" scoped>
.bg {
background: #F7F7F7;
min-height: 100vh;
padding: 26.67rpx 26.67rpx 200rpx;
}
.top-box {
background: #FFFFFF;
border-radius: 13rpx;
padding: 30rpx 36rpx 30rpx 19rpx;
.top-title {
font-weight: bold;
font-size: 31rpx;
color: #000000;
line-height: 40rpx;
}
.top-subtitle {
margin-top: 15rpx;
font-weight: 500;
font-size: 27rpx;
color: #333333;
}
}
.num-box {
height: 200rpx;
background: #FFFFFF;
border-radius: 13rpx;
margin-top: 26.67rpx;
padding: 20rpx 22rpx;
justify-content: space-around;
&>view:first-child {
font-weight: bold;
font-size: 31rpx;
color: #000000;
span {
font-weight: 500;
font-size: 24rpx;
color: #666666;
margin-left: 18rpx;
}
}
&>view:last-child {
font-weight: 500;
font-size: 24rpx;
color: #DC2525;
}
image {
width: 46.67rpx;
height: 46.67rpx;
}
.num {
width: 67rpx;
text-align: center;
font-weight: bold;
font-size: 29rpx;
color: #000000;
}
}
.people-box {
margin-top: 27.33rpx;
background: #FFFFFF;
border-radius: 13rpx;
font-weight: bold;
font-size: 31rpx;
color: #000000;
&>view {
padding: 40rpx 20rpx;
}
&>view:nth-child(n+2) {
border-top: 1rpx solid rgba(204, 204, 204, .5);
}
&>view:last-child {
input {
font-weight: 500;
font-size: 31rpx;
color: #999999;
flex: 1;
margin: 0 40rpx;
}
image {
width: 20rpx;
height: 20rpx;
}
}
11 months ago
.people-seld {
display: flex;
flex-wrap: wrap;
.people-seldItem {
padding: 0 50rpx;
line-height: 70rpx;
background: #F9F5F0;
border-radius: 11rpx;
border: 2rpx solid #96684F;
position: relative;
font-weight: 400;
font-size: 29rpx;
color: #000000;
margin: 0 15rpx 10rpx 0;
image {
width: 28rpx;
height: 28rpx;
position: absolute;
bottom: 0;
right: 0;
}
}
.people-more {
width: 110rpx;
line-height: 73rpx;
background: #F6F1EA;
border-radius: 11rpx;
text-align: center;
font-weight: 500;
font-size: 29rpx;
color: #96684F;
}
}
11 months ago
.people-list {
.people-item {
padding: 0 20rpx;
11 months ago
margin-top: 20rpx;
11 months ago
.del-img {
width: 45.33rpx;
height: 45.33rpx;
}
.item-peopleNum {
font-weight: 400;
font-size: 27rpx;
color: #000000;
}
.item-text {
.name {
font-weight: 400;
font-size: 31rpx;
color: #000000;
}
.subtitle {
font-weight: 400;
font-size: 24rpx;
color: #666666;
}
}
.edit-img {
width: 32.67rpx;
height: 32.67rpx;
}
}
}
.people-add {
height: 80rpx;
background: #F9F5F0;
border-radius: 13rpx;
display: flex;
align-items: center;
font-weight: 500;
font-size: 27rpx;
color: #96684F;
padding: 0 20rpx;
.add-img {
width: 45.33rpx;
height: 45.33rpx;
margin-right: 28rpx;
}
.right-img {
width: 20rpx;
height: 20rpx;
margin-left: auto;
}
}
.people-add:not(:first-child) {
margin-top: 26rpx;
}
}
11 months ago
.people-popup {
padding: 26rpx;
height: 800rpx;
background: #F7F7F7;
.ptop-box {
height: 120rpx;
display: flex;
align-items: center;
.top {
position: fixed;
left: 0;
right: 0;
color: #000;
height: 80rpx;
font-size: 0;
overflow: hidden;
padding: 0 26rpx;
text {
text-align: left;
font-size: 35rpx;
font-weight: 400;
color: #000000;
}
.confirm {
font-weight: 400;
color: #000000;
}
}
}
.popup-list {
height: 666rpx;
overflow: scroll;
.popup-item {
border-radius: 12rpx;
padding: 2rpx;
margin-top: 24rpx;
font-size: 24rpx;
color: #333333;
font-weight: 400;
background-color: #ffffff;
.item-top {
border-radius: 12rpx;
padding: 30rpx 40rpx;
background-color: #ffffff;
image {
color: #666666;
width: 40rpx;
height: 40rpx;
}
.name {
overflow: hidden;
font-family: PingFang SC;
font-weight: 400;
font-size: 32rpx;
text {
color: #666;
font-size: 25rpx;
}
.tag {
padding: 0 8rpx;
height: 32rpx;
border-radius: 7rpx;
line-height: 30rpx;
text-align: center;
font-size: 23rpx;
font-family: PingFang SC;
font-weight: 500;
color: #ffffff;
background: #96684F;
margin-left: 10rpx;
}
}
.com-flex-start {
margin: 0 0 30rpx;
}
.subtitle {
font-weight: 400;
flex: 1;
text-align: left;
margin-top: 33rpx;
color: #666666;
font-size: 25rpx;
.mobile {
margin-bottom: 36rpx;
}
}
.status {
width: 40rpx;
height: 40rpx;
line-height: 40rpx;
border-radius: 50%;
text-align: center;
box-sizing: border-box;
img {
width: 27rpx;
height: 21rpx;
}
}
.statuss {
background: linear-gradient(90deg, #fa2b66, #ff9834);
border: none;
}
.noSelect {
border: 1rpx solid #999999;
}
}
.item-site {
color: #666666;
display: flex;
align-items: center;
padding: 36rpx 0;
view {
width: 23rpx;
height: 23rpx;
margin-right: 10rpx;
border: 1rpx solid #999999;
border-radius: 50%;
view {
width: 8rpx;
height: 8rpx;
background: #000000;
border-radius: 50%;
margin: auto;
}
}
}
}
.popup-item.active{
border: 2rpx solid #96684F;
}
.popup-item.disabled{
.item-top {
background-color: #CCC;
}
}
}
.button {
text-align: center;
width: 100%;
height: 80rpx;
line-height: 80rpx;
background-color: #ffffff;
border-radius: 40rpx;
font-family: PingFang SC;
font-weight: 400;
font-size: 33rpx;
color: #000000;
}
.add-edit-content{
border-radius: 13rpx;
min-height: 800rpx;
margin: 0 22rpx;
}
}
footer {
width: 750rpx;
height: 153rpx;
background: #FFFFFF;
box-shadow: 0rpx 0rpx 13rpx 0rpx rgba(82,82,82,0.25);
position: fixed;
bottom: 0;
left: 0;
.footer-left {
margin-left: 26rpx;
&>view:first-child {
font-weight: bold;
font-size: 32rpx;
color: #000000;
span {
font-size: 40rpx;
color: #DC2525;
}
span::before {
font-size: 24rpx;
content: '¥';
}
}
&>view:last-child {
display: flex;
align-items: center;
font-weight: 500;
font-size: 24rpx;
color: #666666;
span {
width: 31rpx;
height: 31rpx;
border-radius: 50%;
border: 1rpx solid #666666;
margin-right: 11rpx;
image {
width: 100%;
height: 100%;
}
}
}
}
.order-btn {
width: 233rpx;
line-height: 73rpx;
border-radius: 11rpx;
background: #DC2525;
text-align: center;
font-weight: bold;
font-size: 32rpx;
color: #FFFFFF;
margin-right: 26rpx;
}
.order-disable {
background: #CCCCCC;
}
}
.agreement-box {
width: 100vw;
height: 60vh;
padding: 80rpx 26rpx 200rpx 26rpx;
position: relative;
.agreement-cha {
width: 31.33rpx;
height: 31.33rpx;
position: absolute;
right: 26rpx;
top: 26rpx;
}
.agreement-content {
font-weight: 500;
font-size: 29rpx;
color: #666666;
padding-bottom: 50rpx;
height: 45vh;
.agreement-title {
font-weight: bold;
font-size: 32rpx;
color: #000000;
text-align: center;
margin-bottom: 36rpx;
}
}
.agreement-btn {
width: 750rpx;
height: 153rpx;
background: #FFFFFF;
box-shadow: 0rpx 0rpx 13rpx 0rpx rgba(82,82,82,0.25);
position: absolute;
bottom: 0;
left: 0;
view {
width: 697rpx;
height: 73rpx;
background: #DC2525;
border-radius: 11rpx;
font-weight: bold;
font-size: 32rpx;
color: #FFFFFF;
}
.agreement-disable {
background: #CCCCCC;
}
}
}
11 months ago
</style>