更新登录页及优化相关功能
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
-- 隧道物料流转:MySQL 增量补丁
|
||||
-- 前置条件:已执行 20260922_test_data_batch_mysql.sql,且数据库中存在 biz_test_batch。
|
||||
-- 本补丁只生成脚本,不在应用启动时自动执行;执行前请备份数据库并由 DBA 审核。
|
||||
-- 业务层将新托盘/新装填固定为 100 包,数据库不增加 capacity_packages = 100
|
||||
-- 约束,以兼容已有历史非 100 包托盘数据。
|
||||
|
||||
-- 隧道主数据:一个客户现场下的隧道编号唯一;current_trace_no 表示当前混批溯源号。
|
||||
CREATE TABLE biz_tunnel (
|
||||
tunnel_id BIGINT NOT NULL AUTO_INCREMENT COMMENT '隧道ID',
|
||||
test_batch_id BIGINT NULL COMMENT '测试数据批次ID;NULL表示正式数据',
|
||||
site_id BIGINT NOT NULL COMMENT '现场ID',
|
||||
tunnel_code VARCHAR(64) NOT NULL COMMENT '隧道编号',
|
||||
tunnel_name VARCHAR(100) NOT NULL COMMENT '隧道名称',
|
||||
current_trace_no VARCHAR(64) NULL COMMENT '当前隧道物料溯源号',
|
||||
current_trace_started_at DATETIME NULL COMMENT '当前溯源批次开始时间',
|
||||
status CHAR(1) NOT NULL DEFAULT '0' COMMENT '状态(0正常 1停用)',
|
||||
create_by VARCHAR(64) NULL DEFAULT '' COMMENT '创建者',
|
||||
create_time DATETIME NULL COMMENT '创建时间',
|
||||
update_by VARCHAR(64) NULL DEFAULT '' COMMENT '更新者',
|
||||
update_time DATETIME NULL COMMENT '更新时间',
|
||||
remark VARCHAR(500) NULL COMMENT '备注',
|
||||
PRIMARY KEY (tunnel_id),
|
||||
KEY idx_biz_tunnel_test_batch_id (test_batch_id),
|
||||
CONSTRAINT uq_biz_tunnel_site_code UNIQUE (site_id, tunnel_code),
|
||||
CONSTRAINT fk_biz_tunnel_test_batch_id FOREIGN KEY (test_batch_id) REFERENCES biz_test_batch (batch_id),
|
||||
CONSTRAINT fk_biz_tunnel_site FOREIGN KEY (site_id) REFERENCES biz_customer_site (site_id),
|
||||
CONSTRAINT ck_biz_tunnel_status CHECK (status IN ('0', '1'))
|
||||
) ENGINE=InnoDB COMMENT='客户现场隧道主数据表';
|
||||
|
||||
-- 使用记录:保留入隧隧道、溯源号和生产批次快照;产线改为可选。
|
||||
ALTER TABLE biz_usage_record
|
||||
ADD COLUMN tunnel_id BIGINT NULL COMMENT '隧道ID;历史记录可能为空' AFTER site_id,
|
||||
ADD COLUMN trace_no VARCHAR(64) NULL COMMENT '隧道物料内部溯源号;历史记录可能为空' AFTER tunnel_id,
|
||||
ADD COLUMN batch_no_snapshot VARCHAR(64) NULL COMMENT '生产批次快照;历史记录可能为空' AFTER trace_no,
|
||||
MODIFY COLUMN line_id BIGINT NULL COMMENT '产线ID(可选)',
|
||||
ADD CONSTRAINT fk_biz_usage_record_tunnel FOREIGN KEY (tunnel_id) REFERENCES biz_tunnel (tunnel_id);
|
||||
|
||||
-- 退回明细:保存申请时的隧道、溯源号和批次快照。
|
||||
ALTER TABLE biz_return_item
|
||||
ADD COLUMN tunnel_id_snapshot BIGINT NULL COMMENT '申请时隧道ID快照' AFTER active_filling_id_snapshot,
|
||||
ADD COLUMN trace_no_snapshot VARCHAR(64) NULL COMMENT '申请时物料溯源号快照' AFTER tunnel_id_snapshot,
|
||||
ADD COLUMN batch_no_snapshot VARCHAR(64) NULL COMMENT '申请时生产批次快照' AFTER trace_no_snapshot,
|
||||
ADD CONSTRAINT fk_biz_return_item_tunnel FOREIGN KEY (tunnel_id_snapshot) REFERENCES biz_tunnel (tunnel_id);
|
||||
|
||||
-- 当前库存:隧道归属和当前溯源号随托盘一起锁定维护。
|
||||
ALTER TABLE biz_pallet_inventory
|
||||
ADD COLUMN tunnel_id BIGINT NULL COMMENT '当前隧道ID' AFTER site_id,
|
||||
ADD COLUMN trace_no VARCHAR(64) NULL COMMENT '当前隧道物料溯源号' AFTER tunnel_id,
|
||||
ADD CONSTRAINT fk_biz_pallet_inventory_tunnel FOREIGN KEY (tunnel_id) REFERENCES biz_tunnel (tunnel_id);
|
||||
|
||||
-- 流转事件:为入隧、使用、退回保留隧道和溯源快照。
|
||||
ALTER TABLE biz_pallet_event
|
||||
ADD COLUMN before_tunnel_id BIGINT NULL COMMENT '变更前隧道ID' AFTER before_site_id,
|
||||
ADD COLUMN after_tunnel_id BIGINT NULL COMMENT '变更后隧道ID' AFTER after_site_id,
|
||||
ADD COLUMN trace_no VARCHAR(64) NULL COMMENT '事件关联物料溯源号' AFTER after_remaining_packages,
|
||||
ADD COLUMN batch_no_snapshot VARCHAR(64) NULL COMMENT '事件生产批次快照' AFTER trace_no,
|
||||
ADD CONSTRAINT fk_biz_pallet_event_before_tunnel FOREIGN KEY (before_tunnel_id) REFERENCES biz_tunnel (tunnel_id),
|
||||
ADD CONSTRAINT fk_biz_pallet_event_after_tunnel FOREIGN KEY (after_tunnel_id) REFERENCES biz_tunnel (tunnel_id);
|
||||
|
||||
ALTER TABLE biz_pallet_event
|
||||
DROP CHECK ck_biz_pallet_event_event_type,
|
||||
ADD CONSTRAINT ck_biz_pallet_event_event_type CHECK (
|
||||
event_type IN (
|
||||
'INBOUND_CONFIRMED',
|
||||
'FILLING_CONFIRMED',
|
||||
'SHIPMENT_CONFIRMED',
|
||||
'TUNNEL_ENTERED',
|
||||
'USAGE_RECORDED',
|
||||
'RETURN_REQUESTED',
|
||||
'RETURN_CONFIRMED'
|
||||
)
|
||||
);
|
||||
|
||||
-- 菜单:只提供隧道查询/新增/修改权限,不提供物理删除权限。
|
||||
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, update_by, update_time, remark
|
||||
)
|
||||
SELECT 520, '隧道资料', 121, 7, 'tunnel', 'master/tunnel/index', '', '',
|
||||
1, 0, 'C', '0', '0', 'master:tunnel:list', '#', 'admin', SYSDATE(), '', NULL, '隧道资料菜单'
|
||||
WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE menu_id = 520);
|
||||
|
||||
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, update_by, update_time, remark
|
||||
)
|
||||
SELECT 1116, '隧道查询', 520, 1, '#', '', '', '',
|
||||
1, 0, 'F', '0', '0', 'master:tunnel:query', '#', 'admin', SYSDATE(), '', NULL, ''
|
||||
WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE menu_id = 1116);
|
||||
|
||||
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, update_by, update_time, remark
|
||||
)
|
||||
SELECT 1117, '隧道新增', 520, 2, '#', '', '', '',
|
||||
1, 0, 'F', '0', '0', 'master:tunnel:add', '#', 'admin', SYSDATE(), '', NULL, ''
|
||||
WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE menu_id = 1117);
|
||||
|
||||
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, update_by, update_time, remark
|
||||
)
|
||||
SELECT 1118, '隧道修改', 520, 3, '#', '', '', '',
|
||||
1, 0, 'F', '0', '0', 'master:tunnel:edit', '#', 'admin', SYSDATE(), '', NULL, ''
|
||||
WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE menu_id = 1118);
|
||||
|
||||
-- 重要:DDL 会隐式提交,不能依赖事务整体回滚;本文件未执行任何数据库操作。
|
||||
@@ -0,0 +1,10 @@
|
||||
-- 生产日期与有效期补齐;执行前备份,且仅执行一次。
|
||||
-- 历史日期保留 NULL,禁止使用装填/发货时间自动推算真实生产日期。
|
||||
-- 需在部署包含日期字段的新后端前执行;本文件不会由应用自动执行。
|
||||
ALTER TABLE biz_filling_record
|
||||
ADD COLUMN production_date DATE NULL COMMENT '来源生产日期;历史未登记为空' AFTER batch_no,
|
||||
ADD COLUMN expiry_date DATE NULL COMMENT '有效期至;历史未登记为空' AFTER production_date,
|
||||
ADD CONSTRAINT ck_biz_filling_record_material_dates CHECK (
|
||||
(production_date IS NULL AND expiry_date IS NULL) OR
|
||||
(production_date IS NOT NULL AND expiry_date IS NOT NULL AND expiry_date >= production_date)
|
||||
);
|
||||
@@ -0,0 +1,125 @@
|
||||
-- 发货收货核对:MySQL 8 单次增量迁移(最低 8.0.16,需强制执行 CHECK)。
|
||||
-- 执行顺序:20260922_test_data_batch_mysql.sql
|
||||
-- -> 20261005_tunnel_material_flow_mysql.sql
|
||||
-- -> 20261008_material_dates_mysql.sql -> 本脚本 -> 部署收货核对版本。
|
||||
-- 执行前必须停写(业务接口、后台任务、导入及其他写入来源),完成备份并验证可恢复。
|
||||
-- 由 DBA 审核后在明确选定的目标库单次执行;不得使用 --force 或遇错继续的 SQL 客户端模式。
|
||||
-- 本脚本仅随代码交付,不在应用启动时执行;本次开发未连接数据库、未运行 SQL。
|
||||
-- 警告:MySQL DDL 会隐式提交,下面的 ROLLBACK 仅能撤销 DML,不能整体回滚已完成的 DDL。
|
||||
-- 中途失败应保持停写,依据备份和已完成步骤人工恢复;禁止直接重跑或启动新旧应用。
|
||||
-- 旧 CONFIRMED 单只标 LEGACY;不迁移旧库存状态、不补扣库存、不造收货事件、不伪造收货时间。
|
||||
-- 正式数据与各测试批次采用相同历史标记规则;所有原 test_batch_id 保持不变。
|
||||
-- 权限只新增 sys_menu,不写 sys_role_menu;上线后由管理员按现场职责手动授权。
|
||||
|
||||
DELIMITER $$
|
||||
CREATE PROCEDURE migrate_shipment_receipt_20261008()
|
||||
BEGIN
|
||||
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
||||
BEGIN
|
||||
ROLLBACK;
|
||||
RESIGNAL;
|
||||
END;
|
||||
|
||||
-- 所有环境、前置结构、菜单冲突检查均先于业务表 DDL。
|
||||
IF DATABASE() IS NULL THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Select the target database before migration';
|
||||
END IF;
|
||||
IF SUBSTRING_INDEX(VERSION(), '.', 1) <> '8'
|
||||
OR (CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(VERSION(), '.', 2), '.', -1) AS UNSIGNED) = 0
|
||||
AND CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(VERSION(), '.', 3), '.', -1) AS UNSIGNED) < 16) THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'MySQL 8.0.16 or newer MySQL 8 is required';
|
||||
END IF;
|
||||
|
||||
IF (SELECT COUNT(*) FROM information_schema.tables
|
||||
WHERE table_schema = DATABASE() AND engine = 'InnoDB'
|
||||
AND table_name IN ('biz_shipment_order', 'biz_pallet_inventory', 'biz_pallet_event',
|
||||
'biz_filling_record', 'biz_tunnel', 'sys_menu', 'sys_role_menu', 'sys_user')) <> 8 THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Required InnoDB tables or tunnel migration are missing';
|
||||
END IF;
|
||||
IF (SELECT COUNT(*) FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND ((table_name = 'biz_filling_record' AND column_name IN ('production_date', 'expiry_date'))
|
||||
OR (table_name = 'biz_pallet_inventory' AND column_name IN ('tunnel_id', 'trace_no'))
|
||||
OR (table_name = 'biz_pallet_event'
|
||||
AND column_name IN ('before_tunnel_id', 'after_tunnel_id', 'trace_no', 'batch_no_snapshot')))) <> 8 THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Apply tunnel and material date migrations first';
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.check_constraints
|
||||
WHERE constraint_schema = DATABASE() AND constraint_name = 'ck_biz_filling_record_material_dates')
|
||||
OR NOT EXISTS (SELECT 1 FROM information_schema.check_constraints
|
||||
WHERE constraint_schema = DATABASE() AND constraint_name = 'ck_biz_pallet_event_event_type'
|
||||
AND UPPER(check_clause) LIKE '%TUNNEL_ENTERED%')
|
||||
OR NOT EXISTS (SELECT 1 FROM information_schema.check_constraints
|
||||
WHERE constraint_schema = DATABASE() AND constraint_name = 'ck_biz_pallet_inventory_flow_state') THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Required material date or flow CHECK constraints are missing';
|
||||
END IF;
|
||||
|
||||
-- 任何新增字段已存在均说明已执行或部分执行,禁止将已收货数据重新标成 LEGACY。
|
||||
IF EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND ((table_name = 'biz_shipment_order'
|
||||
AND column_name IN ('receipt_state', 'received_by', 'received_at',
|
||||
'receipt_idempotency_key', 'receipt_request_hash'))
|
||||
OR (table_name = 'biz_pallet_inventory' AND column_name = 'site_arrived_at'))) THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Receipt columns already exist; do not rerun this migration';
|
||||
END IF;
|
||||
IF EXISTS (SELECT 1 FROM sys_menu WHERE menu_id = 1119 OR perms = 'business:shipment:receive') THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Menu 1119 or shipment receive permission already exists';
|
||||
END IF;
|
||||
-- 避免已有孤立授权在插入 1119 时自动变成有效收货权限。
|
||||
IF EXISTS (SELECT 1 FROM sys_role_menu WHERE menu_id = 1119) THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Orphan role grants for menu 1119 must be reviewed first';
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM sys_menu WHERE menu_id = 510 AND perms = 'business:shipment:list'
|
||||
AND menu_type = 'C') THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Shipment parent menu 510 does not match the expected contract';
|
||||
END IF;
|
||||
|
||||
ALTER TABLE biz_shipment_order
|
||||
ADD COLUMN receipt_state VARCHAR(16) NOT NULL DEFAULT 'PENDING' COMMENT '收货状态;LEGACY表示历史未登记' AFTER confirmed_at,
|
||||
ADD COLUMN received_by BIGINT NULL COMMENT '收货核对人ID' AFTER receipt_state,
|
||||
ADD COLUMN received_at DATETIME NULL COMMENT '实际收货核对时间' AFTER received_by,
|
||||
ADD COLUMN receipt_idempotency_key VARCHAR(64) NULL COMMENT '收货确认幂等键' AFTER received_at,
|
||||
ADD COLUMN receipt_request_hash VARCHAR(64) NULL COMMENT '收货核对请求摘要' AFTER receipt_idempotency_key,
|
||||
ADD CONSTRAINT uq_biz_shipment_receipt_site_key UNIQUE (target_site_id, receipt_idempotency_key),
|
||||
ADD CONSTRAINT fk_biz_shipment_order_received_by FOREIGN KEY (received_by) REFERENCES sys_user (user_id),
|
||||
ADD CONSTRAINT ck_biz_shipment_order_receipt_state CHECK (receipt_state IN ('PENDING', 'RECEIVED', 'LEGACY'));
|
||||
|
||||
ALTER TABLE biz_pallet_inventory
|
||||
ADD COLUMN site_arrived_at DATETIME NULL COMMENT '本轮实际收货核对时间;历史未登记为空' AFTER remaining_packages,
|
||||
DROP CHECK ck_biz_pallet_inventory_flow_state,
|
||||
ADD CONSTRAINT ck_biz_pallet_inventory_flow_state CHECK (
|
||||
flow_state IN ('UNSTOCKED', 'EMPTY_IN_WAREHOUSE', 'FILLED_IN_WAREHOUSE', 'IN_TRANSIT',
|
||||
'AT_SITE_UNUSED', 'AT_SITE_PARTIAL', 'AT_SITE_EMPTY', 'RETURNING')
|
||||
);
|
||||
|
||||
ALTER TABLE biz_pallet_event
|
||||
DROP CHECK ck_biz_pallet_event_event_type,
|
||||
ADD CONSTRAINT ck_biz_pallet_event_event_type CHECK (
|
||||
event_type IN ('INBOUND_CONFIRMED', 'FILLING_CONFIRMED', 'SHIPMENT_CONFIRMED', 'SHIPMENT_RECEIVED',
|
||||
'TUNNEL_ENTERED', 'USAGE_RECORDED', 'RETURN_REQUESTED', 'RETURN_CONFIRMED')
|
||||
);
|
||||
|
||||
-- DDL 已隐式提交;以下事务只覆盖历史标记及权限菜单插入。
|
||||
START TRANSACTION;
|
||||
UPDATE biz_shipment_order SET receipt_state = 'LEGACY' WHERE status = 'CONFIRMED';
|
||||
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, update_by, update_time, remark
|
||||
) VALUES (
|
||||
1119, '收货核对', 510, 6, '', '', '', '',
|
||||
1, 0, 'F', '0', '0', 'business:shipment:receive', '#', 'admin',
|
||||
SYSDATE(), '', NULL, ''
|
||||
);
|
||||
COMMIT;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
CALL migrate_shipment_receipt_20261008();
|
||||
DROP PROCEDURE migrate_shipment_receipt_20261008;
|
||||
|
||||
-- 核验:历史确认单应为 LEGACY,新草稿为 PENDING,收货时间/人员和原库存保持未登记。
|
||||
SELECT status, receipt_state, COUNT(*) AS order_count
|
||||
FROM biz_shipment_order GROUP BY status, receipt_state;
|
||||
SELECT menu_id, parent_id, perms FROM sys_menu WHERE menu_id = 1119;
|
||||
@@ -0,0 +1,35 @@
|
||||
-- 允许跳过先到托盘,但需填写原因并保存当时的推荐快照。
|
||||
-- 在20261008日期、收货补丁之后执行;先停写、备份、恢复演练。
|
||||
-- 单次增量;不修改历史事实,不为旧记录补造原因或真实收货时间。
|
||||
-- DDL隐式提交,中途失败不得盲目重跑。
|
||||
DELIMITER $$
|
||||
CREATE PROCEDURE migrate_usage_fifo_20261008()
|
||||
BEGIN
|
||||
IF DATABASE() IS NULL THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Select target database first';
|
||||
END IF;
|
||||
IF (SELECT COUNT(*) FROM information_schema.tables
|
||||
WHERE table_schema = DATABASE() AND engine = 'InnoDB'
|
||||
AND table_name IN ('biz_usage_record', 'biz_pallet_event')) <> 2 THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Required InnoDB usage and event tables are missing';
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE() AND table_name = 'biz_pallet_inventory'
|
||||
AND column_name = 'site_arrived_at') THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Apply shipment receipt migration first';
|
||||
END IF;
|
||||
IF EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE() AND table_name IN ('biz_usage_record', 'biz_pallet_event')
|
||||
AND column_name IN ('fifo_skip_reason', 'fifo_recommendation')) THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'FIFO columns already exist; do not rerun';
|
||||
END IF;
|
||||
ALTER TABLE biz_usage_record
|
||||
ADD COLUMN fifo_skip_reason VARCHAR(500) NULL COMMENT '跳过先到托盘原因',
|
||||
ADD COLUMN fifo_recommendation JSON NULL COMMENT '跳过时先到托盘身份及到货时间快照';
|
||||
ALTER TABLE biz_pallet_event
|
||||
ADD COLUMN fifo_skip_reason VARCHAR(500) NULL COMMENT '跳过先到托盘原因',
|
||||
ADD COLUMN fifo_recommendation JSON NULL COMMENT '跳过时先到托盘身份及到货时间快照';
|
||||
END$$
|
||||
DELIMITER ;
|
||||
CALL migrate_usage_fifo_20261008();
|
||||
DROP PROCEDURE migrate_usage_fifo_20261008;
|
||||
Reference in New Issue
Block a user