song.jun
3 天以前 a3f4e4f2423a8d71b4c65e90920db34f2001aa7d
refs
用户 song.jun <lion0756@qq.com>
星期一, 四月 13, 2026 12:34 +0800
提交者 song.jun <lion0756@qq.com>
星期一, 四月 13, 2026 12:34 +0800
提交a3f4e4f2423a8d71b4c65e90920db34f2001aa7d
目录 dd5031303fc7d461f21c277aaffe8df6881ef9dd 目录 | zip | gz
parent 81067c70291d115f34df877e4cf581785ea6592e 查看 | 对比
修复 QCDistributionRegisterInfo 重复登记问题

问题:qcDistId=41 下 QC269 出现两条 (QCDistributionId, LabId, ProjectId)
完全相同的登记记录,ConfigrmFee 的 FirstOrDefault 静默命中其中一条导致
IsCharged 状态不同步,在 OutputUnderTakenLabs 导出时暴露。已手工清理 5
组历史脏数据(Id=2944/7508/7509/7664/7666)。

代码修改(不动 DDL,全部在业务层):

- QCService.SaveQcDistributionRegister:Id==0 时按业务唯一键查重,命中
既有行则按 MergeRegisterInfo 合并后 UPDATE,并写 [WARN] 日志。作为
所有 Insert 路径的最后一道防线,覆盖未来任何新调用方。
- MergeRegisterInfo:刻意不对称的合并规则——string/DateTime? 仅非 null
才覆盖,bool 只能 false→true 不能反向,防止一次脏 Save 把 IsCharged=1
意外清零。
- QCDistributionInfoViewModel.ToEntity:SaveLabList 路径的第一道防线,
新行插入前按 (QCDist, LabId, ProjectId) 查重,存在则复用走 Update。
- QCDistributionRegisterInfoViewModel.ToEntityByLabCode:查询条件补上
ProjectId 过滤,让 ConfigrmFee/ConfigrmEMS/switchNextOne 在"一个实
验室多项目"场景下能精准命中目标登记行,不再静默合并。
- BackstageController.ImportLabs:加 oriDistId==TargetDistId 和目标为
null 的前置守卫;源读取后按 GroupBy(LabId, ProjectId) 去重,阻止脏
数据跨分发传染。
- BackstageController.OutputUnderTakenLabs:清理 headers/cellKes 中重
复的"是否收费"/isCharged 列(残留自上次 15e82c0 提交)。

CLAUDE.md 新增"QCDistributionRegisterInfo 保存契约"章节,记录上述约定
及已知残余风险(多管理员并发编辑同一分发的理论窗口)。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
5个文件已修改
109 ■■■■■ 已修改文件
CLAUDE.md 20 ●●●●● 对比 | 查看 | 原始文档 | blame | 历史
sbcLabSystem.Service/QC/QCService.cs 42 ●●●●● 对比 | 查看 | 原始文档 | blame | 历史
sbcLabSystem/Controllers/BackstageController.cs 18 ●●●● 对比 | 查看 | 原始文档 | blame | 历史
sbcLabSystem/Models/Backstage/QCDistributionInfoViewModel.cs 23 ●●●● 对比 | 查看 | 原始文档 | blame | 历史
sbcLabSystem/Models/Backstage/QCDistributionRegisterInfoViewModel.cs 6 ●●●●● 对比 | 查看 | 原始文档 | blame | 历史