模块接入:
- 新增 ruoyi-device(org.dromara.device)并注册到根/ruoyi-modules/ruoyi-admin pom
APP 侧(/app/**,需登录,仅本人绑定设备):
- 账号闭环:短信/邮箱验证码注册登录、密码重置(不跨界返回散列)
- 设备:绑定/列表/详情/重命名/解绑(越权统一"设备不存在",防 IDOR)
- 眼罩开关(/app/device/{deviceNo}/hood,低电不对称拦截)
- 定位(/app/device/{deviceNo}/location)
- 直播(/app/stream 6 端点 + /app/device/{deviceNo}/live,自建 ZLMediaKit,设备主动推流)
后台(/device/**):
- 设备 CRUD/统计/删除/导出(ExcelBuilder)
- OTA(6 端点:升级包管理 + 批量下发,total==created+skipped+failed)
MQTT(T05):
- 遥测/事件/ack 监听、指令下发+回执(防串设备)、离线扫描、低电告警
- 报文身份仅来自 Topic,反查 device_id 防跨设备伪造
数据与脚本:
- script/sql/ry_device.sql(6 表/字典/权限字/菜单)、bm_patch.sql
- script/mqtt 设备模拟器(mqtt-simulate.js)
安全:
- MQTT broker 凭据外置为环境变量 MQTT_USERNAME/MQTT_PASSWORD,不落明文
- ZLM webhook 密钥外置为环境变量 ZLM_SECRET(未配置时 /zlm/hook/** 失败关闭),不落明文
240 lines
21 KiB
SQL
240 lines
21 KiB
SQL
-- ----------------------------------------------------------------------------
|
||
-- 智能飞禽物联平台 · 设备域建表脚本(阶段1 / 迭代 I1)
|
||
-- 说明:
|
||
-- 1. 6 张设备表 + 8 个字典 + 设备菜单 + 8 个权限字 + 2 个角色及其菜单关联。
|
||
-- 2. 严禁出现任何直播字段(stream_url / play_url / live_*)与医疗模板字段。
|
||
-- 3. 逻辑删除取值与框架配置一致:0 存在 / 1 删除(common-mybatis.yml: logicDeleteValue=1)。
|
||
-- 4. 唯一索引(device_no / imei)叠加逻辑删除,存在「逻辑删除后编号不可复用」的既有约束,
|
||
-- 与 RuoYi 既有模式一致,已在字段注释中写明;如需复用时改用物理删除策略。
|
||
-- 作者:Kou 日期:2026-09-16
|
||
-- ----------------------------------------------------------------------------
|
||
|
||
-- ============================ 一、设备主表 ============================
|
||
drop table if exists bm_device;
|
||
create table bm_device (
|
||
device_id bigint(20) not null comment '主键(雪花,仅内部关联)',
|
||
device_no varchar(32) not null comment '业务编号,唯一(逻辑删除后编号不可复用)',
|
||
imei varchar(32) not null comment '绑定码IMEI,唯一(逻辑删除后不可复用)',
|
||
name varchar(64) default null comment '用户侧名称≤20字符',
|
||
model varchar(64) default null comment '型号',
|
||
sn varchar(64) default null comment '出厂序列号',
|
||
hw_version varchar(32) default null comment '硬件版本',
|
||
sw_version varchar(32) default null comment '软件版本',
|
||
fw_version varchar(32) default null comment '固件版本',
|
||
pkg_version varchar(32) default null comment '数据包版本',
|
||
ip varchar(64) default null comment '设备IP',
|
||
mac varchar(64) default null comment 'MAC',
|
||
wifi_ssid varchar(64) default null comment 'WiFi SSID',
|
||
status char(1) not null default '0' comment '状态(0未激活 1在线 2离线)',
|
||
bind_user_id bigint(20) default null comment '当前绑定APP用户',
|
||
bind_time datetime default null comment '最近一次绑定时间',
|
||
hood_connected char(1) not null default '0' comment '头套(0断开 1已连接)',
|
||
hood_cover_on char(1) not null default '0' comment '眼罩(0打开 1遮盖)',
|
||
signal_level tinyint not null default 0 comment '信号等级(0离线 1弱 2一般 3强)',
|
||
hood_battery tinyint default null comment '头套电量0-100',
|
||
ring_battery tinyint default null comment '脚环电量0-100',
|
||
lng decimal(10,7) default null comment '最新经度',
|
||
lat decimal(10,7) default null comment '最新纬度',
|
||
address varchar(255) default null comment '地址(设备上报)',
|
||
last_online_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 (device_id),
|
||
unique key uk_device_no (device_no),
|
||
unique key uk_imei (imei),
|
||
key idx_bind_user (bind_user_id),
|
||
key idx_status (status),
|
||
key idx_last_online (last_online_time)
|
||
) engine=innodb comment = '设备主表';
|
||
|
||
-- ============================ 二、设备绑定流水 ============================
|
||
drop table if exists bm_device_bind;
|
||
create table bm_device_bind (
|
||
bind_id bigint(20) not null comment '主键(雪花)',
|
||
device_id bigint(20) not null comment '设备物理主键',
|
||
device_no varchar(32) default null comment '设备编号(冗余,便于审计/后台展示)',
|
||
user_id bigint(20) not null comment '操作APP用户',
|
||
imei varchar(32) default null comment 'IMEI(冗余快照)',
|
||
action varchar(16) not null comment '动作(bind/unbind/rebind)',
|
||
bind_time datetime not null comment '操作时间',
|
||
remark varchar(255) default null comment '备注',
|
||
primary key (bind_id),
|
||
key idx_device_id (device_id),
|
||
key idx_user_id (user_id),
|
||
key idx_device_action_time (device_id, action, bind_time)
|
||
) engine=innodb comment = '设备绑定流水(无逻辑删除,禁止抹除历史)';
|
||
|
||
-- ============================ 三、设备遥测历史 ============================
|
||
drop table if exists bm_device_telemetry;
|
||
create table bm_device_telemetry (
|
||
telemetry_id bigint(20) not null comment '主键(雪花)',
|
||
device_id bigint(20) not null comment '设备主键',
|
||
device_no varchar(32) default null comment '设备编号(冗余)',
|
||
hood_battery tinyint default null comment '头套电量0-100',
|
||
ring_battery tinyint default null comment '脚环电量0-100',
|
||
signal_level tinyint default null comment '信号等级(0离线 1弱 2一般 3强)',
|
||
hood_connected char(1) default null comment '头套连接(0断开 1已连接)',
|
||
hood_cover_on char(1) default null comment '眼罩状态(0打开 1遮盖)',
|
||
lng decimal(10,7) default null comment '经度',
|
||
lat decimal(10,7) default null comment '纬度',
|
||
address varchar(255) default null comment '地址',
|
||
report_time datetime not null comment '设备上报时间',
|
||
primary key (telemetry_id),
|
||
key idx_device_time (device_id, report_time)
|
||
) engine=innodb comment = '设备遥测历史(一期仅落库,不做轨迹回放)';
|
||
|
||
-- ============================ 四、设备告警 ============================
|
||
drop table if exists bm_device_alert;
|
||
create table bm_device_alert (
|
||
alert_id bigint(20) not null comment '主键(雪花)',
|
||
device_id bigint(20) not null comment '设备主键',
|
||
device_no varchar(32) default null comment '设备编号(冗余)',
|
||
alert_type varchar(32) not null comment '告警类型(offline/low_battery_hood/low_battery_ring)',
|
||
alert_level char(1) not null comment '告警级别(0提示 1警告 2严重)',
|
||
alert_value varchar(64) default null comment '触发值(如电量)',
|
||
content varchar(255) default null comment '告警文案',
|
||
status char(1) not null comment '状态(0未处理 1已处理,一期只读展示)',
|
||
alert_time datetime not null comment '告警时间',
|
||
primary key (alert_id),
|
||
key idx_device_id (device_id),
|
||
key idx_alert_type (alert_type),
|
||
key idx_alert_time (alert_time)
|
||
) engine=innodb comment = '设备告警';
|
||
|
||
-- ============================ 五、OTA 升级包 ============================
|
||
drop table if exists bm_ota_package;
|
||
create table bm_ota_package (
|
||
package_id bigint(20) not null comment '主键(雪花)',
|
||
model varchar(64) not null comment '适用型号',
|
||
version varchar(32) not null comment '版本号',
|
||
oss_id bigint(20) default null comment '关联sys_oss.oss_id',
|
||
file_url varchar(500) default null comment '文件URL(冗余)',
|
||
file_name varchar(255) default null comment '文件名',
|
||
file_size bigint(20) default null comment '文件字节数',
|
||
md5 varchar(64) default null comment '校验值MD5',
|
||
changelog varchar(500) default null comment '更新说明',
|
||
status char(1) not null default '0' comment '状态(0停用 1启用)',
|
||
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 (package_id),
|
||
unique key uk_model_version (model, version),
|
||
key idx_status (status)
|
||
) engine=innodb comment = 'OTA升级包';
|
||
|
||
-- ============================ 六、OTA 升级任务 ============================
|
||
drop table if exists bm_ota_task;
|
||
create table bm_ota_task (
|
||
task_id bigint(20) not null comment '主键(雪花)',
|
||
package_id bigint(20) not null comment '升级包',
|
||
version varchar(32) default null comment '冗余版本',
|
||
device_id bigint(20) not null comment '设备主键',
|
||
device_no varchar(32) default null comment '冗余编号',
|
||
status char(1) not null default '0' comment '状态(0待升级 1升级中 2成功 3失败)',
|
||
result_msg varchar(500) default null comment '结果信息',
|
||
progress tinyint default null comment '进度0-100',
|
||
operator_id bigint(20) default null comment '操作人(后台用户)',
|
||
times int(4) not null default 0 comment '下发次数',
|
||
start_time datetime default null comment '开始时间',
|
||
finish_time datetime 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 (task_id),
|
||
key idx_device_no (device_no),
|
||
key idx_status (status),
|
||
key idx_package_id (package_id)
|
||
) engine=innodb comment = 'OTA升级任务';
|
||
|
||
-- ============================ 七、字典类型(8 个) ============================
|
||
insert into sys_dict_type values(1771500000000000001, '设备状态', 'bm_device_status', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '设备状态列表');
|
||
insert into sys_dict_type values(1771500000000000002, '信号等级', 'bm_signal_level', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '信号等级列表');
|
||
insert into sys_dict_type values(1771500000000000003, '头套连接', 'bm_hood_connected', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '头套连接列表');
|
||
insert into sys_dict_type values(1771500000000000004, '眼罩状态', 'bm_hood_cover', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '眼罩状态列表');
|
||
insert into sys_dict_type values(1771500000000000005, 'OTA任务状态', 'bm_ota_task_status', 1761000000000000103, 1761100000000000001, sysdate(), null, null, 'OTA任务状态列表');
|
||
insert into sys_dict_type values(1771500000000000006, '升级包状态', 'bm_ota_package_status', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '升级包状态列表');
|
||
insert into sys_dict_type values(1771500000000000007, '告警类型', 'bm_alert_type', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '告警类型列表');
|
||
insert into sys_dict_type values(1771500000000000008, '绑定动作', 'bm_bind_action', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '绑定动作列表');
|
||
|
||
-- ============================ 八、字典数据 ============================
|
||
-- 设备状态
|
||
insert into sys_dict_data values(1771600000000000001, 1, '未激活', '0', 'bm_device_status', '', 'info', 'Y', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '未激活');
|
||
insert into sys_dict_data values(1771600000000000002, 2, '在线', '1', 'bm_device_status', '', 'success', 'N', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '在线');
|
||
insert into sys_dict_data values(1771600000000000003, 3, '离线', '2', 'bm_device_status', '', 'danger', 'N', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '离线');
|
||
-- 信号等级
|
||
insert into sys_dict_data values(1771600000000000004, 1, '离线', '0', 'bm_signal_level', '', 'danger', 'Y', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '离线');
|
||
insert into sys_dict_data values(1771600000000000005, 2, '弱', '1', 'bm_signal_level', '', 'warning', 'N', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '弱');
|
||
insert into sys_dict_data values(1771600000000000006, 3, '一般', '2', 'bm_signal_level', '', 'primary', 'N', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '一般');
|
||
insert into sys_dict_data values(1771600000000000007, 4, '强', '3', 'bm_signal_level', '', 'success', 'N', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '强');
|
||
-- 头套连接
|
||
insert into sys_dict_data values(1771600000000000008, 1, '已断开', '0', 'bm_hood_connected', '', 'danger', 'Y', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '已断开');
|
||
insert into sys_dict_data values(1771600000000000009, 2, '已连接', '1', 'bm_hood_connected', '', 'success', 'N', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '已连接');
|
||
-- 眼罩状态
|
||
insert into sys_dict_data values(1771600000000000010, 1, '打开', '0', 'bm_hood_cover', '', 'primary', 'Y', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '打开');
|
||
insert into sys_dict_data values(1771600000000000011, 2, '遮盖', '1', 'bm_hood_cover', '', 'success', 'N', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '遮盖');
|
||
-- OTA任务状态
|
||
insert into sys_dict_data values(1771600000000000012, 1, '待升级', '0', 'bm_ota_task_status', '', 'info', 'Y', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '待升级');
|
||
insert into sys_dict_data values(1771600000000000013, 2, '升级中', '1', 'bm_ota_task_status', '', 'primary', 'N', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '升级中');
|
||
insert into sys_dict_data values(1771600000000000014, 3, '成功', '2', 'bm_ota_task_status', '', 'success', 'N', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '成功');
|
||
insert into sys_dict_data values(1771600000000000015, 4, '失败', '3', 'bm_ota_task_status', '', 'danger', 'N', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '失败');
|
||
-- 升级包状态
|
||
insert into sys_dict_data values(1771600000000000016, 1, '停用', '0', 'bm_ota_package_status', '', 'danger', 'N', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '停用');
|
||
insert into sys_dict_data values(1771600000000000017, 2, '启用', '1', 'bm_ota_package_status', '', 'success', 'Y', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '启用');
|
||
-- 告警类型
|
||
insert into sys_dict_data values(1771600000000000018, 1, '设备离线', 'offline', 'bm_alert_type', '', 'danger', 'N', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '设备离线');
|
||
insert into sys_dict_data values(1771600000000000019, 2, '头套低电', 'low_battery_hood', 'bm_alert_type', '', 'warning', 'N', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '头套低电');
|
||
insert into sys_dict_data values(1771600000000000020, 3, '脚环低电', 'low_battery_ring', 'bm_alert_type', '', 'warning', 'N', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '脚环低电');
|
||
-- 绑定动作
|
||
insert into sys_dict_data values(1771600000000000021, 1, '绑定', 'bind', 'bm_bind_action', '', 'primary', 'N', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '绑定');
|
||
insert into sys_dict_data values(1771600000000000022, 2, '解绑', 'unbind', 'bm_bind_action', '', 'danger', 'N', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '解绑');
|
||
insert into sys_dict_data values(1771600000000000023, 3, '换绑', 'rebind', 'bm_bind_action', '', 'warning', 'N', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '换绑');
|
||
|
||
-- ============================ 九、菜单 + 权限字 ============================
|
||
-- 一级目录
|
||
insert into sys_menu values(1771400000000000001, '设备管理', 0, 6, 'device', null, '', 'N', 'Y', 'M', '0', '0', '', 'dashboard', '', '', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '设备管理目录');
|
||
-- 二级菜单
|
||
insert into sys_menu values(1771400000000000002, '设备列表', 1771400000000000001, 1, 'device', 'device/device/index', '', 'N', 'Y', 'C', '0', '0', 'device:device:list', 'form', '', '', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '设备列表菜单');
|
||
insert into sys_menu values(1771400000000000003, 'OTA管理', 1771400000000000001, 2, 'ota', 'device/ota/index', '', 'N', 'Y', 'C', '0', '0', 'device:ota:list', 'upload', '', '', 1761000000000000103, 1761100000000000001, sysdate(), null, null, 'OTA管理菜单');
|
||
-- 设备列表按钮
|
||
insert into sys_menu values(1771400000000000011, '设备查询', 1771400000000000002, 1, '', '', '', 'N', 'Y', 'F', '0', '0', 'device:device:query', '#', '', '', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '');
|
||
insert into sys_menu values(1771400000000000012, '设备新增', 1771400000000000002, 2, '', '', '', 'N', 'Y', 'F', '0', '0', 'device:device:add', '#', '', '', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '');
|
||
insert into sys_menu values(1771400000000000013, '设备修改', 1771400000000000002, 3, '', '', '', 'N', 'Y', 'F', '0', '0', 'device:device:edit', '#', '', '', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '');
|
||
insert into sys_menu values(1771400000000000014, '设备删除', 1771400000000000002, 4, '', '', '', 'N', 'Y', 'F', '0', '0', 'device:device:remove', '#', '', '', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '');
|
||
insert into sys_menu values(1771400000000000015, '设备导出', 1771400000000000002, 5, '', '', '', 'N', 'Y', 'F', '0', '0', 'device:device:export', '#', '', '', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '');
|
||
-- OTA 按钮
|
||
insert into sys_menu values(1771400000000000016, 'OTA新增', 1771400000000000003, 1, '', '', '', 'N', 'Y', 'F', '0', '0', 'device:ota:add', '#', '', '', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '');
|
||
|
||
-- ============================ 十、角色 ============================
|
||
insert into sys_role values(1771300000000000001, '设备管理员', 'device_admin', 5, 1, 1, 1, '0', '0', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '设备域管理角色');
|
||
insert into sys_role values(1771300000000000002, '审计员', 'device_auditor', 6, 1, 1, 1, '0', '0', 1761000000000000103, 1761100000000000001, sysdate(), null, null, '设备域只读审计角色');
|
||
|
||
-- ============================ 十一、角色-菜单关联 ============================
|
||
-- 设备管理员:全部设备菜单
|
||
insert into sys_role_menu values (1771300000000000001, 1771400000000000001);
|
||
insert into sys_role_menu values (1771300000000000001, 1771400000000000002);
|
||
insert into sys_role_menu values (1771300000000000001, 1771400000000000003);
|
||
insert into sys_role_menu values (1771300000000000001, 1771400000000000011);
|
||
insert into sys_role_menu values (1771300000000000001, 1771400000000000012);
|
||
insert into sys_role_menu values (1771300000000000001, 1771400000000000013);
|
||
insert into sys_role_menu values (1771300000000000001, 1771400000000000014);
|
||
insert into sys_role_menu values (1771300000000000001, 1771400000000000015);
|
||
insert into sys_role_menu values (1771300000000000001, 1771400000000000016);
|
||
-- 审计员:目录 + 列表 + 详情 + 导出 + OTA 列表
|
||
insert into sys_role_menu values (1771300000000000002, 1771400000000000001);
|
||
insert into sys_role_menu values (1771300000000000002, 1771400000000000002);
|
||
insert into sys_role_menu values (1771300000000000002, 1771400000000000003);
|
||
insert into sys_role_menu values (1771300000000000002, 1771400000000000011);
|
||
insert into sys_role_menu values (1771300000000000002, 1771400000000000015);
|