<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.pictures[0]" 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="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.length > 5 ? item.explain.slice(0,4) + '...' : item.explain}}</view> <view style="font-weight: 600;" :id="indextwo == index ? 'active' : ''">¥{{item.price == null ? '--' : item.price}}</view> </view> </view> </view> <!-- <view class="tcxz" v-else style="display: block;">v-if="tclist[0].mode == 2" <view class="tcxzname"> 收费方式: </view> <view class="taocan" style="width: 600rpx; font-weight: 400; font-size: 28rpx; flex-wrap: wrap;"> {{tclist[0].price == null ? '--' : tclist[0].price}}元/小时,最低消费{{tclist[0].minHours == null ? '--' : tclist[0].minHours}}小时,押金金额{{tclist[0].deposit == null ? '--' : tclist[0].deposit}}元 </view> </view> --> <view class="shichangxz"> <view class="tcxzname"> 时长选择: </view> <view class="shijianinp"> <view class="kaishi" style="background-color: #eee;"> {{kstime.slice(10,16)}} </view> 至 <view class="kaishi" style="background-color: #eee;"> {{jstime.length > 10 ? jstime.slice(10,16) : 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="" v-if="tcobj.mode == 1">预存费用</view><view class="" v-else>订单总价</view> <view class="pricered">¥{{price == null ? '--' : price}}</view> </view> <view class="yuding" v-if="tcobj.mode == 1"> <view class="">计费规则</view> <view class="">1小时{{tcobj.price}}元</view> </view> <view class="yuding" v-else> <view class="">预定时长</view> <view class="">{{hourstime == null ? '--' : hourstime}}小时</view> </view> <view class="yudingtime" v-if="tcobj.mode == 1"> <view class="">预存费用剩余金额会根据您实际使用时间扣除使用后退还您的账户</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="yu_e" @click="btnchongzhi"> <view class="">账户余额</view> <view class="yu_eno" v-if="price > (user.balance == null ? '0' : user.balance)"> 余额不足,请充值 <image src="https://api.ccttiot.com/smartmeter/img/static/uYHtrgPzlait1i05RQYy" mode=""></image> </view> <view class="yu_eno" v-else> {{user.balance == null ? '0' : user.balance}} <image src="https://api.ccttiot.com/smartmeter/img/static/uYHtrgPzlait1i05RQYy" mode=""></image> </view> </view> @click="shows = true"--> <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=""> 开始时间:{{kstime.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、订单开始前{{user.agoCancel == null ? '--' : user.agoCancel}}分钟内取消订单需核收¥{{user.penalty == null ? '--' : user.penalty * 10}}退单费, 请合理规划您的时间; </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: '微信支付' }], kstime: '', jstime: '', timetype: '', roomId: '', shopobj: {}, hourPointsArray: [], roomList: [], hours: [], reservationStatus: {}, weekdayAndDateSequence: [], tclist: [], arr: [], huors: [], tcobj: {}, pricedd: '', price: '', hourstime: '', ksriqi: '', user: {}, zfss: '微信支付', zfssid: 'wx', timeshijian:'', orderNo:'', biaoqianlist:[], viewType:'', ruleId:'' } }, onLoad(option) { this.roomId = option.roomId this.orderNo = option.orderNo this.viewType = option.viewType this.getstoredetail() this.getstoredetails() this.getbiaoqian() this.hourPointsArray = this.getCurrentHourPoints() //计算从当前时间往后推24小时 }, onShow() { this.getinfo() }, mounted() { let arr = this.getCurrentWeekdayAndNextFiveDays(); this.weekdayAndDateSequence = this.convertDates(arr) console.log(this.weekdayAndDateSequence); }, methods: { // 拿到房间标签进行对比 getMatchingLabel(val) { const matchingItem = this.biaoqianlist.find(item => item.dictValue === val) return matchingItem ? matchingItem.dictLabel : val }, // 获取房间标签 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(startHour == endHour){ if (timefen == '00'){ if (this.arr[i] <= endHour) { room.reservationStatus[i] = true } }else{ if (this.arr[i] <= Number(endHour) + 1) { room.reservationStatus[i] = true } } }else 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 if(res.data[0].mode == 1){ // this.kstime = e.hour + ':' + e.minute // 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) // } this.jstime = this.addOneHourToTimess(this.kstime.slice(10,16)) console.log(this.jstime,this.kstime); this.price = this.tclist[0].deposit //订单金额 this.hourstime = Math.ceil(this.tclist[0].deposit / this.tclist[0].price) //订单时间 } } }) }, // 押金计算结束时间 addOneHourToTimess(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() + Math.ceil(this.tclist[0].deposit / this.tclist[0].price)) //加上套餐中的小时 let newHours = timeDate.getHours() let newMinutes = String(timeDate.getMinutes()).padStart(2, '0') // 格式化分钟为两位数 return `${String(newHours).padStart(2, '0')}:${newMinutes}` }, // 查询个人信息 getinfo() { this.$u.get(`/getAppInfo`).then(res => { if (res.code == 200) { this.user = res.user } }) }, // 点击立即续单 btnljyd() { // let time = '20' + this.ksriqi + ' ' + this.kstime + ':00' // let formattedDateString = time.replace(/\//g, "-") let data = { payType: this.zfssid, ruleId:this.ruleId, type2:this.viewType, // type: 2, mode: this.tclist[this.indextwo].mode, hours: this.hourstime, price: this.price, originalOrderNo:this.orderNo } this.$u.post(`/app/order/reOrder`, 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.reLaunch({ url:'/page_user/dingdanxq?orderNo=' + orderNo }) }, fail(err) { uni.showToast({ title: '支付失败', icon: 'none', duration: 2000 }) } }) } 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.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, '/')) targetDate.setSeconds(1) let currentDate = new Date(); currentDate.setSeconds(0) 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, '/')) targetDate.setSeconds(1) let currentDate = new Date(); currentDate.setSeconds(0) 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 // this.kstime 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() } } }) }, // 根据订单号查询 getstoredetails() { this.$u.get(`/appVerify/orderInfo?orderNo=${this.orderNo}`).then(res => { if (res.code == 200) { this.kstime = res.data.reserveEndTime this.gettaocan() } }) }, // 选择开始时间 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(startHour == endHour){ if (timefen == '00'){ if (this.arr[i].slice(0,2) <= endHour) { room.reservationStatus[i] = true } }else{ if (this.arr[i].slice(0,2) <= Number(endHour) + 1) { room.reservationStatus[i] = true } } }else 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.ruleId = item.ruleId if(item.mode == 1){ this.price = this.tcobj.deposit //订单金额 this.hourstime = Math.ceil(this.tcobj.deposit / this.tcobj.price) //订单时间 }else{ this.price = item.price //订单金额 this.hourstime = item.hours //订单时间 } this.indextwo = index const originalDateTime = this.kstime const date = new Date(originalDateTime.replace(/-/g, '/')) date.setTime(date.getTime() + item.hours * 60 * 60 * 1000) this.jstime = this.formatDateTime(date) console.log(this.jstime); // if (this.kstime != '') { // this.jstime = this.addOneHourToTime(this.kstime) // } }, // 处理转化结束时间 formatDateTime(date) { const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始,需要加1 const day = String(date.getDate()).padStart(2, '0'); const hours = String(date.getHours()).padStart(2, '0'); const minutes = String(date.getMinutes()).padStart(2, '0'); const seconds = String(date.getSeconds()).padStart(2, '0'); return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; }, // 日期格式化 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: 78vh; // padding-bottom: 200rpx; box-sizing: border-box; overflow: scroll; } page { background: #fff; margin-top: 18rpx; padding-bottom: 220rpx; box-sizing: border-box; .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; margin-top: 10rpx; } } } .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: 30rpx; // 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; width: 3000rpx; } .tcxz .tcxzname { font-size: 32rpx; color: #3D3D3D; font-weight: 600; width: 160rpx; } .tcxz .taocan { display: flex; width: 420rpx; overflow-x: auto; -webkit-overflow-scrolling: touch; } .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; image { width: 54rpx; height: 54rpx; } .yyshijian { display: flex; justify-content: space-between; .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; .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>