Files
doorcontrol/base/RuoYi-Vue-master/sql/upgrade_d19_stay.sql
T
zfjia 271e4ca77c chore: 导入门锁迭代开发工程基线
包含 RuoYi-Vue 后端(ruoyi-iot 门禁模块)、RuoYi-Vue2 前端、设计文档与升级脚本。
忽略构建产物(target/node_modules/dist)、IDE 配置、运行日志与数据库转储。
2026-11-01 19:44:40 +08:00

199 lines
14 KiB
SQL
Raw 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.
-- =========================================================================
-- 存量升级: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;