102 lines
7.1 KiB
SQL
102 lines
7.1 KiB
SQL
-- =============================================
|
||
-- 用户系统设置(用户维度)+ 设备侧全局开关入库
|
||
-- 维度判据:读的时候拿不拿得到 userId
|
||
-- · 拿得到(HTTP 请求,有 SecurityContext)→ sys_user_setting,per-user
|
||
-- · 拿不到(设备上电 @Async 线程)→ sys_config,全局
|
||
-- 配套代码:SysUserSetting* / PowerOnTriggerTaskExecutor:93
|
||
-- 版本: 1.0 2026-10-05
|
||
-- =============================================
|
||
|
||
-- ------------------------------------------------------------
|
||
-- 一、用户维度设置表
|
||
-- 一行一用户;所有设置列 NOT NULL + DEFAULT,不设「未配置过」这种 NULL 态
|
||
-- 业务默认值由 Java 常量兜底(UserSettingConstants),不依赖 DB 兜底
|
||
--
|
||
-- pinned_tags:任务栏「固定标签到任务栏」的 JSON 数组,按固定顺序存 route path。
|
||
-- * 原实现存浏览器 localStorage(key: pinned-tags),换浏览器/换电脑就丢,
|
||
-- 现改为落库,同一账号在任何设备登录都能恢复固定区。
|
||
-- * 只存用户右键固定的 pinned 集合;路由自身声明的 affix(首页,router/index.js:80)
|
||
-- 由 constantRoutes 天然重建,不入此列。
|
||
-- * **写入语义:单条增量**。接口是 POST/DELETE 一个 path,服务端在事务里
|
||
-- 「SELECT ... FOR UPDATE → 读数组 → 改 → UPDATE 整列」。
|
||
-- 刻意**不提供提交整份列表的覆盖写接口**:前端手里那份列表可能已被
|
||
-- 另一个标签页/另一台设备改过,整份提交会把对方的改动静默抹掉,
|
||
-- 这正是固定标签「用着用着就少了」的成因。
|
||
-- * 增删都在 Java 侧按列表处理,**未使用任何 MySQL JSON 函数**。
|
||
-- * DEFAULT ('[]') 是 MySQL 8.0.13+ 的表达式默认值。TEXT 列不能带字面量 DEFAULT,
|
||
-- 不给默认值时 STRICT_TRANS_TABLES 下会直接报错,故必须显式写空数组。
|
||
-- 低版本数据库请改为 VARCHAR(2000) NOT NULL DEFAULT '[]'。
|
||
--
|
||
-- 已建过表的库用下面的 ALTER 补列(可重复执行前请先确认列不存在):
|
||
-- ALTER TABLE `sys_user_setting`
|
||
-- ADD COLUMN `pinned_tags` text NOT NULL DEFAULT ('[]')
|
||
-- COMMENT '任务栏固定标签JSON数组,按序存 path;空数组表示未固定'
|
||
-- AFTER `login_redirect`;
|
||
-- ALTER TABLE `sys_user_setting`
|
||
-- ADD COLUMN `query_gateway_child` tinyint(1) NOT NULL DEFAULT 0
|
||
-- COMMENT '按编号查询时是否查网关子设备(0否1是)'
|
||
-- AFTER `pinned_tags`;
|
||
--
|
||
-- query_gateway_child:开启后 /iot/device/shortList **按设备编号查询时**(serialNumber 非空):
|
||
-- ① 命中的若是网关子设备编号,返回其所属的网关设备(子设备 gw_dev_code 存的就是网关 serial_number,
|
||
-- 取 ifnull(gw_dev_code, serial_number) 换算);
|
||
-- ② 放开产品类型为「网关子设备(4)」的过滤 —— 这类设备 gw_dev_code 为空、实为独立设备,
|
||
-- 只是产品被标成 4,默认在列表中被隐藏(否则设备管理页会多出一大批),仅在按编号精确定位时可见。
|
||
-- 该开关**不改变列表范围** —— gw_dev_code is null 恒生效,不带编号时 device_type != 4 依然过滤,
|
||
-- 所以短列表始终只出顶层设备(网关 + 直连),既不出现挂在网关下的真子设备,
|
||
-- 默认列表也不会多出 device_type=4 的设备。
|
||
-- 默认 0。读该值的入口是 DeviceController#shortList,有 SecurityContext,故为 per-user 设置。
|
||
-- ------------------------------------------------------------
|
||
CREATE TABLE IF NOT EXISTS `sys_user_setting` (
|
||
`setting_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '设置主键',
|
||
`user_id` bigint(20) NOT NULL COMMENT '用户ID(sys_user.user_id)',
|
||
`login_redirect` varchar(128) NOT NULL DEFAULT '/bigscreen' COMMENT '登录后跳转路由path',
|
||
`pinned_tags` text NOT NULL DEFAULT ('[]') COMMENT '任务栏固定标签JSON数组,按序存 path;空数组表示未固定',
|
||
`query_gateway_child` tinyint(1) NOT NULL DEFAULT 0 COMMENT '按编号查询时是否查网关子设备(0否1是)',
|
||
`create_by` varchar(64) DEFAULT NULL COMMENT '创建者',
|
||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||
`update_by` varchar(64) DEFAULT NULL COMMENT '更新者',
|
||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
|
||
PRIMARY KEY (`setting_id`) USING BTREE,
|
||
UNIQUE KEY `uk_sys_user_setting_user` (`user_id`) USING BTREE COMMENT '每用户仅一行'
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
|
||
ROW_FORMAT=DYNAMIC COMMENT='用户系统设置表';
|
||
|
||
-- ------------------------------------------------------------
|
||
-- 二、设备侧全局开关 → 复用已有 sys_config 表
|
||
-- 原实现:PowerOnTriggerTaskExecutor 直读运维手动写入的裸 Redis key
|
||
-- "get_imei_iccid"(经 BackendController /set 写入)
|
||
-- 新实现:改读 sys_config,运维改用已有的 PUT /system/config
|
||
-- config_type='Y' = 系统内置,deleteConfigByIds 会拒删
|
||
-- ------------------------------------------------------------
|
||
INSERT INTO `sys_config`
|
||
(`config_name`, `config_key`, `config_value`, `config_type`, `create_by`, `create_time`, `remark`)
|
||
SELECT '是否下发读取设备IMEI/ICCID指令', 'iot.power_on.read_imei_iccid', 'true', 'Y', 'system', NOW(),
|
||
'设备上电后是否下发 AT+IMEI/AT+ICCID/AT+LBS 指令读取;读该值的线程无登录上下文,故为全局配置'
|
||
WHERE NOT EXISTS (
|
||
SELECT 1 FROM `sys_config` WHERE `config_key` = 'iot.power_on.read_imei_iccid'
|
||
);
|
||
|
||
-- ------------------------------------------------------------
|
||
-- 三、菜单:系统管理 → 个人设置
|
||
-- 不设 system:setting:list 权限点的原因:
|
||
-- 接口读写的是「当前登录用户自己的」设置,无需菜单级授权;
|
||
-- 若填了权限点,非管理员账号将看不到也用不了自己的设置页。
|
||
-- menu_type='C' 菜单,component 指向新建的 views/system/setting/index.vue
|
||
-- ------------------------------------------------------------
|
||
INSERT INTO `sys_menu`
|
||
(`menu_name`, `parent_id`, `order_num`, `path`, `component`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`)
|
||
SELECT '系统设置', 1, 13, 'setting', 'system/setting/index', 1, 0, 'C', '0', '0', '', 'setting', 'system', NOW()
|
||
WHERE NOT EXISTS (
|
||
SELECT 1 FROM `sys_menu` WHERE `parent_id` = 1 AND `path` = 'setting'
|
||
);
|
||
|
||
-- ------------------------------------------------------------
|
||
-- 四、清理历史遗留的裸 Redis key
|
||
-- 原开关 key 无前缀、不在任何 key 生成器中,与 RedisKeyBuilder 规范不符。
|
||
-- 确认线上设备已完成一轮上电、开关已由 sys_config 接管后再执行:
|
||
-- redis-cli DEL get_imei_iccid
|
||
-- 切勿在切换完成前执行,否则 IMEI/ICCID 指令会立即停止下发。
|
||
-- ------------------------------------------------------------
|