619 lines
33 KiB
PL/PgSQL
619 lines
33 KiB
PL/PgSQL
-- ==============================================================================
|
|||
|
|
-- RailwaySystem QA Bootstrap: 02_training_v2_schema.sql (权威最终修复版)
|
||
|
|
-- 目标数据库: railwaysystem_fusion_qa_20261013 (schema: public)
|
||
|
|
-- 依据来源:
|
||
|
|
-- 1. 融合工程最新真实 Java 实体类 (TrainAccommodation, TrainEnrollment, TrainResource, etc.)
|
||
|
|
-- 2. 最新 MyBatis Mapper XML (TrainAccommodationMapper, TrainClassroomInfoMapper, etc.)
|
||
|
|
-- 3. 权威迁移与结构基线:
|
||
|
|
-- - sql/train/v2/rollback/000_phase05_exact_schema.sql
|
||
|
|
-- - sql/train/v2/002_create_new_tables.sql
|
||
|
|
-- - sql/train/v2/003_alter_master_tables.sql
|
||
|
|
-- - sql/train/v2/004_rebuild_business_tables.sql
|
||
|
|
-- - sql/train/v2/005_constraints.sql
|
||
|
|
-- 覆盖范围: 全部 23 张培训业务表、完整列定义、主外键、唯一约束与业务索引
|
||
|
|
-- 安全设计:
|
||
|
|
-- 1. 纯净 DDL: 杜绝 DROP TABLE / TRUNCATE / CTAS,采用 CREATE TABLE IF NOT EXISTS
|
||
|
|
-- 2. 外键统一使用 ON DELETE NO ACTION (杜绝 CASCADE)
|
||
|
|
-- 3. 修复 train_accommodation(enrollment_id) 全局唯一冲突,采用部分唯一索引支持退宿与重新入住
|
||
|
|
-- 4. 字段名严格对齐 Mapper SQL (如 accommodation_id, class_room_id, resource_id, student_id, weight, door_auth_id)
|
||
|
|
-- 5. 显式限定 search_path 至 public
|
||
|
|
-- ==============================================================================
|
||
|
|
|
||
|
|
BEGIN;
|
||
|
|
|
||
|
|
SET search_path TO public, pg_catalog, sys_catalog;
|
||
|
|
|
||
|
|
-- ==============================================================================
|
||
|
|
-- 第一部分: 培训主数据表 (8 张)
|
||
|
|
-- ==============================================================================
|
||
|
|
|
||
|
|
-- 1. 教师主档表 (包含 person_no 门禁人员编号)
|
||
|
|
CREATE TABLE IF NOT EXISTS public.train_teacher (
|
||
|
|
t_id VARCHAR(32) NOT NULL,
|
||
|
|
t_name VARCHAR(50) NOT NULL,
|
||
|
|
person_no VARCHAR(32),
|
||
|
|
t_gender CHAR(1),
|
||
|
|
t_birth DATE,
|
||
|
|
t_department VARCHAR(50),
|
||
|
|
org_name VARCHAR(100),
|
||
|
|
job_title VARCHAR(50),
|
||
|
|
t_title VARCHAR(30),
|
||
|
|
t_phone VARCHAR(20),
|
||
|
|
t_email VARCHAR(100),
|
||
|
|
user_id BIGINT,
|
||
|
|
avatar VARCHAR(255),
|
||
|
|
major VARCHAR(100),
|
||
|
|
courses VARCHAR(255),
|
||
|
|
start_teaching DATE,
|
||
|
|
status SMALLINT DEFAULT 1,
|
||
|
|
create_by VARCHAR(64),
|
||
|
|
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
update_by VARCHAR(64),
|
||
|
|
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
remark VARCHAR(500),
|
||
|
|
del_flag CHAR(1) NOT NULL DEFAULT '0',
|
||
|
|
CONSTRAINT pk_train_teacher PRIMARY KEY (t_id)
|
||
|
|
);
|
||
|
|
COMMENT ON TABLE public.train_teacher IS '教师主档表';
|
||
|
|
COMMENT ON COLUMN public.train_teacher.person_no IS '教师门禁/人脸人员编号 (对接 IoT 门禁系统)';
|
||
|
|
|
||
|
|
-- 2. 学员主档表 (包含 person_no, id_card_ciphertext, face_ref)
|
||
|
|
CREATE TABLE IF NOT EXISTS public.train_student (
|
||
|
|
s_id VARCHAR(32) NOT NULL,
|
||
|
|
s_name VARCHAR(50) NOT NULL,
|
||
|
|
person_no VARCHAR(32),
|
||
|
|
s_gender CHAR(1),
|
||
|
|
s_birth DATE,
|
||
|
|
org_name VARCHAR(100) NOT NULL,
|
||
|
|
s_phone VARCHAR(20),
|
||
|
|
s_email VARCHAR(100),
|
||
|
|
id_card_ciphertext TEXT,
|
||
|
|
id_card_hash VARCHAR(128),
|
||
|
|
id_card_last4 CHAR(4),
|
||
|
|
face_ref VARCHAR(255),
|
||
|
|
source_type SMALLINT NOT NULL DEFAULT 1,
|
||
|
|
user_id BIGINT,
|
||
|
|
avatar VARCHAR(255),
|
||
|
|
duty_level VARCHAR(64),
|
||
|
|
status SMALLINT NOT NULL DEFAULT 1,
|
||
|
|
create_by VARCHAR(64),
|
||
|
|
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
update_by VARCHAR(64),
|
||
|
|
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
remark VARCHAR(500),
|
||
|
|
del_flag CHAR(1) NOT NULL DEFAULT '0',
|
||
|
|
CONSTRAINT pk_train_student PRIMARY KEY (s_id)
|
||
|
|
);
|
||
|
|
COMMENT ON TABLE public.train_student IS '学员主档表';
|
||
|
|
COMMENT ON COLUMN public.train_student.person_no IS '学员门禁/人脸人员编号 (对接 IoT 门禁系统,如 AA000001)';
|
||
|
|
COMMENT ON COLUMN public.train_student.id_card_ciphertext IS '身份证号加密密文';
|
||
|
|
COMMENT ON COLUMN public.train_student.face_ref IS '人脸特征或图片引用路径';
|
||
|
|
|
||
|
|
-- 3. 课程主表 (包含 resource_id 关联教学资源)
|
||
|
|
CREATE TABLE IF NOT EXISTS public.train_course (
|
||
|
|
c_id VARCHAR(32) NOT NULL,
|
||
|
|
c_name VARCHAR(100) NOT NULL,
|
||
|
|
c_code VARCHAR(50),
|
||
|
|
c_type SMALLINT,
|
||
|
|
c_duration INTEGER,
|
||
|
|
teaching_objective TEXT,
|
||
|
|
course_content TEXT,
|
||
|
|
resource_id VARCHAR(32),
|
||
|
|
status SMALLINT NOT NULL DEFAULT 1,
|
||
|
|
create_by VARCHAR(64),
|
||
|
|
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
update_by VARCHAR(64),
|
||
|
|
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
remark VARCHAR(500),
|
||
|
|
del_flag CHAR(1) NOT NULL DEFAULT '0',
|
||
|
|
CONSTRAINT pk_train_course PRIMARY KEY (c_id)
|
||
|
|
);
|
||
|
|
COMMENT ON TABLE public.train_course IS '课程标准库主表';
|
||
|
|
|
||
|
|
-- 4. 教室信息表 (主键 class_room_id 严格对齐 Mapper 与 Phase 0.5 基线)
|
||
|
|
CREATE TABLE IF NOT EXISTS public.train_classroom_info (
|
||
|
|
class_room_id VARCHAR(32) NOT NULL,
|
||
|
|
room_name VARCHAR(50) NOT NULL,
|
||
|
|
room_location VARCHAR(100),
|
||
|
|
capacity INTEGER NOT NULL DEFAULT 30,
|
||
|
|
seat_arrange VARCHAR(100),
|
||
|
|
multimedia SMALLINT DEFAULT 0,
|
||
|
|
projector SMALLINT DEFAULT 0,
|
||
|
|
room_status SMALLINT NOT NULL DEFAULT 1,
|
||
|
|
create_by VARCHAR(64),
|
||
|
|
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
update_by VARCHAR(64),
|
||
|
|
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
remark VARCHAR(500),
|
||
|
|
del_flag CHAR(1) NOT NULL DEFAULT '0',
|
||
|
|
CONSTRAINT pk_train_classroom_info PRIMARY KEY (class_room_id),
|
||
|
|
CONSTRAINT ck_classroom_capacity CHECK (capacity > 0)
|
||
|
|
);
|
||
|
|
COMMENT ON TABLE public.train_classroom_info IS '教室信息表';
|
||
|
|
COMMENT ON COLUMN public.train_classroom_info.class_room_id IS '教室唯一ID (对齐 TrainClassroomInfoMapper)';
|
||
|
|
|
||
|
|
-- 5. 实训场地信息表
|
||
|
|
CREATE TABLE IF NOT EXISTS public.train_training_site (
|
||
|
|
site_id VARCHAR(32) NOT NULL,
|
||
|
|
site_name VARCHAR(50) NOT NULL,
|
||
|
|
site_location VARCHAR(100),
|
||
|
|
capacity INTEGER NOT NULL DEFAULT 20,
|
||
|
|
site_device VARCHAR(200),
|
||
|
|
major VARCHAR(100),
|
||
|
|
seat_arrange VARCHAR(100),
|
||
|
|
site_status SMALLINT NOT NULL DEFAULT 1,
|
||
|
|
create_by VARCHAR(64),
|
||
|
|
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
update_by VARCHAR(64),
|
||
|
|
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
remark VARCHAR(500),
|
||
|
|
del_flag CHAR(1) NOT NULL DEFAULT '0',
|
||
|
|
CONSTRAINT pk_train_training_site PRIMARY KEY (site_id),
|
||
|
|
CONSTRAINT ck_site_capacity CHECK (capacity > 0)
|
||
|
|
);
|
||
|
|
COMMENT ON TABLE public.train_training_site IS '实训场地信息表';
|
||
|
|
|
||
|
|
-- 6. 电子班牌终端表 (包含 api_endpoint)
|
||
|
|
CREATE TABLE IF NOT EXISTS public.train_electronic_board (
|
||
|
|
board_id VARCHAR(32) NOT NULL,
|
||
|
|
board_sn VARCHAR(50) NOT NULL,
|
||
|
|
board_name VARCHAR(50) NOT NULL,
|
||
|
|
bind_classroom_id VARCHAR(32),
|
||
|
|
board_ip VARCHAR(40),
|
||
|
|
api_endpoint VARCHAR(255),
|
||
|
|
support_checkin_type VARCHAR(100),
|
||
|
|
board_status SMALLINT NOT NULL DEFAULT 1,
|
||
|
|
last_heartbeat TIMESTAMP,
|
||
|
|
create_by VARCHAR(64),
|
||
|
|
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
update_by VARCHAR(64),
|
||
|
|
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
remark VARCHAR(500),
|
||
|
|
del_flag CHAR(1) NOT NULL DEFAULT '0',
|
||
|
|
CONSTRAINT pk_train_electronic_board PRIMARY KEY (board_id)
|
||
|
|
);
|
||
|
|
COMMENT ON TABLE public.train_electronic_board IS '电子班牌终端表';
|
||
|
|
|
||
|
|
-- 7. 宿舍房间信息表 (包含 lock_device_sn)
|
||
|
|
CREATE TABLE IF NOT EXISTS public.train_dormitory_info (
|
||
|
|
dorm_id VARCHAR(32) NOT NULL,
|
||
|
|
dorm_building VARCHAR(50) NOT NULL,
|
||
|
|
dorm_floor VARCHAR(20) NOT NULL,
|
||
|
|
dorm_room VARCHAR(20) NOT NULL,
|
||
|
|
capacity INTEGER NOT NULL DEFAULT 4,
|
||
|
|
gender_type SMALLINT NOT NULL DEFAULT 1,
|
||
|
|
dorm_status SMALLINT NOT NULL DEFAULT 1,
|
||
|
|
lock_device_sn VARCHAR(64),
|
||
|
|
create_by VARCHAR(64),
|
||
|
|
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
update_by VARCHAR(64),
|
||
|
|
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
remark VARCHAR(500),
|
||
|
|
del_flag CHAR(1) NOT NULL DEFAULT '0',
|
||
|
|
CONSTRAINT pk_train_dormitory_info PRIMARY KEY (dorm_id),
|
||
|
|
CONSTRAINT ck_dorm_capacity CHECK (capacity > 0),
|
||
|
|
CONSTRAINT ck_dorm_gender CHECK (gender_type IN (1, 2))
|
||
|
|
);
|
||
|
|
COMMENT ON TABLE public.train_dormitory_info IS '宿舍房间信息表';
|
||
|
|
|
||
|
|
-- 8. 培训班级计划表 (字段与 TrainClassPlanMapper 严格对齐)
|
||
|
|
CREATE TABLE IF NOT EXISTS public.train_class_plan (
|
||
|
|
plan_id VARCHAR(32) NOT NULL,
|
||
|
|
plan_name VARCHAR(100) NOT NULL,
|
||
|
|
start_time TIMESTAMP,
|
||
|
|
end_time TIMESTAMP,
|
||
|
|
report_deadline TIMESTAMP,
|
||
|
|
train_address VARCHAR(255),
|
||
|
|
recruit_num INTEGER DEFAULT 0,
|
||
|
|
apply_condition TEXT,
|
||
|
|
plan_status SMALLINT NOT NULL DEFAULT 0,
|
||
|
|
create_by VARCHAR(64),
|
||
|
|
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
update_by VARCHAR(64),
|
||
|
|
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
remark VARCHAR(500),
|
||
|
|
del_flag CHAR(1) NOT NULL DEFAULT '0',
|
||
|
|
CONSTRAINT pk_train_class_plan PRIMARY KEY (plan_id)
|
||
|
|
);
|
||
|
|
COMMENT ON TABLE public.train_class_plan IS '培训班级计划表';
|
||
|
|
|
||
|
|
|
||
|
|
-- ==============================================================================
|
||
|
|
-- 第二部分: 教学与参训业务表 (8 张)
|
||
|
|
-- ==============================================================================
|
||
|
|
|
||
|
|
-- 9. 统一教学资源主表 (主键 resource_id 严格对齐 TrainResourceMapper)
|
||
|
|
CREATE TABLE IF NOT EXISTS public.train_resource (
|
||
|
|
resource_id VARCHAR(32) NOT NULL,
|
||
|
|
resource_name VARCHAR(150) NOT NULL,
|
||
|
|
resource_type SMALLINT NOT NULL,
|
||
|
|
resource_url TEXT NOT NULL,
|
||
|
|
description TEXT,
|
||
|
|
status SMALLINT NOT NULL DEFAULT 1,
|
||
|
|
create_by VARCHAR(64),
|
||
|
|
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
update_by VARCHAR(64),
|
||
|
|
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
remark VARCHAR(500),
|
||
|
|
del_flag CHAR(1) NOT NULL DEFAULT '0',
|
||
|
|
CONSTRAINT pk_train_resource PRIMARY KEY (resource_id)
|
||
|
|
);
|
||
|
|
COMMENT ON TABLE public.train_resource IS '统一教学资源主表';
|
||
|
|
|
||
|
|
-- 10. 课程与教学资源关联表 (外键 resource_id 对齐 TrainCourseResourceMapper)
|
||
|
|
CREATE TABLE IF NOT EXISTS public.train_course_resource (
|
||
|
|
id BIGINT GENERATED BY DEFAULT AS IDENTITY,
|
||
|
|
c_id VARCHAR(32) NOT NULL,
|
||
|
|
resource_id VARCHAR(32) NOT NULL,
|
||
|
|
sort_no INTEGER DEFAULT 0,
|
||
|
|
create_by VARCHAR(64),
|
||
|
|
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
CONSTRAINT pk_train_course_resource PRIMARY KEY (id)
|
||
|
|
);
|
||
|
|
COMMENT ON TABLE public.train_course_resource IS '课程与教学资源关联表';
|
||
|
|
|
||
|
|
-- 11. 培训班与课程关联表 (主键 plan_course_id)
|
||
|
|
CREATE TABLE IF NOT EXISTS public.train_plan_course (
|
||
|
|
plan_course_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
|
||
|
|
plan_id VARCHAR(32) NOT NULL,
|
||
|
|
c_id VARCHAR(32) NOT NULL,
|
||
|
|
sort_no INTEGER DEFAULT 0,
|
||
|
|
create_by VARCHAR(64),
|
||
|
|
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
remark VARCHAR(500),
|
||
|
|
CONSTRAINT pk_train_plan_course PRIMARY KEY (plan_course_id)
|
||
|
|
);
|
||
|
|
COMMENT ON TABLE public.train_plan_course IS '培训班与课程关联表';
|
||
|
|
|
||
|
|
-- 12. 学员参训报名表 (外键 student_id 对齐 TrainEnrollmentMapper)
|
||
|
|
CREATE TABLE IF NOT EXISTS public.train_enrollment (
|
||
|
|
enrollment_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
|
||
|
|
plan_id VARCHAR(32) NOT NULL,
|
||
|
|
student_id VARCHAR(32) NOT NULL,
|
||
|
|
source_type SMALLINT NOT NULL DEFAULT 1,
|
||
|
|
enrollment_status SMALLINT NOT NULL DEFAULT 0,
|
||
|
|
accommodation_required SMALLINT NOT NULL DEFAULT 0,
|
||
|
|
join_time TIMESTAMP,
|
||
|
|
complete_time TIMESTAMP,
|
||
|
|
create_by VARCHAR(64),
|
||
|
|
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
update_by VARCHAR(64),
|
||
|
|
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
remark VARCHAR(500),
|
||
|
|
CONSTRAINT pk_train_enrollment PRIMARY KEY (enrollment_id)
|
||
|
|
);
|
||
|
|
COMMENT ON TABLE public.train_enrollment IS '学员参训报名档案表';
|
||
|
|
COMMENT ON COLUMN public.train_enrollment.student_id IS '学员ID (关联 train_student.s_id)';
|
||
|
|
|
||
|
|
-- 13. 宿舍住宿安排表 (主键 accommodation_id, accommodation_status, assigned_time)
|
||
|
|
-- 依据 sql/train/v2/002_create_new_tables.sql 行 136-156 与 TrainAccommodationMapper
|
||
|
|
CREATE TABLE IF NOT EXISTS public.train_accommodation (
|
||
|
|
accommodation_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
|
||
|
|
enrollment_id BIGINT NOT NULL,
|
||
|
|
dorm_id VARCHAR(32) NOT NULL,
|
||
|
|
bed_no VARCHAR(20),
|
||
|
|
assigned_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
accommodation_status SMALLINT NOT NULL DEFAULT 0,
|
||
|
|
create_by VARCHAR(64),
|
||
|
|
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
update_by VARCHAR(64),
|
||
|
|
update_time TIMESTAMP,
|
||
|
|
remark VARCHAR(500),
|
||
|
|
CONSTRAINT pk_train_accommodation PRIMARY KEY (accommodation_id)
|
||
|
|
);
|
||
|
|
COMMENT ON TABLE public.train_accommodation IS '宿舍住宿安排记录表';
|
||
|
|
COMMENT ON COLUMN public.train_accommodation.accommodation_id IS '住宿安排ID (自增主键)';
|
||
|
|
COMMENT ON COLUMN public.train_accommodation.accommodation_status IS '住宿状态 (0:预分配, 1:已入住, 2:已退宿)';
|
||
|
|
|
||
|
|
-- 14. 培训课表排课记录表 (外键关联 plan_course_id, class_room_id)
|
||
|
|
CREATE TABLE IF NOT EXISTS public.train_lesson (
|
||
|
|
lesson_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
|
||
|
|
plan_course_id BIGINT NOT NULL,
|
||
|
|
t_id VARCHAR(32) NOT NULL,
|
||
|
|
start_time TIMESTAMP NOT NULL,
|
||
|
|
end_time TIMESTAMP NOT NULL,
|
||
|
|
venue_type SMALLINT NOT NULL,
|
||
|
|
class_room_id VARCHAR(32),
|
||
|
|
site_id VARCHAR(32),
|
||
|
|
create_by VARCHAR(64),
|
||
|
|
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
update_by VARCHAR(64),
|
||
|
|
update_time TIMESTAMP,
|
||
|
|
remark VARCHAR(500),
|
||
|
|
CONSTRAINT pk_train_lesson PRIMARY KEY (lesson_id),
|
||
|
|
CONSTRAINT ck_lesson_time CHECK (end_time > start_time),
|
||
|
|
CONSTRAINT ck_lesson_venue CHECK (
|
||
|
|
(venue_type = 1 AND class_room_id IS NOT NULL AND site_id IS NULL) OR
|
||
|
|
(venue_type = 2 AND site_id IS NOT NULL AND class_room_id IS NULL)
|
||
|
|
)
|
||
|
|
);
|
||
|
|
COMMENT ON TABLE public.train_lesson IS '培训课表排课记录表';
|
||
|
|
|
||
|
|
-- 15. 课程考核分项配置表 (列名 weight, score_item_id 对齐 002 及 TrainScoreInfoMapper)
|
||
|
|
CREATE TABLE IF NOT EXISTS public.train_score_item (
|
||
|
|
score_item_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
|
||
|
|
plan_id VARCHAR(32) NOT NULL,
|
||
|
|
plan_course_id BIGINT,
|
||
|
|
item_name VARCHAR(100) NOT NULL,
|
||
|
|
item_type SMALLINT NOT NULL DEFAULT 1,
|
||
|
|
weight NUMERIC(5,2) NOT NULL DEFAULT 0.00,
|
||
|
|
full_score NUMERIC(5,2) NOT NULL DEFAULT 100.00,
|
||
|
|
sort_no INTEGER DEFAULT 0,
|
||
|
|
create_by VARCHAR(64),
|
||
|
|
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
update_by VARCHAR(64),
|
||
|
|
update_time TIMESTAMP,
|
||
|
|
remark VARCHAR(500),
|
||
|
|
CONSTRAINT pk_train_score_item PRIMARY KEY (score_item_id),
|
||
|
|
CONSTRAINT ck_score_item_weight CHECK (weight >= 0.00 AND weight <= 100.00)
|
||
|
|
);
|
||
|
|
COMMENT ON TABLE public.train_score_item IS '课程考核分项配置表';
|
||
|
|
COMMENT ON COLUMN public.train_score_item.weight IS '所占综合权重百分比 (对齐 002_create_new_tables)';
|
||
|
|
|
||
|
|
-- 16. 学员考核成绩明细表 (关联 score_item_id, enrollment_id)
|
||
|
|
CREATE TABLE IF NOT EXISTS public.train_student_score (
|
||
|
|
score_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
|
||
|
|
enrollment_id BIGINT NOT NULL,
|
||
|
|
score_item_id BIGINT NOT NULL,
|
||
|
|
score NUMERIC(7,2) NOT NULL,
|
||
|
|
source_type SMALLINT NOT NULL DEFAULT 1,
|
||
|
|
source_system VARCHAR(100),
|
||
|
|
source_event_id VARCHAR(100),
|
||
|
|
import_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
create_by VARCHAR(64),
|
||
|
|
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
update_by VARCHAR(64),
|
||
|
|
update_time TIMESTAMP,
|
||
|
|
remark VARCHAR(500),
|
||
|
|
CONSTRAINT pk_train_student_score PRIMARY KEY (score_id),
|
||
|
|
CONSTRAINT ck_student_score_val CHECK (score >= 0.00)
|
||
|
|
);
|
||
|
|
COMMENT ON TABLE public.train_student_score IS '学员考核成绩明细表';
|
||
|
|
|
||
|
|
|
||
|
|
-- ==============================================================================
|
||
|
|
-- 第三部分: 业务过程扩展表 (5 张)
|
||
|
|
-- ==============================================================================
|
||
|
|
|
||
|
|
-- 17. 门禁授权同步过程表 (包含完整 DMS/物联桥接状态列)
|
||
|
|
CREATE TABLE IF NOT EXISTS public.train_dorm_auth (
|
||
|
|
auth_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
|
||
|
|
accommodation_id BIGINT NOT NULL,
|
||
|
|
auth_status VARCHAR(32) DEFAULT 'PENDING',
|
||
|
|
credential_type VARCHAR(32) DEFAULT 'FACE',
|
||
|
|
latest_operation_id BIGINT,
|
||
|
|
operation_version BIGINT DEFAULT 0,
|
||
|
|
auth_start TIMESTAMP,
|
||
|
|
auth_end TIMESTAMP,
|
||
|
|
face_sync_status SMALLINT NOT NULL DEFAULT 0,
|
||
|
|
retry_count INTEGER NOT NULL DEFAULT 0,
|
||
|
|
last_error VARCHAR(500),
|
||
|
|
external_auth_id VARCHAR(100),
|
||
|
|
last_sync_time TIMESTAMP,
|
||
|
|
create_by VARCHAR(64),
|
||
|
|
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
update_by VARCHAR(64),
|
||
|
|
update_time TIMESTAMP,
|
||
|
|
remark VARCHAR(500),
|
||
|
|
CONSTRAINT pk_train_dorm_auth PRIMARY KEY (auth_id)
|
||
|
|
);
|
||
|
|
COMMENT ON TABLE public.train_dorm_auth IS '宿舍门禁授权同步过程表';
|
||
|
|
|
||
|
|
-- 18. 班级报到记录表
|
||
|
|
CREATE TABLE IF NOT EXISTS public.train_class_report (
|
||
|
|
report_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
|
||
|
|
enrollment_id BIGINT NOT NULL,
|
||
|
|
report_way SMALLINT NOT NULL DEFAULT 1,
|
||
|
|
report_device_sn VARCHAR(64),
|
||
|
|
report_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
verify_result SMALLINT NOT NULL DEFAULT 1,
|
||
|
|
verify_note VARCHAR(500),
|
||
|
|
create_by VARCHAR(64),
|
||
|
|
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
remark VARCHAR(500),
|
||
|
|
CONSTRAINT pk_train_class_report PRIMARY KEY (report_id)
|
||
|
|
);
|
||
|
|
COMMENT ON TABLE public.train_class_report IS '班级报到记录表';
|
||
|
|
|
||
|
|
-- 19. 学员课次考勤打卡表
|
||
|
|
CREATE TABLE IF NOT EXISTS public.train_student_checkin (
|
||
|
|
checkin_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
|
||
|
|
enrollment_id BIGINT NOT NULL,
|
||
|
|
lesson_id BIGINT NOT NULL,
|
||
|
|
board_id VARCHAR(32),
|
||
|
|
checkin_way SMALLINT NOT NULL DEFAULT 1,
|
||
|
|
sign_in_time TIMESTAMP,
|
||
|
|
sign_out_time TIMESTAMP,
|
||
|
|
attendance_status SMALLINT NOT NULL DEFAULT 0,
|
||
|
|
manual_flag SMALLINT NOT NULL DEFAULT 0,
|
||
|
|
create_by VARCHAR(64),
|
||
|
|
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
update_by VARCHAR(64),
|
||
|
|
update_time TIMESTAMP,
|
||
|
|
remark VARCHAR(500),
|
||
|
|
CONSTRAINT pk_train_student_checkin PRIMARY KEY (checkin_id)
|
||
|
|
);
|
||
|
|
COMMENT ON TABLE public.train_student_checkin IS '学员课次考勤打卡记录表';
|
||
|
|
|
||
|
|
-- 20. 实际学习学时记录表 (主键 dur_id)
|
||
|
|
CREATE TABLE IF NOT EXISTS public.train_study_duration (
|
||
|
|
dur_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
|
||
|
|
enrollment_id BIGINT NOT NULL,
|
||
|
|
plan_course_id BIGINT,
|
||
|
|
resource_id VARCHAR(32),
|
||
|
|
learning_content VARCHAR(200),
|
||
|
|
source_system VARCHAR(100),
|
||
|
|
source_event_id VARCHAR(100),
|
||
|
|
start_time TIMESTAMP,
|
||
|
|
end_time TIMESTAMP,
|
||
|
|
study_seconds INTEGER NOT NULL DEFAULT 0,
|
||
|
|
sync_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
create_by VARCHAR(64),
|
||
|
|
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
remark VARCHAR(500),
|
||
|
|
CONSTRAINT pk_train_study_duration PRIMARY KEY (dur_id),
|
||
|
|
CONSTRAINT ck_study_seconds CHECK (study_seconds >= 0)
|
||
|
|
);
|
||
|
|
COMMENT ON TABLE public.train_study_duration IS '实际学习学时记录表';
|
||
|
|
|
||
|
|
-- 21. 学员培训画像统计表
|
||
|
|
CREATE TABLE IF NOT EXISTS public.train_student_portrait (
|
||
|
|
portrait_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
|
||
|
|
enrollment_id BIGINT NOT NULL,
|
||
|
|
attendance_rate NUMERIC(5,2),
|
||
|
|
theory_score NUMERIC(7,2),
|
||
|
|
practical_score NUMERIC(7,2),
|
||
|
|
total_study_hour NUMERIC(8,2),
|
||
|
|
label_tag TEXT,
|
||
|
|
portrait_content TEXT,
|
||
|
|
generated_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
create_by VARCHAR(64),
|
||
|
|
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
update_by VARCHAR(64),
|
||
|
|
update_time TIMESTAMP,
|
||
|
|
remark VARCHAR(500),
|
||
|
|
CONSTRAINT pk_train_student_portrait PRIMARY KEY (portrait_id)
|
||
|
|
);
|
||
|
|
COMMENT ON TABLE public.train_student_portrait IS '学员培训画像综合统计表';
|
||
|
|
|
||
|
|
|
||
|
|
-- ==============================================================================
|
||
|
|
-- 第四部分: 外部资源对接与操作审计表 (2 张)
|
||
|
|
-- ==============================================================================
|
||
|
|
|
||
|
|
-- 22. 外部资源映射关联表 (DMS 适配支持)
|
||
|
|
CREATE TABLE IF NOT EXISTS public.train_external_resource_mapping (
|
||
|
|
mapping_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
|
||
|
|
dorm_id VARCHAR(32) NOT NULL,
|
||
|
|
vendor_code VARCHAR(32) NOT NULL,
|
||
|
|
local_resource_type VARCHAR(32) NOT NULL,
|
||
|
|
external_resource_type VARCHAR(32) NOT NULL,
|
||
|
|
external_resource_id VARCHAR(64) NOT NULL,
|
||
|
|
external_parent_id VARCHAR(64),
|
||
|
|
external_hardware_id VARCHAR(64),
|
||
|
|
external_project_id VARCHAR(64),
|
||
|
|
is_primary SMALLINT NOT NULL DEFAULT 1,
|
||
|
|
mapping_status VARCHAR(32) NOT NULL DEFAULT 'ACTIVE',
|
||
|
|
last_sync_time TIMESTAMP,
|
||
|
|
create_by VARCHAR(64),
|
||
|
|
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
update_by VARCHAR(64),
|
||
|
|
update_time TIMESTAMP,
|
||
|
|
remark VARCHAR(500),
|
||
|
|
CONSTRAINT pk_train_ext_res_map PRIMARY KEY (mapping_id)
|
||
|
|
);
|
||
|
|
COMMENT ON TABLE public.train_external_resource_mapping IS '外部资源映射关联表';
|
||
|
|
|
||
|
|
-- 23. 外部对接操作流水与补偿表 (列名 door_auth_id, business_type 严格对齐 Mapper)
|
||
|
|
CREATE TABLE IF NOT EXISTS public.train_external_operation (
|
||
|
|
operation_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
|
||
|
|
door_auth_id BIGINT,
|
||
|
|
business_type VARCHAR(32) NOT NULL,
|
||
|
|
vendor_code VARCHAR(32) NOT NULL,
|
||
|
|
operation_type VARCHAR(32) NOT NULL,
|
||
|
|
operation_status VARCHAR(32) NOT NULL DEFAULT 'PENDING',
|
||
|
|
idempotency_key VARCHAR(64) NOT NULL,
|
||
|
|
external_operation_id VARCHAR(64),
|
||
|
|
external_request_type VARCHAR(64),
|
||
|
|
external_hardware_id VARCHAR(64),
|
||
|
|
external_key_id VARCHAR(64),
|
||
|
|
attempt_count INTEGER NOT NULL DEFAULT 0,
|
||
|
|
next_poll_time TIMESTAMP,
|
||
|
|
requested_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
completed_at TIMESTAMP,
|
||
|
|
last_error_code VARCHAR(64),
|
||
|
|
last_error_message VARCHAR(500),
|
||
|
|
create_by VARCHAR(64),
|
||
|
|
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
update_by VARCHAR(64),
|
||
|
|
update_time TIMESTAMP,
|
||
|
|
remark VARCHAR(500),
|
||
|
|
CONSTRAINT pk_train_external_operation PRIMARY KEY (operation_id)
|
||
|
|
);
|
||
|
|
COMMENT ON TABLE public.train_external_operation IS '外部对接操作流水与补偿表';
|
||
|
|
COMMENT ON COLUMN public.train_external_operation.door_auth_id IS '门锁授权ID (对齐 TrainExternalOperationMapper)';
|
||
|
|
COMMENT ON COLUMN public.train_external_operation.business_type IS '业务类型 (对齐 TrainExternalOperationMapper)';
|
||
|
|
|
||
|
|
|
||
|
|
-- ==============================================================================
|
||
|
|
-- 第五部分: 唯一约束 (UNIQUE)
|
||
|
|
-- ==============================================================================
|
||
|
|
ALTER TABLE public.train_student ADD CONSTRAINT uq_student_idcard_hash UNIQUE (id_card_hash);
|
||
|
|
CREATE UNIQUE INDEX IF NOT EXISTS uq_student_person_no ON public.train_student (person_no) WHERE person_no IS NOT NULL AND del_flag = '0';
|
||
|
|
CREATE UNIQUE INDEX IF NOT EXISTS uq_teacher_person_no ON public.train_teacher (person_no) WHERE person_no IS NOT NULL AND del_flag = '0';
|
||
|
|
ALTER TABLE public.train_course ADD CONSTRAINT uq_course_code UNIQUE (c_code);
|
||
|
|
ALTER TABLE public.train_electronic_board ADD CONSTRAINT uq_board_sn UNIQUE (board_sn);
|
||
|
|
ALTER TABLE public.train_dormitory_info ADD CONSTRAINT uq_dorm_building_room UNIQUE (dorm_building, dorm_room);
|
||
|
|
ALTER TABLE public.train_course_resource ADD CONSTRAINT uq_course_resource UNIQUE (c_id, resource_id);
|
||
|
|
ALTER TABLE public.train_plan_course ADD CONSTRAINT uq_plan_course UNIQUE (plan_id, c_id);
|
||
|
|
ALTER TABLE public.train_enrollment ADD CONSTRAINT uq_enrollment UNIQUE (plan_id, student_id);
|
||
|
|
|
||
|
|
-- 【核心修复】废弃硬性全局 UNIQUE(enrollment_id),使用部分唯一索引保障:同一参训档案至多拥有1条激活中住宿(0预分配或1入住),同时支持历史退宿与重新入住
|
||
|
|
CREATE UNIQUE INDEX IF NOT EXISTS uq_accommodation_active_enroll
|
||
|
|
ON public.train_accommodation (enrollment_id)
|
||
|
|
WHERE accommodation_status IN (0, 1);
|
||
|
|
|
||
|
|
ALTER TABLE public.train_dorm_auth ADD CONSTRAINT uq_dorm_auth_accomm UNIQUE (accommodation_id);
|
||
|
|
ALTER TABLE public.train_class_report ADD CONSTRAINT uq_class_report_enroll UNIQUE (enrollment_id);
|
||
|
|
ALTER TABLE public.train_student_checkin ADD CONSTRAINT uq_student_checkin_enroll_lesson UNIQUE (enrollment_id, lesson_id);
|
||
|
|
CREATE UNIQUE INDEX IF NOT EXISTS uq_study_duration_idempotent ON public.train_study_duration (source_system, source_event_id) WHERE source_system IS NOT NULL AND source_event_id IS NOT NULL;
|
||
|
|
ALTER TABLE public.train_student_portrait ADD CONSTRAINT uq_student_portrait_enroll UNIQUE (enrollment_id);
|
||
|
|
CREATE UNIQUE INDEX IF NOT EXISTS uq_ext_res_map_vendor_dorm ON public.train_external_resource_mapping (vendor_code, dorm_id);
|
||
|
|
CREATE UNIQUE INDEX IF NOT EXISTS uq_ext_op_idempotency ON public.train_external_operation (idempotency_key);
|
||
|
|
|
||
|
|
|
||
|
|
-- ==============================================================================
|
||
|
|
-- 第六部分: 外键约束 (FOREIGN KEY - ON DELETE NO ACTION)
|
||
|
|
-- ==============================================================================
|
||
|
|
ALTER TABLE public.train_course_resource ADD CONSTRAINT fk_cr_course FOREIGN KEY (c_id) REFERENCES public.train_course(c_id) ON DELETE NO ACTION;
|
||
|
|
ALTER TABLE public.train_course_resource ADD CONSTRAINT fk_cr_resource FOREIGN KEY (resource_id) REFERENCES public.train_resource(resource_id) ON DELETE NO ACTION;
|
||
|
|
|
||
|
|
ALTER TABLE public.train_plan_course ADD CONSTRAINT fk_pc_plan FOREIGN KEY (plan_id) REFERENCES public.train_class_plan(plan_id) ON DELETE NO ACTION;
|
||
|
|
ALTER TABLE public.train_plan_course ADD CONSTRAINT fk_pc_course FOREIGN KEY (c_id) REFERENCES public.train_course(c_id) ON DELETE NO ACTION;
|
||
|
|
|
||
|
|
ALTER TABLE public.train_enrollment ADD CONSTRAINT fk_enroll_plan FOREIGN KEY (plan_id) REFERENCES public.train_class_plan(plan_id) ON DELETE NO ACTION;
|
||
|
|
ALTER TABLE public.train_enrollment ADD CONSTRAINT fk_enroll_student FOREIGN KEY (student_id) REFERENCES public.train_student(s_id) ON DELETE NO ACTION;
|
||
|
|
|
||
|
|
ALTER TABLE public.train_accommodation ADD CONSTRAINT fk_accomm_enroll FOREIGN KEY (enrollment_id) REFERENCES public.train_enrollment(enrollment_id) ON DELETE NO ACTION;
|
||
|
|
ALTER TABLE public.train_accommodation ADD CONSTRAINT fk_accomm_dorm FOREIGN KEY (dorm_id) REFERENCES public.train_dormitory_info(dorm_id) ON DELETE NO ACTION;
|
||
|
|
|
||
|
|
ALTER TABLE public.train_lesson ADD CONSTRAINT fk_lesson_pc FOREIGN KEY (plan_course_id) REFERENCES public.train_plan_course(plan_course_id) ON DELETE NO ACTION;
|
||
|
|
ALTER TABLE public.train_lesson ADD CONSTRAINT fk_lesson_teacher FOREIGN KEY (t_id) REFERENCES public.train_teacher(t_id) ON DELETE NO ACTION;
|
||
|
|
ALTER TABLE public.train_lesson ADD CONSTRAINT fk_lesson_classroom FOREIGN KEY (class_room_id) REFERENCES public.train_classroom_info(class_room_id) ON DELETE NO ACTION;
|
||
|
|
ALTER TABLE public.train_lesson ADD CONSTRAINT fk_lesson_site FOREIGN KEY (site_id) REFERENCES public.train_training_site(site_id) ON DELETE NO ACTION;
|
||
|
|
|
||
|
|
ALTER TABLE public.train_score_item ADD CONSTRAINT fk_si_plan FOREIGN KEY (plan_id) REFERENCES public.train_class_plan(plan_id) ON DELETE NO ACTION;
|
||
|
|
ALTER TABLE public.train_student_score ADD CONSTRAINT fk_ss_item FOREIGN KEY (score_item_id) REFERENCES public.train_score_item(score_item_id) ON DELETE NO ACTION;
|
||
|
|
ALTER TABLE public.train_student_score ADD CONSTRAINT fk_ss_enroll FOREIGN KEY (enrollment_id) REFERENCES public.train_enrollment(enrollment_id) ON DELETE NO ACTION;
|
||
|
|
|
||
|
|
ALTER TABLE public.train_dorm_auth ADD CONSTRAINT fk_da_accomm FOREIGN KEY (accommodation_id) REFERENCES public.train_accommodation(accommodation_id) ON DELETE NO ACTION;
|
||
|
|
ALTER TABLE public.train_class_report ADD CONSTRAINT fk_cr_enroll FOREIGN KEY (enrollment_id) REFERENCES public.train_enrollment(enrollment_id) ON DELETE NO ACTION;
|
||
|
|
ALTER TABLE public.train_student_checkin ADD CONSTRAINT fk_sci_enroll FOREIGN KEY (enrollment_id) REFERENCES public.train_enrollment(enrollment_id) ON DELETE NO ACTION;
|
||
|
|
ALTER TABLE public.train_student_checkin ADD CONSTRAINT fk_sci_lesson FOREIGN KEY (lesson_id) REFERENCES public.train_lesson(lesson_id) ON DELETE NO ACTION;
|
||
|
|
ALTER TABLE public.train_study_duration ADD CONSTRAINT fk_sd_enroll FOREIGN KEY (enrollment_id) REFERENCES public.train_enrollment(enrollment_id) ON DELETE NO ACTION;
|
||
|
|
ALTER TABLE public.train_student_portrait ADD CONSTRAINT fk_sp_enroll FOREIGN KEY (enrollment_id) REFERENCES public.train_enrollment(enrollment_id) ON DELETE NO ACTION;
|
||
|
|
|
||
|
|
ALTER TABLE public.train_external_resource_mapping ADD CONSTRAINT fk_erm_dorm FOREIGN KEY (dorm_id) REFERENCES public.train_dormitory_info(dorm_id) ON DELETE NO ACTION;
|
||
|
|
|
||
|
|
|
||
|
|
-- ==============================================================================
|
||
|
|
-- 第七部分: 业务索引 (INDEXES)
|
||
|
|
-- ==============================================================================
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_teacher_user_id ON public.train_teacher (user_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_teacher_person_no ON public.train_teacher (person_no);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_student_user_id ON public.train_student (user_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_student_person_no ON public.train_student (person_no);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_course_status ON public.train_course (status);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_dorm_gender ON public.train_dormitory_info (gender_type, dorm_status);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_dorm_lock_sn ON public.train_dormitory_info (lock_device_sn);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_class_plan_date ON public.train_class_plan (start_time, end_time);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_class_plan_status ON public.train_class_plan (plan_status);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_enrollment_plan ON public.train_enrollment (plan_id, enrollment_status);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_accommodation_dorm ON public.train_accommodation (dorm_id, accommodation_status);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_lesson_pc ON public.train_lesson (plan_course_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_lesson_teacher ON public.train_lesson (t_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_score_item_plan ON public.train_score_item (plan_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_student_score_enroll ON public.train_student_score (enrollment_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_dorm_auth_sync ON public.train_dorm_auth (face_sync_status, auth_status);
|
||
|
|
|
||
|
|
COMMIT;
|