55 lines
4.6 KiB
Markdown
55 lines
4.6 KiB
Markdown
# 复诊指派队列后端独立审阅
|
||
|
||
2026-10-16。范围:`RevisitCohortCalculator` / `RevisitCohortLogic`、两个 Controller、菜单 SQL、两项新增测试。未修改产品代码、未读凭据、未连接业务数据库。
|
||
|
||
主代理处理结果:下述释放返还问题已修复,计算器以实际时间线判断持有人是否变化;新增两项纯计算及两项 MySQL 集成回归通过。性能观察也已处理:先按周期(及选中医助)查询候选诊单,再分块读取对应完整时间线。
|
||
|
||
## 需要修复:1 项
|
||
|
||
### [P2] 释放后重新指派给原医助被误当作自指派,患者和后续订单全部漏计
|
||
|
||
- 位置:`server/app/adminapi/logic/stats/RevisitCohortCalculator.php:39`,`$from === $aid` 直接跳过整条事件,既不入组也不更新持有时间线。
|
||
- 写入侧证据:`DiagnosisLogic::assign` 第 714~715 行在诊单当前 `assistant_id=0` 时调用 `inferPreviousAssistantIdFromLatestAssignLog`;该方法在最近日志为 `A→0` 时回落其 `from_assistant_id=A`。因此用户实际执行的“未分配→A”会写成 `from=A,to=A`,这与真实自指派有相同字段,但不是无操作。
|
||
- 最小复现(同一诊单,日志 / 订单按要求排序):
|
||
|
||
| 时间戳 | 事件 |
|
||
| --- | --- |
|
||
| 10 | 指派 `0→7`,新指派 |
|
||
| 11 | 第 1 笔有效订单 |
|
||
| 20 | 释放 `7→0` |
|
||
| 30 | 从未分配重新指派给 7;现有写入逻辑记录 `7→7`,`is_inherit=0` |
|
||
| 31 | 第 2 笔有效订单 |
|
||
|
||
调用 `compute($logs,$orders,[],[],[],25,35,100,'new')` 后,实测 `assigned_count=0, visit2_count=0`,应各为 1。若重新承接时勾选继承,日志为 `7→7,is_inherit=1`,同样漏掉本次继承患者和其首单二诊。
|
||
|
||
这还会影响区间更早的原医助队列:重新承接事件被跳过后,时间线一直停在释放状态,后续成交不再归属任何有效持有段。
|
||
|
||
建议根据同一诊单此前真实时间线的最后目标判断是否“持有人没有变化”,不能仅比较日志的 `from/to`;至少识别前一有效事件为 `to=0` 的重新承接。保留真实 `A→A` 的不入组、不重置行为。增加“释放后返还同一医助”的新指派及继承两个纯函数 / 数据库用例,区别于已有“转到其他人后再次继承”测试。
|
||
|
||
## 其余检查
|
||
|
||
- 已确认日期筛选约束入组事件,成交累计到 `time()`;区间外患者不会进入分子,后续转派 / 释放终止该持有段。
|
||
- 继承后订单以段内序号 `+1` 从二诊起算,忽略全局诊次 / offset;新指派保留全局诊次。真实自指派当前测试覆盖且不重置。
|
||
- 历史 rollback 关联键参与继承识别,`is_inherit=0` 回退不会混入新指派。被拒收 / 退款的诊单同时从队列分母、分子剔除,无孤立分子。
|
||
- 医助筛选先作用于整个 context,再构造部门 / 总计及明细;部门仍限制二中心。部门 / 总计按患者、诊次去重,明细与指标一致。
|
||
- 继承 Controller 用 `static::COHORT_TYPE` 固定类型,不能通过请求参数切换到另一类;继承 Controller 可正常 autoload。
|
||
- 菜单 SQL 按对应权限逐项授予原角色,未扩大只有患者明细角色的订单明细权限;页面与三个接口都登记。部署仍须执行 SQL 并清理 `AdminAuthCache`,否则系统现有“未登记接口默认放行”规则会作用于新接口。
|
||
- 旧 `RevisitRateLogic` 仅将共用读取方法改为 protected,自动指派 / 个人业绩仍调用旧口径,未发现行为改动。
|
||
|
||
## 性能观察(未作为阻塞问题)
|
||
|
||
`RevisitCohortLogic::cohortContext` 第 188~198 行先把所有未删诊单截至当前的全部历史指派日志读入 PHP,再计算候选诊单并过滤;即使只查一天、单个医助甚至空队列,首个查询扫描 / 返回的数据量仍与全量历史指派数相关。随后订单扫描已收窄到候选诊单。建议后续先在 SQL 查区间内候选诊单,再按候选诊单拉全量持有时间线,保持释放 / 转派语义;本次没有业务库规模和执行计划,无法证明已有请求达到超时 / 内存上限,因此不将其列为已复现缺陷。
|
||
|
||
## 验证
|
||
|
||
独立运行通过:
|
||
|
||
```text
|
||
RevisitCohortCalculatorTest OK (32 checks)
|
||
RevisitRateContractTest OK (45 checks)
|
||
RevisitRateInheritSlotTest OK (57 checks)
|
||
RevisitVisitSlotServiceTest OK (20 checks)
|
||
```
|
||
|
||
四个新增 / 修改核心 PHP 文件 `php -l` 通过。额外通过 PHP 标准输入执行上述最小复现,确认实际输出为全零。主代理报告的隔离 MySQL 5.7 数据库测试 20 checks 已阅读源码,本次未重跑其临时数据库。数据库测试目前没有“释放后返还原医助”场景。
|