337 lines
16 KiB
SQL
337 lines
16 KiB
SQL
-- PostgreSQL Database Schema for iMeeting (Multi-tenant)
|
|
-- 0 为系统预留租户 ID
|
|
|
|
-- ----------------------------
|
|
-- 0. 租户与组织
|
|
-- ----------------------------
|
|
|
|
-- 租户表
|
|
CREATE TABLE sys_tenant (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
tenant_code VARCHAR(64) NOT NULL UNIQUE,
|
|
tenant_name VARCHAR(128) NOT NULL,
|
|
status SMALLINT NOT NULL DEFAULT 1,
|
|
expire_time TIMESTAMP(6),
|
|
contact_name VARCHAR(64),
|
|
contact_phone VARCHAR(32),
|
|
remark VARCHAR(255),
|
|
created_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
is_deleted SMALLINT DEFAULT 0
|
|
);
|
|
CREATE UNIQUE INDEX uk_tenant_code ON sys_tenant (tenant_code) WHERE is_deleted = FALSE;
|
|
|
|
-- 组织架构表
|
|
DROP TABLE IF EXISTS sys_org CASCADE;
|
|
|
|
CREATE TABLE sys_org (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
tenant_id BIGINT NOT NULL,
|
|
parent_id BIGINT,
|
|
org_name VARCHAR(128) NOT NULL,
|
|
org_code VARCHAR(64),
|
|
org_path VARCHAR(512),
|
|
sort_order INTEGER DEFAULT 0,
|
|
status SMALLINT DEFAULT 1,
|
|
created_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
is_deleted SMALLINT DEFAULT 0,
|
|
CONSTRAINT fk_org_parent FOREIGN KEY (parent_id)
|
|
REFERENCES sys_org(id),
|
|
CONSTRAINT fk_org_tenant FOREIGN KEY (tenant_id)
|
|
REFERENCES sys_tenant(id)
|
|
);
|
|
|
|
CREATE INDEX idx_org_tenant ON sys_org (tenant_id);
|
|
|
|
-- ----------------------------
|
|
-- 1. 用户与角色
|
|
-- ----------------------------
|
|
|
|
-- 用户表
|
|
DROP TABLE IF EXISTS sys_user CASCADE;
|
|
|
|
CREATE TABLE sys_user (
|
|
user_id BIGSERIAL PRIMARY KEY,
|
|
username VARCHAR(50) NOT NULL UNIQUE,
|
|
display_name VARCHAR(50) NOT NULL,
|
|
email VARCHAR(100),
|
|
phone VARCHAR(30) UNIQUE,
|
|
password_hash VARCHAR(255) NOT NULL,
|
|
status SMALLINT NOT NULL DEFAULT 1,
|
|
is_deleted SMALLINT NOT NULL DEFAULT 0,
|
|
pwd_reset_required SMALLINT DEFAULT 1,
|
|
created_at TIMESTAMP(6) NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMP(6) NOT NULL DEFAULT now(),
|
|
is_platform_admin BOOLEAN DEFAULT false
|
|
);
|
|
CREATE UNIQUE INDEX uk_user_username ON sys_user (username) WHERE is_deleted = FALSE;
|
|
|
|
-- 角色表
|
|
DROP TABLE IF EXISTS sys_role CASCADE;
|
|
|
|
CREATE TABLE sys_role (
|
|
role_id BIGSERIAL PRIMARY KEY,
|
|
tenant_id BIGINT,
|
|
role_code VARCHAR(50) NOT NULL UNIQUE,
|
|
role_name VARCHAR(50) NOT NULL,
|
|
status SMALLINT NOT NULL DEFAULT 1,
|
|
remark TEXT,
|
|
is_deleted SMALLINT NOT NULL DEFAULT 0,
|
|
created_at TIMESTAMP(6) NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMP(6) NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX idx_sys_role_tenant ON sys_role (tenant_id);
|
|
CREATE UNIQUE INDEX uk_role_code ON sys_role (tenant_id, role_code) WHERE is_deleted = FALSE;
|
|
|
|
-- 用户-角色关联表 (无 tenant_id, 随 User/Role 隔离)
|
|
DROP TABLE IF EXISTS sys_user_role CASCADE;
|
|
|
|
CREATE TABLE sys_user_role (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
tenant_id BIGINT,
|
|
user_id BIGINT NOT NULL,
|
|
role_id BIGINT NOT NULL,
|
|
is_deleted SMALLINT NOT NULL DEFAULT 0,
|
|
created_at TIMESTAMP(6) NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMP(6) NOT NULL DEFAULT now(),
|
|
UNIQUE (user_id, role_id)
|
|
);
|
|
|
|
-- ----------------------------
|
|
-- 2. 权限/字典/参数 (全局共享, 无 tenant_id)
|
|
-- ----------------------------
|
|
|
|
DROP TABLE IF EXISTS sys_permission CASCADE;
|
|
|
|
CREATE TABLE sys_permission (
|
|
perm_id BIGSERIAL PRIMARY KEY,
|
|
parent_id BIGINT,
|
|
name VARCHAR(100) NOT NULL,
|
|
code VARCHAR(100) NOT NULL UNIQUE,
|
|
perm_type VARCHAR(20) NOT NULL,
|
|
level INTEGER NOT NULL,
|
|
path VARCHAR(255),
|
|
component VARCHAR(255),
|
|
icon VARCHAR(100),
|
|
sort_order INTEGER NOT NULL DEFAULT 0,
|
|
is_visible SMALLINT NOT NULL DEFAULT 1,
|
|
status SMALLINT NOT NULL DEFAULT 1,
|
|
description TEXT,
|
|
meta JSONB,
|
|
is_deleted SMALLINT NOT NULL DEFAULT 0,
|
|
created_at TIMESTAMP(6) NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMP(6) NOT NULL DEFAULT now()
|
|
);
|
|
|
|
DROP TABLE IF EXISTS sys_tenant_user CASCADE;
|
|
|
|
CREATE TABLE sys_tenant_user (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
user_id BIGINT NOT NULL,
|
|
tenant_id BIGINT NOT NULL,
|
|
org_id BIGINT,
|
|
status SMALLINT DEFAULT 1,
|
|
is_deleted SMALLINT DEFAULT 0,
|
|
created_at TIMESTAMP(6) NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMP(6) NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE UNIQUE INDEX uk_tenant_user
|
|
ON sys_tenant_user (user_id, tenant_id)
|
|
WHERE is_deleted = 0;
|
|
CREATE TABLE sys_dict_type (
|
|
dict_type_id BIGSERIAL PRIMARY KEY,
|
|
type_code VARCHAR(50) UNIQUE NOT NULL,
|
|
type_name VARCHAR(50) NOT NULL,
|
|
status SMALLINT DEFAULT 1,
|
|
remark TEXT,
|
|
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
is_deleted SMALLINT DEFAULT 0
|
|
);
|
|
|
|
CREATE TABLE sys_dict_item (
|
|
dict_item_id BIGSERIAL PRIMARY KEY,
|
|
type_code VARCHAR(50) NOT NULL,
|
|
item_label VARCHAR(100) NOT NULL,
|
|
item_value VARCHAR(100) NOT NULL,
|
|
sort_order INT DEFAULT 0,
|
|
status SMALLINT DEFAULT 1,
|
|
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
is_deleted SMALLINT DEFAULT 0
|
|
);
|
|
CREATE INDEX idx_dict_item_type ON sys_dict_item (type_code);
|
|
CREATE UNIQUE INDEX uk_dict_item_value ON sys_dict_item (type_code, item_value);
|
|
|
|
CREATE TABLE sys_param (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
param_key VARCHAR(100) UNIQUE NOT NULL,
|
|
param_value TEXT NOT NULL,
|
|
param_type VARCHAR(20) NOT NULL,
|
|
is_system SMALLINT DEFAULT 0,
|
|
status SMALLINT DEFAULT 1,
|
|
description TEXT,
|
|
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
is_deleted SMALLINT DEFAULT 0
|
|
);
|
|
|
|
-- ----------------------------
|
|
-- 3. 日志 (租户隔离)
|
|
-- ----------------------------
|
|
|
|
CREATE TABLE sys_log (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
tenant_id BIGINT NOT NULL DEFAULT 0,
|
|
user_id BIGINT,
|
|
username VARCHAR(50),
|
|
log_type VARCHAR(20), -- LOGIN, OPERATION
|
|
operation VARCHAR(100) NOT NULL,
|
|
method VARCHAR(200),
|
|
params TEXT,
|
|
status SMALLINT DEFAULT 1,
|
|
ip VARCHAR(50),
|
|
duration BIGINT,
|
|
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
|
);
|
|
CREATE INDEX idx_log_tenant_type ON sys_log (tenant_id, log_type, created_at);
|
|
|
|
-- ----------------------------
|
|
-- 4. 平台配置 (系统品牌化)
|
|
-- ----------------------------
|
|
DROP TABLE IF EXISTS sys_platform_config CASCADE;
|
|
CREATE TABLE sys_platform_config (
|
|
id BIGINT PRIMARY KEY, -- 固定为 1
|
|
project_name VARCHAR(128) NOT NULL,
|
|
logo_url VARCHAR(512),
|
|
icon_url VARCHAR(512),
|
|
login_bg_url VARCHAR(512),
|
|
icp_info VARCHAR(128),
|
|
copyright_info VARCHAR(255),
|
|
system_description TEXT,
|
|
created_at TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP,
|
|
is_deleted SMALLINT DEFAULT 0
|
|
);
|
|
|
|
INSERT INTO sys_platform_config (id, project_name, copyright_info)
|
|
VALUES (1, 'iMeeting 智能会议系统', '© 2026 iMeeting Team. All rights reserved.');
|
|
|
|
-- ----------------------------
|
|
-- 6. 业务模块 - 声纹管理
|
|
-- ----------------------------
|
|
DROP TABLE IF EXISTS biz_speakers CASCADE;
|
|
CREATE TABLE biz_speakers (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
user_id BIGINT NOT NULL, -- 关联系统用户ID
|
|
name VARCHAR(100) NOT NULL, -- 发言人姓名
|
|
voice_path VARCHAR(512), -- 原始声纹文件存储路径
|
|
voice_ext VARCHAR(10), -- 文件后缀
|
|
voice_size BIGINT, -- 文件大小
|
|
status SMALLINT DEFAULT 1, -- 状态: 1=已保存, 2=注册中, 3=已注册, 4=失败
|
|
embedding VECTOR(512), -- 声纹特征向量 (预留 pgvector 字段)
|
|
remark TEXT, -- 备注
|
|
created_at TIMESTAMP(6) NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMP(6) NOT NULL DEFAULT now(),
|
|
is_deleted SMALLINT NOT NULL DEFAULT 0
|
|
);
|
|
|
|
CREATE INDEX idx_speaker_user ON biz_speakers (user_id) WHERE is_deleted = 0;
|
|
|
|
COMMENT ON TABLE biz_speakers IS '声纹发言人基础信息表 (用户全局资源)';
|
|
|
|
-- ----------------------------
|
|
-- 7. 业务模块 - 热词管理
|
|
-- ----------------------------
|
|
DROP TABLE IF EXISTS biz_hot_words CASCADE;
|
|
CREATE TABLE biz_hot_words (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
tenant_id BIGINT NOT NULL, -- 租户ID (强制隔离)
|
|
word VARCHAR(100) NOT NULL, -- 热词原文
|
|
pinyin_list JSONB, -- 拼音数组 (支持多音字, 如 ["i mi ting", "i mei ting"])
|
|
match_strategy SMALLINT DEFAULT 1, -- 匹配策略: 1:精确匹配, 2:拼音模糊匹配
|
|
category VARCHAR(50), -- 类别 (人名、术语、地名)
|
|
weight INTEGER DEFAULT 10, -- 权重 (1-100)
|
|
status SMALLINT DEFAULT 1, -- 状态: 1:启用, 0:禁用
|
|
is_synced SMALLINT DEFAULT 0, -- 是否已同步至第三方引擎: 0:未同步, 1:已同步
|
|
remark TEXT, -- 备注
|
|
created_at TIMESTAMP(6) NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMP(6) NOT NULL DEFAULT now(),
|
|
is_deleted SMALLINT NOT NULL DEFAULT 0
|
|
);
|
|
|
|
CREATE INDEX idx_hotword_tenant ON biz_hot_words (tenant_id);
|
|
CREATE INDEX idx_hotword_word ON biz_hot_words (word) WHERE is_deleted = 0;
|
|
|
|
COMMENT ON TABLE biz_hot_words IS '语音识别热词表';
|
|
|
|
-- ----------------------------
|
|
-- 8. 业务模块 - 提示词模板
|
|
-- ----------------------------
|
|
DROP TABLE IF EXISTS biz_prompt_templates CASCADE;
|
|
CREATE TABLE biz_prompt_templates (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
tenant_id BIGINT NOT NULL DEFAULT 0, -- 租户ID (0为系统级)
|
|
template_name VARCHAR(100) NOT NULL, -- 模板名称
|
|
category VARCHAR(20), -- 分类 (字典: biz_prompt_category)
|
|
is_system SMALLINT DEFAULT 0, -- 是否系统预置 (1:是, 0:否)
|
|
prompt_content TEXT NOT NULL, -- 提示词内容
|
|
status SMALLINT DEFAULT 1, -- 状态: 1:启用, 0:禁用
|
|
remark VARCHAR(255), -- 备注
|
|
created_at TIMESTAMP(6) NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMP(6) NOT NULL DEFAULT now(),
|
|
is_deleted SMALLINT NOT NULL DEFAULT 0
|
|
);
|
|
|
|
CREATE INDEX idx_prompt_tenant ON biz_prompt_templates (tenant_id);
|
|
CREATE INDEX idx_prompt_system ON biz_prompt_templates (is_system) WHERE is_deleted = 0;
|
|
|
|
COMMENT ON TABLE biz_prompt_templates IS '会议总结提示词模板表';
|
|
|
|
-- ----------------------------
|
|
-- 5. 基础初始化数据
|
|
-- ----------------------------
|
|
|
|
-- 字典初始化数据
|
|
-- sys_common_status
|
|
INSERT INTO sys_dict_type (type_code, type_name, remark) VALUES ('sys_common_status', '通用状态', '0=禁用, 1=启用');
|
|
INSERT INTO sys_dict_item (type_code, item_label, item_value, sort_order) VALUES ('sys_common_status', '启用', '1', 1);
|
|
INSERT INTO sys_dict_item (type_code, item_label, item_value, sort_order) VALUES ('sys_common_status', '禁用', '0', 2);
|
|
|
|
-- sys_permission_type
|
|
INSERT INTO sys_dict_type (type_code, type_name, remark) VALUES ('sys_permission_type', '权限类型', 'directory=目录, menu=菜单, button=按钮');
|
|
INSERT INTO sys_dict_item (type_code, item_label, item_value, sort_order) VALUES ('sys_permission_type', '目录', 'directory', 1);
|
|
INSERT INTO sys_dict_item (type_code, item_label, item_value, sort_order) VALUES ('sys_permission_type', '菜单', 'menu', 2);
|
|
INSERT INTO sys_dict_item (type_code, item_label, item_value, sort_order) VALUES ('sys_permission_type', '按钮', 'button', 3);
|
|
|
|
-- sys_common_visibility
|
|
INSERT INTO sys_dict_type (type_code, type_name, remark) VALUES ('sys_common_visibility', '可见性', '0=隐藏, 1=显示');
|
|
INSERT INTO sys_dict_item (type_code, item_label, item_value, sort_order) VALUES ('sys_common_visibility', '显示', '1', 1);
|
|
INSERT INTO sys_dict_item (type_code, item_label, item_value, sort_order) VALUES ('sys_common_visibility', '隐藏', '0', 2);
|
|
|
|
-- sys_permission_level
|
|
INSERT INTO sys_dict_type (type_code, type_name, remark) VALUES ('sys_permission_level', '权限层级', '1=一级入口, 2=二级子项, 3=三级按钮');
|
|
INSERT INTO sys_dict_item (type_code, item_label, item_value, sort_order) VALUES ('sys_permission_level', '一级入口', '1', 1);
|
|
INSERT INTO sys_dict_item (type_code, item_label, item_value, sort_order) VALUES ('sys_permission_level', '二级子项', '2', 2);
|
|
INSERT INTO sys_dict_item (type_code, item_label, item_value, sort_order) VALUES ('sys_permission_level', '三级按钮', '3', 3);
|
|
|
|
-- sys_log_type
|
|
INSERT INTO sys_dict_type (type_code, type_name, remark) VALUES ('sys_log_type', '日志类型', 'LOGIN=登录, OPERATION=操作');
|
|
INSERT INTO sys_dict_item (type_code, item_label, item_value, sort_order) VALUES ('sys_log_type', '登录', 'LOGIN', 1);
|
|
INSERT INTO sys_dict_item (type_code, item_label, item_value, sort_order) VALUES ('sys_log_type', '操作', 'OPERATION', 2);
|
|
|
|
-- sys_param_type
|
|
INSERT INTO sys_dict_type (type_code, type_name, remark) VALUES ('sys_param_type', '参数类型', 'String, Number, Boolean, JSON');
|
|
INSERT INTO sys_dict_item (type_code, item_label, item_value, sort_order) VALUES ('sys_param_type', 'String', 'String', 1);
|
|
INSERT INTO sys_dict_item (type_code, item_label, item_value, sort_order) VALUES ('sys_param_type', 'Number', 'Number', 2);
|
|
INSERT INTO sys_dict_item (type_code, item_label, item_value, sort_order) VALUES ('sys_param_type', 'Boolean', 'Boolean', 3);
|
|
INSERT INTO sys_dict_item (type_code, item_label, item_value, sort_order) VALUES ('sys_param_type', 'JSON', 'JSON', 4);
|
|
|
|
-- sys_log_status
|
|
INSERT INTO sys_dict_type (type_code, type_name, remark) VALUES ('sys_log_status', '操作状态', '1=成功, 0=失败');
|
|
INSERT INTO sys_dict_item (type_code, item_label, item_value, sort_order) VALUES ('sys_log_status', '成功', '1', 1);
|
|
INSERT INTO sys_dict_item (type_code, item_label, item_value, sort_order) VALUES ('sys_log_status', '失败', '0', 2);
|