心理健康2.0
This commit is contained in:
1 parent
067957256d
commit
3b492479b5
63 files changed
+10278
-642
No files matched your search
@@ -33,6 +33,19 @@ export const getAvailableDetailSlots = (date, timeSlot) => {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取日历视图的排班数据(带预约状态)- 直接从xljk_consultation_schedule表查询
|
||||
* @param {string} startDate 开始日期 YYYY-MM-DD
|
||||
* @param {string} endDate 结束日期 YYYY-MM-DD
|
||||
*/
|
||||
export const getCalendarSchedules = (startDate, endDate) => {
|
||||
return request({
|
||||
url: '/xljk/consultation/appointment/calendar-schedules',
|
||||
method: 'GET',
|
||||
params: { startDate, endDate }
|
||||
});
|
||||
};
|
||||
|
||||
// ===== 预约记录管理 API =====
|
||||
|
||||
/**
|
||||
@@ -171,6 +184,16 @@ export const getClassOptions = (collegeName, majorName) => {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取咨询主题选项(字典数据)
|
||||
*/
|
||||
export const getConsultThemeOptions = () => {
|
||||
return request({
|
||||
url: '/system/dict/data/type/xljk_consult_theme',
|
||||
method: 'GET'
|
||||
});
|
||||
};
|
||||
|
||||
// ===== 移动端专用辅助方法 =====
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,11 +19,11 @@
|
||||
<view class="filter-section">
|
||||
<view class="filter-tabs">
|
||||
<view
|
||||
v-for="(tab, index) in filterTabs"
|
||||
v-for="(tab, index) in visibleFilterTabs"
|
||||
:key="index"
|
||||
class="filter-tab"
|
||||
:class="{ active: activeFilterIndex === index }"
|
||||
@click="switchFilter(index)"
|
||||
:class="{ active: getOriginalTabIndex(index) === activeFilterIndex }"
|
||||
@click="switchFilter(getOriginalTabIndex(index))"
|
||||
>
|
||||
<text class="tab-text">{{ tab.label }}</text>
|
||||
<!-- 只有待咨询标签显示圆形标记 -->
|
||||
@@ -71,12 +71,15 @@
|
||||
></u-avatar>
|
||||
</view>
|
||||
<view class="counselor-info">
|
||||
<text class="counselor-name">{{ appointment.counselorName || '未知咨询师' }}</text>
|
||||
<view class="counselor-name-row">
|
||||
<text class="counselor-name">{{ appointment.counselorName || '未知咨询师' }}</text>
|
||||
<text class="appointment-office">{{ appointment.office || '暂无办公室信息' }}</text>
|
||||
</view>
|
||||
<text class="appointment-reason">{{ appointment.reason || '心理咨询' }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 取消按钮 -->
|
||||
<view v-if="appointment.status === '0'" class="inline-action">
|
||||
<view v-if="appointment.status === '0' || appointment.status === '4'" class="inline-action">
|
||||
<button
|
||||
class="cancel-button-inline"
|
||||
@click.stop="handleCancelClick(appointment)"
|
||||
@@ -113,7 +116,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getMyAppointments, cancelAppointment } from '@/api/xljk'
|
||||
import { getMyAppointments, cancelAppointment, getCounselorOptions } from '@/api/xljk'
|
||||
|
||||
export default {
|
||||
name: 'MyAppointments',
|
||||
@@ -124,8 +127,10 @@ export default {
|
||||
{ label: '全部', value: 'all', count: 0 },
|
||||
{ label: '待咨询', value: '0', count: 0 },
|
||||
{ label: '已完成', value: '1', count: 0 },
|
||||
{ label: '已取消', value: '2', count: 0 },
|
||||
{ label: '未到访', value: '3', count: 0 }
|
||||
{ label: '已取消', value: '2', count: 0, hidden: true }, // 隐藏已取消标签
|
||||
{ label: '未到访', value: '3', count: 0 },
|
||||
{ label: '待审核', value: '4', count: 0, hidden: true }, // 隐藏待审核标签
|
||||
{ label: '已驳回', value: '5', count: 0 }
|
||||
],
|
||||
activeFilterIndex: 0,
|
||||
|
||||
@@ -140,6 +145,12 @@ export default {
|
||||
cancelingAppointmentId: null // 正在取消的预约ID
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 获取可见的筛选标签(过滤掉隐藏的标签)
|
||||
visibleFilterTabs() {
|
||||
return this.filterTabs.filter(tab => !tab.hidden)
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
// 初始化时重置取消相关状态
|
||||
this.resetCancelState()
|
||||
@@ -152,6 +163,12 @@ export default {
|
||||
this.loadAppointments()
|
||||
},
|
||||
methods: {
|
||||
// 获取可见标签在原始数组中的索引
|
||||
getOriginalTabIndex(visibleIndex) {
|
||||
const visibleTab = this.visibleFilterTabs[visibleIndex]
|
||||
return this.filterTabs.findIndex(tab => tab.value === visibleTab.value)
|
||||
},
|
||||
|
||||
// 返回上一页
|
||||
goBack() {
|
||||
uni.navigateBack()
|
||||
@@ -203,14 +220,38 @@ export default {
|
||||
response.data.forEach((item, index) => {
|
||||
console.log(`🔍 [我的预约] 数据${index}: ID=${item.appointmentId}, status=${item.status} (${typeof item.status})`)
|
||||
})
|
||||
|
||||
// 获取咨询师信息用于补充办公室字段
|
||||
let counselors = []
|
||||
try {
|
||||
const counselorRes = await getCounselorOptions()
|
||||
if (counselorRes.code === 200 && counselorRes.data) {
|
||||
counselors = counselorRes.data
|
||||
console.log('🔍 [我的预约] 获取到咨询师列表:', counselors)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取咨询师信息失败:', error)
|
||||
}
|
||||
|
||||
// 转换API数据格式
|
||||
const appointments = response.data.map(item => {
|
||||
// 补充办公室信息
|
||||
let office = item.office || '暂无办公室信息'
|
||||
if (item.counselorId && counselors.length > 0) {
|
||||
const counselor = counselors.find(c => c.id === item.counselorId)
|
||||
if (counselor && counselor.office) {
|
||||
office = counselor.office
|
||||
console.log('🔍 [我的预约] 补充咨询师办公室信息:', { counselorId: item.counselorId, office: counselor.office })
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
id: item.id, // 修复:使用 id 而不是 appointmentId
|
||||
appointmentDate: item.appointmentDate,
|
||||
appointmentTime: item.appointmentDetailTime || item.appointmentTime,
|
||||
counselorName: item.counselorName,
|
||||
counselorAvatar: '',
|
||||
office: office, // 使用补充后的办公室信息
|
||||
reason: item.reason,
|
||||
status: String(item.status), // 转换为字符串,便于筛选比较
|
||||
originalData: item
|
||||
@@ -249,14 +290,18 @@ export default {
|
||||
const status1Count = this.allAppointments.filter(item => item.status === '1').length
|
||||
const status2Count = this.allAppointments.filter(item => item.status === '2').length
|
||||
const status3Count = this.allAppointments.filter(item => item.status === '3').length
|
||||
const status4Count = this.allAppointments.filter(item => item.status === '4').length
|
||||
const status5Count = this.allAppointments.filter(item => item.status === '5').length
|
||||
|
||||
console.log('🔍 [我的预约] 状态统计: 待咨询(0)=', status0Count, ', 已完成(1)=', status1Count, ', 已取消(2)=', status2Count, ', 未到访(3)=', status3Count)
|
||||
console.log('🔍 [我的预约] 状态统计: 待咨询(0)=', status0Count, ', 已完成(1)=', status1Count, ', 已取消(2)=', status2Count, ', 未到访(3)=', status3Count, ', 待审核(4)=', status4Count, ', 已驳回(5)=', status5Count)
|
||||
|
||||
this.filterTabs[0].count = this.allAppointments.length // 全部
|
||||
this.filterTabs[1].count = status0Count // 待咨询
|
||||
this.filterTabs[2].count = status1Count // 已完成
|
||||
this.filterTabs[3].count = status2Count // 已取消
|
||||
this.filterTabs[4].count = status3Count // 未到访
|
||||
this.filterTabs[5].count = status4Count // 待审核
|
||||
this.filterTabs[6].count = status5Count // 已驳回
|
||||
},
|
||||
|
||||
// 切换筛选器
|
||||
@@ -288,6 +333,8 @@ export default {
|
||||
'1': '已完成',
|
||||
'2': '已取消',
|
||||
'3': '未到访',
|
||||
'4': '待审核',
|
||||
'5': '已驳回',
|
||||
// 兼容英文状态值
|
||||
'pending': '待咨询',
|
||||
'completed': '已完成',
|
||||
@@ -304,6 +351,8 @@ export default {
|
||||
'1': 'success',
|
||||
'2': 'primary', // 已取消状态使用蓝色
|
||||
'3': 'info', // 未到访状态使用灰色
|
||||
'4': 'info', // 待审核状态使用灰色
|
||||
'5': 'error', // 已驳回状态使用红色
|
||||
// 兼容英文状态值
|
||||
'pending': 'warning',
|
||||
'completed': 'success',
|
||||
@@ -321,7 +370,9 @@ export default {
|
||||
'0': '暂无待咨询预约',
|
||||
'1': '暂无已完成预约',
|
||||
'2': '暂无已取消预约',
|
||||
'3': '暂无未到访预约'
|
||||
'3': '暂无未到访预约',
|
||||
'4': '暂无待审核预约',
|
||||
'5': '暂无已驳回预约'
|
||||
}
|
||||
return textMap[currentFilter.value] || '暂无数据'
|
||||
},
|
||||
@@ -355,9 +406,9 @@ export default {
|
||||
cancelAppointment(appointment) {
|
||||
console.log('点击取消预约按钮,预约信息:', appointment)
|
||||
|
||||
if (appointment.status !== '0') {
|
||||
if (appointment.status !== '0' && appointment.status !== '4') {
|
||||
uni.showToast({
|
||||
title: '只能取消待咨询的预约',
|
||||
title: '只能取消待咨询或待审核的预约',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
@@ -670,12 +721,26 @@ export default {
|
||||
.counselor-info {
|
||||
flex: 1;
|
||||
|
||||
.counselor-name {
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
display: block;
|
||||
margin-bottom: 8rpx;
|
||||
.counselor-name-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 6rpx;
|
||||
|
||||
.counselor-name {
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
|
||||
.appointment-office {
|
||||
font-size: 24rpx;
|
||||
color: #1890ff;
|
||||
background: rgba(24, 144, 255, 0.1);
|
||||
padding: 4rpx 8rpx;
|
||||
border-radius: 8rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.appointment-reason {
|
||||
|
||||
@@ -43,10 +43,10 @@
|
||||
|
||||
<!-- 分组时间段列表 -->
|
||||
<view v-else-if="timeSlots.length > 0" class="grouped-time-slots">
|
||||
<!-- 上午时段组 -->
|
||||
<!-- 中午时段组 -->
|
||||
<view v-if="groupedTimeSlots.morning.length > 0" class="time-group">
|
||||
<view class="group-header">
|
||||
<text class="group-title">上午时段</text>
|
||||
<text class="group-title">中午时段</text>
|
||||
</view>
|
||||
<view class="slots-grid">
|
||||
<view
|
||||
@@ -133,6 +133,30 @@
|
||||
<text class="detail-label">咨询师:</text>
|
||||
<text class="detail-value">{{ selectedBookingSlot && selectedBookingSlot.counselorName }}</text>
|
||||
</view>
|
||||
<view class="booking-detail-item">
|
||||
<text class="detail-label">办公室:</text>
|
||||
<text class="detail-value">{{ selectedBookingSlot && selectedBookingSlot.office || '暂无信息' }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 咨询主题选择 -->
|
||||
<view class="booking-detail-item">
|
||||
<text class="detail-label required">咨询主题:</text>
|
||||
</view>
|
||||
<view class="theme-select-container">
|
||||
<u-picker
|
||||
:show="showThemePicker"
|
||||
:columns="themeColumns"
|
||||
@confirm="onThemeConfirm"
|
||||
@cancel="showThemePicker = false"
|
||||
keyName="dictLabel"
|
||||
></u-picker>
|
||||
<view class="theme-select-input" @click="showThemePicker = true">
|
||||
<text class="theme-select-text" :class="{ placeholder: !selectedTheme }">
|
||||
{{ selectedTheme ? selectedTheme.dictLabel : '请选择咨询主题' }}
|
||||
</text>
|
||||
<u-icon name="arrow-down" size="14" color="#c0c4cc"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 咨询原因输入框 -->
|
||||
<view class="booking-detail-item reason-item">
|
||||
@@ -158,7 +182,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getAvailableTimeSlots, getAvailableDetailSlots, submitAppointment } from '@/api/xljk'
|
||||
import { getAvailableTimeSlots, getAvailableDetailSlots, getCalendarSchedules, submitAppointment, getConsultThemeOptions, getCounselorOptions } from '@/api/xljk'
|
||||
|
||||
export default {
|
||||
name: 'XljkReservation',
|
||||
@@ -182,7 +206,13 @@ export default {
|
||||
showBookingModal: false,
|
||||
selectedBookingSlot: null,
|
||||
bookingLoading: false,
|
||||
consultationReason: ''
|
||||
consultationReason: '',
|
||||
|
||||
// 咨询主题相关
|
||||
showThemePicker: false,
|
||||
themeOptions: [],
|
||||
themeColumns: [[]],
|
||||
selectedTheme: null
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
@@ -190,6 +220,7 @@ export default {
|
||||
console.log('🔍 [预约页面] 开始初始化')
|
||||
this.initWeekDates()
|
||||
this.selectTodayAsDefault()
|
||||
this.loadConsultThemeOptions()
|
||||
console.log('🔍 [预约页面] 初始化完成')
|
||||
} catch (error) {
|
||||
console.error('🔍 [预约页面] 初始化失败:', error)
|
||||
@@ -286,88 +317,104 @@ export default {
|
||||
return `${date.getMonth() + 1}月${date.getDate()}日`
|
||||
},
|
||||
|
||||
// 加载时间段数据 - 优化为加载详细时段
|
||||
// 加载时间段数据 - 直接从xljk_consultation_schedule表获取
|
||||
async loadTimeSlots(date) {
|
||||
this.loadingTimeSlots = true
|
||||
this.timeSlots = []
|
||||
this.groupedTimeSlots = { morning: [], afternoon: [] }
|
||||
|
||||
try {
|
||||
// 1. 先获取大时段列表 - 增加参数验证
|
||||
// 参数验证
|
||||
if (!date) {
|
||||
throw new Error('日期参数无效')
|
||||
}
|
||||
|
||||
console.log('🔍 开始获取大时段数据,日期:', date)
|
||||
const bigSlotsResponse = await getAvailableTimeSlots(date, date)
|
||||
console.log('🔍 大时段API返回:', bigSlotsResponse)
|
||||
console.log('🔍 开始获取排班数据,日期:', date)
|
||||
|
||||
// 直接调用calendar-schedules接口获取排班数据(跟web端一样)
|
||||
const response = await getCalendarSchedules(date, date)
|
||||
console.log('🔍 排班数据API返回:', response)
|
||||
|
||||
// 验证API响应结构
|
||||
if (!bigSlotsResponse || typeof bigSlotsResponse !== 'object') {
|
||||
if (!response || typeof response !== 'object') {
|
||||
throw new Error('API响应格式异常')
|
||||
}
|
||||
|
||||
if (bigSlotsResponse.code === 200 && bigSlotsResponse.data && bigSlotsResponse.data.length > 0) {
|
||||
// 2. 并行获取所有详细时段 - 增加数据安全性检查
|
||||
const detailPromises = bigSlotsResponse.data
|
||||
.filter(bigSlot => bigSlot && bigSlot.timeSlot) // 过滤无效数据
|
||||
.map(bigSlot =>
|
||||
getAvailableDetailSlots(date, bigSlot.timeSlot)
|
||||
.then(response => ({
|
||||
bigSlot,
|
||||
detailSlots: response && response.data ? response.data : []
|
||||
}))
|
||||
.catch(error => {
|
||||
console.error(`获取时段 ${bigSlot.timeSlot} 的详细数据失败:`, error)
|
||||
return { bigSlot, detailSlots: [] }
|
||||
})
|
||||
)
|
||||
if (response.code === 200 && response.data && Array.isArray(response.data)) {
|
||||
// 如果排班数据缺少办公室信息,获取咨询师信息来补充
|
||||
let counselors = []
|
||||
const hasMissingOfficeInfo = response.data.some(schedule =>
|
||||
(!schedule.office || schedule.office.trim() === '') && schedule.counselorId
|
||||
)
|
||||
|
||||
const allDetailResults = await Promise.all(detailPromises)
|
||||
console.log('🔍 详细时段API返回:', allDetailResults)
|
||||
if (hasMissingOfficeInfo) {
|
||||
try {
|
||||
console.log('🔍 检测到缺少办公室信息,开始获取咨询师详细信息...')
|
||||
const counselorRes = await getCounselorOptions()
|
||||
if (counselorRes.code === 200 && counselorRes.data) {
|
||||
counselors = counselorRes.data
|
||||
console.log('🔍 获取到咨询师列表:', counselors)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取咨询师信息失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 扁平化并增强数据 - 增加数据安全性检查
|
||||
const allDetailSlots = []
|
||||
allDetailResults.forEach(({ bigSlot, detailSlots }) => {
|
||||
// 确保 bigSlot 和 detailSlots 都是有效的
|
||||
if (!bigSlot || !Array.isArray(detailSlots)) {
|
||||
console.warn('无效的时段数据:', { bigSlot, detailSlots })
|
||||
// 处理排班数据,转换为移动端需要的格式
|
||||
const scheduleSlots = []
|
||||
|
||||
response.data.forEach(schedule => {
|
||||
// 确保必要的字段存在
|
||||
if (!schedule || !schedule.startTime || !schedule.endTime) {
|
||||
console.warn('无效的排班数据:', schedule)
|
||||
return
|
||||
}
|
||||
|
||||
detailSlots.forEach(detail => {
|
||||
// 确保必要的字段存在
|
||||
if (!detail || !detail.timeSlot) {
|
||||
console.warn('无效的详细时段数据:', detail)
|
||||
return
|
||||
try {
|
||||
// 构建时间范围显示
|
||||
const timeRange = `${schedule.startTime}-${schedule.endTime}`
|
||||
|
||||
// 判断是否可预约
|
||||
const available = !schedule.isFullyBooked && !schedule.isExpired
|
||||
|
||||
// 补充办公室信息
|
||||
let office = schedule.office || '暂无信息'
|
||||
if ((!schedule.office || schedule.office.trim() === '') && schedule.counselorId && counselors.length > 0) {
|
||||
const counselor = counselors.find(c => c.id === schedule.counselorId)
|
||||
if (counselor && counselor.office) {
|
||||
office = counselor.office
|
||||
console.log('🔍 补充排班办公室信息:', { scheduleId: schedule.scheduleId, counselorId: schedule.counselorId, office: counselor.office })
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
allDetailSlots.push({
|
||||
id: `${bigSlot.scheduleId || 'unknown'}_${detail.timeSlot}`,
|
||||
timeRange: detail.timeSlot,
|
||||
available: !detail.isBooked && !detail.isExpired,
|
||||
isBooked: Boolean(detail.isBooked),
|
||||
isExpired: Boolean(detail.isExpired),
|
||||
counselorName: bigSlot.counselorName || '未知咨询师',
|
||||
counselorId: bigSlot.counselorId || null,
|
||||
counselorAvatar: '',
|
||||
dateText: this.selectedDateText || '',
|
||||
originalData: {
|
||||
...detail,
|
||||
parentScheduleId: bigSlot.scheduleId || null,
|
||||
counselorId: bigSlot.counselorId || null,
|
||||
timeSlot: bigSlot.timeSlot || null
|
||||
}
|
||||
})
|
||||
} catch (err) {
|
||||
console.error('处理时段数据时出错:', err, { bigSlot, detail })
|
||||
}
|
||||
})
|
||||
scheduleSlots.push({
|
||||
id: `schedule_${schedule.scheduleId}`,
|
||||
timeRange: timeRange,
|
||||
available: available,
|
||||
isBooked: Boolean(schedule.isFullyBooked),
|
||||
isExpired: Boolean(schedule.isExpired),
|
||||
counselorName: schedule.counselorName || '未知咨询师',
|
||||
counselorId: schedule.counselorId || null,
|
||||
counselorAvatar: '',
|
||||
office: office, // 使用补充后的办公室信息
|
||||
dateText: this.selectedDateText || '',
|
||||
originalData: {
|
||||
scheduleId: schedule.scheduleId,
|
||||
counselorId: schedule.counselorId,
|
||||
timeSlot: schedule.timeSlot,
|
||||
startTime: schedule.startTime,
|
||||
endTime: schedule.endTime,
|
||||
available: available,
|
||||
office: office // 在原始数据中也保存补充后的办公室信息
|
||||
}
|
||||
})
|
||||
} catch (err) {
|
||||
console.error('处理排班数据时出错:', err, schedule)
|
||||
}
|
||||
})
|
||||
|
||||
// 4. 按时间排序 - 增加安全性检查
|
||||
allDetailSlots.sort((a, b) => {
|
||||
// 按时间排序
|
||||
scheduleSlots.sort((a, b) => {
|
||||
try {
|
||||
// 安全地获取时间用于排序
|
||||
const timeA = (a.timeRange && typeof a.timeRange === 'string') ? a.timeRange.split('-')[0] : '00:00'
|
||||
@@ -375,27 +422,27 @@ export default {
|
||||
return timeA.localeCompare(timeB)
|
||||
} catch (err) {
|
||||
console.error('时间排序出错:', err, { a, b })
|
||||
return 0 // 如果排序出错,保持原顺序
|
||||
return 0
|
||||
}
|
||||
})
|
||||
|
||||
// 5. 按上午下午分组
|
||||
this.groupAndSetTimeSlots(allDetailSlots)
|
||||
// 按上午下午分组
|
||||
this.groupAndSetTimeSlots(scheduleSlots)
|
||||
|
||||
console.log('🔍 最终处理的详细时段数据:', {
|
||||
total: allDetailSlots.length,
|
||||
console.log('🔍 最终处理的排班时段数据:', {
|
||||
total: scheduleSlots.length,
|
||||
morning: this.groupedTimeSlots.morning.length,
|
||||
afternoon: this.groupedTimeSlots.afternoon.length
|
||||
})
|
||||
|
||||
} else {
|
||||
// 如果没有大时段数据
|
||||
// 如果没有排班数据
|
||||
this.timeSlots = []
|
||||
this.groupedTimeSlots = { morning: [], afternoon: [] }
|
||||
// 移除Toast提示,避免在没有排班时显示不必要的消息
|
||||
console.log('🔍 当天无排班数据')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载详细时段失败:', error)
|
||||
console.error('加载排班时段失败:', error)
|
||||
|
||||
// 网络错误时显示友好提示
|
||||
uni.showToast({
|
||||
@@ -412,7 +459,7 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
// 按上午下午分组时段 - 增加安全性检查
|
||||
// 按时段分组 - 基于timeSlot字段分组(0-中午时段,1-下午时段)
|
||||
groupAndSetTimeSlots(detailSlots) {
|
||||
try {
|
||||
// 确保输入是有效数组
|
||||
@@ -423,35 +470,29 @@ export default {
|
||||
return
|
||||
}
|
||||
|
||||
// 按上午下午分组 - 增加安全性检查
|
||||
// 基于timeSlot字段分组 - 增加安全性检查
|
||||
const morningSlots = detailSlots.filter(slot => {
|
||||
try {
|
||||
if (!slot || !slot.timeRange || typeof slot.timeRange !== 'string') {
|
||||
if (!slot || !slot.originalData || slot.originalData.timeSlot === undefined) {
|
||||
console.warn('缺少timeSlot数据的时段:', slot)
|
||||
return false
|
||||
}
|
||||
const timeParts = slot.timeRange.split(':')
|
||||
if (timeParts.length === 0) {
|
||||
return false
|
||||
}
|
||||
const hour = parseInt(timeParts[0])
|
||||
return !isNaN(hour) && hour < 12
|
||||
// timeSlot为0的是中午时段
|
||||
return slot.originalData.timeSlot === 0 || slot.originalData.timeSlot === '0'
|
||||
} catch (err) {
|
||||
console.warn('处理上午时段时出错:', err, slot)
|
||||
console.warn('处理中午时段时出错:', err, slot)
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
const afternoonSlots = detailSlots.filter(slot => {
|
||||
try {
|
||||
if (!slot || !slot.timeRange || typeof slot.timeRange !== 'string') {
|
||||
if (!slot || !slot.originalData || slot.originalData.timeSlot === undefined) {
|
||||
console.warn('缺少timeSlot数据的时段:', slot)
|
||||
return false
|
||||
}
|
||||
const timeParts = slot.timeRange.split(':')
|
||||
if (timeParts.length === 0) {
|
||||
return false
|
||||
}
|
||||
const hour = parseInt(timeParts[0])
|
||||
return !isNaN(hour) && hour >= 12
|
||||
// timeSlot为1的是下午时段
|
||||
return slot.originalData.timeSlot === 1 || slot.originalData.timeSlot === '1'
|
||||
} catch (err) {
|
||||
console.warn('处理下午时段时出错:', err, slot)
|
||||
return false
|
||||
@@ -459,13 +500,15 @@ export default {
|
||||
})
|
||||
|
||||
this.groupedTimeSlots = {
|
||||
morning: morningSlots,
|
||||
morning: morningSlots, // 实际上是中午时段
|
||||
afternoon: afternoonSlots
|
||||
}
|
||||
|
||||
// 保持原有的timeSlots格式兼容现有代码
|
||||
this.timeSlots = [...morningSlots, ...afternoonSlots]
|
||||
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.error('分组时段时出错:', error)
|
||||
// 发生错误时设置为空数组
|
||||
@@ -479,6 +522,39 @@ export default {
|
||||
this.loadTimeSlots(this.selectedDate)
|
||||
},
|
||||
|
||||
// 加载咨询主题选项
|
||||
async loadConsultThemeOptions() {
|
||||
try {
|
||||
const response = await getConsultThemeOptions()
|
||||
console.log('🔍 咨询主题字典数据:', response)
|
||||
|
||||
if (response.code === 200 && response.data && Array.isArray(response.data)) {
|
||||
this.themeOptions = response.data // 直接使用所有字典数据
|
||||
this.themeColumns = [this.themeOptions]
|
||||
console.log('🔍 处理后的咨询主题选项:', this.themeOptions)
|
||||
} else {
|
||||
console.warn('咨询主题字典数据格式异常:', response)
|
||||
this.themeOptions = []
|
||||
this.themeColumns = [[]]
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载咨询主题选项失败:', error)
|
||||
this.themeOptions = []
|
||||
this.themeColumns = [[]]
|
||||
// 不显示错误提示,避免影响用户体验
|
||||
}
|
||||
},
|
||||
|
||||
// 确认选择咨询主题
|
||||
onThemeConfirm(value) {
|
||||
console.log('🔍 选择的咨询主题:', value)
|
||||
if (value && value.value && value.value.length > 0) {
|
||||
this.selectedTheme = value.value[0]
|
||||
console.log('🔍 设置选中的咨询主题:', this.selectedTheme)
|
||||
}
|
||||
this.showThemePicker = false
|
||||
},
|
||||
|
||||
// 处理时间段点击
|
||||
handleTimeSlotClick(slot) {
|
||||
console.log('🔍 点击时间段:', slot)
|
||||
@@ -500,6 +576,7 @@ export default {
|
||||
}
|
||||
|
||||
this.selectedBookingSlot = slot
|
||||
this.selectedTheme = null // 重置咨询主题选择
|
||||
this.showBookingModal = true
|
||||
console.log('🔍 设置弹窗显示状态:', this.showBookingModal)
|
||||
console.log('🔍 选中的预约时段数据:', this.selectedBookingSlot)
|
||||
@@ -509,6 +586,15 @@ export default {
|
||||
async confirmBooking() {
|
||||
if (this.bookingLoading) return
|
||||
|
||||
// 验证咨询主题
|
||||
if (!this.selectedTheme || !this.selectedTheme.dictValue) {
|
||||
uni.showToast({
|
||||
title: '请选择咨询主题',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 验证咨询原因
|
||||
if (!this.consultationReason || this.consultationReason.trim() === '') {
|
||||
uni.showToast({
|
||||
@@ -567,12 +653,13 @@ export default {
|
||||
// 构造预约数据
|
||||
const appointmentData = {
|
||||
studentId: studentId,
|
||||
scheduleId: this.selectedBookingSlot.originalData.parentScheduleId,
|
||||
scheduleId: this.selectedBookingSlot.originalData.scheduleId,
|
||||
counselorId: this.selectedBookingSlot.originalData.counselorId,
|
||||
appointmentDate: this.selectedDate,
|
||||
appointmentTime: this.selectedBookingSlot.originalData.timeSlot,
|
||||
appointmentDetailTime: this.selectedBookingSlot.timeRange,
|
||||
reason: this.consultationReason.trim() // 使用用户输入的咨询原因
|
||||
reason: this.consultationReason.trim(), // 使用用户输入的咨询原因
|
||||
consultTheme: this.selectedTheme.dictValue // 咨询主题字典值
|
||||
}
|
||||
|
||||
// 调用真实API提交预约
|
||||
@@ -587,6 +674,7 @@ export default {
|
||||
this.showBookingModal = false
|
||||
this.selectedBookingSlot = null
|
||||
this.consultationReason = '' // 重置咨询原因
|
||||
this.selectedTheme = null // 重置咨询主题
|
||||
|
||||
// 刷新时间段数据
|
||||
this.refreshTimeSlots()
|
||||
@@ -625,6 +713,7 @@ export default {
|
||||
this.showBookingModal = false
|
||||
this.selectedBookingSlot = null
|
||||
this.consultationReason = '' // 重置咨询原因
|
||||
this.selectedTheme = null // 重置咨询主题
|
||||
},
|
||||
|
||||
|
||||
@@ -981,11 +1070,36 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
.theme-select-container {
|
||||
margin-bottom: 24rpx;
|
||||
|
||||
.theme-select-input {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 16rpx 20rpx;
|
||||
border: 2rpx solid #e0e0e0;
|
||||
border-radius: 8rpx;
|
||||
background-color: #fafafa;
|
||||
min-height: 60rpx;
|
||||
|
||||
.theme-select-text {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
flex: 1;
|
||||
|
||||
&.placeholder {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.reason-input-container {
|
||||
margin-bottom: 24rpx;
|
||||
padding: 0 4rpx;
|
||||
border: 2rpx solid #e0e0e0;
|
||||
border-radius: 12rpx;
|
||||
border-radius: 8rpx;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user