feat(C2-C4): 物模型编辑器支持语义编辑 + 修复全量替换撞唯一索引
SpecEditor.vue:
- 属性表新增 语义/分组/主开关 三列
- 属性编辑表单新增 semantic 下拉(17种标签, 与后端 SpecSemanticResolver 一一对应)、
grp 下拉(8种分组)、is_primary 开关
- 分组说明写明: switch 组的开关位支持整组联动(switch_1~4 一起开关)
- 语义说明写明: 决定客户端如何渲染与能否作为主开关, 取代按名称猜测
后端 saveSpec 修复:
- 全量替换由逻辑删除改为物理删除
原因: 逻辑删除留下同 (product_id, code) 的软删行, 与 V22 的
(product_id, code, deleted) 唯一索引冲突 —— 连续保存两次即报错
- 新增 ProductEventMapper/ProductActionMapper.physicallyDeleteByProductId
- 语义缺失时自动推导(与 SpecSemanticResolver 规则一致)
- 状态量被误标 write 时强制只读
- 保存后调用 applyPrimary 重算主开关
- action 缺省 completionMode=SYNC
applyPrimary 语义修正:
- 人工优先: 已存在人工标记(is_primary=1)则保留人工选择, 不自动改写
- 仅在无人工标记时按语义规则自动补齐
(reconcile 场景重建后无标记 -> 自动选; 后台编辑场景有人工标记 -> 尊重)
V22 迁移顺序修正:
- 唯一索引统一移到'软删重复行清理'之后执行, 避免索引创建即失败
- 新增软删重复行物理清理(同 (product_id, code) 只保留 id 最小的一条)
- 索引语句去重
验证: mvn BUILD SUCCESS; vite build 通过(ProductDetail chunk 已更新)