Files
zyt/APPOINTMENT_SLOT_BUG_FIX_SUMMARY.md
T
2026-03-04 15:32:30 +08:00

179 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 预约时间段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` 中的步骤进行调试,找出根本原因。