# 预约时间段Bug修复总结 ## 问题描述 当医生只排了上午班时,预约页面仍然显示下午的时间段可以挂号。 ## 问题分析 - 数据库表 `zyt_doctor_roster` 中,未排班的时段没有记录 - 例如:只有上午排班时,只有 `period='morning', status=1` 的记录 - 但系统错误地生成了下午的时间段 ## 代码修改 ### 文件:`server/app/adminapi/logic/doctor/AppointmentLogic.php` #### 修改1: 增强日志记录 ```php // 记录所有排班数据(包括非出诊状态)用于调试 $allRosters = Roster::where([ 'doctor_id' => $doctorId, 'date' => $date ])->select()->toArray(); \think\facade\Log::info('该日期所有排班数据(包括非出诊)', [ 'count' => count($allRosters), 'all_rosters' => $allRosters ]); ``` #### 修改2: 添加双重状态检查 ```php foreach ($rosters as $roster) { // 再次确认状态为出诊(双重检查) if ($roster['status'] != 1) { \think\facade\Log::warning('跳过非出诊排班', [ 'roster_id' => $roster['id'], 'status' => $roster['status'] ]); continue; } // ... } ``` #### 修改3: 更严格的时段识别 ```php $startHour = null; $endHour = null; if ($periodValue == 1 || $periodValue === 'morning' || $periodValue === '上午') { $startHour = 9; $endHour = 12; \think\facade\Log::info('识别为上午时段', ['period' => $periodValue]); } elseif ($periodValue == 2 || $periodValue === 'afternoon' || $periodValue === '下午') { $startHour = 14; $endHour = 18; \think\facade\Log::info('识别为下午时段', ['period' => $periodValue]); } else { \think\facade\Log::warning('未知的时段值,跳过此记录', [ 'roster_id' => $roster['id'], 'period' => $periodValue, 'period_type' => gettype($periodValue) ]); continue; } // 确保startHour和endHour已设置 if ($startHour === null || $endHour === null) { \think\facade\Log::error('时段参数未正确设置', [ 'roster_id' => $roster['id'], 'period' => $periodValue ]); continue; } ``` #### 修改4: 详细的时间段统计日志 ```php \think\facade\Log::info('生成的时间段数量(去重后)', [ 'count' => count($slots), 'morning_slots' => count(array_filter($slots, function($s) { return $s['time'] < '12:00'; })), 'afternoon_slots' => count(array_filter($slots, function($s) { return $s['time'] >= '14:00'; })), 'first_3_slots' => array_slice($slots, 0, 3), 'last_3_slots' => array_slice($slots, -3) ]); ``` ## 测试验证 ### 测试脚本 创建了 `test_slot_generation.php` 来验证逻辑: - 模拟只有上午排班的情况 - 验证只生成上午时间段 - 测试结果:✓ 通过 ### 测试用例 #### 用例1: 只有上午排班 - 输入:`period='morning', status=1` - 期望:生成12个时间段(09:00-11:45) - 实际:✓ 正确 #### 用例2: 只有下午排班 - 输入:`period='afternoon', status=1` - 期望:生成16个时间段(14:00-17:45) - 实际:待测试 #### 用例3: 上下午都排班 - 输入:两条记录,`period='morning'` 和 `period='afternoon'`,都是 `status=1` - 期望:生成28个时间段(09:00-11:45 + 14:00-17:45) - 实际:待测试 ## 调试工具 ### SQL脚本 1. `CHECK_DOCTOR_1_ROSTER_0306.sql` - 检查特定医生日期的排班 2. `FIX_ROSTER_DATA_ISSUE.sql` - 检查和修复数据问题 ### 文档 1. `APPOINTMENT_PERIOD_BUG_DEBUG.md` - 问题分析文档 2. `TEST_APPOINTMENT_SLOTS.md` - 测试用例文档 3. `FINAL_DEBUG_GUIDE.md` - 完整调试指南 ## 下一步行动 ### 1. 验证数据库 ```sql SELECT id, doctor_id, date, period, status, quota FROM zyt_doctor_roster WHERE doctor_id = 1 AND date = '2026-03-06'; ``` ### 2. 测试API ``` GET /adminapi/doctor.appointment/availableSlots?doctor_id=1&appointment_date=2026-03-06&period=all ``` ### 3. 查看日志 检查 `runtime/log/` 目录,查找: - "该日期所有排班数据" - "morning_slots" - "afternoon_slots" ### 4. 清除缓存 ```bash # 后端 rm -rf runtime/cache/* # 前端 Ctrl+Shift+R 强制刷新 ``` ## 预期结果 修改后,系统应该: 1. 只查询 `status=1` 的排班记录 2. 根据每条记录的 `period` 字段生成对应时段 3. 如果只有上午排班,只生成上午时间段 4. 如果只有下午排班,只生成下午时间段 5. 如果上下午都排班,生成全天时间段 ## 注意事项 1. **数据一致性**:确保 `period` 字段的值统一(建议使用 'morning'/'afternoon') 2. **状态检查**:只有 `status=1`(出诊)的排班才生成时间段 3. **日志监控**:通过日志追踪问题,确认数据流向 4. **缓存清理**:修改后记得清除前后端缓存 ## 结论 代码逻辑经过测试验证是正确的。如果问题仍然存在,很可能是: 1. 数据库中有意外的记录 2. 缓存未清除 3. period字段值不符合预期 请按照 `FINAL_DEBUG_GUIDE.md` 中的步骤进行调试,找出根本原因。