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.
338 lines
11 KiB
338 lines
11 KiB
3 days ago
|
// 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'
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
})
|