91 lines
2.6 KiB
Markdown
91 lines
2.6 KiB
Markdown
# 诊单列表排序规则修改
|
|
|
|
## 修改内容
|
|
|
|
修改了诊单列表的排序逻辑,按照新的业务规则对数据进行排序。
|
|
|
|
## 排序规则
|
|
|
|
### 优先级顺序
|
|
1. **已过号** (status=4) - 最优先显示
|
|
2. **已预约** (status=1) - 第二优先
|
|
3. **已完成** (status=3) - 第三优先
|
|
4. **其他状态** - 最后显示
|
|
|
|
### 同状态内排序
|
|
在同一状态内,按以下规则升序排列:
|
|
- 挂号日期 (appointment_date)
|
|
- 挂号时间 (appointment_time)
|
|
- 诊单ID (id) 降序
|
|
|
|
## 技术实现
|
|
|
|
### 排序SQL逻辑
|
|
|
|
```php
|
|
// 获取最早的挂号状态(用于排序优先级)
|
|
$minAptStatusExpr = '(SELECT apt.status FROM ' . $aptTbl . ' apt
|
|
WHERE apt.patient_id = ' . $diagTbl . '.id
|
|
AND apt.status IN (1,3,4)' . $minAptDateCond . '
|
|
ORDER BY CASE apt.status
|
|
WHEN 4 THEN 1
|
|
WHEN 1 THEN 2
|
|
WHEN 3 THEN 3
|
|
ELSE 4
|
|
END,
|
|
apt.appointment_date ASC,
|
|
apt.appointment_time ASC
|
|
LIMIT 1)';
|
|
|
|
// 获取最早的挂号时间(用于同状态内排序)
|
|
$minAptExpr = '(SELECT MIN(CONCAT(apt.appointment_date, \' \',
|
|
IFNULL(NULLIF(TRIM(apt.appointment_time), \'\'), \'00:00:00\')))
|
|
FROM ' . $aptTbl . ' apt
|
|
WHERE apt.patient_id = ' . $diagTbl . '.id
|
|
AND apt.status IN (1,3,4)' . $minAptDateCond . ')';
|
|
|
|
// 最终排序
|
|
->orderRaw('CASE IFNULL(' . $minAptStatusExpr . ', 999)
|
|
WHEN 4 THEN 1
|
|
WHEN 1 THEN 2
|
|
WHEN 3 THEN 3
|
|
ELSE 4
|
|
END ASC,
|
|
IFNULL(' . $minAptExpr . ", '9999-12-31 23:59:59') ASC,
|
|
{$diagTbl}.id DESC")
|
|
```
|
|
|
|
### 关键点
|
|
|
|
1. **子查询获取状态**: 使用子查询获取每个诊单最早的挂号状态
|
|
2. **CASE表达式**: 将状态映射为排序优先级数字 (1-4)
|
|
3. **IFNULL处理**: 对于没有挂号的诊单,使用默认值 999 和 '9999-12-31 23:59:59'
|
|
4. **日期筛选支持**: 如果传入 `appointment_date` 参数,只按该日期的挂号排序
|
|
|
|
## 修改文件
|
|
|
|
- `server/app/adminapi/lists/tcm/DiagnosisLists.php`
|
|
|
|
## 验证步骤
|
|
|
|
1. 清除缓存: `php think clear` ✅
|
|
2. 访问诊单列表页面
|
|
3. 验证排序顺序:
|
|
- 已过号的诊单显示在最前面
|
|
- 然后是已预约的诊单
|
|
- 最后是已完成的诊单
|
|
4. 验证同状态内按挂号时间升序排列
|
|
|
|
## 业务场景
|
|
|
|
此排序规则适用于以下场景:
|
|
- 医生/医助需要优先处理已过号的患者(可能需要重新安排)
|
|
- 然后关注即将到来的预约
|
|
- 最后查看已完成的历史记录
|
|
|
|
## 注意事项
|
|
|
|
- 排序只考虑状态为 1(已预约)、3(已完成)、4(已过号) 的挂号记录
|
|
- 没有挂号记录的诊单会排在最后
|
|
- 如果一个诊单有多条挂号记录,取最早的一条进行排序
|