8.0 KiB
8.0 KiB
复诊接诊率:指派 / 继承写入与兼容性研究
2026-10-16。只读检查产品源码;未读取 .env 或凭据;未连接数据库。项目存在 AGENTS.md,但 .trellis/workflow.md 不存在,无法读取 Trellis 流程与分层规范。
关键结论
- 现有报表是“当月指派分母 + 当月成交分子”,不是“指派日期区间内患者的后续接诊队列”。仅把
month换成起止日期会继续产生区间外患者进入分子的错误。 - 新指派、继承已有可用事件字段,无需为重新起算修改患者全局诊次。应在统计层根据入组指派事件重新计算后续订单;
RevisitVisitSlotService同时服务诊单节点、到期快照,改变它会影响其他业务。 - 自动指派和个人业绩都直接依赖当前统计实现。页面改队列口径时要明确兼容入口;尤其不要悄悄改变自动指派档位。
写入侧与数据字段
| 入口 | 现有行为 | 注意点 |
|---|---|---|
DiagnosisLogic::assign(约 673 行) |
诊单行 FOR UPDATE;更新 assistant_id、assign_read_at;同事务插入指派日志。is_inherit=1 仅在目标医助大于 0 时成立。 |
from==to 允许写入;当前 slot 统计忽略该行,旧 exclude 仍计入新指派。新队列避免把自指派当成新承接事件。 |
| 同上,继承 | 同事务用 slotAtTime($id,$now) 写 inherit_visit_slot 和 inherit_visit_slot_calc_time。 |
快照只用于展示 / 对账。现有统计通过有效订单实时重算 k,所以事后退款、取消、offset 修改会联动。不能把快照当唯一订单数依据;历史回退没有快照。 |
AutoAssignPendingDiagnosis::applyAssignment(约 567 行) |
is_inherit=0、操作人 0、名称“系统自动分配”;同事务改医助并写日志;from 可推断为一中心原医助。 |
自动指派属于新指派,不能以 from>0 判定继承。 |
AutoAssignLogLogic::rollbackOne(约 72 行) |
锁自动指派日志和诊单;仅当前医助仍为自动分配目标时允许回退;回到前任 / 0。写指派日志 is_inherit=0,并写自动分配日志 rollback 字段。 |
保留写入规则;新口径需把历史回退识别为继承,目标 0 的释放行不入组。 |
ExpressTrackingService(约 702 行) |
发货释放写 to_assistant_id=0,未显式写 is_inherit(列默认 0)。 |
释放不是新指派,但会终止原医助持有时间段。 |
主要表 / 模型:
DiagnosisAssignLog只设置表名tcm_diagnosis_assign_log,关闭自动时间戳,无字段白名单。指派核心数据:id, diagnosis_id, from_assistant_id, to_assistant_id, operator_admin_id, create_time, is_inherit, inherit_visit_slot, inherit_visit_slot_calc_time;还含最新订单创建人 / 时间快照与操作人信息。tcm_diagnosis:assistant_id是当前归属,不应代替历史持有时间线;revisit_slot_start_offset为全局诊次偏移(钳制 0~20)。tcm_prescription_order:有效业务单剔除软删、履约状态 4/9/10;统一调用YejiStatsLogic::applyPrescriptionOrderNotCancelledForPerformanceQuery;序列稳定排序(diagnosis_id, create_time, id)。- 迁移:
server/sql/1.9.20260601/add_diagnosis_assign_log_is_inherit.sql;server/sql/1.9.20261012/06_add_diagnosis_assign_log_inherit_visit_slot.sql。继承标记引入前的数据无法可靠恢复继承类型,不应按from>0猜测。 - 现有订单复合索引迁移:
server/sql/1.9.20261012/01_add_prescription_order_diag_ct_index.sql,(diagnosis_id, delete_time, fulfillment_status, create_time)。源码内未找到指派日志建表 DDL,不能据此断言线上索引情况。
rollback 与重新起算
RevisitRateLogic::fetchRollbackKeySet使用diagnosis_id | rollback_time | rollback_admin_id关联到指派日志diagnosis_id | create_time | operator_admin_id;同一事务同一$now保证当前写入可匹配。需要继承独立页时复用这一兼容规则,不能只筛is_inherit=1。- 现有
RevisitRateCalculator::compute在 slot 模式将命中回退的日志当继承;exclude 模式完全保留其is_inherit=0的旧语义。回退无继承快照,订单实时计算仍可用。 - 新继承“重新起算”应按继承事件时间切开序列,继承前历史单不进入继承后的接诊次数。保留同一秒约定:日志时间
t <= order.create_time时归新医助,继承前完成单计数用严格< t。 - 转派 / 释放 / 再次继承会形成多个持有段;要先明确入组去重,再把订单归属到有效段,避免同一订单被多个队列事件重复领取。当前实现按同一医助 × 诊单去重,继承取区间内最早,且同区间新指派优先覆盖继承;这一合并规则不适合直接复用到“新指派和继承分别统计”。
- 当前拒收 / 退款处理是“该诊单存在任意时间状态 9/10 有效订单,则整诊单从分母剔除”,分子只是剔除对应无效单。若沿用需在两个独立页面和明细保持一致;不要无意中改变这一业务规则。
当前统计调用方
AutoAssignPendingDiagnosis::execute调RevisitRateLogic::overview(['month'=>上个自然月,'inherit_mode'=>'slot']),再从部门 children 中取医助率。配置实际值为project.revisit_rate.auto_assign_tier_field='visit2_rate_new_assign',页面默认实际是default_inherit_mode='exclude'(部分注释仍写默认 slot)。- 分档字段白名单仅
visit2_rate_new_assign/visit2_rate,对应rate_version=v1/v2。无分母必须继续返回null,否则可能改变谁参与自动指派。 - 自动日志同时记录两套率。历史 v1 行无
visit2_rate_new_assign时,前端回落visit2_rate。不要重解释历史日志字段;如变更分档口径要单独版本化。
- 分档字段白名单仅
AssistantPerformanceController::revisitRate只收month,Logic 从配置取 mode,再调RevisitRateLogic::assistantOverview,只返回本人行。- 本人统计有 600 秒缓存,key 为
month + assistantId + mode。改统计口径需更新缓存 key 版本;加日期范围 / 队列类型需纳入 key。 - 前端个人业绩卡片仍按月,响应类型依赖
month, inherit_mode, slots, in_scope, row。保持 month 兼容可避免页面破坏,但卡片文案和规则应同步说明指派队列口径。
- 本人统计有 600 秒缓存,key 为
RevisitRateLogic::overview目前不处理assistant_id;只有两个下钻方法调用applyRowScope。新增医助筛选需同时约束 overview 的医助行、部门汇总、总计以及下钻集合。部门归属取当前admin_dept中最小有效 dept_id,默认限二中心子树。YejiStatsLogic的“被指派数”仍独立按is_inherit=0、区间指派、医助×诊单去重;避免此次顺带修改整个业绩看板。
新独立页还需菜单 / 权限迁移与 MCP review 文案。AuthMiddleware 对未登记接口默认放行,因此新增接口须登记权限。现有 deptOptions 还被复诊到期页复用,不应改成仅某一队列的选项。
测试运行方式与已验证基线
无根级 PHPUnit 配置,server/composer.json 无 test script / PHPUnit;相关测试是独立 PHP CLI 脚本,仅加载 server/vendor/autoload.php,不启动应用、不连库。当前 PATH PHP:D:/phpstudy_pro/Extensions/php/php8.2.9nts/php.exe。
已从项目根目录运行并通过:
php server/tests/RevisitRateContractTest.php # 45 checks
php server/tests/RevisitRateInheritSlotTest.php # 57 checks
php server/tests/RevisitVisitSlotServiceTest.php # 20 checks
RevisitRateContractTest 是源码字符串 / Reflection 契约,明确锁住“分子按当月下单”“继承从 k+1 列入分母”等旧实现,新队列实现需要合理更新这些断言,不能仅为通过保留过时语义。建议纯函数覆盖:区间指派后跨月成交、区间外患者同月成交不计入、自指派、转派终止归属、多次继承与重置、回退继承、同秒排序、医助筛选汇总和两类明细对账;保留全局诊次服务现有测试。