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

7.4 KiB
Raw Blame History

排班时段格式兼容性修复

问题描述

数据库中的 period 字段存储的是字符串格式:

  • "morning" - 上午
  • "afternoon" - 下午

但代码中只处理了数字格式:

  • 1 - 上午
  • 2 - 下午

导致无法生成可预约时段。

数据库结构

-- period 字段定义
period varchar(20)

-- 实际存储的值
'morning'    -- 上午
'afternoon'  -- 下午

问题根源

原来的代码

if ($periodValue == 1) {
    // 上午:9:00-12:00
    $startHour = 9;
    $endHour = 12;
} elseif ($periodValue == 2) {
    // 下午:14:00-18:00
    $startHour = 14;
    $endHour = 18;
} else {
    continue;  // ❌ 跳过了 'morning' 和 'afternoon'
}

问题

period = 'morning''afternoon' 时:

  • 不匹配 == 1== 2
  • 进入 else 分支,被跳过
  • 不生成任何时间段
  • 结果:返回空数组

解决方案

修复后的代码

// 支持多种格式
if ($periodValue == 1 || $periodValue === 'morning' || $periodValue === '上午') {
    // 上午:9:00-12:00
    $startHour = 9;
    $endHour = 12;
} elseif ($periodValue == 2 || $periodValue === 'afternoon' || $periodValue === '下午') {
    // 下午:14:00-18:00
    $startHour = 14;
    $endHour = 18;
} else {
    \think\facade\Log::warning('未知的时段值', [
        'period' => $periodValue,
        'period_type' => gettype($periodValue)
    ]);
    continue;
}

支持的格式

格式 类型 说明
1 int 数字格式 - 上午
2 int 数字格式 - 下午
'morning' string 英文格式 - 上午
'afternoon' string 英文格式 - 下午
'上午' string 中文格式 - 上午
'下午' string 中文格式 - 下午

验证修复

1. 检查数据库中的 period 值

-- 查看所有不同的 period 值
SELECT DISTINCT period, COUNT(*) as count
FROM zyt_doctor_roster
GROUP BY period;

可能的结果:

+------------+-------+
| period     | count |
+------------+-------+
| morning    | 150   |
| afternoon  | 150   |
+------------+-------+

或者:

+------------+-------+
| period     | count |
+------------+-------+
| 1          | 150   |
| 2          | 150   |
+------------+-------+

2. 测试接口

# 测试医生ID=4在2026-03-04的可用时段
curl -X GET "http://your-domain/adminapi/doctor.appointment/availableSlots?doctor_id=4&appointment_date=2026-03-04&period=all" \
  -H "token: your-token"

预期响应(修复前):

{
  "code": 1,
  "data": {
    "slots": []  // ❌ 空数组
  }
}

预期响应(修复后):

{
  "code": 1,
  "data": {
    "slots": [
      {"time": "09:00", "available": true, "quota": 1, "period": "morning"},
      {"time": "09:15", "available": true, "quota": 1, "period": "morning"},
      ...
      {"time": "14:00", "available": true, "quota": 1, "period": "afternoon"},
      {"time": "14:15", "available": true, "quota": 1, "period": "afternoon"},
      ...
    ]
  }
}

3. 查看日志

# 查看处理日志
tail -f runtime/log/202403/04.log | grep "处理排班时段"

修复前的日志:

[warning] 未知的时段值 {"period":"morning","period_type":"string"}
[warning] 未知的时段值 {"period":"afternoon","period_type":"string"}

修复后的日志:

[info] 处理排班时段 {"roster_id":1,"period":"morning","period_type":"string"}
[info] 处理排班时段 {"roster_id":2,"period":"afternoon","period_type":"string"}
[info] 生成的时间段数量 {"count":28}

数据迁移(可选)

如果想统一使用数字格式,可以执行以下迁移:

方案 1:字符串转数字

-- 备份数据
CREATE TABLE zyt_doctor_roster_backup AS SELECT * FROM zyt_doctor_roster;

-- 修改字段类型
ALTER TABLE zyt_doctor_roster MODIFY COLUMN period int(10);

-- 更新数据
UPDATE zyt_doctor_roster SET period = 1 WHERE period = 'morning' OR period = '上午';
UPDATE zyt_doctor_roster SET period = 2 WHERE period = 'afternoon' OR period = '下午';

-- 验证
SELECT DISTINCT period FROM zyt_doctor_roster;

方案 2:保持字符串格式

不需要修改数据库,代码已经兼容字符串格式。

测试用例

测试 1morning 格式

-- 插入测试数据
INSERT INTO zyt_doctor_roster (doctor_id, date, period, status, quota, max_patients, booked_count, create_time, update_time) 
VALUES (99, '2026-03-10', 'morning', 1, 20, 20, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());

测试接口:

curl -X GET "http://your-domain/adminapi/doctor.appointment/availableSlots?doctor_id=99&appointment_date=2026-03-10&period=all"

预期: 返回上午时段(09:00-11:45

测试 2afternoon 格式

INSERT INTO zyt_doctor_roster (doctor_id, date, period, status, quota, max_patients, booked_count, create_time, update_time) 
VALUES (99, '2026-03-10', 'afternoon', 1, 20, 20, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());

测试接口:

curl -X GET "http://your-domain/adminapi/doctor.appointment/availableSlots?doctor_id=99&appointment_date=2026-03-10&period=all"

预期: 返回下午时段(14:00-17:45

测试 3:数字格式

INSERT INTO zyt_doctor_roster (doctor_id, date, period, status, quota, max_patients, booked_count, create_time, update_time) 
VALUES (99, '2026-03-11', 1, 1, 20, 20, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());

测试接口:

curl -X GET "http://your-domain/adminapi/doctor.appointment/availableSlots?doctor_id=99&appointment_date=2026-03-11&period=all"

预期: 返回上午时段(09:00-11:45

测试 4:中文格式

INSERT INTO zyt_doctor_roster (doctor_id, date, period, status, quota, max_patients, booked_count, create_time, update_time) 
VALUES (99, '2026-03-11', '上午', 1, 20, 20, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());

测试接口:

curl -X GET "http://your-domain/adminapi/doctor.appointment/availableSlots?doctor_id=99&appointment_date=2026-03-11&period=all"

预期: 返回上午时段(09:00-11:45

兼容性说明

向后兼容

修复后的代码完全向后兼容:

  • 支持旧的数字格式(1, 2
  • 支持新的字符串格式('morning', 'afternoon'
  • 支持中文格式('上午', '下午'

不影响现有功能

  • 排班管理功能正常
  • 预约管理功能正常
  • 前端显示正常
  • 数据查询正常

建议

短期建议

保持当前的字符串格式,代码已经兼容。

长期建议

如果要统一格式,建议:

  1. 使用数字格式(推荐)

    • 优点:节省存储空间,查询效率高
    • 缺点:需要数据迁移
  2. 使用枚举类型

    ALTER TABLE zyt_doctor_roster 
    MODIFY COLUMN period ENUM('morning', 'afternoon');
    
    • 优点:类型安全,节省空间
    • 缺点:不够灵活
  3. 保持字符串格式

    • 优点:直观易读,无需迁移
    • 缺点:占用空间稍大

已修改的文件

  • server/app/adminapi/logic/doctor/AppointmentLogic.php

总结

问题已修复,代码现在支持:

  • 数字格式:1, 2
  • 英文格式:'morning', 'afternoon'
  • 中文格式:'上午', '下午'

无需修改数据库,无需数据迁移,完全向后兼容!


修复日期: 2024-03-04 状态: 完成 影响范围: 挂号预约功能