新视频推送接收(未测) app升级 告警 国际短信跟谷歌邮箱接入
This commit is contained in:
@@ -199,3 +199,237 @@ ALTER TABLE bm_device
|
||||
ALTER TABLE bm_device
|
||||
ADD COLUMN ring_battery_threshold tinyint NOT NULL DEFAULT 20
|
||||
COMMENT '脚环低电告警阈值0-100(≤该值触发,0=不触发)';
|
||||
|
||||
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- 补丁 5:sys_user.phone_number 加长以支持国际号码
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- 背景:APP 国际短信按 E.164 落库为「+国家码+号码」(最长 16 位),原 varchar(11) 装不下。
|
||||
-- 国内存量 11 位号码不受影响。
|
||||
--
|
||||
-- ★ 回滚
|
||||
-- ALTER TABLE sys_user MODIFY COLUMN phone_number varchar(11) DEFAULT NULL COMMENT '手机号码';
|
||||
-- ----------------------------------------------------------------------------
|
||||
ALTER TABLE sys_user MODIFY COLUMN phone_number varchar(20) DEFAULT NULL COMMENT '手机号码';
|
||||
|
||||
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- 补丁 6:告警记录「处理流转」+ APP 消息表(告警消息推送)
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- 背景:
|
||||
-- 原设计(一期初版)把告警定为「只读展示」:bm_device_alert 只有 status 一个状态列,
|
||||
-- 没有处理人/处理时间,也没有逻辑删除;APP 侧不做消息中心(开发计划 D8)。
|
||||
-- 本次范围变更为:
|
||||
-- 1) 后台「告警记录」页支持「标记处理 / 批量处理 / 删除」——需要处理痕迹与可追溯删除;
|
||||
-- 2) 告警发生时向**设备绑定的 APP 用户**推送一条消息(全部类型:离线 + 头套低电 + 脚环低电),
|
||||
-- APP 需要未读角标 ⇒ 消息必须有「已读」状态。
|
||||
--
|
||||
-- ★ 为什么新建 bm_app_message 而不是复用框架的 sys_message
|
||||
-- 1) sys_message **没有「已读」字段**(只有 sendUserIds 接收人串),无法支撑 APP 未读角标;
|
||||
-- 2) 给 sys_message 加列 = 改框架表,违反项目铁律「ruoyi-* 框架不改,业务只在 ruoyi-device」;
|
||||
-- 3) 告警消息需要携带 device_no / alert_id 以便 APP 点击跳设备详情,属业务字段。
|
||||
-- 职责划分:bm_device_alert = 设备事实(含处理流程);bm_app_message = 推送副本(含收件人与已读)。
|
||||
--
|
||||
-- ★ del_flag 的语义与既有约束
|
||||
-- 与 bm_device 一致:0 存在 / 1 删除(common-mybatis.yml: logicDeleteValue=1)。
|
||||
-- 后台「删除」走 MyBatis-Plus 逻辑删除,**不物理抹除**告警审计痕迹。
|
||||
--
|
||||
-- ★ 执行前必读 · 前置检查(确认列尚不存在,避免重复执行报 1060)
|
||||
-- SELECT column_name FROM information_schema.columns
|
||||
-- WHERE table_schema = 'bird_monitoring' AND table_name = 'bm_device_alert'
|
||||
-- AND column_name IN ('handle_by', 'handle_time', 'message_user_id', 'del_flag');
|
||||
-- → 期望返回 0 行。
|
||||
--
|
||||
-- ★ 重复执行本文件时的预期报错(可忽略)
|
||||
-- ERROR 1060 (42S21): Duplicate column name 'handle_by'
|
||||
-- ERROR 1050 (42S01): Table 'bm_app_message' already exists
|
||||
-- ERROR 1062 (23000): Duplicate entry '1771400000000000005' for key 'PRIMARY'(菜单重复插入)
|
||||
--
|
||||
-- ★ 回滚
|
||||
-- ALTER TABLE bm_device_alert
|
||||
-- DROP COLUMN handle_by, DROP COLUMN handle_time, DROP COLUMN message_user_id,
|
||||
-- DROP COLUMN del_flag,
|
||||
-- DROP INDEX idx_status_time;
|
||||
-- DROP TABLE bm_app_message;
|
||||
-- DELETE FROM sys_role_menu WHERE menu_id IN (1771400000000000005,1771400000000000019,
|
||||
-- 1771400000000000020,1771400000000000021);
|
||||
-- DELETE FROM sys_menu WHERE menu_id IN (1771400000000000005,1771400000000000019,
|
||||
-- 1771400000000000020,1771400000000000021);
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
-- 步骤 1:告警表补「处理人 / 处理时间 / 逻辑删除」
|
||||
-- 注:status 列原注释写着「一期只读展示」,本次变更后已失效,一并纠正注释。
|
||||
ALTER TABLE bm_device_alert
|
||||
MODIFY COLUMN status char(1) NOT NULL COMMENT '处理状态(0未处理 1已处理)';
|
||||
|
||||
ALTER TABLE bm_device_alert
|
||||
ADD COLUMN handle_by bigint(20) DEFAULT NULL COMMENT '处理人(sys_user.user_id,后台账号)';
|
||||
|
||||
ALTER TABLE bm_device_alert
|
||||
ADD COLUMN handle_time datetime DEFAULT NULL COMMENT '处理时间';
|
||||
|
||||
-- 告警行同时承担消息 outbox:保存告警发生时的收件人快照,消息写入失败后可据此安全补偿。
|
||||
ALTER TABLE bm_device_alert
|
||||
ADD COLUMN message_user_id bigint(20) DEFAULT NULL COMMENT '告警发生时的APP收件人快照(用于消息补偿)';
|
||||
|
||||
-- del_flag 用 NOT NULL DEFAULT '0':与 bm_device / bm_ota_package / bm_ota_task 保持一致。
|
||||
-- 必须 NOT NULL:MyBatis-Plus 逻辑删除生成 WHERE del_flag = '0',
|
||||
-- 若某行是 NULL 会被静默排除在所有查询之外(数据「消失」而非报错)。
|
||||
-- 存量行由 ADD COLUMN 的 DEFAULT 一次性回填 '0'(全部视为存在),升级零行为变化。
|
||||
ALTER TABLE bm_device_alert
|
||||
ADD COLUMN del_flag char(1) NOT NULL DEFAULT '0' COMMENT '逻辑删除(0存在 1删除)';
|
||||
|
||||
-- 「未处理优先 + 时间倒序」是告警列表的默认排序,建复合索引支撑。
|
||||
ALTER TABLE bm_device_alert ADD INDEX idx_status_time (status, alert_time);
|
||||
|
||||
-- 步骤 2:APP 消息表
|
||||
CREATE TABLE IF NOT EXISTS bm_app_message (
|
||||
message_id bigint(20) NOT NULL COMMENT '主键(雪花)',
|
||||
user_id bigint(20) NOT NULL COMMENT '接收用户(sys_user.user_id,APP 用户)',
|
||||
device_id bigint(20) DEFAULT NULL COMMENT '关联设备主键',
|
||||
device_no varchar(32) DEFAULT NULL COMMENT '关联设备编号(冗余,供展示与跳转)',
|
||||
alert_id bigint(20) DEFAULT NULL COMMENT '关联告警主键(bm_device_alert)',
|
||||
alert_type varchar(32) DEFAULT NULL COMMENT '告警类型(offline/low_battery_hood/low_battery_ring)',
|
||||
alert_level char(1) DEFAULT NULL COMMENT '告警级别(0提示 1警告 2严重)',
|
||||
title varchar(128) NOT NULL COMMENT '消息标题',
|
||||
content varchar(255) DEFAULT NULL COMMENT '消息内容',
|
||||
read_flag char(1) NOT NULL DEFAULT '0' COMMENT '已读标记(0未读 1已读)',
|
||||
read_time datetime DEFAULT NULL COMMENT '已读时间',
|
||||
create_time datetime NOT NULL COMMENT '产生时间',
|
||||
PRIMARY KEY (message_id),
|
||||
UNIQUE KEY uk_alert_id (alert_id),
|
||||
KEY idx_user_read (user_id, read_flag),
|
||||
KEY idx_user_time (user_id, create_time, message_id)
|
||||
) ENGINE=InnoDB COMMENT = 'APP 消息(一期仅承载设备告警通知)';
|
||||
|
||||
-- 步骤 3:菜单 + 权限字(与 ry_device.sql「十、菜单 + 权限字」保持一致)
|
||||
INSERT INTO sys_menu VALUES(1771400000000000005, '告警记录', 1771400000000000001, 4, 'alert', 'device/alert/index', '', 'N', 'Y', 'C', '0', '0', 'device:alert:list', 'message', '', '', 1761000000000000103, 1761100000000000001, sysdate(), NULL, NULL, '告警记录菜单');
|
||||
INSERT INTO sys_menu VALUES(1771400000000000019, '告警查询', 1771400000000000005, 1, '', '', '', 'N', 'Y', 'F', '0', '0', 'device:alert:query', '#', '', '', 1761000000000000103, 1761100000000000001, sysdate(), NULL, NULL, '');
|
||||
INSERT INTO sys_menu VALUES(1771400000000000020, '告警处理', 1771400000000000005, 2, '', '', '', 'N', 'Y', 'F', '0', '0', 'device:alert:edit', '#', '', '', 1761000000000000103, 1761100000000000001, sysdate(), NULL, NULL, '');
|
||||
INSERT INTO sys_menu VALUES(1771400000000000021, '告警删除', 1771400000000000005, 3, '', '', '', 'N', 'Y', 'F', '0', '0', 'device:alert:remove', '#', '', '', 1761000000000000103, 1761100000000000001, sysdate(), NULL, NULL, '');
|
||||
|
||||
-- 步骤 4:角色-菜单关联
|
||||
-- 设备管理员:全部告警权限
|
||||
INSERT INTO sys_role_menu VALUES (1771300000000000001, 1771400000000000005);
|
||||
INSERT INTO sys_role_menu VALUES (1771300000000000001, 1771400000000000019);
|
||||
INSERT INTO sys_role_menu VALUES (1771300000000000001, 1771400000000000020);
|
||||
INSERT INTO sys_role_menu VALUES (1771300000000000001, 1771400000000000021);
|
||||
-- 审计员:只读(菜单 + 查询,不含处理与删除)
|
||||
INSERT INTO sys_role_menu VALUES (1771300000000000002, 1771400000000000005);
|
||||
INSERT INTO sys_role_menu VALUES (1771300000000000002, 1771400000000000019);
|
||||
|
||||
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- 补丁 7:APP 客户端版本升级(bm_app_version 表 + 2 字典 + 菜单/权限字 + 角色授权
|
||||
-- + 设备管理员补授框架上传权限 system:oss:upload)
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- 背景:
|
||||
-- 平台此前无「APP 客户端版本」概念,APP 发新版后老用户无感知,且缺少「不升级不可用」手段。
|
||||
-- 本补丁落地「APP 客户端版本升级」功能的数据基线:后台登记 APP 安装包(Android / iOS 口径一致)
|
||||
-- 与可选的 App Store 引导地址,APP 冷启动调用 GET /app/version/latest 判定是否有新版。
|
||||
-- 业务上**与设备 OTA 固件升级完全独立**
|
||||
-- (不共表、不共权限字、不共页面),仅共用「上传包到 OSS」这一技术手段。
|
||||
--
|
||||
-- ★ 关键口径(务必遵守)
|
||||
-- 1) 版本比较**只用整数构建号 version_code**(int,32 位正整数,人工递增),version_name 仅展示。
|
||||
-- ⚠️ 禁止用时间戳式构建号:int 上界 2147483647,时间戳(如 202609181200)会直接溢出。
|
||||
-- 建议公式:主版本*1000000 + 次版本*1000 + 修订号(1.0.10 → 1000010)。
|
||||
-- 2) 唯一键 uk_platform_version_code (platform, version_code) **不区分逻辑删除**(沿用项目既有约定,
|
||||
-- 与 bm_device.device_no「逻辑删除后编号不可复用」同口径):记录被逻辑删除后,同平台同构建号
|
||||
-- **不可再新增**。构建号填错的正确处理是**编辑(PUT)修正**,不是删除重建。
|
||||
-- 3) file_size 用 bigint(对齐 OTA 先例);框架把 Long 序列化为**字符串**,APP 端需 Number() 后转换展示。
|
||||
-- 数值由前端从本地文件对象 file.raw.size 取值一并提交(框架上传响应体不含 fileSize)。
|
||||
-- 4) md5 本期**不采集**(框架上传响应只有 url/fileName/ossId):列保留但允许为空,不参与任何校验。
|
||||
-- 5) 两平台(Android / iOS)均上传安装包、字段与校验口径一致;App Store 引导地址 store_url 为**选填**,
|
||||
-- 填了就落库、就在检查更新接口下发,不填存 null。强更对 iOS 仍只能引导、无法真正拦截(系统限制)。
|
||||
--
|
||||
-- ★ 执行前必读 · 前置检查(确认表/菜单尚不存在,避免重复执行报错)
|
||||
-- SELECT COUNT(*) FROM information_schema.tables
|
||||
-- WHERE table_schema='bird_monitoring' AND table_name='bm_app_version'; -- 期望 0
|
||||
-- SELECT COUNT(*) FROM sys_menu WHERE menu_id=1771400000000000006; -- 期望 0
|
||||
--
|
||||
-- ★ 重复执行本文件时的预期报错(可忽略)
|
||||
-- ERROR 1050 (42S01): Table 'bm_app_version' already exists
|
||||
-- ERROR 1062 (23000): Duplicate entry '1771500000000000009' for key 'PRIMARY'(字典类型重复)
|
||||
-- ERROR 1062 (23000): Duplicate entry '1771600000000000024' for key 'PRIMARY'(字典数据重复)
|
||||
-- ERROR 1062 (23000): Duplicate entry '1771400000000000006' for key 'PRIMARY'(菜单重复)
|
||||
-- ERROR 1062 (23000): Duplicate entry '1771300000000000001-1761400000000001601' for key 'PRIMARY'(角色授权重复)
|
||||
--
|
||||
-- ★ 影响面提示
|
||||
-- 仅新增表 / 字典 / 菜单 / 授权,不改动任何既有表结构与既有业务数据。
|
||||
-- 设备管理员补授 system:oss:upload 后,该角色即可调用框架 POST /resource/oss/upload
|
||||
-- (此前 403 的根因即缺此权限字,本修复同时惠及既有 OTA 上传页);**只补上传这一条**,
|
||||
-- 读/删/改配置(system:oss:list/query/remove、system:ossConfig:*)仍属超管职责,不授。
|
||||
--
|
||||
-- ★ 回滚
|
||||
-- DELETE FROM sys_role_menu WHERE menu_id IN (1771400000000000006,1771400000000000022,
|
||||
-- 1771400000000000023,1771400000000000024,1771400000000000025)
|
||||
-- OR (role_id=1771300000000000001 AND menu_id=1761400000000001601);
|
||||
-- DELETE FROM sys_menu WHERE menu_id IN (1771400000000000006,1771400000000000022,
|
||||
-- 1771400000000000023,1771400000000000024,1771400000000000025);
|
||||
-- DELETE FROM sys_dict_data WHERE dict_type IN ('bm_app_platform','bm_app_version_status');
|
||||
-- DELETE FROM sys_dict_type WHERE dict_type IN ('bm_app_platform','bm_app_version_status');
|
||||
-- DROP TABLE bm_app_version;
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
-- 步骤 1:APP 客户端版本表(第 8 张业务表)
|
||||
CREATE TABLE IF NOT EXISTS bm_app_version (
|
||||
version_id bigint(20) NOT NULL COMMENT '主键(雪花)',
|
||||
platform varchar(16) NOT NULL COMMENT '平台(android/ios,字典 bm_app_platform)',
|
||||
version_name varchar(32) NOT NULL COMMENT '展示版本号,如 1.0.10(仅展示,不参与比较)',
|
||||
version_code int(11) NOT NULL COMMENT '构建号,32位正整数、单调递增、平台内唯一(唯一比较依据;禁止时间戳式构建号)',
|
||||
force_update char(1) NOT NULL DEFAULT '0' COMMENT '强制更新(0否 1是;无字典,页面本地映射)',
|
||||
oss_id bigint(20) DEFAULT NULL COMMENT '关联 sys_oss.oss_id(安装包,两平台均上传)',
|
||||
file_url varchar(500) DEFAULT NULL COMMENT '安装包 URL(两平台均上传;冗余自 sys_oss,供 APP 直接下载)',
|
||||
file_name varchar(255) DEFAULT NULL COMMENT '安装包文件名(两平台均上传)',
|
||||
file_size bigint(20) DEFAULT NULL COMMENT '安装包字节数(两平台均上传;框架序列化为字符串,前端取 file.raw.size 提交)',
|
||||
md5 varchar(64) DEFAULT NULL COMMENT '安装包校验值 MD5(预留,本期不填,不参与校验)',
|
||||
store_url varchar(500) DEFAULT NULL COMMENT 'App Store 引导地址(选填)',
|
||||
changelog varchar(500) DEFAULT NULL COMMENT '更新说明(纯文本)',
|
||||
status char(1) NOT NULL DEFAULT '0' COMMENT '状态(0停用 1启用,字典 bm_app_version_status)',
|
||||
publish_time datetime DEFAULT NULL COMMENT '发布时间(首次置为启用时写入)',
|
||||
remark varchar(500) DEFAULT NULL COMMENT '备注',
|
||||
create_dept bigint(20) DEFAULT NULL COMMENT '创建部门',
|
||||
create_by bigint(20) DEFAULT NULL COMMENT '创建者',
|
||||
create_time datetime COMMENT '创建时间',
|
||||
update_by bigint(20) DEFAULT NULL COMMENT '更新者',
|
||||
update_time datetime COMMENT '更新时间',
|
||||
del_flag char(1) NOT NULL DEFAULT '0' COMMENT '逻辑删除(0存在 1删除)',
|
||||
PRIMARY KEY (version_id),
|
||||
UNIQUE KEY uk_platform_version_code (platform, version_code),
|
||||
UNIQUE KEY uk_platform_version_name (platform, version_name),
|
||||
KEY idx_platform_status (platform, status),
|
||||
KEY idx_create_time (create_time)
|
||||
) ENGINE=InnoDB COMMENT = 'APP客户端版本(后台维护,APP冷启动检查更新)';
|
||||
|
||||
-- 步骤 2:字典类型(2 个)
|
||||
INSERT INTO sys_dict_type VALUES(1771500000000000009, 'APP平台', 'bm_app_platform', 1761000000000000103, 1761100000000000001, sysdate(), NULL, NULL, 'APP平台列表');
|
||||
INSERT INTO sys_dict_type VALUES(1771500000000000010, 'APP版本状态', 'bm_app_version_status', 1761000000000000103, 1761100000000000001, sysdate(), NULL, NULL, 'APP版本状态列表');
|
||||
|
||||
-- 步骤 3:字典数据(4 条)
|
||||
INSERT INTO sys_dict_data VALUES(1771600000000000024, 1, '安卓', 'android', 'bm_app_platform', '', 'success', 'Y', 1761000000000000103, 1761100000000000001, sysdate(), NULL, NULL, '安卓');
|
||||
INSERT INTO sys_dict_data VALUES(1771600000000000025, 2, 'iOS', 'ios', 'bm_app_platform', '', 'primary', 'N', 1761000000000000103, 1761100000000000001, sysdate(), NULL, NULL, 'iOS');
|
||||
INSERT INTO sys_dict_data VALUES(1771600000000000026, 1, '停用', '0', 'bm_app_version_status', '', 'danger', 'N', 1761000000000000103, 1761100000000000001, sysdate(), NULL, NULL, '停用');
|
||||
INSERT INTO sys_dict_data VALUES(1771600000000000027, 2, '启用', '1', 'bm_app_version_status', '', 'success', 'Y', 1761000000000000103, 1761100000000000001, sysdate(), NULL, NULL, '启用');
|
||||
|
||||
-- 步骤 4:菜单 + 权限字(挂「设备管理」目录 1771400000000000001;component 填 src/views/ 之后路径)
|
||||
INSERT INTO sys_menu VALUES(1771400000000000006, 'APP版本管理', 1771400000000000001, 5, 'app-version', 'device/appVersion/index', '', 'N', 'Y', 'C', '0', '0', 'device:appversion:list', 'list', '', '', 1761000000000000103, 1761100000000000001, sysdate(), NULL, NULL, 'APP版本管理菜单');
|
||||
INSERT INTO sys_menu VALUES(1771400000000000022, '版本查询', 1771400000000000006, 1, '', '', '', 'N', 'Y', 'F', '0', '0', 'device:appversion:query', '#', '', '', 1761000000000000103, 1761100000000000001, sysdate(), NULL, NULL, '');
|
||||
INSERT INTO sys_menu VALUES(1771400000000000023, '版本新增', 1771400000000000006, 2, '', '', '', 'N', 'Y', 'F', '0', '0', 'device:appversion:add', '#', '', '', 1761000000000000103, 1761100000000000001, sysdate(), NULL, NULL, '');
|
||||
INSERT INTO sys_menu VALUES(1771400000000000024, '版本修改', 1771400000000000006, 3, '', '', '', 'N', 'Y', 'F', '0', '0', 'device:appversion:edit', '#', '', '', 1761000000000000103, 1761100000000000001, sysdate(), NULL, NULL, '');
|
||||
INSERT INTO sys_menu VALUES(1771400000000000025, '版本删除', 1771400000000000006, 4, '', '', '', 'N', 'Y', 'F', '0', '0', 'device:appversion:remove', '#', '', '', 1761000000000000103, 1761100000000000001, sysdate(), NULL, NULL, '');
|
||||
|
||||
-- 步骤 5:角色授权
|
||||
-- 设备管理员:菜单 + 全部 4 个按钮
|
||||
INSERT INTO sys_role_menu VALUES (1771300000000000001, 1771400000000000006);
|
||||
INSERT INTO sys_role_menu VALUES (1771300000000000001, 1771400000000000022);
|
||||
INSERT INTO sys_role_menu VALUES (1771300000000000001, 1771400000000000023);
|
||||
INSERT INTO sys_role_menu VALUES (1771300000000000001, 1771400000000000024);
|
||||
INSERT INTO sys_role_menu VALUES (1771300000000000001, 1771400000000000025);
|
||||
-- 设备管理员:补授框架上传权限字 system:oss:upload
|
||||
-- 该权限字挂在框架基线菜单 sys_menu.menu_id = 1761400000000001601('文件上传',见 ry_vue.sql:318)。
|
||||
-- RuoYi 权限 = 角色所映射菜单的 perms 并集,故只需插这一行即可获得上传权,无需挂父菜单。
|
||||
INSERT INTO sys_role_menu VALUES (1771300000000000001, 1761400000000001601);
|
||||
-- 审计员:菜单 + 仅 query(不含新增/编辑/删除,符合只读审计定位)
|
||||
INSERT INTO sys_role_menu VALUES (1771300000000000002, 1771400000000000006);
|
||||
INSERT INTO sys_role_menu VALUES (1771300000000000002, 1771400000000000022);
|
||||
|
||||
Reference in New Issue
Block a user