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

5.0 KiB
Raw Blame History

预约时间段Bug修复总结

问题描述

当医生只排了上午班时,预约页面仍然显示下午的时间段可以挂号。

问题分析

  • 数据库表 zyt_doctor_roster 中,未排班的时段没有记录
  • 例如:只有上午排班时,只有 period='morning', status=1 的记录
  • 但系统错误地生成了下午的时间段

代码修改

文件:server/app/adminapi/logic/doctor/AppointmentLogic.php

修改1: 增强日志记录

// 记录所有排班数据(包括非出诊状态)用于调试
$allRosters = Roster::where([
    'doctor_id' => $doctorId,
    'date' => $date
])->select()->toArray();
\think\facade\Log::info('该日期所有排班数据(包括非出诊)', [
    'count' => count($allRosters),
    'all_rosters' => $allRosters
]);

修改2: 添加双重状态检查

foreach ($rosters as $roster) {
    // 再次确认状态为出诊(双重检查)
    if ($roster['status'] != 1) {
        \think\facade\Log::warning('跳过非出诊排班', [
            'roster_id' => $roster['id'],
            'status' => $roster['status']
        ]);
        continue;
    }
    // ...
}

修改3: 更严格的时段识别

$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: 详细的时间段统计日志

\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. 验证数据库

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. 清除缓存

# 后端
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 中的步骤进行调试,找出根本原因。