<template> <view class="page"> <u-navbar title="下单" :border-bottom="false" :background="bgc" back-icon-color="#262B37" title-color='#262B37' title-size='36' height='36' id="navbar"> </u-navbar> <image src="https://api.ccttiot.com/smartmeter/img/static/u3lZnmhqSqkMd7gHKtMD" mode="" class="imgbj"></image> <view class="boxda"> <view class="fangjian"> <view class="top"> <text></text>【{{shopobj.storeName == null ? '--' : shopobj.storeName}}】 </view> <view class="bd"> <view class="lt"> <image :src="shopobj.picture" mode=""></image> </view> <view class="rt"> <view class="name"> {{shopobj.roomName == null ? '--' : shopobj.roomName}} </view> <view class="leixing"> <view class="" v-for="(item,index) in shopobj.tags"> {{getMatchingLabel(item)}} </view> </view> <view class="price"> ¥{{shopobj.hour == null ? '--' : shopobj.hour}}/小时 </view> </view> </view> </view> <view class="appointment"> <!-- <view class="riqi"> <view class="tcxzname"> 日期选择: </view> <view class="yyshijian"> <view class="shijian_item" v-for="(item,index) in weekdayAndDateSequence" :id="indexone == index ? 'active' : ''" :key="index" @click="btnyd(index,item)"> <view class="xingqi">{{item.weekday}}</view> <view class="yueri">{{item.date.slice(-5)}}</view> </view> </view> </view> --> <view class="tcxz"> <view class="tcxzname"> 套餐选择: </view> <view class="taocan"> <view class="tclist" v-for="(item,index) in tclist" :id="indextwo == index ? 'active' : ''" :key="index" @click="btntc(index,item)"> <view style="font-weight: 600;" :id="indextwo == index ? 'active' : ''">{{item.explain == null ? '--' : item.explain}}</view> <view style="font-weight: 600;" :id="indextwo == index ? 'active' : ''">¥{{item.price == null ? '--' : item.price}}</view> </view> </view> </view> <view class="shichangxz"> <view class="tcxzname"> 时长选择: </view> <view class="shijianinp"> <view class="kaishi" @click="btnks"> {{kstime}} </view> 至 <view class="kaishi" style="background-color: #eee;"> {{jstime}} </view> </view> </view> <view class="bot"> <view class="duan"> <view v-for="(isReserved, hourStr) in roomList" :key="hourStr" :class="['hour-item', { 'is-reserved': isReserved }]"> </view> </view> <view class="shijian"> <view style="width: 16rpx;" v-for="(item,index) in hourPointsArray" :key="index"> {{item == '00:00:00' ? '次日' : item.slice(0,2)}} </view> </view> <view class="ydshiduan"> <view class="yi"> <text></text> 已被预订时段 </view> <view class="wei"> <text></text> 可预订时段 </view> </view> </view> </view> <view class="money"> <image src="https://api.ccttiot.com/smartmeter/img/static/uP8ymRHTDQ6YdwwnxQAb" mode="" class="moneyimg"> </image> <view class="moneytop"> <view class="zongjia"> <view class="">订单总价</view> <view class="pricered">¥{{price == null ? '--' : price}}</view> </view> <view class="yuding"> <view class="">下单时长</view> <view class="">{{hourstime == null ? '--' : hourstime}}小时</view> </view> <view class="yudingtime"> <view class="">下单时间段</view> <view class="time" v-if="ksriqi != '' && kstime !=''"> {{timeshijian.slice(0,-3) + '至'}}{{jstime == null ? '--' : jstime}}</view> <view class="time" v-else>--</view> </view> </view> <view class="moneybot"> <view class="xudan"> <view class="">续单</view> <view class="">{{shopobj.hour == null ? '--' : shopobj.hour}}元/小时</view> </view> <view class="koukuan" > <view class="">扣款策略</view> <view class="">{{zfss}} <image src="https://api.ccttiot.com/smartmeter/img/static/uYHtrgPzlait1i05RQYy" mode=""></image> </view> </view> </view> </view> </view> <view class="heji"> <view class="lt"> <view class="hejitishi"> 合计: </view> <view class="price"> <text>¥{{price == null ? '--' : price}}</text> 共{{hourstime == null ? '--' : hourstime}}小时 </view> </view> <view class="rt"> <view class="qdyd" @click="btnqdyd"> 确认下单 </view> </view> </view> <view class="mask" v-if="yudingflag"></view> <view class="yudingtrue" v-if="yudingflag"> <view class="top"> <image src="https://api.ccttiot.com/smartmeter/img/static/usPNNZmaPaHGnzKkwwa9" mode=""></image> <view class="name"> 下单信息确认 </view> </view> <view class="bd"> <view class=""> 下单门店:【{{shopobj.storeName == null ? '--' : shopobj.storeName}}】 </view> <view class=""> 下单包间:{{shopobj.roomName == null ? '--' : shopobj.roomName}} </view> <view class=""> 开始时间:{{timeshijian.slice(0,-3)}} </view> <view class=""> 下单时长:{{hourstime}}小时 </view> </view> <view class="shuom"> <view class="xuzhi"> 下单须知: </view> <view class=""> 1、下单的订单将全时段保留。迟到不可顺延和退款; </view> <view class=""> 2、为避免包厢被其他用户预约而给您带来不好的体 验,如需续单,请提前续单! </view> <view class=""> 3、订单开始前1小时内取消订单需核收15%退单费, 请合理规划您的时间; </view> </view> <view class="anniu"> <view class="fanhui" @click=" yudingflag = false "> 返回修改 </view> <view class="ljyd" @click="btnljyd"> 立即预订 </view> </view> </view> <u-select v-model="show" mode="mutil-column" title="选择时长" confirm-color="#48893B" :list="list" @confirm="confirm"></u-select> <u-select v-model="shows" title="选择扣款方式" confirm-color="#48893B" :list="lists" @confirm="confirms"></u-select> </view> </template> <script> export default { data() { return { bgc: { backgroundColor: "", }, indexone: -1, indextwo: -1, yudingflag: false, show: false, shows: false, lists: [{ value: 'ye', label: '使用门店余额' }, { value: 'wx', label: '微信支付' }], list: [ [{ value: '1', label: '00' }, { value: '2', label: '01' }, { value: '3', label: '02' }, { value: '4', label: '03' }, { value: '5', label: '04' }, { value: '6', label: '05' }, { value: '7', label: '06' }, { value: '8', label: '07' }, { value: '9', label: '08' }, { value: '10', label: '09' }, { value: '11', label: '10' }, { value: '12', label: '11' }, { value: '13', label: '12' }, { value: '14', label: '13' }, { value: '15', label: '14' }, { value: '16', label: '15' }, { value: '17', label: '16' }, { value: '18', label: '17' }, { value: '19', label: '18' }, { value: '20', label: '19' }, { value: '21', label: '20' }, { value: '22', label: '21' }, { value: '23', label: '22' }, { value: '24', label: '23' }, ], [{ value: '3', label: '00' }, { value: '4', label: '30' } ], ], kstime: '', jstime: '', timetype: '', roomId: '', shopobj: {}, hourPointsArray: [], roomList: [], hours: [], reservationStatus: {}, weekdayAndDateSequence: [], tclist: [], arr: [], huors: [], tcobj: {}, pricedd: '', price: '', hourstime: '', ksriqi: '', user: {}, zfss: '微信支付', zfssid: 'wx', timeshijian:'' } }, onLoad(option) { this.roomId = option.roomId // this.roomId = 35 this.getbiaoqian() this.getstoredetail() this.gettaocan() this.hourPointsArray = this.getCurrentHourPoints() //计算从当前时间往后推24小时 }, onShow() { this.getinfo() }, mounted() { let arr = this.getCurrentWeekdayAndNextFiveDays(); this.weekdayAndDateSequence = this.convertDates(arr) }, methods: { // 拿到标签进行对比 getMatchingLabel(item) { const matchingItem = this.biaoqianlist.find(items => items.dictValue === item) return matchingItem ? matchingItem.dictLabel : item }, // 获取标签 getbiaoqian(){ this.$u.get(`/appVerify/getDictData?dictType=ss_room_tags`).then((res) => { if (res.code == 200) { this.biaoqianlist = res.data } }) }, convertDates(array) { return array.map(item => { // 将日期字符串转换为 Date 对象 // 注意:这里的解析可能需要根据实际的日期字符串格式进行调整 let dateStr = item.date; let dateParts = dateStr.match(/(\w+) (\w+) (\d+) (\d+)/); if (!dateParts) { console.error('日期字符串格式不正确:', dateStr); return item; // 或者你可以抛出一个错误,或者返回一个特殊值 } let [, weekday, monthName, day, year] = dateParts; let monthMap = { Jan: '01', Feb: '02', Mar: '03', Apr: '04', May: '05', Jun: '06', Jul: '07', Aug: '08', Sep: '09', Oct: '10', Nov: '11', Dec: '12' }; let month = monthMap[monthName]; if (!month) { console.error('无法识别的月份:', monthName); return item; // 或者处理错误 } // 构建新的日期字符串 let newDateStr = `${year.slice(2,4)}-${month}-${day.padStart(2, '0')}`; // 返回一个新的对象,或者你可以直接修改原始对象(但通常不推荐这样做,因为它会改变原始数据) return { ...item, date: newDateStr }; }); }, // 拿到当前时间后24小时格式成两位数 initializeData() { // 获取当前时间 const now = new Date() // 获取当前时间的小时部分(0-23) const currentHour = now.getHours() // 初始化小时数组 this.hours = []; this.arr = [] // 遍历从当前小时开始的24个小时 for (let i = 0; i < 24; i++) { // 计算小时数,注意要处理超过23点的情况 let hour = (currentHour + i) % 24 let arrsum = currentHour + i if (hour == '00') { //如果是00:00 则改成24:00 hour = 24 } else { hour = hour } // 推入数组 this.arr.push(arrsum) this.hours.push(hour) } }, // 更新房间的预订状态且与initializeData进行匹对 updateRoomReservationStatus() { this.roomList.forEach(room => { room.reservationStatus = {} // 为每个房间创建一个新的预订状态对象 this.hours.forEach(hour => { room.reservationStatus[hour] = false // 初始化为未预订状态 }) // console.log(room.reservationStatus,'02.0230.'); // room.forEach(period => { let startHour = room.startTime.slice(room.startTime.length - 8, room.startTime.length - 6) //取下单开始时间小时 let endHour = room.endTime.slice(room.endTime.length - 8, room.endTime.length - 6) //取下单结束时间小时 let timefen = room.startTime.slice(room.endTime.length - 5, room.endTime.length - 3) //取下单结束时间分钟 // 获取当前日期 const now = new Date(); const year = now.getFullYear(); const month = String(now.getMonth() + 1).padStart(2, '0'); // 月份从0开始,所以要加1,并用padStart确保是两位数 const day = String(now.getDate()).padStart(2, '0'); // 用padStart确保是两位数 let riqione = `${year}-${month}-${day}` //当前日期 let riqitwo = room.endTime.slice(0, 10) //下单结束日期 let dateOne = new Date(riqione) let dateTwo = new Date(riqitwo) if (dateOne < dateTwo) { //将开始和结束日期进行对比 判断是否是第二天 if (endHour < startHour) { endHour = 24 + Number(endHour) } else { endHour = 24 + Number(endHour) startHour = 24 + Number(startHour) } } else { console.log("第一个日期不小于第二个日期") } console.log(startHour, endHour, room.startTime, room.endTime) for (let i = 0; i < 24; i++) { if (timefen == '00') { //判断下单结束是否包含分钟 不包含正常走判断 包含则将时间往后延长1 if (this.arr[i] > startHour && this.arr[i] <= endHour) { room.reservationStatus[i] = true } } else { if (this.arr[i] > startHour && Number(this.arr[i] - 1) <= endHour) { room.reservationStatus[i] = true } } } }) this.roomList = this.mergeReservationStatuses(this.roomList) }, // 将this.roomlist中的三个数组合并成一个 mergeReservationStatuses(array) { let mergedStatus = {} array.forEach(obj => { for (let time in obj.reservationStatus) { if (!(time in mergedStatus)) { mergedStatus[time] = false } mergedStatus[time] = mergedStatus[time] || obj.reservationStatus[time] } }) return mergedStatus }, //计算从当前时间往后推24小时 getCurrentHourPoints() { const now = new Date(); const startHour = now.getHours(); const startDate = new Date(now); startDate.setMinutes(0, 0, 0); // 确保分钟、秒和毫秒都是0 const options = { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' }; const hourPoints = []; for (let i = 0; i < 24; i++) { const newDate = new Date(startDate); newDate.setHours((startHour + i) % 24, 0, 0, 0); if (newDate.getHours() === 0 && i !== 0) { newDate.setDate(newDate.getDate() + 1); } const hours = String(newDate.getHours()).padStart(2, '0'); const minutes = String(newDate.getMinutes()).padStart(2, '0'); const seconds = String(newDate.getSeconds()).padStart(2, '0'); const formattedDateString = `${hours}:${minutes}:${seconds}`; hourPoints.push(formattedDateString); } return hourPoints; }, // 获取当前时间和日期+后面五天时间 getCurrentWeekdayAndNextFiveDays() { // 获取当前日期和时间 const now = new Date(); // 获取当前是星期几(0代表周日,1代表周一,...,6代表周六) const currentWeekday = now.getDay(); const result = []; result.push({ date: now.toLocaleDateString('zh-CN', { year: '2-digit', month: '2-digit', day: '2-digit' }), weekday: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'][currentWeekday] }); // 往后推五天,并添加到数组中 for (let i = 1; i < 5; i++) { const newDate = new Date(now); newDate.setDate(now.getDate() + i); result.push({ date: newDate.toLocaleDateString('zh-CN', { year: '2-digit', month: '2-digit', day: '2-digit' }), weekday: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'][newDate.getDay()] }) } return result }, // 根据房间id获取套餐 gettaocan() { this.$u.get(`/app/rule/getListByRoomId?roomId=${this.roomId}`).then(res => { if (res.code == 200) { this.tclist = res.data } }) }, // 查询个人信息 getinfo() { this.$u.get(`/getAppInfo`).then(res => { if (res.code == 200) { this.user = res.user }else if(res.code == 401){ uni.showModal({ title: '温馨提示', content: '您该操作需登录,请前去登录', success: function (res) { if (res.confirm) { uni.navigateTo({ url:'/pages/login/index' }) }else if(res.cancel){ uni.navigateBack() } } }) } }) }, // 点击立即下单 btnljyd() { // let time = '20' + this.ksriqi + ' ' + this.kstime + ':00' // let formattedDateString = time.replace(/\//g, "-") let data = { roomId: this.roomId, payType: this.zfssid, ruleId: this.tcobj.ruleId, type: 1, reserveStartTime: this.timeshijian, mode: 2, hours: this.hourstime, price: this.price } this.$u.post(`/app/order/createOrder`, data).then(res => { if (res.code == 200) { let orderNo = res.data.orderNo uni.requestPayment({ provider: 'wxpay', timeStamp: res.data.response.timeStamp, nonceStr: res.data.response.nonceStr, package: res.data.response.packageVal, signType: res.data.response.signType, paySign: res.data.response.paySign, success: (res) => { console.log(res, '支付成功') uni.navigateTo({ url:'/page_user/dingdanxq?orderNo=' + orderNo }) }, fail(err) { uni.showToast({ title: '支付失败', icon: 'none', duration: 2000 }) } }) }else if(res.code == 401){ uni.showModal({ title: '温馨提示', content: '您该操作需登录,是否前去登录?', success: function (res) { if (res.confirm) { uni.navigateTo({ url:'/pages/login/index' }) } else if (res.cancel) { } } }) } else { uni.showToast({ title: res.msg, icon: 'none', duration: 2000 }) } }) }, // 确认选择支付方式 confirms(e) { this.zfss = e[0].label this.zfssid = e[0].value }, // 点击确定下单进行判断 btnqdyd() { if (this.ksriqi == '') { uni.showToast({ title: '请先选择日期', icon: 'none', duration: 2000 }) } else if (!this.tcobj.hours) { uni.showToast({ title: '请先选择套餐', icon: 'none', duration: 2000 }) } else if (this.kstime == '') { uni.showToast({ title: '请先选择开始时间', icon: 'none', duration: 2000 }) } else if (this.zfss == '') { uni.showToast({ title: '请先选择扣款方式', icon: 'none', duration: 2000 }) } else if (this.zfss == '使用门店余额') { if (this.user.balance == null || this.user.balance == undefined || this.user.balance < this.price) { uni.showToast({ title: '您的余额不足,请先充值', icon: 'none', duration: 2000 }) } else { let mergedData = this.hourPointsArray.map((time, index) => { let roomNumber = Object.keys(this.roomList)[index] let roomStatus = this.roomList[roomNumber] return { roomNumber: parseInt(roomNumber, 10), roomStatus: roomStatus, time: time } }) let kaishi = this.kstime + ':00' let jieshu = this.jstime + ':00' let isBooked = false; // 假设没有预订 mergedData.forEach(item => { let itemTime = item.time if ((itemTime >= kaishi && itemTime <= jieshu) && item.roomStatus) { isBooked = true // 如果有预订,设置 isBooked 为 true } }) // 根据 isBooked 的值来执行操作 if (!isBooked) { let timeshijian = this.timeshijian let targetDate = new Date(timeshijian.replace(/-/g, '/')) let currentDate = new Date(); console.log(targetDate,currentDate,'020202'); if (targetDate < currentDate) { uni.showToast({ title: '请选择当前时间之后', icon: 'none', duration: 2000 }) } else { this.yudingflag = true } } else { uni.showToast({ title: '该时间段已被预订,请选择其他时间段', icon: 'none', duration: 2000 }) } } } else { let mergedData = this.hourPointsArray.map((time, index) => { let roomNumber = Object.keys(this.roomList)[index] let roomStatus = this.roomList[roomNumber] return { roomNumber: parseInt(roomNumber, 10), roomStatus: roomStatus, time: time } }) let kaishi = this.kstime + ':00' let jieshu = this.jstime + ':00' let isBooked = false; // 假设没有预订 mergedData.forEach(item => { let itemTime = item.time if ((itemTime >= kaishi && itemTime <= jieshu) && item.roomStatus) { isBooked = true // 如果有预订,设置 isBooked 为 true } }) // 根据 isBooked 的值来执行操作 if (!isBooked) { let timeshijian = this.timeshijian let targetDate = new Date(timeshijian.replace(/-/g, '/')) let currentDate = new Date(); console.log(targetDate,currentDate,'020202'); if (targetDate < currentDate) { uni.showToast({ title: '请选择当前时间之后', icon: 'none', duration: 2000 }) } else { this.yudingflag = true } } else { uni.showToast({ title: '该时间段已被预订,请选择其他时间段', icon: 'none', duration: 2000 }) } } }, // 点击跳转到充值页 btnchongzhi() { uni.navigateTo({ url: '/page_user/chongzhi' }) }, // 确认选择时间 confirm(e) { this.kstime = e[0].label + ':' + e[1].label let shijian = '20' + this.ksriqi + ' ' + this.kstime console.log(shijian,shijian.slice(2,5)); if(shijian.slice(2,5) == 'Wed'){ this.timeshijian = this.formatDate(shijian) }else{ this.timeshijian = this.parseTime(shijian) } if (this.tcobj.hours) { this.jstime = this.addOneHourToTime(this.kstime) } }, // 判断是否需要格式化 isValidDateFormatOnly(inputString) { const parts = inputString.split(/[\s/]/); return parts.length === 5 && !isNaN(parts[0]) && parts[0].length === 4 && // 年份 !isNaN(parts[1]) && parts[1].length === 2 && // 月份 !isNaN(parts[2]) && parts[2].length === 2 && // 日期 !isNaN(parts[3]) && parts[3].length === 2 && // 小时 !isNaN(parts[4]) && parts[4].length === 2; // 分钟 }, // 计算结束时间 addOneHourToTime(timeString, date = new Date()) { let [hours, minutes] = timeString.split(':').map(Number) let timeDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), hours, minutes, 0, 0) timeDate.setHours(timeDate.getHours() + Number(this.tcobj.hours)) //加上套餐中的小时 let newHours = timeDate.getHours() let newMinutes = String(timeDate.getMinutes()).padStart(2, '0') // 格式化分钟为两位数 return `${String(newHours).padStart(2, '0')}:${newMinutes}` }, // 请求门店详细信息 getstoredetail() { this.$u.get(`/app/room/${this.roomId}`).then(res => { if (res.code == 200) { this.shopobj = res.data if(res.data.reservedTimePeriods == null){ this.roomList = [] for(let i = 0;i < 24;i++){ this.roomList.push(false) } }else{ this.roomList = res.data.reservedTimePeriods this.initializeData() this.updateRoomReservationStatus() } } }) }, // 选择开始时间 btnks() { this.show = true }, // 选择日期 btnyd(index, item) { this.ksriqi = item.date let shijian = '20' + this.ksriqi + ' ' + this.kstime if(shijian.slice(2,5) == 'Wed'){ this.timeshijian = this.formatDate(shijian) }else{ this.timeshijian = this.parseTime(shijian) } if (this.tcobj.hours && this.kstime != '') { this.jstime = this.addOneHourToTime(this.kstime) } this.indexone = index if(index != 0){ this.$u.get(`/app/order/getReservedTimePeriods?roomId=${this.roomId}&startTime=${'20' + this.ksriqi}`).then(res => { if (res.code == 200) { if(res.data == ''){ this.roomList = [] for(let i = 0;i < 24;i++){ this.roomList.push(false) } this.hourPointsArray = this.getDangtiantime() }else{ this.roomList = res.data this.hourPointsArray = this.getDangtiantime() this.arr = this.getDangtiantimes() this.getgengxinriqiday() } } }) }else{ this.getstoredetail() this.gettaocan() this.hourPointsArray = this.getCurrentHourPoints() //计算从当前时间往后推24小时 } }, // 更新日期 getgengxinriqiday() { this.roomList.forEach(room => { room.reservationStatus = {} // 为每个房间创建一个新的预订状态对象 this.hours.forEach(hour => { room.reservationStatus[hour] = false // 初始化为未预订状态 }) let startHour = room.startTime.slice(room.startTime.length - 8, room.startTime.length - 6) //取下单开始时间小时 let endHour = room.endTime.slice(room.endTime.length - 8, room.endTime.length - 6) //取下单结束时间小时 let timefen = room.startTime.slice(room.endTime.length - 5, room.endTime.length - 3) //取下单结束时间分钟 // 获取当前日期 const now = new Date(); const year = now.getFullYear(); const month = String(now.getMonth() + 1).padStart(2, '0'); // 月份从0开始,所以要加1,并用padStart确保是两位数 const day = String(now.getDate()).padStart(2, '0'); // 用padStart确保是两位数 if(endHour < startHour){ startHour = '00' } console.log(startHour, endHour, room.startTime, room.endTime) for (let i = 0; i < 24; i++) { if (timefen == '00') { //判断下单结束是否包含分钟 不包含正常走判断 包含则将时间往后延长1 if (this.arr[i].slice(0,2) > startHour && this.arr[i].slice(0,2) <= endHour) { room.reservationStatus[i] = true } } else { if (this.arr[i].slice(0,2) > startHour && Number(this.arr[i].slice(0,2) - 1) <= Number(endHour)) { room.reservationStatus[i] = true } } } }) this.roomList = this.mergeReservationStatuses(this.roomList) }, // 展示this.hourPointsArray使用方法 01:00 - 24:00 getDangtiantime() { let hourPoints = []; let timeString = '' for (let hour = 0; hour < 24; hour++) { let formattedHour = String(hour).padStart(2, '0') if(formattedHour == '00'){ timeString = `00:00:01`; }else{ timeString = `${formattedHour}:00:00` } hourPoints.push(timeString); } return hourPoints; }, // this.arr使用方法 00:00 - 23:00 getDangtiantimes() { const hourPoints = []; for (let hour = 0; hour < 24; hour++) { const formattedHour = String(hour).padStart(2, '0'); const timeString = `${formattedHour}:00:00`; hourPoints.push(timeString); } return hourPoints; }, // 选择套餐 btntc(index, item) { this.tcobj = item this.price = item.price //订单金额 this.hourstime = item.hours //订单时间 this.indextwo = index if (this.kstime != '') { this.jstime = this.addOneHourToTime(this.kstime) } }, // 日期格式化 parseTime(time, pattern) { if (arguments.length === 0 || !time) { return null } const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}' let date if (typeof time === 'object') { date = time } else { if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) { time = parseInt(time) } else if (typeof time === 'string') { time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), ''); } if ((typeof time === 'number') && (time.toString().length === 10)) { time = time * 1000 } date = new Date(time) } const formatObj = { y: date.getFullYear(), m: date.getMonth() + 1, d: date.getDate(), h: date.getHours(), i: date.getMinutes(), s: date.getSeconds(), a: date.getDay() } const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => { let value = formatObj[key] // Note: getDay() returns 0 on Sunday if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] } if (result.length > 0 && value < 10) { value = '0' + value } return value || 0 }) return time_str }, formatDate(inputDate) { const parts = inputDate.match(/(\d+)\D+(\w+)\s+(\w+)\s+(\d+)\s+(\d+)\s+(\d+):(\d+)/); if (!parts) { throw new Error('Invalid date format'); } const [, dayOfMonth, , month, , year, hour, minute] = parts; const monthMap = { Jan: '01', Feb: '02', Mar: '03', Apr: '04', May: '05', Jun: '06', Jul: '07', Aug: '08', Sep: '09', Oct: '10', Nov: '11', Dec: '12' }; const monthNum = monthMap[month]; let formattedHour = (parseInt(hour, 10) + 1).toString().padStart(2, '0'); let formattedMinute = minute.padStart(2, '0'); let formattedSecond = '00'; // 原始字符串中没有秒,所以默认为00 const formattedDate = `${year}-${monthNum}-${dayOfMonth.padStart(2, '0')} ${formattedHour}:${formattedMinute}:${formattedSecond}`; return formattedDate; } } } </script> <style lang="scss"> .hour-item { width: 100%; text-align: center; margin: 2px 0; background-color: gray; /* 默认灰色 */ color: white; /* 确保文本在灰色背景上清晰可见 */ } .hour-item.is-reserved { background-color: #48893B !important; } #active { background: #48893B !important; border: 2rpx solid #48893B !important; color: #fff !important; } .boxda{ width: 100%; height: 88vh; overflow: scroll; padding-bottom: 200rpx; box-sizing: border-box; } page { background: #fff; margin-top: 18rpx; padding-bottom: 220rpx; box-sizing: border-box; height: 100vh; overflow: hidden; .yudingtrue { width: 600rpx; max-height: 999rpx; background: #FFFFFF; border-radius: 32rpx 32rpx 32rpx 32rpx; padding: 0 20rpx; box-sizing: border-box; position: fixed; top: 388rpx; left: 50%; transform: translateX(-50%); padding-bottom: 30rpx; .shuom { .xuzhi { font-weight: 600; font-size: 28rpx; color: #FF1818; margin-top: 22rpx; } view { font-size: 24rpx; color: #FF1818; margin-top: 12rpx; } } .anniu { display: flex; justify-content: space-between; margin-top: 36rpx; padding: 0 40rpx; box-sizing: border-box; .fanhui { width: 212rpx; height: 62rpx; border: 1rpx solid #48893B; font-weight: 600; font-size: 32rpx; color: #48893B; text-align: center; line-height: 62rpx; border-radius: 50rpx; } .ljyd { width: 212rpx; height: 62rpx; background: #48893B; border-radius: 50rpx; font-weight: 600; font-size: 32rpx; color: #FFFFFF; text-align: center; line-height: 62rpx; } } .bd { width: 100%; margin-top: 24rpx; border-bottom: 1rpx solid #D8D8D8; box-sizing: border-box; padding-bottom: 36rpx; view { width: 100%; padding: 0 10rpx; box-sizing: border-box; font-size: 28rpx; color: #7C7C7C; margin-top: 12rpx; } } .top { width: 100%; border-bottom: 1rpx solid #D8D8D8; text-align: center; position: relative; padding-top: 100rpx; box-sizing: border-box; padding-bottom: 20rpx; image { position: absolute; top: -100rpx; left: 50%; transform: translateX(-50%); width: 188rpx; height: 188rpx; } .name { font-weight: 600; font-size: 32rpx; color: #3D3D3D; } } } .mask { width: 100%; height: 100vh; position: fixed; top: 0; left: 0; opacity: .5; background-color: #000; } .heji { width: 750rpx; height: 166rpx; background: #FFFFFF; box-shadow: 0rpx 8rpx 20rpx 0rpx rgba(0, 0, 0, 0.3); border-radius: 0rpx 0rpx 0rpx 0rpx; position: fixed; bottom: 0; left: 0; display: flex; justify-content: space-between; padding: 40rpx 38rpx; box-sizing: border-box; .lt { .hejitishi { font-weight: 600; font-size: 32rpx; color: #3D3D3D; } .price { font-size: 28rpx; color: #3D3D3D; text { font-weight: 600; font-size: 40rpx; color: #FF4848; margin-right: 30rpx; } } } .rt { width: 302rpx; height: 86rpx; background: #48893B; border-radius: 49rpx 49rpx 49rpx 49rpx; font-weight: 600; font-size: 40rpx; color: #FFFFFF; text-align: center; line-height: 86rpx; } } .money { width: 710rpx; margin: auto; position: relative; overflow: hidden; .moneybot { padding: 30rpx 38rpx; box-sizing: border-box; .xudan { display: flex; justify-content: space-between; view { font-size: 28rpx; color: #3D3D3D; } } .yu_e { display: flex; justify-content: space-between; margin-top: 20rpx; view { font-size: 28rpx; color: #3D3D3D; display: flex; align-items: center; } .yu_eno { color: #FF1818; display: flex; align-items: center; image { width: 14rpx; height: 36rpx; display: flex; align-items: center; margin-left: 12rpx; } } } .koukuan { display: flex; justify-content: space-between; margin-top: 20rpx; view { font-size: 28rpx; color: #3D3D3D; display: flex; align-items: center; image { width: 14rpx; height: 36rpx; display: flex; align-items: center; margin-left: 12rpx; } } } } .moneytop { padding: 46rpx 38rpx; box-sizing: border-box; .yudingtime { font-size: 28rpx; color: #3D3D3D; display: flex; justify-content: space-between; margin-top: 20rpx; .time { color: #48893B; } } .yuding { margin-top: 34rpx; display: flex; justify-content: space-between; font-size: 28rpx; color: #3D3D3D; } .zongjia { display: flex; justify-content: space-between; border-bottom: 1px solid #D8D8D8; padding-bottom: 20rpx; box-sizing: border-box; view { font-weight: 600; font-size: 36rpx; color: #3D3D3D; } .pricered { font-size: 36rpx; color: #FF1818; font-weight: 600; } } } .moneyimg { width: 710rpx; height: 529rpx; position: absolute; top: 0; left: 0; z-index: -1; } } .fangjian { width: 674rpx; max-height: 932rpx; background: #FFFFFF; box-shadow: 0rpx 2rpx 12rpx 0rpx rgba(0, 0, 0, 0.15); border-radius: 18rpx 18rpx 18rpx 18rpx; margin: auto; margin-top: 20rpx; padding: 30rpx 32rpx; box-sizing: border-box; .top { display: flex; align-items: center; text { display: inline-block; width: 8rpx; height: 44rpx; background: #48893B; border-radius: 6rpx 6rpx 6rpx 6rpx; margin-right: 12rpx; } } .bd { margin-top: 40rpx; display: flex; .rt { .name { font-size: 32rpx; color: #3D3D3D; font-weight: 600; } .price { font-size: 32rpx; color: #7C7C7C; margin-top: 20rpx; } .leixing { margin-top: 24rpx; display: flex; text-align: center; flex-wrap: wrap; view { margin-right: 14rpx; width: 94rpx; height: 46rpx; border-radius: 6rpx 6rpx 6rpx 6rpx; border: 1rpx solid #48893B; font-size: 26rpx; color: #48893B; line-height: 46rpx; } } } .lt { margin-right: 42rpx; image { width: 176rpx; height: 176rpx; border-radius: 10rpx; } } } } .imgbj { width: 750rpx; height: 424rpx; position: fixed; top: 0; left: 0; z-index: -1; } .bot { margin-top: 28rpx; .ydshiduan { display: flex; margin-top: 30rpx; .yi { display: flex; align-items: center; margin-right: 32rpx; text { display: inline-block; width: 28rpx; height: 4rpx; background: #48893B; margin-right: 14rpx; } font-size: 24rpx; color: #48893B; } .wei { display: flex; align-items: center; text { display: inline-block; width: 28rpx; height: 4rpx; background: #B8B8B8; margin-right: 14rpx; } font-size: 24rpx; color: #3D3D3D; } } .duan { width: 100%; display: flex; justify-content: center; view { width: 28rpx; height: 4rpx; background-color: #B8B8B8; margin-right: 1rpx; } } .shijian { display: flex; font-size: 16rpx; color: #3D3D3D; justify-content: center; justify-content: space-between; box-sizing: border-box; padding-right: 6rpx; } } .shichangxz { display: flex; align-items: center; margin-top: 50rpx; // width: 3000rpx; justify-content: space-between; .shijianinp { display: flex; align-items: center; .kaishi { width: 148rpx; height: 54rpx; border-radius: 27rpx 27rpx 27rpx 27rpx; border: 2rpx solid #7C7C7C; text-align: center; line-height: 54rpx; margin-right: 20rpx; margin-left: 20rpx; } } .tcxzname { font-size: 32rpx; color: #3D3D3D; font-weight: 600; width: 160rpx; } } .tcxz { // display: flex; // align-items: center; margin-top: 30rpx; width: 3000rpx; } .tcxz .tcxzname { font-size: 32rpx; color: #3D3D3D; font-weight: 600; width: 160rpx; } .tcxz .taocan { display: flex; width: 610rpx; overflow-x: auto; -webkit-overflow-scrolling: touch; margin-top: 22rpx; } .tcxz .taocan .tclist { width: 186rpx; height: 110rpx; border-radius: 10rpx; border: 2rpx solid #7C7C7C; text-align: center; display: flex; flex-direction: column; justify-content: center; align-items: center; margin-right: 16rpx; } .tcxz .taocan .tclist view { font-size: 32rpx; color: #3D3D3D; // font-weight: 600; box-sizing: border-box; width: 182rpx; } .riqi { margin-top: 42rpx; .tcxzname { font-size: 32rpx; color: #3D3D3D; font-weight: 600; width: 160rpx; } image { width: 54rpx; height: 54rpx; } .yyshijian { display: flex; justify-content: space-between; margin-top: 22rpx; .shijian_item { width: 112rpx; height: 88rpx; background: #fff; border-radius: 8rpx 8rpx 8rpx 8rpx; border: 2rpx solid #fff; text-align: center; padding-top: 6rpx; box-sizing: border-box; margin-right: 10rpx; } } } .appointment { width: 674rpx; max-height: 1104rpx; background: #FFFFFF; box-shadow: 0rpx 8rpx 20rpx 0rpx rgba(0, 0, 0, 0.15); border-radius: 30rpx; padding: 38rpx; box-sizing: border-box; margin: auto; overflow: hidden; margin-top: 24rpx; padding-top: 0; .top { display: flex; justify-content: space-between; .yytime { font-size: 36rpx; color: #3D3D3D; font-weight: 600; } .yincang { image { width: 50rpx; height: 50rpx; } } } } } /deep/ .u-indicator-item-number { padding: 12rpx 16rpx !important; margin-bottom: 60rpx !important; border-radius: 10rpx !important; height: 52rpx !important; color: #fff !important; } /deep/ .u-swiper-indicator { padding: 0 44rpx !important; } </style>