diff --git a/api/index.js b/api/index.js index e327d30..e5bf3d2 100644 --- a/api/index.js +++ b/api/index.js @@ -83,3 +83,7 @@ export function spacePage(pamars) { export function spaceInfo(pamars) { return fly.get(`/bys/mzShareSpace/detail`, pamars); } +// 根据共享空间和日期查询可预约时间段; +export function queryAppointTime(pamars) { + return fly.get(`/bys/mzShareSpace/queryAppointTime`, pamars); +} diff --git a/images/mine/s3.png b/images/mine/s3.png new file mode 100644 index 0000000..d983785 Binary files /dev/null and b/images/mine/s3.png differ diff --git a/pages/mine/mine.wxml b/pages/mine/mine.wxml index 8a6112a..eba6bbc 100644 --- a/pages/mine/mine.wxml +++ b/pages/mine/mine.wxml @@ -79,7 +79,7 @@ - {{item.label}} + {{item.label}} diff --git a/subpages/images/icon01.png b/subpages/images/icon01.png new file mode 100644 index 0000000..7fcc058 Binary files /dev/null and b/subpages/images/icon01.png differ diff --git a/subpages/images/icon02.png b/subpages/images/icon02.png new file mode 100644 index 0000000..d983785 Binary files /dev/null and b/subpages/images/icon02.png differ diff --git a/subpages/mine/mySpace/mySpace.js b/subpages/mine/mySpace/mySpace.js index e27afc7..99ec1ad 100644 --- a/subpages/mine/mySpace/mySpace.js +++ b/subpages/mine/mySpace/mySpace.js @@ -93,12 +93,10 @@ Page({ const newData = res.data.records.map((item) => { return { ...item, - // 格式化预约日期和时间 + // 格式化预约日期和时间(保留展示所需字段) appointmentDate: item.appointmentDate || "", appointTime: item.appointTime || "", - // 添加状态显示 - statusText: this.getStatusText(item), - statusColor: this.getStatusColor(item) + statusColor: this.getColorByStatus(item.currentStatus) }; }); @@ -151,32 +149,9 @@ Page({ }); }, - // 获取状态文本 - getStatusText(item) { - // 根据实际业务逻辑判断状态 - const now = new Date(); - const appointmentDate = new Date(item.appointmentDate); - - if (appointmentDate > now) { - return '已预约'; - } else if (appointmentDate.toDateString() === now.toDateString()) { - return '使用中'; - } else { - return '已完成'; - } - }, - - // 获取状态颜色 - getStatusColor(item) { - const now = new Date(); - const appointmentDate = new Date(item.appointmentDate); - - if (appointmentDate > now) { - return '#17C4C4'; // 已预约 - 青色 - } else if (appointmentDate.toDateString() === now.toDateString()) { - return '#FA9E0A'; // 使用中 - 橙色 - } else { - return '#999'; // 已完成 - 灰色 - } - }, + getColorByStatus(status) { + if (status === 1) return '#17C4C4'; + if (status === 2) return '#FA9E0A'; + return '#999'; + } }); \ No newline at end of file diff --git a/subpages/mine/mySpace/mySpace.wxml b/subpages/mine/mySpace/mySpace.wxml index 56f4863..b1731e1 100644 --- a/subpages/mine/mySpace/mySpace.wxml +++ b/subpages/mine/mySpace/mySpace.wxml @@ -2,15 +2,16 @@ - {{item.apartmentName}} + + + {{item.apartmentName}} + - - {{item.name}} - + {{item.name}} {{item.address}} @@ -18,12 +19,11 @@ {{item.appointmentDate}} {{item.appointTime}} - {{item.statusText}} + {{item.currentStatus==1?'已预约':item.currentStatus==2?'使用中':item.currentStatus==3?'已完成':''}} - 加载中... diff --git a/subpages/space/list/list.js b/subpages/space/list/list.js index 13ac693..a6449cf 100644 --- a/subpages/space/list/list.js +++ b/subpages/space/list/list.js @@ -60,7 +60,7 @@ Page({ onShareAppMessage() {}, toReserve(e) { wx.navigateTo({ - url: `/subpages/space/reserve/reserve?id=${e.currentTarget.dataset.item.id}&roomName=${e.currentTarget.dataset.item.name}&openDate=${e.currentTarget.dataset.item.appointmentWeekText}&openTimeText=${e.currentTarget.dataset.item.appointmentTimeText}&imgUrls=${e.currentTarget.dataset.item.imgUrls}`, + url: `/subpages/space/reserve/reserve?id=${e.currentTarget.dataset.item.id}&roomName=${e.currentTarget.dataset.item.name}&openDate=${e.currentTarget.dataset.item.appointmentWeekText}&openTimeText=${e.currentTarget.dataset.item.appointmentTimeText}&imgUrls=${e.currentTarget.dataset.item.imgUrls[0]}&address=${e.currentTarget.dataset.item.address}`, }); }, getList(isRefresh = false) { diff --git a/subpages/space/list/list.wxml b/subpages/space/list/list.wxml index b8c4d98..0d7af11 100644 --- a/subpages/space/list/list.wxml +++ b/subpages/space/list/list.wxml @@ -1,15 +1,19 @@ + + + + {{item.address}} + + + - - - {{item.name}} - + + + {{item.name}} {{item.appointmentWeekText}} {{item.appointmentTimeText}} {{item.inDate}} 至 {{item.outDate}} @@ -20,12 +24,11 @@ - + 预约 - @@ -33,5 +36,4 @@ - \ No newline at end of file diff --git a/subpages/space/list/list.wxss b/subpages/space/list/list.wxss index 9afccee..430af8b 100644 --- a/subpages/space/list/list.wxss +++ b/subpages/space/list/list.wxss @@ -1,6 +1,6 @@ /* subpages/space/list/list.wxss */ .card{ - height:280rpx ; + height:370rpx ; } .name { font-size: 32rpx; diff --git a/subpages/space/reserve/reserve.js b/subpages/space/reserve/reserve.js index 6b1604b..c5a758c 100644 --- a/subpages/space/reserve/reserve.js +++ b/subpages/space/reserve/reserve.js @@ -1,12 +1,12 @@ // subpages/space/reserve/reserve.js -import { appointment, spaceInfo } from "../../../api/index"; +import { appointment, spaceInfo, queryAppointTime } from "../../../api/index"; Page({ /** * 页面的初始数据 */ data: { - bannerUrl: 'https://img.yzcdn.cn/vant/cat.jpeg', + bannerUrl: '', roomName: '第一会议室', openDate: '周一至周五', openTimeText: '上午09:00-下午18:00', @@ -18,7 +18,8 @@ Page({ chosenText: '', spaceDetail: null, appointDates: [], - appointmentTimes: [] + appointmentTimes: [], + address: '', }, /** @@ -32,6 +33,7 @@ Page({ openDate: options.openDate, openTimeText: options.openTimeText, bannerUrl: options.imgUrls, + address: options.address, }); this.getDetail(); // 获取详情后会自动初始化日期和时间段 }, @@ -78,7 +80,7 @@ Page({ this.setData({ spaceDetail: res.data, appointDates: res.data.appointDates || [], - appointmentTimes: res.data.appointmentTimes || [] + appointmentTimes: [] }); // 根据接口数据初始化日期和时间段 this.initDatesFromAPI(); @@ -86,7 +88,7 @@ Page({ } }).catch(err => { wx.showToast({ - title: err.msg || '获取详情失败', + title: err.msg , icon: 'none' }); }) @@ -115,12 +117,20 @@ Page({ initDatesFromAPI() { const { appointDates } = this.data; if (!appointDates || appointDates.length === 0) { - this.initDates(); // 如果没有接口数据,使用默认逻辑 + // 删除默认逻辑:当无可预约日期时,直接清空并返回 + this.setData({ + dateList: [], + selectedDateIndex: 0, + timeSlots: [], + rangeStartIndex: -1, + rangeEndIndex: -1, + chosenText: '' + }); return; } const today = new Date().toISOString().split('T')[0]; // 今天的日期 YYYY-MM-DD - const dates = appointDates.map((item, index) => { + const dates = appointDates.map((item) => { const date = new Date(item.appointDate); const isToday = item.appointDate === today; return { @@ -145,60 +155,46 @@ Page({ dateList: dates, selectedDateIndex: defaultIndex, }); - }, - initTimeSlots() { - const ranges = [ - ['09:00', '09:30'], ['09:30', '10:00'], ['10:00', '10:30'], ['10:30', '11:00'], - ['11:00', '11:30'], ['11:30', '12:00'], ['12:00', '12:30'], ['12:30', '13:00'], - ['13:00', '13:30'], ['13:30', '14:00'], ['14:00', '14:30'], ['14:30', '15:00'], - ['15:00', '15:30'], ['15:30', '16:00'], ['16:00', '16:30'], ['16:30', '17:00'], - ['17:00', '17:30'], ['17:30', '18:00'], ['18:00', '18:30'], ['18:30', '19:00'], - ]; - const slots = ranges.map((r, idx) => ({ - id: `${r[0]}-${r[1]}`, - start: r[0], - end: r[1], - status: idx < 3 ? 'disabled' : 'available' - })); - this.setData({ timeSlots: slots, rangeStartIndex: -1, rangeEndIndex: -1, chosenText: '' }); + // 初始化默认日期的时间段(调用后端 queryAppointTime) + const defaultDate = dates[defaultIndex] && dates[defaultIndex].date; + if (defaultDate) { + this.fetchTimeSlotsForDate(defaultDate); + } }, - // 根据接口数据初始化时间段 + + + // 根据接口数据初始化时间段(新的数据结构:时间段挂在 appointDates 每个日期项内) initTimeSlotsFromAPI() { - const { appointmentTimes } = this.data; + const { appointDates, selectedDateIndex } = this.data; + if (!appointDates || appointDates.length === 0) return; + const dateItem = appointDates[selectedDateIndex] || {}; + const appointmentTimes = dateItem.appointmentTimes || dateItem.times || []; if (!appointmentTimes || appointmentTimes.length === 0) { - this.initTimeSlots(); // 如果没有接口数据,使用默认逻辑 + this.setData({ timeSlots: [], rangeStartIndex: -1, rangeEndIndex: -1, chosenText: '' }); return; } - const slots = appointmentTimes.map((item, index) => { - // 解析时间段,例如 "09:00至09:29" -> start: "09:00", end: "09:29" - const timeMatch = item.appointmentTime.match(/(\d{2}:\d{2})至(\d{2}:\d{2})/); + const slots = appointmentTimes.map((item) => { + const timeMatch = (item.appointmentTime || '').match(/(\d{2}:\d{2})至(\d{2}:\d{2})/); let start = '00:00'; let end = '00:30'; - if (timeMatch) { start = timeMatch[1]; end = timeMatch[2]; } - return { id: item.id, - apiId: item.id, // 保存接口返回的ID - start: start, - end: end, + apiId: item.id, + start, + end, timeText: item.appointmentTime, status: item.canAppoint ? 'available' : 'disabled' }; }); - this.setData({ - timeSlots: slots, - rangeStartIndex: -1, - rangeEndIndex: -1, - chosenText: '' - }); + this.setData({ timeSlots: slots, rangeStartIndex: -1, rangeEndIndex: -1, chosenText: '' }); }, selectDate(e) { @@ -215,7 +211,8 @@ Page({ } this.setData({ selectedDateIndex: index }); - this.initTimeSlotsFromAPI(); // 使用接口数据初始化时间段 + // 每次选择都请求后端查询当日可预约时间段 + this.fetchTimeSlotsForDate(selectedDate.date); }, toggleSlot(e) { @@ -334,5 +331,36 @@ Page({ icon: 'none' }); }); + }, + + // 根据日期查询可预约时间段 + fetchTimeSlotsForDate(date) { + const { id } = this.data; + if (!id || !date) return; + queryAppointTime({ id, currentDate: date }) + .then((res) => { + if (res.code === 200 && Array.isArray(res.data)) { + const { appointDates, selectedDateIndex } = this.data; + const dateItem = appointDates[selectedDateIndex] || {}; + dateItem.appointmentTimes = res.data; // 将查询到的时间段更新到 appointDates 的对应日期项中 + appointDates[selectedDateIndex] = dateItem; + this.setData({ + appointDates, // 更新 appointDates 数组 + appointmentTimes: [], // 清空独立的 appointmentTimes + }); + this.initTimeSlotsFromAPI(); // 重新初始化时间段 + } else { + wx.showToast({ + title: res.msg || "获取时间段失败", + icon: "none", + }); + } + }) + .catch((err) => { + wx.showToast({ + title: err.msg || "获取时间段失败", + icon: "none", + }); + }); } }) \ No newline at end of file diff --git a/subpages/space/reserve/reserve.wxml b/subpages/space/reserve/reserve.wxml index 00ec3ee..7e15b60 100644 --- a/subpages/space/reserve/reserve.wxml +++ b/subpages/space/reserve/reserve.wxml @@ -5,6 +5,7 @@ diff --git a/subpages/space/reserve/reserve.wxss b/subpages/space/reserve/reserve.wxss index 932ac8b..7b423ef 100644 --- a/subpages/space/reserve/reserve.wxss +++ b/subpages/space/reserve/reserve.wxss @@ -3,22 +3,27 @@ background: #f8f8f8; min-height: 100vh; } + .banner { position: relative; } + .banner-overlay { padding: 20rpx; background: #fff; } + .room-name { font-size: 32rpx; font-weight: 600; } + .open-time { margin-top: 8rpx; font-size: 26rpx; color: #BFBFBF; } + .section { margin: 0 18rpx; margin-top: 12rpx; @@ -27,27 +32,32 @@ border-radius: 20rpx; } -.section-row{ + +.section-row { display: flex; align-items: center; justify-content: space-between; } + .section-title { font-size: 32rpx; font-weight: 600; margin-bottom: 16rpx; margin-left: 10rpx; } -.range-switch{ + +.range-switch { display: flex; align-items: center; color: #666; font-size: 26rpx; } + .date-strip { white-space: nowrap; padding-bottom: 12rpx; } + .date-item { display: inline-flex; flex-direction: column; @@ -59,9 +69,11 @@ color: #666; margin-right: 16rpx; } + .date-item .date-label { font-size: 26rpx; } + .date-item .date-day { margin-top: 8rpx; width: 56rpx; @@ -70,62 +82,78 @@ text-align: center; border-radius: 50%; } + .date-item.active { /* background: #e6fffb; */ color: #13c2c2; } + .date-item.active .date-day { background: #13c2c2; color: #fff; } + .date-item.disabled { color: #bfbfbf; opacity: 0.5; } + .date-item.disabled .date-day { background: #f0f0f0; color: #bfbfbf; } + .slot-grid { - display: flex; - flex-wrap: wrap; + display: grid; + grid-template-columns: repeat(4, 1fr); + grid-column-gap: 16rpx; + grid-row-gap: 16rpx; margin-top: 12rpx; } + .slot { - width: calc(25% - 16rpx); - margin-right: 16rpx; - margin-top: 16rpx; + width: 100%; + margin: 0; + box-sizing: border-box; border-radius: 16rpx; padding: 12rpx 0; text-align: center; background: #f7f8fa; color: #000; - border:1px solid rgba(111, 195, 160, 1); + border: 1px solid rgba(111, 195, 160, 1); + } + .slot:nth-child(4n) { margin-right: 0; } + .slot .slot-line { font-size: 28rpx; } + .slot .slot-sep { font-size: 24rpx; color: inherit; } + .slot.disabled { background: #ededed; color: #bfbfbf; border: none; } + .slot.selected { background: #13c2c2; color: #fff; } -.chosen{ + +.chosen { margin-top: 20rpx; color: #13c2c2; font-size: 26rpx; } + .footer { padding: 24rpx; } \ No newline at end of file