diff --git a/api/index.js b/api/index.js index 6097067..e327d30 100644 --- a/api/index.js +++ b/api/index.js @@ -67,3 +67,19 @@ export function repairList(pamars) { export function incidentsList(pamars) { return fly.get(`/bysmp/incidents/list`,pamars) } +// 共享空间预约 +export function appointment(data) { + return fly.post(`/bys/mzShareAppointmentRec/appointment`, data); +} +// 预约记录 +export function appointmentRecList(pamars) { + return fly.get(`/bys/mzShareAppointmentRec/page`, pamars); +} +// 共享空间列表 +export function spacePage(pamars) { + return fly.get(`/bys/mzShareSpace/page`, pamars); +} +// 共享空间详情 +export function spaceInfo(pamars) { + return fly.get(`/bys/mzShareSpace/detail`, pamars); +} diff --git a/app.json b/app.json index 0bcdea1..3f54aeb 100644 --- a/app.json +++ b/app.json @@ -29,7 +29,8 @@ "evaluate/evaluate", "checkInEvaluate/checkInEvaluate", "repairList/repairList", - "eventList/eventList" + "eventList/eventList", + "mySpace/mySpace" ] }, { @@ -65,6 +66,13 @@ "pages": [ "signingCompleted/signingCompleted" ] + },{ + "root": "subpages/space", + "name":"space", + "pages":[ + "list/list", + "reserve/reserve" + ] } ], "window": { @@ -89,6 +97,11 @@ "text": "我的", "pagePath": "pages/mine/mine", "iconPath": "images/icon/home.png" + },{ + "text": "服务", + "pagePath": "pages/serve/serve", + "iconPath": "images/icon/serve Copy.png" + } ] }, diff --git a/custom-tab-bar/index.js b/custom-tab-bar/index.js index c5cc6d3..8e0a8da 100644 --- a/custom-tab-bar/index.js +++ b/custom-tab-bar/index.js @@ -22,13 +22,13 @@ Component({ // selectedIconPath: "/images/icon/message-a.png", // text: "消息", // }, - // { - // pagePath: "/pages/serve/serve", - // iconPath: "/images/icon/serve-a.png", - // selectedIconPath: "/images/icon/serve.png", - // bulge:false, - // text: "服务", - // }, + { + pagePath: "/pages/serve/serve", + iconPath: "/images/icon/serve-a.png", + selectedIconPath: "/images/icon/serve.png", + bulge:false, + text: "服务", + }, // { // pagePath: "/pages/life/life", // iconPath: "/images/icon/life.png", diff --git a/pages/index/index.js b/pages/index/index.js index 993dc7c..802b600 100644 --- a/pages/index/index.js +++ b/pages/index/index.js @@ -57,7 +57,8 @@ Page({ searchValue: "", policyList:[],//政策列表 getUserInfo:{}, - bindPhone:false + bindPhone:false, + userInfo: {} }, /** @@ -221,7 +222,7 @@ Page({ }) }else if(e.currentTarget.dataset.url === '/subpages/OCRCard/pages/index/index'){ if(!this.data.bindPhone){ - if(this.data.userInfo.idCard){ + if(this.data.userInfo && this.data.userInfo.idCard){ this.selectMzGraduateInfo({idCard:this.data.userInfo.idCard}) }else{ wx.navigateTo({ @@ -235,7 +236,7 @@ Page({ } }else if(e.currentTarget.dataset.url === '/subpages/index/checkOutConfirm/index/index'){ if(!this.data.bindPhone){ - if(this.data.userInfo.idCard){ + if(this.data.userInfo && this.data.userInfo.idCard){ wx.navigateTo({ url: `/subpages/index/checkOutConfirm/index/index`, }) diff --git a/pages/mine/mine.js b/pages/mine/mine.js index 4deaab0..b3dfa68 100644 --- a/pages/mine/mine.js +++ b/pages/mine/mine.js @@ -29,10 +29,10 @@ Page({ label:'问题反馈', url:'/subpages/mine/eventList/eventList' }, - // { - // label:'共享空间', - // url:'' - // } + { + label:'共享空间', + url:'/subpages/mine/mySpace/mySpace' + } ], registerFlag:false }, diff --git a/pages/serve/serve.js b/pages/serve/serve.js index e2ca39f..a318dad 100644 --- a/pages/serve/serve.js +++ b/pages/serve/serve.js @@ -1,13 +1,16 @@ // pages/serve/serve.js const app = getApp() +import { getUserInfo as fetchUserInfo } from "../../api/user"; +import { selectMzGraduateInfo } from "../../api/index"; Page({ /** * 页面的初始数据 */ data: { - + userInfo: {}, + bindPhone: false, }, /** @@ -31,7 +34,7 @@ Page({ * 生命周期函数--监听页面显示 */ onShow() { - + this.getUserInfo() }, /** @@ -67,13 +70,55 @@ Page({ */ onShareAppMessage() { + }, + getUserInfo() { + fetchUserInfo().then((res) => { + app.globalData.userInfo = res.data; + this.setData({ + userInfo: res.data, + bindPhone: !Boolean(res.data && res.data.phone) + }); + }) }, toEventAdd(){ wx.navigateTo({ url: '/subpages/eventAdd/add/add', }) }, + selectMzGraduateInfo(obj) { + selectMzGraduateInfo({ idCard: obj.idCard }) + .then((res) => { + if (res.data.signType === 0 && res.data.contract) { + app.globalData.userInfo.chooseRoomId = res.data.chooseRecId; + res.data.contract = res.data.contract.replace( + "https://h5.esign.cn", + "https://hxm5112004501.h5.esign.cn" + ); + wx.navigateTo({ + url: + "/pages/webView/webView?url=" + + encodeURIComponent(res.data.contract), + }); + } else if (res.data.signType === 1) { + wx.navigateTo({ + url: "/pages/noData/noData?msg=暂无合同签订&idCard=" + obj.idCard, + }); + } else { + wx.navigateTo({ + url: "/pages/noData/noData?msg=暂无合同签订&idCard=" + obj.idCard, + }); + } + }) + .catch(() => { + wx.navigateTo({ + url: "/pages/noData/noData?msg=暂无合同签订&idCard=" + obj.idCard, + }); + }); + }, toPage(e){ + if (!wx.getStorageSync('token')) { + return + } console.log(e); if(e.currentTarget.dataset.url && e.currentTarget.dataset.url != '/subpages/OCRCard/pages/index/index' && e.currentTarget.dataset.url != '/subpages/index/checkOutConfirm/index/index'){ if(e.currentTarget.dataset.url === '/pages/serve/serve'){ @@ -86,10 +131,8 @@ Page({ }) }else if(e.currentTarget.dataset.url === '/subpages/OCRCard/pages/index/index'){ if(!this.data.bindPhone){ - if(this.data.userInfo.idCard){ - wx.navigateTo({ - url: `/subpages/index/checkInUser/checkInUser?idCard=${this.data.userInfo.idCard}&name=${this.data.userInfo.name}&phone=${this.data.userInfo.phone}`, - }) + if(this.data.userInfo && this.data.userInfo.idCard){ + this.selectMzGraduateInfo({ idCard: this.data.userInfo.idCard }) }else{ wx.navigateTo({ url: `/subpages/OCRCard/pages/index/index`, @@ -102,7 +145,7 @@ Page({ } }else if(e.currentTarget.dataset.url === '/subpages/index/checkOutConfirm/index/index'){ if(!this.data.bindPhone){ - if(this.data.userInfo.idCard){ + if(this.data.userInfo && this.data.userInfo.idCard){ wx.navigateTo({ url: `/subpages/index/checkOutConfirm/index/index`, }) @@ -122,5 +165,10 @@ Page({ wx.navigateTo({ url: '/subpages/bsPage/bsPage/bsPage', }) - } + }, + toYuyue(){ + wx.navigateTo({ + url: '/subpages/space/list/list', + }) + } }) \ No newline at end of file diff --git a/pages/serve/serve.wxml b/pages/serve/serve.wxml index 03dfd70..2632c69 100644 --- a/pages/serve/serve.wxml +++ b/pages/serve/serve.wxml @@ -40,12 +40,12 @@ 去报事 --> - + \ No newline at end of file diff --git a/project.private.config.json b/project.private.config.json index 2ba5663..fa28701 100644 --- a/project.private.config.json +++ b/project.private.config.json @@ -15,12 +15,54 @@ "miniprogram": { "list": [ { - "name": "subpages/mine/editUser/editUser", - "pathName": "subpages/mine/editUser/editUser", + "name": "subpages/mine/mySpace/mySpace", + "pathName": "subpages/mine/mySpace/mySpace", "query": "", "scene": null, "launchMode": "default" }, + { + "name": "subpages/space/list/list", + "pathName": "subpages/space/list/list", + "query": "", + "launchMode": "default", + "scene": null + }, + { + "name": "subpages/mine/mySpace/mySpace", + "pathName": "subpages/mine/mySpace/mySpace", + "query": "", + "launchMode": "default", + "scene": null + }, + { + "name": "subpages/space/reserve/reserve", + "pathName": "subpages/space/reserve/reserve", + "query": "", + "launchMode": "default", + "scene": null + }, + { + "name": "subpages/space/list/list", + "pathName": "subpages/space/list/list", + "query": "", + "launchMode": "default", + "scene": null + }, + { + "name": "pages/serve/serve", + "pathName": "pages/serve/serve", + "query": "", + "launchMode": "default", + "scene": null + }, + { + "name": "subpages/mine/editUser/editUser", + "pathName": "subpages/mine/editUser/editUser", + "query": "", + "launchMode": "default", + "scene": null + }, { "name": "pages/noData/noData", "pathName": "pages/noData/noData", diff --git a/subpages/mine/mySpace/mySpace.js b/subpages/mine/mySpace/mySpace.js new file mode 100644 index 0000000..e27afc7 --- /dev/null +++ b/subpages/mine/mySpace/mySpace.js @@ -0,0 +1,182 @@ +// subpages/mine/mySpace/mySpace.js +import { appointmentRecList } from "../../../api/index"; +Page({ + /** + * 页面的初始数据 + */ + data: { + list: [], + pageNum: 1, + pageSize: 10, + total: 0, + loading: false, + refreshing: false, + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad(options) {}, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady() {}, + + /** + * 生命周期函数--监听页面显示 + */ + onShow() { + this.setData({ + list: [], + pageNum: 1, + }); + this.getList(); + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide() {}, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload() {}, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh() { + this.setData({ + refreshing: true, + pageNum: 1, + list: [] + }); + this.getList().finally(() => { + wx.stopPullDownRefresh(); + this.setData({ + refreshing: false + }); + }); + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom() {}, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage() {}, + toReserve(e) { + wx.navigateTo({ + url: `/subpages/space/reserve/reserve?id=${e.currentTarget.dataset.item.id}`, + }); + }, + getList() { + if (this.data.loading) return; + + this.setData({ + loading: true + }); + + let parm = { + pageSize: this.data.pageSize, + pageNum: this.data.pageNum, + }; + + return appointmentRecList(parm) + .then((res) => { + if (res.code === 200) { + const newData = res.data.records.map((item) => { + return { + ...item, + // 格式化预约日期和时间 + appointmentDate: item.appointmentDate || "", + appointTime: item.appointTime || "", + // 添加状态显示 + statusText: this.getStatusText(item), + statusColor: this.getStatusColor(item) + }; + }); + + this.setData({ + list: this.data.pageNum === 1 ? newData : this.data.list.concat(newData), + total: res.data.total, + loading: false + }); + } + }) + .catch((err) => { + this.setData({ + loading: false + }); + wx.showToast({ + title: err.msg || "获取数据失败", + duration: 2000, + icon: "none", + }); + }); + }, + scrolltolower() { + if (this.data.loading) return; + + if (this.data.list.length < this.data.total) { + this.setData({ + pageNum: this.data.pageNum + 1, + }); + this.getList(); + } else if (this.data.list.length > 0) { + wx.showToast({ + icon: "none", + title: "没有更多了", + }); + } + }, + toEvaluate(e) { + wx.navigateTo({ + url: `/subpages/mine/evaluate/evaluate?id=${ + e.currentTarget.dataset.item.checkInRecId + }&obj=${JSON.stringify({ + apartmentName: e.currentTarget.dataset.item.apartmentName, + buildingName: e.currentTarget.dataset.item.buildingName, + buildingName: e.currentTarget.dataset.item.buildingName, + roomType: e.currentTarget.dataset.item.roomType, + unitName: e.currentTarget.dataset.item.unitName, + checkInRecId: e.currentTarget.dataset.item.checkInRecId, + houseName: e.currentTarget.dataset.item.houseName, + })}`, + }); + }, + + // 获取状态文本 + 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'; // 已完成 - 灰色 + } + }, +}); \ No newline at end of file diff --git a/subpages/mine/mySpace/mySpace.json b/subpages/mine/mySpace/mySpace.json new file mode 100644 index 0000000..8310f18 --- /dev/null +++ b/subpages/mine/mySpace/mySpace.json @@ -0,0 +1,11 @@ +{ + "usingComponents": { + "no-data": "../../../components/noData/nodata", + "van-divider": "@vant/weapp/divider/index", + "van-button": "@vant/weapp/button/index", + "van-rate": "@vant/weapp/rate/index" + }, + "navigationBarTitleText": "我的共享空间", + "enablePullDownRefresh": true, + "backgroundTextStyle": "dark" +} diff --git a/subpages/mine/mySpace/mySpace.wxml b/subpages/mine/mySpace/mySpace.wxml new file mode 100644 index 0000000..56f4863 --- /dev/null +++ b/subpages/mine/mySpace/mySpace.wxml @@ -0,0 +1,32 @@ + + + + + {{item.apartmentName}} + + + + + + + {{item.name}} + + + {{item.address}} + + + {{item.appointmentDate}} {{item.appointTime}} + + + {{item.statusText}} + + + + + + + + 加载中... + + + \ No newline at end of file diff --git a/subpages/mine/mySpace/mySpace.wxss b/subpages/mine/mySpace/mySpace.wxss new file mode 100644 index 0000000..87611fe --- /dev/null +++ b/subpages/mine/mySpace/mySpace.wxss @@ -0,0 +1,37 @@ +/* subpages/mine/mySpace/mySpace.wxss */ + + +.name { + font-size: 32rpx; +} + +.position { + font-size: 30rpx; + line-height: 32rpx; +} + +.date { + font-size: 26rpx; + color: #BFBFBF; + line-height: 40rpx; +} +.status{ + font-size: 26rpx; + margin-top: 10rpx; +} + +.btn { + position: relative; +} + +.doc { + color: #08b3b3; + font-size: 20rpx; +} + +.scroll-view { + padding: 20rpx; + box-sizing: border-box; + background: #eff0f3; + min-height: 100vh; +} \ No newline at end of file diff --git a/subpages/space/list/list.js b/subpages/space/list/list.js new file mode 100644 index 0000000..13ac693 --- /dev/null +++ b/subpages/space/list/list.js @@ -0,0 +1,202 @@ +// subpages/space/list/list.js +import { spacePage } from "../../../api/index"; +Page({ + /** + * 页面的初始数据 + */ + data: { + list: [], + pageNum: 1, + pageSize: 10, + total: 0, + loading: false, + hasMore: true, + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad(options) {}, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady() {}, + + /** + * 生命周期函数--监听页面显示 + */ + onShow() { + this.getList(true); // 页面显示时刷新数据 + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide() {}, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload() {}, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh() { + this.getList(true); // 下拉刷新 + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom() { + this.loadMore(); // 上拉加载更多 + }, + + /** + * 用户点击右上角分享 + */ + 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}`, + }); + }, + getList(isRefresh = false) { + // 如果正在加载中,直接返回 + if (this.data.loading) return; + + // 如果是刷新,重置分页参数 + if (isRefresh) { + this.setData({ + pageNum: 1, + list: [], + hasMore: true, + }); + } + + // 如果没有更多数据,直接返回 + if (!this.data.hasMore && !isRefresh) { + wx.showToast({ + icon: "none", + title: "没有更多了", + }); + return; + } + + this.setData({ loading: true }); + + let parm = { + pageSize: this.data.pageSize, + pageNum: this.data.pageNum, + }; + + spacePage(parm) + .then((res) => { + if (res.code === 200) { + const newData = res.data.records.map((item) => { + return { + ...item, + // 处理可预约周几的显示 + appointmentWeekText: this.formatAppointmentWeek( + item.appointmentWeek + ), + // 处理预约时间段的显示 + appointmentTimeText: this.formatAppointmentTime( + item.appointmentTimeAm, + item.appointmentTimePm + ), + }; + }); + + const currentList = isRefresh ? [] : this.data.list; + const updatedList = currentList.concat(newData); + + // 判断是否还有更多数据 + const hasMore = newData.length === this.data.pageSize && updatedList.length < res.data.total; + + this.setData({ + list: updatedList, + total: res.data.total, + hasMore: hasMore, + loading: false, + }); + + // 如果是下拉刷新,停止刷新动画 + if (isRefresh) { + wx.stopPullDownRefresh(); + } + } + }) + .catch((err) => { + this.setData({ loading: false }); + + wx.showToast({ + title: err.msg || "加载失败", + duration: 2000, + icon: "none", + }); + + // 如果是下拉刷新,停止刷新动画 + if (isRefresh) { + wx.stopPullDownRefresh(); + } + }); + }, + scrolltolower() { + this.loadMore(); + }, + + loadMore() { + if (!this.data.hasMore) { + wx.showToast({ + icon: "none", + title: "没有更多了", + }); + return; + } + + // 增加页码 + this.setData({ + pageNum: this.data.pageNum + 1, + }); + + this.getList(); + }, + + // 格式化可预约周几 + formatAppointmentWeek(appointmentWeek) { + if (!appointmentWeek || !Array.isArray(appointmentWeek)) { + return ""; + } + + // 将中文周几转换为显示格式 + const weekMap = { + 一: "周一", + 二: "周二", + 三: "周三", + 四: "周四", + 五: "周五", + 六: "周六", + 日: "周日", + }; + + return appointmentWeek.map((week) => weekMap[week] || week).join(","); + }, + + // 格式化预约时间段 + formatAppointmentTime(appointmentTimeAm, appointmentTimePm) { + const timeSlots = []; + + if (appointmentTimeAm) { + timeSlots.push(`上午 ${appointmentTimeAm}`); + } + + if (appointmentTimePm) { + timeSlots.push(`下午 ${appointmentTimePm}`); + } + + return timeSlots.join(" "); + }, +}); diff --git a/subpages/space/list/list.json b/subpages/space/list/list.json new file mode 100644 index 0000000..9247526 --- /dev/null +++ b/subpages/space/list/list.json @@ -0,0 +1,11 @@ +{ + "usingComponents": { + "no-data": "../../../components/noData/nodata", + "van-divider": "@vant/weapp/divider/index", + "van-button": "@vant/weapp/button/index", + "van-rate": "@vant/weapp/rate/index" + }, + "navigationBarTitleText": "共享空间", + "enablePullDownRefresh": true, + "onReachBottomDistance": 50 +} diff --git a/subpages/space/list/list.wxml b/subpages/space/list/list.wxml new file mode 100644 index 0000000..b8c4d98 --- /dev/null +++ b/subpages/space/list/list.wxml @@ -0,0 +1,37 @@ + + + + + + + + + {{item.name}} + + {{item.appointmentWeekText}} + {{item.appointmentTimeText}} + {{item.inDate}} 至 {{item.outDate}} + + {{item.inDate}} 至 {{item.actualOutDate}} + + + + + + + 预约 + + + + + + + + 加载中... + + + + + \ No newline at end of file diff --git a/subpages/space/list/list.wxss b/subpages/space/list/list.wxss new file mode 100644 index 0000000..9afccee --- /dev/null +++ b/subpages/space/list/list.wxss @@ -0,0 +1,60 @@ +/* subpages/space/list/list.wxss */ +.card{ + height:280rpx ; +} +.name { + font-size: 32rpx; +} +.position{ + font-size: 30rpx; + line-height: 32rpx; +} +.date { + font-size: 26rpx; + color: #BFBFBF; + line-height: 40rpx; +} +.btn{ + position: relative; +} + +.doc { + color: #08b3b3; + font-size: 20rpx; +} + +.scroll-view { + padding: 20rpx; + box-sizing: border-box; + background: #eff0f3; + min-height: 100vh; +} + +/* 加载更多样式 */ +.load-more { + padding: 20rpx 0; + text-align: center; +} + +.loading-text, .no-more-text { + font-size: 28rpx; + color: #999; +} + +.loading-text text::before { + content: ''; + display: inline-block; + width: 20rpx; + height: 20rpx; + border: 2rpx solid #ccc; + border-top-color: #0DC6C6; + border-radius: 50%; + animation: spin 1s linear infinite; + margin-right: 10rpx; + vertical-align: middle; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} \ No newline at end of file diff --git a/subpages/space/reserve/reserve.js b/subpages/space/reserve/reserve.js new file mode 100644 index 0000000..6b1604b --- /dev/null +++ b/subpages/space/reserve/reserve.js @@ -0,0 +1,338 @@ +// subpages/space/reserve/reserve.js +import { appointment, spaceInfo } from "../../../api/index"; +Page({ + + /** + * 页面的初始数据 + */ + data: { + bannerUrl: 'https://img.yzcdn.cn/vant/cat.jpeg', + roomName: '第一会议室', + openDate: '周一至周五', + openTimeText: '上午09:00-下午18:00', + dateList: [], + selectedDateIndex: 0, + timeSlots: [], + rangeStartIndex: -1, + rangeEndIndex: -1, + chosenText: '', + spaceDetail: null, + appointDates: [], + appointmentTimes: [] + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad(options) { + console.log("11",options); + this.setData({ + id: options.id, + roomName: options.roomName, + openDate: options.openDate, + openTimeText: options.openTimeText, + bannerUrl: options.imgUrls, + }); + this.getDetail(); // 获取详情后会自动初始化日期和时间段 + }, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady() {}, + + /** + * 生命周期函数--监听页面显示 + */ + onShow() {}, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide() {}, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload() {}, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh() {}, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom() {}, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage() { }, + // 获取详情 + getDetail() { + spaceInfo({ id: this.data.id }).then(res => { + console.log(res); + if (res.code === 200 && res.data) { + this.setData({ + spaceDetail: res.data, + appointDates: res.data.appointDates || [], + appointmentTimes: res.data.appointmentTimes || [] + }); + // 根据接口数据初始化日期和时间段 + this.initDatesFromAPI(); + this.initTimeSlotsFromAPI(); + } + }).catch(err => { + wx.showToast({ + title: err.msg || '获取详情失败', + icon: 'none' + }); + }) + }, + + initDates() { + const weekMap = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']; + const today = new Date(); + const dates = []; + for (let i = 0; i < 7; i++) { + const d = new Date(today.getFullYear(), today.getMonth(), today.getDate() + i); + const isToday = i === 0; + dates.push({ + label: isToday ? '今天' : weekMap[d.getDay()], + day: d.getDate(), + date: `${d.getFullYear()}-${('0' + (d.getMonth() + 1)).slice(-2)}-${('0' + d.getDate()).slice(-2)}`, + }); + } + this.setData({ + dateList: dates, + selectedDateIndex: 0, + }); + }, + + // 根据接口数据初始化日期 + initDatesFromAPI() { + const { appointDates } = this.data; + if (!appointDates || appointDates.length === 0) { + this.initDates(); // 如果没有接口数据,使用默认逻辑 + return; + } + + const today = new Date().toISOString().split('T')[0]; // 今天的日期 YYYY-MM-DD + const dates = appointDates.map((item, index) => { + const date = new Date(item.appointDate); + const isToday = item.appointDate === today; + return { + label: isToday ? '今天' : item.week, + day: date.getDate(), + date: item.appointDate, + canAppoint: item.canAppoint, + disabled: !item.canAppoint + }; + }); + + // 找到第一个可预约的日期作为默认选中 + let defaultIndex = 0; + for (let i = 0; i < dates.length; i++) { + if (dates[i].canAppoint) { + defaultIndex = i; + break; + } + } + + this.setData({ + 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: '' }); + }, + + // 根据接口数据初始化时间段 + initTimeSlotsFromAPI() { + const { appointmentTimes } = this.data; + if (!appointmentTimes || appointmentTimes.length === 0) { + this.initTimeSlots(); // 如果没有接口数据,使用默认逻辑 + 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})/); + 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, + timeText: item.appointmentTime, + status: item.canAppoint ? 'available' : 'disabled' + }; + }); + + this.setData({ + timeSlots: slots, + rangeStartIndex: -1, + rangeEndIndex: -1, + chosenText: '' + }); + }, + + selectDate(e) { + const { index } = e.currentTarget.dataset; + const selectedDate = this.data.dateList[index]; + + // 检查是否可预约 + if (selectedDate.disabled) { + wx.showToast({ + title: '该日期不可预约', + icon: 'none' + }); + return; + } + + this.setData({ selectedDateIndex: index }); + this.initTimeSlotsFromAPI(); // 使用接口数据初始化时间段 + }, + + toggleSlot(e) { + const { index } = e.currentTarget.dataset; + const list = this.data.timeSlots.slice(); + const slot = list[index]; + if (slot.status === 'disabled') return; + + const { rangeStartIndex, rangeEndIndex } = this.data; + + // 无选择 -> 单选 + if (rangeStartIndex === -1) { + for (let i = 0; i < list.length; i++) if (list[i].status === 'selected') list[i].status = 'available'; + list[index].status = 'selected'; + this.setData({ + timeSlots: list, + rangeStartIndex: index, + rangeEndIndex: index, + chosenText: `${slot.start} - ${slot.end}` + }); + return; + } + + // 已有单选 + if (rangeStartIndex !== -1 && rangeEndIndex === rangeStartIndex) { + // 点击同一格 -> 清空 + if (index === rangeStartIndex) { + list[index].status = 'available'; + this.setData({ timeSlots: list, rangeStartIndex: -1, rangeEndIndex: -1, chosenText: '' }); + return; + } + // 点击另一格 -> 扩展成区间(需避开禁用) + const start = Math.min(rangeStartIndex, index); + const end = Math.max(rangeStartIndex, index); + for (let i = start; i <= end; i++) if (list[i].status === 'disabled') { + wx.showToast({ icon: 'none', title: '所选区间包含不可预约时段' }); + return; + } + for (let i = start; i <= end; i++) list[i].status = 'selected'; + this.setData({ + timeSlots: list, + rangeStartIndex: start, + rangeEndIndex: end, + chosenText: `${list[start].start} - ${list[end].end}` + }); + return; + } + + // 已有区间 -> 下一次点击无论何处都折叠为所点单格 + if (rangeStartIndex !== -1 && rangeEndIndex !== -1) { + // 清空之前区间 + for (let i = 0; i < list.length; i++) { + if (list[i].status === 'selected') list[i].status = 'available'; + } + // 选中新点为单选 + list[index].status = 'selected'; + this.setData({ + timeSlots: list, + rangeStartIndex: index, + rangeEndIndex: index, + chosenText: `${list[index].start} - ${list[index].end}` + }); + return; + } + }, + + confirmReserve() { + const { rangeStartIndex, rangeEndIndex, timeSlots, selectedDateIndex, dateList, id } = this.data; + if (rangeStartIndex === -1) { + wx.showToast({ icon: 'none', title: '请先选择预约时段' }); + return; + } + + const start = rangeStartIndex; + const end = rangeEndIndex === -1 ? rangeStartIndex : rangeEndIndex; + const selectedDate = dateList[selectedDateIndex]; + const startSlot = timeSlots[start]; + const endSlot = timeSlots[end]; + + // 收集选中的时间段ID + const selectedTimeIds = []; + for (let i = start; i <= end; i++) { + if (timeSlots[i].apiId) { + selectedTimeIds.push(timeSlots[i].apiId); + } + } + + const appointmentData = { + shareSpaceId: id, + appointmentDate: selectedDate.date, + timeIds: selectedTimeIds, + }; + + console.log('预约数据:', appointmentData); + + // 调用预约接口 + appointment(appointmentData).then(res => { + if (res.code === 200) { + wx.showToast({ + title: '预约成功', + icon: 'success' + }); + // 可以跳转到预约成功页面或返回上一页 + setTimeout(() => { + wx.navigateBack(); + }, 1500); + } 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.json b/subpages/space/reserve/reserve.json new file mode 100644 index 0000000..cbae814 --- /dev/null +++ b/subpages/space/reserve/reserve.json @@ -0,0 +1,8 @@ +{ + "usingComponents": { + "van-image": "@vant/weapp/image/index", + "van-divider": "@vant/weapp/divider/index", + "van-button": "@vant/weapp/button/index", + "van-tag": "@vant/weapp/tag/index" + } +} \ No newline at end of file diff --git a/subpages/space/reserve/reserve.wxml b/subpages/space/reserve/reserve.wxml new file mode 100644 index 0000000..00ec3ee --- /dev/null +++ b/subpages/space/reserve/reserve.wxml @@ -0,0 +1,35 @@ + + + + + + + + + {{item.label}} + {{item.day}} + + + 预约时段 + + + {{item.start}} + + {{item.end}} + + + + 已选择:{{chosenText}} + + + + 确定 + + + \ No newline at end of file diff --git a/subpages/space/reserve/reserve.wxss b/subpages/space/reserve/reserve.wxss new file mode 100644 index 0000000..932ac8b --- /dev/null +++ b/subpages/space/reserve/reserve.wxss @@ -0,0 +1,131 @@ +/* subpages/space/reserve/reserve.wxss */ +.page { + 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; + padding: 18rpx; + background: #fff; + border-radius: 20rpx; + +} +.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{ + 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; + align-items: center; + justify-content: center; + width: 100rpx; + height: 120rpx; + border-radius: 16rpx; + color: #666; + margin-right: 16rpx; +} +.date-item .date-label { + font-size: 26rpx; +} +.date-item .date-day { + margin-top: 8rpx; + width: 56rpx; + height: 56rpx; + line-height: 56rpx; + 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; + margin-top: 12rpx; +} +.slot { + width: calc(25% - 16rpx); + margin-right: 16rpx; + margin-top: 16rpx; + border-radius: 16rpx; + padding: 12rpx 0; + text-align: center; + background: #f7f8fa; + color: #000; + 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{ + margin-top: 20rpx; + color: #13c2c2; + font-size: 26rpx; +} +.footer { + padding: 24rpx; +} \ No newline at end of file