包含 RuoYi-Vue 后端(ruoyi-iot 门禁模块)、RuoYi-Vue2 前端、设计文档与升级脚本。 忽略构建产物(target/node_modules/dist)、IDE 配置、运行日志与数据库转储。
199 lines
14 KiB
SQL
199 lines
14 KiB
SQL
-- =========================================================================
|
||
-- 存量升级:D19 住宿管理(v1 库)
|
||
--
|
||
-- 背景:新增「房间」与「入住单」两个业务对象。房间是住宿主体,门锁分配给
|
||
-- 房间(一房一锁);入住单记录谁在什么时间段住哪个房间,入住/退房/换房
|
||
-- 都翻译成对既有 lock_auth 的操作(有效期 + 幂等新增 + 单人删除),
|
||
-- 不新建"住宿授权表"。
|
||
--
|
||
-- 本文档对应设计:doc/住宿管理模块设计.md
|
||
--
|
||
-- 执行前置:
|
||
-- 1) 备份 lock_device / sys_dict_type / sys_dict_data / sys_menu;
|
||
-- 2) 本脚本可重复执行(建表 if not exists、字典先删后插、回填 insert ignore);
|
||
-- 3) 建议在门禁业务低峰期执行;S1 上线只需本脚本,S2(住宿页)另追加菜单。
|
||
--
|
||
-- 阶段说明:
|
||
-- - S1(房间管理):建两张表、三组字典、房间菜单与按钮;
|
||
-- - S2(住宿管理):追加 2130 住宿菜单与前端页面,无需再改表结构。
|
||
-- =========================================================================
|
||
|
||
set names utf8mb4;
|
||
|
||
|
||
-- =========================================================================
|
||
-- 1、房间表
|
||
-- 一房一锁:device_id 唯一(未绑锁的房间 device_id 为 null,不参与唯一约束)。
|
||
-- room_status 兼作入住闸门:只有 0空闲 可办理入住;1在住/2维修/3停用 不可。
|
||
-- current_stay_id / current_person_no 为房态冗余,入住/退房时与 lock_stay 同事务维护。
|
||
-- =========================================================================
|
||
create table if not exists lock_room (
|
||
room_id bigint(20) not null auto_increment comment '房间ID',
|
||
room_code varchar(64) not null comment '房间编码(全局唯一,建议 公寓编号-房号,如 FFFA26102918-1203)',
|
||
room_no varchar(32) not null comment '房号(显示用,如 1203)',
|
||
room_name varchar(64) default null comment '房间名称/房型说明',
|
||
group_id bigint(20) default null comment '所属公寓/分区(lock_group.group_id)',
|
||
building varchar(32) default null comment '楼栋',
|
||
floor int(4) default null comment '楼层',
|
||
capacity int(4) default 1 comment '可住人数(仅作参考,系统不限制入住人数)',
|
||
device_id bigint(20) default null comment '绑定门锁(lock_device.device_id),一房一锁',
|
||
room_status char(1) default '0' comment '房态(0空闲 1在住 2维修 3停用,字典 lock_room_status)',
|
||
current_stay_id bigint(20) default null comment '当前在住入住单ID(冗余,空即无人在住)',
|
||
current_person_no varchar(32) default null comment '当前在住人员编号(冗余)',
|
||
del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)',
|
||
create_by varchar(64) default '' comment '创建者',
|
||
create_time datetime comment '创建时间',
|
||
update_by varchar(64) default '' comment '更新者',
|
||
update_time datetime comment '更新时间',
|
||
remark varchar(500) default null comment '备注',
|
||
primary key (room_id),
|
||
unique key uk_lock_room_code (room_code),
|
||
unique key uk_lock_room_device (device_id),
|
||
key idx_lock_room_group (group_id),
|
||
key idx_lock_room_status (room_status),
|
||
key idx_lock_room_no (room_no)
|
||
) engine=innodb comment = '房间表';
|
||
|
||
|
||
-- =========================================================================
|
||
-- 2、入住单表
|
||
-- 一条入住单对应一条 lock_auth(auth_type='01' 人脸);
|
||
-- stay_status 0待入住 1在住 2已退房 3已换房 4已取消。
|
||
-- 同一房间同时只能一条 1在住(房间行锁保证);同一人可同时在多个房间。
|
||
-- =========================================================================
|
||
create table if not exists lock_stay (
|
||
stay_id bigint(20) not null auto_increment comment '入住单ID',
|
||
stay_no varchar(32) not null comment '入住编号(业务唯一,建议 STAY+日期+序号)',
|
||
person_id bigint(20) not null comment '人员ID',
|
||
person_no varchar(32) not null comment '人员编号(协议键,冗余)',
|
||
person_name varchar(64) default null comment '人员姓名(冗余快照)',
|
||
guest_type char(1) default '0' comment '入住人员类型(0内部 1外部,字典 lock_guest_type)',
|
||
room_id bigint(20) not null comment '房间ID',
|
||
room_code varchar(64) default null comment '房间编码(冗余快照)',
|
||
device_id bigint(20) default null comment '入住时的门锁ID(冗余快照)',
|
||
device_sn varchar(32) default null comment '门锁SN(冗余快照)',
|
||
auth_id bigint(20) default null comment '对应 lock_auth.auth_id',
|
||
begin_time datetime not null comment '入住开始时间(授权生效起)',
|
||
end_time datetime not null comment '预计退房时间(授权生效止)',
|
||
checkin_time datetime comment '实际入住时间',
|
||
checkout_time datetime comment '实际退房/换房时间',
|
||
change_from_id bigint(20) default null comment '换房来源入住单ID',
|
||
stay_status char(1) default '0' comment '入住状态(0待入住 1在住 2已退房 3已换房 4已取消,字典 lock_stay_status)',
|
||
auth_status char(1) default '0' comment '人脸授权状态(0待下发 1已下发 2成功 3失败,字典 lock_sync_status)',
|
||
auth_msg varchar(512) default null comment '授权下发结果说明',
|
||
del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)',
|
||
create_by varchar(64) default '' comment '创建者',
|
||
create_time datetime comment '创建时间',
|
||
update_by varchar(64) default '' comment '更新者',
|
||
update_time datetime comment '更新时间',
|
||
remark varchar(500) default null comment '备注',
|
||
primary key (stay_id),
|
||
unique key uk_lock_stay_no (stay_no),
|
||
key idx_lock_stay_person (person_no, stay_status),
|
||
key idx_lock_stay_room (room_id, stay_status),
|
||
key idx_lock_stay_end (end_time, stay_status),
|
||
key idx_lock_stay_auth (auth_id)
|
||
) engine=innodb comment = '入住单表';
|
||
|
||
|
||
-- =========================================================================
|
||
-- 3、字典
|
||
-- =========================================================================
|
||
delete from sys_dict_data where dict_type in ('lock_room_status', 'lock_guest_type', 'lock_stay_status');
|
||
|
||
delete from sys_dict_type where dict_type in ('lock_room_status', 'lock_guest_type', 'lock_stay_status');
|
||
|
||
insert into sys_dict_type (dict_name, dict_type, status, create_by, create_time, remark) values
|
||
('房间状态', 'lock_room_status', '0', 'admin', now(), '住宿房间房态'),
|
||
('入住人员类型', 'lock_guest_type', '0', 'admin', now(), '住宿入住人员内部/外部'),
|
||
('入住状态', 'lock_stay_status', '0', 'admin', now(), '入住单状态');
|
||
|
||
insert into sys_dict_data (dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, remark) values
|
||
(1, '空闲', '0', 'lock_room_status', '', 'success', 'Y', '0', 'admin', now(), '可办理入住'),
|
||
(2, '在住', '1', 'lock_room_status', '', 'primary', 'N', '0', 'admin', now(), ''),
|
||
(3, '维修', '2', 'lock_room_status', '', 'warning', 'N', '0', 'admin', now(), '不可办理入住'),
|
||
(4, '停用', '3', 'lock_room_status', '', 'danger', 'N', '0', 'admin', now(), '不可办理入住'),
|
||
(1, '内部', '0', 'lock_guest_type', '', 'primary', 'Y', '0', 'admin', now(), '住户/员工'),
|
||
(2, '外部', '1', 'lock_guest_type', '', 'info', 'N', '0', 'admin', now(), '访客等外部人员'),
|
||
(1, '待入住', '0', 'lock_stay_status', '', 'info', 'N', '0', 'admin', now(), ''),
|
||
(2, '在住', '1', 'lock_stay_status', '', 'success', 'Y', '0', 'admin', now(), ''),
|
||
(3, '已退房', '2', 'lock_stay_status', '', 'info', 'N', '0', 'admin', now(), ''),
|
||
(4, '已换房', '3', 'lock_stay_status', '', 'warning', 'N', '0', 'admin', now(), ''),
|
||
(5, '已取消', '4', 'lock_stay_status', '', 'danger', 'N', '0', 'admin', now(), '');
|
||
|
||
|
||
-- =========================================================================
|
||
-- 4、菜单:房间管理(S1)与住宿管理(S2)
|
||
-- 一级目录沿用 2000 门禁管理;号段 2120 房间、2130 住宿,与人员 2100 错开。
|
||
-- =========================================================================
|
||
delete from sys_menu where perms like 'lock:room:%';
|
||
|
||
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark) values
|
||
(2120, '房间管理', 2000, 11, 'room', 'iot/room/index', '', '', 1, 0, 'C', '0', '0', 'lock:room:list', 'tree', 'admin', CURRENT_TIMESTAMP, '住宿房间菜单');
|
||
|
||
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark) values
|
||
(2121, '房间查询', 2120, 1, '', null, '', '', 1, 0, 'F', '0', '0', 'lock:room:query', '#', 'admin', CURRENT_TIMESTAMP, ''),
|
||
(2122, '房间新增', 2120, 2, '', null, '', '', 1, 0, 'F', '0', '0', 'lock:room:add', '#', 'admin', CURRENT_TIMESTAMP, ''),
|
||
(2123, '房间修改', 2120, 3, '', null, '', '', 1, 0, 'F', '0', '0', 'lock:room:edit', '#', 'admin', CURRENT_TIMESTAMP, ''),
|
||
(2124, '房间删除', 2120, 4, '', null, '', '', 1, 0, 'F', '0', '0', 'lock:room:remove', '#', 'admin', CURRENT_TIMESTAMP, ''),
|
||
(2125, '房间导出', 2120, 5, '', null, '', '', 1, 0, 'F', '0', '0', 'lock:room:export', '#', 'admin', CURRENT_TIMESTAMP, ''),
|
||
(2126, '分配门锁', 2120, 6, '', null, '', '', 1, 0, 'F', '0', '0', 'lock:room:bind', '#', 'admin', CURRENT_TIMESTAMP, '门锁与房间绑定/解绑');
|
||
|
||
delete from sys_menu where perms like 'lock:stay:%';
|
||
|
||
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark) values
|
||
(2130, '住宿管理', 2000, 12, 'stay', 'iot/stay/index', '', '', 1, 0, 'C', '0', '0', 'lock:stay:list', 'peoples', 'admin', CURRENT_TIMESTAMP, '住宿入住/退房菜单');
|
||
|
||
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark) values
|
||
(2131, '住宿查询', 2130, 1, '', null, '', '', 1, 0, 'F', '0', '0', 'lock:stay:query', '#', 'admin', CURRENT_TIMESTAMP, ''),
|
||
(2132, '入住登记', 2130, 2, '', null, '', '', 1, 0, 'F', '0', '0', 'lock:stay:checkin', '#', 'admin', CURRENT_TIMESTAMP, '含外部人员一步建档'),
|
||
(2133, '退房', 2130, 3, '', null, '', '', 1, 0, 'F', '0', '0', 'lock:stay:checkout', '#', 'admin', CURRENT_TIMESTAMP, ''),
|
||
(2134, '换房', 2130, 4, '', null, '', '', 1, 0, 'F', '0', '0', 'lock:stay:change', '#', 'admin', CURRENT_TIMESTAMP, 'S3 启用'),
|
||
(2135, '续住', 2130, 5, '', null, '', '', 1, 0, 'F', '0', '0', 'lock:stay:extend', '#', 'admin', CURRENT_TIMESTAMP, 'S3 启用'),
|
||
(2136, '住宿导出', 2130, 6, '', null, '', '', 1, 0, 'F', '0', '0', 'lock:stay:export', '#', 'admin', CURRENT_TIMESTAMP, '');
|
||
|
||
|
||
-- =========================================================================
|
||
-- 5、存量回填:按 lock_device.room_no 建房间并绑定门锁
|
||
-- 规则(见设计文档 §11.1):
|
||
-- - room_code = 公寓编号-房号(无公寓编号时直接用房号);
|
||
-- - 同一 room_code 只保留 device_id 最小的一条(最早的锁),其余由人工在页面处理;
|
||
-- - 回填只建房间、绑门锁,不改 lock_device 任何字段。
|
||
-- 执行后跑第 6 节核对语句,确认未回填的门锁。
|
||
-- =========================================================================
|
||
insert ignore into lock_room (room_code, room_no, group_id, device_id, room_status, del_flag,
|
||
create_by, create_time, remark)
|
||
select t.room_code, t.room_no, t.group_id, t.device_id, '0', '0', 'system', now(), '由 lock_device.room_no 回填'
|
||
from (
|
||
select case
|
||
when g.group_code is null or trim(g.group_code) = '' then trim(d.room_no)
|
||
else concat(trim(g.group_code), '-', trim(d.room_no))
|
||
end as room_code,
|
||
min(trim(d.room_no)) as room_no,
|
||
any_value(d.group_id) as group_id,
|
||
min(d.device_id) as device_id
|
||
from lock_device d
|
||
left join lock_group g on g.group_id = d.group_id and g.del_flag = '0'
|
||
where d.del_flag = '0'
|
||
and d.room_no is not null
|
||
and trim(d.room_no) <> ''
|
||
group by room_code
|
||
) t;
|
||
|
||
|
||
-- =========================================================================
|
||
-- 6、执行后核对(只读,按需执行)
|
||
-- =========================================================================
|
||
-- 6.1 房间数与回填门锁数
|
||
-- select (select count(1) from lock_room where del_flag = '0') as room_cnt,
|
||
-- (select count(1) from lock_room where del_flag = '0' and device_id is not null) as bound_cnt;
|
||
--
|
||
-- 6.2 有房号但未回填到房间的门锁(多为同房号重复或 room_code 冲突,需人工处理)
|
||
-- select d.device_id, d.device_sn, d.room_no, d.group_id
|
||
-- from lock_device d
|
||
-- where d.del_flag = '0' and d.room_no is not null and trim(d.room_no) <> ''
|
||
-- and not exists (select 1 from lock_room r where r.device_id = d.device_id and r.del_flag = '0');
|
||
--
|
||
-- 6.3 一把锁被多个房间绑定的异常数据(应为空,唯一键保证)
|
||
-- select device_id, count(1) from lock_room
|
||
-- where del_flag = '0' and device_id is not null group by device_id having count(1) > 1; |