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.

852 lines
25 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view class="container">
<image class="cbg" :src="base.imgHost('common_bg.png')"></image>
<view class="wrap">
<view style="text-align: center;padding-top: 20rpx;color: #999;">
{{bookName}}可预约时间为每天的{{bookStartTime}}~{{bookEndTime}}
</view>
<u-form :model="form" ref="uForm" :label-width="140" :label-align="'left'" :error-type="['message']">
<u-form-item label="预约场地" prop="siteName" required>
<u-input :placeholder="'请选择'" v-model="form.siteName" type="select" @click="showSite" />
</u-form-item>
<u-form-item label="预约开始时间" :label-width="180" prop="start_time" required>
<u-input :placeholder="'请选择'" @click="startTimeShow" v-model="form.start_time"
:type="'select'" />
</u-form-item>
<u-form-item label="预约结束时间" :label-width="180" prop="end_time" required>
<u-input :placeholder="'请选择'" @click="endTimeShow" v-model="form.end_time"
:type="'select'" />
</u-form-item>
<u-form-item label="预约事项" prop="content" required>
<u-input :placeholder="'请输入预约事项'" v-model="form.content" type="textarea" />
</u-form-item>
<u-form-item label="身份证号" prop="idcard" required>
<u-input :placeholder="'请输入身份证号'" v-model="form.idcard" type="idcard" />
</u-form-item>
<u-form-item label="车牌" prop="plate">
<u-button size="mini" type="primary" @click="openPlate(-1)">新增</u-button>
<view v-for="(item,index) in plateList">
<view v-if="plateList[index]['show']"
style="display: flex;justify-content: space-between;align-items: center;">
<u-input :placeholder="''" v-model="plateList[index]['plate']" :disabled="true"
@click="openPlate(index)" />
<u-button size="mini" type="error" @click="delPlate(index)">删除</u-button>
</view>
</view>
</u-form-item>
<u-form-item label="同行人" prop="accompany">
<u-button size="mini" :disabled="isTotal" :type="isTotal?'':'primary'"
@click="addAccompany">新增</u-button>
<text style="margin-left:10rpx" v-if="siteTotal && siteTotal>0">当前场地最多可预约{{siteTotal}}人</text>
<u-table>
<u-tr>
<u-th>姓名</u-th>
<u-th>操作</u-th>
</u-tr>
<u-tr v-for="(item,index) in form.accompany">
<u-td>{{item.name}}</u-td>
<u-td>
<u-button size="mini" type="error" @click="delAccompany(index)">删除</u-button>
</u-td>
</u-tr>
</u-table>
</u-form-item>
</u-form>
<view class="form-btn">
<view @click="submit" type="primary">预约</view>
</view>
</view>
<u-picker @confirm="siteConfirm" v-model="siteShow" :range="siteList" range-key="real_name"
mode="selector"></u-picker>
<u-picker @confirm="startConfirm" :default-time="startTime" :params="timeParams" v-model="showStartTime"
mode="time"></u-picker>
<u-picker @confirm="endConfirm" :default-time="endTime" :params="timeParams" v-model="showEndTime"
mode="time"></u-picker>
<!-- 新增车牌 -->
<view class="modal">
<u-popup v-model="showPlate" mode="bottom" @close="closePlate">
<view class="modal-tip">车牌号</view>
<view class="modal-content" style="height:400rpx">
<plate ref="plates" @listenPlateChange="(val)=>{plateChange(val,index)}"
:defaultPlate="plateNumber" />
</view>
<view class="form-btn" @click="confirmPlate">
<view type="primary">确认</view>
</view>
</u-popup>
</view>
<!-- 新增修改同行人 -->
<view class="modal">
<u-popup v-model="accompanyShow" mode="bottom" @close="">
<view class="modal-tip">同行人</view>
<view class="modal-content">
姓名:<u-input :placeholder="'请输入姓名'" v-model="accompanyObj.name" />
</view>
<view class="modal-content">
身份证:<u-input type="idcard" :placeholder="'请输入身份证'" v-model="accompanyObj.idcard" />
</view>
<view class="modal-content">
手机号:<u-input type="number" :placeholder="'请输入手机号'" v-model="accompanyObj.mobile" />
</view>
<view class="form-btn">
<view @click="submitAccompany" type="primary">提交</view>
</view>
</u-popup>
</view>
<!-- 预约须知 -->
<u-popup v-model="showTips" mode="bottom" height="800rpx" border-radius="30rpx" :mask-close-able="false"
class="configwrap">
<view class="slot-content">
<!-- <view class="configtitle">
{{configInfo.name}}
</view> -->
<view class="slot-content-input">
<view v-html='tips'></view>
</view>
<view class="slot-content-btn" style="padding-top:30rpx">
<view @click="confirmTipsMethods">我已知晓</view>
</view>
</view>
</u-popup>
<!-- 我要放弃 -->
<u-modal v-model="showCancel" negative-top="400" :show-cancel-button="false"
:show-confirm-button="false" :show-title="false" class="cancelWrap">
<view class="slot-content" v-if="myQrcode">
<view class="slot-content-title">提示</view>
<view class="slot-content-tip">您已有一次预约,预约时间为<span
style="color:red">{{myQrcode.mytime}}</span>,预约场地为<span
style="color:red">
<block v-if="myQrcode.site_detail && myQrcode.site_detail.length>0">
<block v-for="(site,index) in myQrcode.site_detail">
{{site.real_name}}<block v-if="index+1<myQrcode.site_detail.length">,</block>
</block>
</block>
</span>,如您想再次预约其他时间,需先取消该预约,请确认是否取消?
</view>
<view class="slot-content-btn">
<view @click="backBook">返回</view>
<view @click="cancelBook">确认取消</view>
</view>
</view>
</u-modal>
</view>
</template>
<script>
import {
plate
} from '@/components/plate/index.vue'
export default {
components: {
plate
},
data() {
return {
showCancel: false, // 是否有预约
myQrcode: null, // 我是否有大于等于今天的 预约
isLocked: false,
showTips: false,
tips: '',
confirmTips: false,
bookName: '',
showStartTime: false,
showEndTime: false,
startTime: '',
endTime: '',
timeParams: {
year: true,
month: true,
day: true,
hour: true,
minute: true,
second: false,
},
bookStartTime: '', //可预约开始时间
bookEndTime: '', // 可预约结束时间
hMin: 0, // 开始时间小时
hMax: 24, //结束时间小时
mStart: 0, // 开始时间分钟
mEnd: 0, // 结束时间分钟
appoinementType: '',
user_id: "",
showPlate: false,
plateIndex: -1,
plateList: [],
plateNumber: ['苏', 'E', '', '', '', '', ''],
form: {
date: '',
timeRange: '',
start_time: '',
end_time: '',
content: '',
idcard: '',
site: "",
siteName: '',
accompany: []
},
siteShow: false,
siteList: [],
siteTotal: 0,
isTotal: false,
accompanyShow: false,
accompanyObj: {
name: '',
idcard: '',
mobile: ''
},
accompanyIndex: -1,
rules: {
date: [{
required: true,
message: '请选择预约日期',
trigger: ['change', 'blur'],
}],
content: [{
required: true,
message: '请输入预约事项',
trigger: ['change', 'blur'],
}],
idcard: [{
required: true,
message: '请输入身份证号',
trigger: ['blur'],
}, {
validator: (rule, value, callback) => {
return this.$u.test.idCard(value);
},
message: '身份证号不正确',
trigger: ['blur'],
}],
start_time: [{
required: true,
message: '请选择预约开始时间',
trigger: ['change', 'blur'],
}],
end_time: [{
required: true,
message: '请选择预约结束时间',
trigger: ['change', 'blur'],
}],
siteName: [{
required: true,
message: '请选择预约场地',
trigger: ['change', 'blur'],
}],
},
startDate: '',
showStartDate: false
}
},
onReady() {
this.$refs.uForm.setRules(this.rules);
},
// computed: {
// startDate() {
// return this.$moment().add(1,'days').format("YYYY-MM-DD").toString()
// }
// },
async onLoad(options) {
this.appoinementType = options.type ? options.type : ''
this.startDate = this.$moment().add(1, 'days').format("YYYY-MM-DD").toString()
this.form.date = this.startDate
// this.showStartDate = true
await this.getUser()
await this.getSites()
},
methods: {
// 判断已预约的日期是否大于或等于当前日期
isCurrentDateGreaterOrEqual(targetDate) {
// 将目标日期转换为Moment对象
const target = this.$moment(targetDate, 'YYYY-MM-DD HH:mm');
// 获取当前日期
const now = this.$moment().format('YYYY-MM-DD HH:mm');
// 比较当前日期是否小于或等于目标日期
return this.$moment(now).isSameOrBefore(target);
},
formatTime(val1, val2) {
console.log("val1",val1, val2)
let val1Day = this.$moment(val1)
let val2Day = this.$moment(val2)
console.log("123", val1Day, val2Day)
if (val1Day.isSame(val2Day, 'days')) {
return val1Day.format("YYYY-MM-DD") + ' ' + this.$moment(val1).format("HH:mm") + '-' + this.$moment(
val2).format("HH:mm")
} else {
return val1 + '至' + val2
}
},
getUser() {
this.$u.api.user().then(res => {
console.log("res", res)
this.form.idcard = res.user.idcard
this.user_id = res.user
if (res.door_appointments) {
if (this.isCurrentDateGreaterOrEqual(res.door_appointments.start_time)) {
this.myQrcode = res.door_appointments
this.myQrcode.mytime = this.formatTime(res.door_appointments.start_time,res.door_appointments.end_time)
}
}
this.$u.vuex('vuex_user', res.user)
})
},
confirmTipsMethods() {
this.confirmTips = true
this.showTips = false
if(this.myQrcode){
this.showCancel = true
}
},
backBook(){
this.showCancel = false
uni.navigateBack(-1)
},
// 取消我的预约
cancelBook() {
let that = this
that.$u.api.scheduleCancel({
id: that.myQrcode.id
}).then(res => {
that.base.toast('取消成功')
that.showCancel = false
})
},
showSite(){
this.siteShow = true
},
startTimeShow(){
this.showStartTime = true
},
endTimeShow(){
this.showEndTime = true
},
startConfirm(e) {
console.log(e)
if (e) {
this.form.start_time = e.year + '-' + e.month + "-" + e.day + " " + e.hour + ":" + e.minute
} else {
this.form.start_time = ''
}
},
endConfirm(e) {
if (e) {
this.form.end_time = e.year + '-' + e.month + "-" + e.day + " " + e.hour + ":" + e.minute
} else {
this.form.end_time = ''
}
},
// 日期
dateConfirm(e) {
if (e) {
this.form.date = e.detail.value
}
},
// 时间段
//确认 时间段
confirmTime(e) {
// 如果是当天
// 开始时间要大于现在时间 结束时间不能小于现在时间
let nowTime = this.$moment().format("HH:mm")
console.log("nowtime", nowTime, e)
// 选择的时间 1、开始时间是否大于 当前时间 2、结束时间是否小于场地预约时间
// 小时是固定选择的 比较分钟
this.form.timeRange = e.start.hour + ":" + e.start.min + '~' + e.end.hour + ":" + e.end.min
this.form.start_time = e.start.hour + ":" + e.start.min
this.form.end_time = e.end.hour + ":" + e.end.min
// this.compareTimes(start_time)
// 开始时间 结束时间都不能小于 当前时间
},
// 场地
getSites() {
let that = this
this.$u.api.otherConfig({
appointment_type_id: this.appoinementType
}).then(res => {
this.siteList = res.appointment.filter(item => item.status === 1)
if (this.siteList.length === 0) {
this.base.toast("当前没有场地可以预约")
} else {
this.siteList = this.siteList.sort((a, b) => a['sort'] - b['sort']);
res.appointment_type.map(item => {
if (that.appoinementType == item.id) {
that.tips = item.tips
that.showTips = true
that.bookName = item.name
that.bookStartTime = item.start_time
that.bookEndTime = item.end_time
let _arr = item.start_time.split(":")
that.hMin = parseInt(_arr[0])
that.mStart = parseInt(_arr[1])
let _arr1 = item.end_time.split(":")
that.hMax = parseInt(_arr1[0])
that.mEnd = parseInt(_arr1[1])
this.startTime = this.$moment().add(1, 'days').format("YYYY-MM-DD")
.toString() + " " + that.hMin + ':' + that.mStart
this.endTime = this.$moment().add(1, 'days').format("YYYY-MM-DD")
.toString() + " " + that.hMax + ':' + that.mEnd
}
})
}
})
},
siteConfirm(e) {
console.log("eee", e)
this.form.site = this.siteList[e[0]].id
this.form.siteName = this.siteList[e[0]].real_name
this.siteTotal = this.siteList[e[0]].total
},
plateChange(val, index) {
console.log(val, this.plateIndex)
if (val.length >= 7) {
this.plateList[this.plateIndex]['plate'] = val.join("")
}
console.log(this.plateList[this.plateIndex])
},
openPlate(index) {
if (index === -1) {
this.showPlate = true
this.plateList.push({
plate: '',
show: false
})
this.plateIndex = this.plateList.length - 1
} else {
this.showPlate = true
this.plateNumber = this.plateList[index]['plate']
this.plateIndex = index
}
},
delPlate(index) {
this.plateList.splice(index, 1)
},
confirmPlate() {
console.log("this.plateList[this.plateIndex]", this.plateList[this.plateIndex])
console.log(this.plateList[this.plateIndex]['plate'])
console.log(this.plateList[this.plateIndex]['plate'].length < 7)
if (!this.plateList[this.plateIndex]) {
this.base.toast("请输入车牌号")
return
}
if (this.base.isNull(this.plateList[this.plateIndex]['plate']) ||
this.plateList[this.plateIndex]['plate'].length < 7) {
this.base.toast("请输入正确的车牌号")
return
}
this.showPlate = false
this.plateList[this.plateIndex]['show'] = true
this.plateIndex = -1
this.$refs.plates.panelReset()
this.plateNumber = ['苏', 'E', '', '', '', '', '']
},
closePlate() {
if (this.plateIndex > -1) {
this.showPlate = false
this.plateList[this.plateIndex]['show'] = false
this.plateIndex = -1
this.$refs.plates.panelReset()
this.plateNumber = ['苏', 'E', '', '', '', '', '']
}
},
// 同行人
addAccompany() {
this.accompanyShow = true
},
submitAccompany() {
if (this.base.isNull(this.accompanyObj.name)) {
this.base.toast("请输入陪同人姓名")
return
}
if (this.base.isNull(this.accompanyObj.idcard)) {
this.base.toast("请输入陪同人身份证")
return
} else {
if (!this.$u.test.idCard(this.accompanyObj.idcard)) {
this.base.toast("陪同人身份证不正确")
return
}
}
if (this.base.isNull(this.accompanyObj.mobile)) {
this.base.toast("请输入陪同人联系方式")
return
} else {
if (!this.$u.test.mobile(this.accompanyObj.mobile)) {
this.base.toast("陪同人联系方式不正确")
return
}
}
this.form.accompany.push(this.accompanyObj)
this.accompanyIndex = -1
this.accompanyObj = {}
this.accompanyShow = false
if (this.siteTotal && this.siteTotal > 0) {
if (this.form.accompany.length === this.siteTotal - 1) {
this.isTotal = true
}
}
},
delAccompany(index) {
this.form.accompany.splice(index, 1)
},
// 比较预约时间 开始时间不能早于当前时间 结束小时数不能晚于可预约的最晚时间
validateTimes(startTime1, endTime1) {
let result = ""
// 转换为 Moment 对象
const startTime = this.$moment(startTime1)
const endTime = this.$moment(endTime1);
const currentTime = this.$moment();
const todayHMax = this.$moment().hours(this.hMax).minutes(this.mEnd).seconds(0).milliseconds(0);
// 获取初始日期 明天的
const startDay = this.$moment(startTime).format('YYYY-MM-DD');
const endDay = this.$moment(endTime).format('YYYY-MM-DD');
// 验证开始时间和结束时间
// 如果开始日期不是今天
const startDayHMin = this.$moment(startDay + ' ' + this.hMin + ':' + this.mStart)
const startDayHMax = this.$moment(startDay + ' ' + this.hMax + ':' + this.mEnd)
const endDayHMin = this.$moment(endDay + ' ' + this.hMin + ':' + this.mStart)
const endDayHMax = this.$moment(endDay + ' ' + this.hMax + ':' + this.mEnd)
if (startTime.isBefore(startDayHMin)) {
this.base.toast('预约开始时间不能早于明日的' + this.bookStartTime)
return false;
}
if (startTime.isAfter(startDayHMax)) {
this.base.toast('预约开始时间不能晚于每天的' + this.bookEndTime)
return false;
}
if (endTime.isBefore(startTime)) {
this.base.toast('预约结束时间不能早于预约开始时间')
return false;
}
if (endTime.isBefore(endDayHMin)) {
this.base.toast('预约结束时间不能早于每天的' + this.bookStartTime)
return false;
}
if (endTime.isAfter(endDayHMax)) {
this.base.toast('预约结束时间不能晚于每天的' + this.bookEndTime)
return false;
}
// 如果所有条件都满足,则显示验证通过的信息
result = '时间验证通过';
return true
console.log("result", result)
},
submit() {
let start_time = ''
let end_time = ''
let that = this
this.$refs.uForm.validate(valid => {
if (valid) {
start_time = this.form.start_time + ':00'
end_time = this.form.end_time + ':00'
this.form.date = this.form.start_time.substring(0, 10)
if (!this.validateTimes(start_time, end_time)) {
return
}
console.log("form", this.form)
// return
this.form.accompany_total = this.form.accompany.length
let _plate = []
if (this.plateList.length > 0) {
this.plateList.map(item => {
if (item.show) {
_plate.push(item.plate)
}
})
if (_plate.length > this.form.accompany_total + 1) {
this.base.toast("车辆数量已经大于预约人数了")
return
}
}
this.form.plate = _plate.join(',')
console.log("plate", this.form)
// return
if (this.isLocked) {
return
}
this.isLocked = true
console.log("this.isLocked", this.isLocked)
this.$u.api.scheduleSave({
...this.form,
start_time: start_time,
end_time: end_time
}).then(res => {
console.log("res", res)
this.saveOther()
}).catch(err => {
console.log("err", err)
that.isLocked = false
})
} else {
console.log('验证失败');
// this.base.toast("验证失败")
}
});
},
async saveOther() {
await this.saveUser()
await this.newsSubscription()
},
saveUser() {
let that = this
// return new Promise((resolve, reject) => {
this.$u.api.saveUser({
...this.user_id,
idcard: this.form.idcard
}).then(res => {
console.log("user")
// resolve('user')
}).catch(err => {
// reject("err", err)
})
// })
},
// 订阅消息
newsSubscription() {
let that = this
uni.getSetting({
withSubscriptions: true, //是否获取用户订阅消息的订阅状态默认false不返回
success(res) {
console.log("resdfg", res)
if (res.subscriptionsSetting.mainSwitch) {
if (res.subscriptionsSetting.itemSettings && res.subscriptionsSetting.itemSettings[
'0WMaFZ_0FOS5gtxEAi-fM3pFcYPySRMwYFNASz9oig0'] === 'accept') {
// 用户已经订阅该消息模板,执行相应操作
that.base.toast("预约已提交", 1500, function() {
setTimeout(function() {
uni.redirectTo({
url: '/packages/mybook/index'
})
}, 1500)
})
} else {
// 用户没有订阅该消息模板,显示订阅弹窗
uni.showModal({
title: '订阅消息',
content: '是否需要订阅预约结果消息',
success(res1) {
if (res1.confirm) {
uni.requestSubscribeMessage({
tmplIds: [
'0WMaFZ_0FOS5gtxEAi-fM3pFcYPySRMwYFNASz9oig0',
],
success(res) {
console.log("success", that.isLocked)
that.base.toast("预约已提交", 1500, function() {
setTimeout(function() {
uni.redirectTo({
url: '/packages/mybook/index'
})
console.log("settime",
that.isLocked)
}, 1500)
})
},
fail(err) {
that.base.toast("预约已提交", 1500, function() {
setTimeout(function() {
uni.redirectTo({
url: '/packages/mybook/index'
})
}, 1500)
})
}
})
} else {
that.base.toast("预约已提交", 1500, function() {
setTimeout(function() {
uni.redirectTo({
url: '/packages/mybook/index'
})
}, 1500)
})
}
}
})
}
} else {
that.base.toast("预约已提交", 1500, function() {
setTimeout(function() {
uni.redirectTo({
url: '/packages/mybook/index'
})
}, 1500)
})
// 用户尚未开启订阅消息总开关,建议提醒用户开启
}
}
});
},
}
}
</script>
<style scoped lang="scss">
::v-deep .u-drawer-content-visible {
border-radius: 30rpx !important;
}
.container {
padding: 30rpx;
width: 100%;
height: 100vh;
.cbg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100vh;
}
.wrap {
background: #fff;
position: relative;
padding: 35rpx;
border-radius: 30rpx;
padding-top: 0;
height: 100%;
overflow: scroll;
}
.configwrap {
.slot-content {
padding: 40rpx;
padding-top: 20rpx;
&>view {
// padding-top: 20rpx;
}
&-title {
text-align: center;
}
&-input {
// height: 700rpx;
// // line-height: 1.6;
// overflow: scroll;
}
&-tip {
text-indent: 2em;
}
&-btn {
display: flex;
align-items: center;
justify-content: space-between;
padding: 30rpx 0;
&>view {
width: 40%;
text-align: center;
margin: 0 auto;
color: #fff;
background: linear-gradient(to right, #5e5fbc, #0d0398);
border-radius: 30rpx;
padding: 10rpx;
}
}
}
}
.cancelWrap {
.slot-content {
padding: 30rpx;
padding-top: 20rpx;
&>view {
padding-top: 20rpx;
}
&-title {
text-align: center;
}
&-tip {
text-indent: 2em;
line-height: 1.5;
}
&-btn {
display: flex;
align-items: center;
justify-content: space-between;
padding-bottom: 20rpx;
&>view {
width: 40%;
text-align: center;
margin: 0 auto;
color: #fff;
background: linear-gradient(to right, #5e5fbc, #0d0398);
border-radius: 30rpx;
padding: 10rpx;
}
&>view:first-child {
background: #ddd;
color: #333
}
}
}
}
.form-btn {
width: 100%;
position: relative;
padding: 60rpx 0;
// z-index:9999;
&>view {
width: 70%;
text-align: center;
margin: 0 auto;
color: #fff;
background: linear-gradient(to right, #5e5fbc, #0d0398);
border-radius: 30rpx;
padding: 20rpx;
}
}
.modal {
::v-deep .u-drawer-bottom {
border-radius: 40rpx;
}
&-tip {
text-align: center;
padding: 30rpx;
font-size: 32rpx;
}
&-content {
// height: 400rpx;
padding: 0 30rpx;
}
}
}
</style>