iotsaas/backend/sql/V24__cleanup_orphan_tuya_devices.sql
2995840376 4c2d92571e feat(K): 规则保存时校验动作参数必须用物模型 code, 禁止 dpId
背景: 规则动作 params 的 key 会被原样当作涂鸦 code 下发(dp_id 从不参与下发), 历史测试数据里出现过 switch_1 与 1 混用, 导致下发失败或指令相互矛盾, 且保存时无任何校验。

后端: 新增 RuleActionValidator, createRule/updateRule 前校验动作参数 key 必须命中 product_property.code; 命中 dp_id 时直接提示应改用的 code; 同步校验值域(bool 取值、数值 min/max 区间、enum 候选值); 目标设备不存在、无产品物模型等场景给出明确业务错误。

前端: 后台规则表单补齐执行动作编辑(JSON), 提交前本地解析校验, 原本表单不提交 actions 导致新建规则必然失败。

Android: 物模型不可用时的回退路径改为优先使用涂鸦 code(反射读取), 避免提交 dpId 被后端拒绝。

V24: scene_run 表不存在时容错跳过, 便于在未执行 V16 的旧结构库上整段执行。
2026-10-28 00:52:04 +08:00

61 lines
3.1 KiB
SQL
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- =====================================================================
-- V24 · 清理测试阶段遗留的孤儿涂鸦设备与测试联动数据
-- ---------------------------------------------------------------------
-- 背景:
-- 1) unbindUser 早期只物理删除 tuya_user_binding 绑定记录,不处理已同步的设备,
-- 于是产生"孤儿涂鸦设备":设备仍在设备列表,却已无涂鸦账号可控制。
-- 定时场景每分钟命中的联动规则会持续对它们下发指令,全部失败并刷错误日志。
-- (代码侧已修复:解绑时联动逻辑删除设备与 AI 档案,重新绑定同步时自动恢复)
-- 2) 测试阶段遗留的联动规则与场景:条件全部相同(switch_1 == true)但动作互相矛盾
-- (switch_1=true / switch_1=0 / {"1":"open"} 混用 dpId),会下发自相矛盾的指令。
--
-- 清理范围:
-- - 逻辑删除孤儿涂鸦设备(owner 已无涂鸦绑定记录)
-- - 逻辑删除指向这些设备的 AI 档案
-- - 删除测试联动规则与测试场景(含每分钟 cron 的 bb 场景)
-- 保留:产品与物模型(product / product_property / product_event / product_action),
-- 家庭与成员、设备活动日志(历史审计)等。
--
-- 无存储过程、无 DELIMITER;幂等可重复执行。
-- =====================================================================
-- ---------- 1) 逻辑删除孤儿涂鸦设备 ----------
UPDATE device d
SET d.deleted = 1,
d.update_time = NOW()
WHERE d.deleted = 0
AND d.platform = 'tuya'
AND d.owner_id > 0
AND NOT EXISTS (SELECT 1 FROM tuya_user_binding b WHERE b.member_id = d.owner_id);
-- ---------- 2) 逻辑删除已解绑用户的 AI 档案 ----------
-- 注意:这里按 owner_id 判定,而不是 JOIN device 比较 device_id——
-- ai_device_profile.device_id 与 device.device_id 的排序规则不同
-- (utf8mb4_unicode_ci vs utf8mb4_0900_ai_ci),跨表字符串比较会报
-- ERROR 1267 Illegal mix of collations。owner_id 为数值列,无此问题。
UPDATE ai_device_profile a
SET a.deleted = 1,
a.update_time = NOW()
WHERE a.deleted = 0
AND a.owner_id > 0
AND NOT EXISTS (SELECT 1 FROM tuya_user_binding b WHERE b.member_id = a.owner_id);
-- ---------- 3) 删除测试联动规则 ----------
DELETE FROM linkage_rule WHERE deleted = 0;
-- ---------- 4) 删除测试场景(bb 场景 cron 为每分钟执行) ----------
DELETE FROM scene WHERE deleted = 0;
-- ---------- 5) 清理场景执行记录 ----------
-- scene_run 表在部分环境(未执行 V16 的库)不存在,用动态 SQL 做存在性判断后再清理,
-- 保证迁移在"旧结构库"上也能整段跑完而不中断。
SET @has_scene_run = (SELECT COUNT(*) FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'scene_run');
SET @s = IF(@has_scene_run > 0,
'DELETE FROM scene_run',
'SELECT ''scene_run table not found, skipped'' AS info');
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;