You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
366 lines
12 KiB
366 lines
12 KiB
// subpages/space/reserve/reserve.js
|
|
import { appointment, spaceInfo, queryAppointTime } from "../../../api/index";
|
|
Page({
|
|
|
|
/**
|
|
* 页面的初始数据
|
|
*/
|
|
data: {
|
|
bannerUrl: '',
|
|
roomName: '第一会议室',
|
|
openDate: '周一至周五',
|
|
openTimeText: '上午09:00-下午18:00',
|
|
dateList: [],
|
|
selectedDateIndex: 0,
|
|
timeSlots: [],
|
|
rangeStartIndex: -1,
|
|
rangeEndIndex: -1,
|
|
chosenText: '',
|
|
spaceDetail: null,
|
|
appointDates: [],
|
|
appointmentTimes: [],
|
|
address: '',
|
|
},
|
|
|
|
/**
|
|
* 生命周期函数--监听页面加载
|
|
*/
|
|
onLoad(options) {
|
|
console.log("11",options);
|
|
this.setData({
|
|
id: options.id,
|
|
roomName: options.roomName,
|
|
openDate: options.openDate,
|
|
openTimeText: options.openTimeText,
|
|
bannerUrl: options.imgUrls,
|
|
address: options.address,
|
|
});
|
|
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: []
|
|
});
|
|
// 根据接口数据初始化日期和时间段
|
|
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.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) => {
|
|
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,
|
|
});
|
|
|
|
// 初始化默认日期的时间段(调用后端 queryAppointTime)
|
|
const defaultDate = dates[defaultIndex] && dates[defaultIndex].date;
|
|
if (defaultDate) {
|
|
this.fetchTimeSlotsForDate(defaultDate);
|
|
}
|
|
},
|
|
|
|
|
|
|
|
// 根据接口数据初始化时间段(新的数据结构:时间段挂在 appointDates 每个日期项内)
|
|
initTimeSlotsFromAPI() {
|
|
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.setData({ timeSlots: [], rangeStartIndex: -1, rangeEndIndex: -1, chosenText: '' });
|
|
return;
|
|
}
|
|
|
|
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,
|
|
start,
|
|
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.fetchTimeSlotsForDate(selectedDate.date);
|
|
},
|
|
|
|
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'
|
|
});
|
|
});
|
|
},
|
|
|
|
// 根据日期查询可预约时间段
|
|
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",
|
|
});
|
|
});
|
|
}
|
|
})
|