2995840376 d7e34efb58 feat(B2-B4): 产品生命周期闭环 - 删除防孤儿 / reconcile 幂等全量 / 同步自愈
B2 deleteProduct 引用校验:
- 原实现直接 deleteById, 会留下 product_id 指向已删产品的孤儿设备,
  且 reconcile 只补 NULL 的设备 => 孤儿永远无法回收
- 现校验 device / firmware / ota_task 三类引用, 任一存在即拒绝删除并提示数量
  (此前前端却提示'已关联设备的产品不可删除', 后端实际毫无校验)

B3 reconcileDevices 幂等全量对齐:
- 原: 仅处理 product_id IS NULL 的设备
- 现: 对所有有 platform_product_id 的设备按 (platform, platform_product_id)
  重新解析产品并校正 product_id, 已对齐的跳过(不产生无谓写)
- 无平台产品ID的纯本地手工设备跳过

B4 同步自愈 (新增 ProductService.ensureDeviceProduct):
- TuyaController 同步路径由「仅当 product_id IS NULL 才解析」改为每次校验
- 产品不存在(含已逻辑删除)/平台产品ID不匹配 => 自动重新解析或创建产品
- 配合 B2 引用校验, 产品删除不再产生不可回收的孤儿

验证: mvn -pl iot-common,iot-device -am compile 通过
2026-10-27 12:34:27 +08:00
..