4.3 KiB
4.3 KiB
诊单编辑:脱敏手机号缺省提交的后端修复
日期:2026-10-17。范围:后端编辑校验及离线 PHP 回归。
根因
桌面医生账户无 tcm.diagnosis/phonePlain 权限时只看到脱敏手机号,保存时会排除 phone/id_card。DiagnosisController::edit() 先执行 DiagnosisValidate::sceneEdit(),后调用 DiagnosisLogic::edit()。编辑场景原样继承全局 phone = require|mobile,因此合法的缺省 phone 请求在到达更新逻辑前就被“请输入手机号”拦截。
同一编辑场景还继承 patient_name、gender、age 的全局 require,即使这些基本信息被业务锁定、调用者仅修改临床信息,省略后也会被拦截。新增回归在修复前首先复现“请输入患者姓名”;另有单独省略 phone、其他基础信息照常提交的用例对应本次医生保存失败。
DiagnosisLogic::edit() 已直接用收到的 $params 更新,不会为缺省手机号补空值。基本信息变更比较也已使用 array_key_exists 跳过未提交字段,因此不需要修改 controller 或 logic。
修改
server/app/adminapi/validate/tcm/DiagnosisValidate.php:仅在sceneEdit()中,将phone、patient_name、gender、age的无条件require替换为requireWhenPresent。- 新规则区分缺省键与显式提交:缺省表示保留;显式空串/null 仍拒绝,原有
mobile、姓名长度、性别范围、年龄类型/范围规则继续执行。require前缀确保 ThinkPHP 对空串/null 也调用此规则。 server/tests/DiagnosisValidateEditSceneTest.php:运行真实 validator 与真实DiagnosisLogic::edit(),仅模型、数据库边界及权限读取使用内存替身,覆盖保存与业务锁行为。
边界与回归覆盖
- 编辑可省略所有受保护的基本信息,也可仅省略手机号而保留姓名/性别/年龄;省略的
phone、id_card、姓名/性别/年龄不会加入 update,原值保持。 - 显式手机号
''、null、156****7862、短号码、带空格号码、false、数组均拒绝;合法新号码仍通过格式校验。 - 显式姓名/性别/年龄为空仍拒绝;姓名超长、非法性别、非法或越界年龄仍拒绝;
gender = 0、age = 0仍有效。 - 编辑 ID 必填且诊单必须存在。
diagnosis_type、local_hospital_name等无关要求不变。 - 新增场景仍要求手机号、姓名、性别、年龄;新增空/脱敏手机号仍拒绝。
- 无额外权限的医生在最近订单未完成时,可以保存不含基本信息的临床修改;任何实际基本信息变更仍返回“最近业务订单未完成,无法修改患者基本信息”,且不会写入。原有 root 编辑能力保持。
- 未修改明文手机号权限、返回数据、创建权限、其他业务授权、统计或 AI 服务实现。
实际验证
执行目录:D:/web/zyt;PHP 8.2.9 CLI。测试未初始化应用、未读取生产配置,数据库/模型/权限边界为测试内存替身,没有数据库或外部服务调用。
| 命令 | 实际结果 |
|---|---|
php server/tests/DiagnosisValidateEditSceneTest.php(修复前) |
exit 1,edit accepts omitted locked/basic/masked fields; got: "请输入患者姓名" |
php -l server/app/adminapi/validate/tcm/DiagnosisValidate.php |
exit 0,No syntax errors detected |
php -l server/tests/DiagnosisValidateEditSceneTest.php |
exit 0,No syntax errors detected |
php server/tests/DiagnosisValidateEditSceneTest.php |
exit 0,Diagnosis edit-scene validation and masked/basic-field preservation: OK |
php server/tests/DiagnosisValidateAddSceneTest.php |
exit 0,Diagnosis add-scene validation: OK |
php server/tests/DiagnosisWorkspaceRowAuthorizationTest.php |
exit 0,Diagnosis workspace row authorization: OK |
php server/tests/DiagnosisAiPrescriptionGeneratePermissionTest.php |
exit 0,Diagnosis AI prescription generation permission: OK |
php server/tests/DiagnosisAiAnalysisSecurityTest.php |
exit 0,Diagnosis AI analysis security: OK |
git diff --check -- server/app/adminapi/validate/tcm/DiagnosisValidate.php server/tests/DiagnosisValidateEditSceneTest.php |
exit 0,无输出 |
本报告证明离线编辑校验、更新参数保留与原有业务锁行为;未进行生产登录或真实数据库写入。