SET NAMES utf8mb4; -- IAM 服务独占数据库:负责租户、成员、双端角色、菜单/页面/按钮/API权限和数据范围。 CREATE DATABASE IF NOT EXISTS baiyue_iam DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci; USE baiyue_iam; CREATE TABLE IF NOT EXISTS iam_tenant ( id BIGINT NOT NULL COMMENT '租户ID(雪花ID)', tenant_code VARCHAR(64) NOT NULL COMMENT '全局唯一租户编码', tenant_name VARCHAR(128) NOT NULL COMMENT '租户名称', tenant_type VARCHAR(20) NOT NULL DEFAULT 'MERCHANT' COMMENT '租户类型', status VARCHAR(20) NOT NULL DEFAULT 'PROFILE_REQUIRED' COMMENT '租户状态:PROFILE_REQUIRED、PENDING、ACTIVE、REJECTED、DISABLED', legal_name VARCHAR(128) NULL COMMENT '企业法定名称', unified_social_credit_code VARCHAR(32) NULL COMMENT '统一社会信用代码', contact_name VARCHAR(64) NULL COMMENT '企业联系人', contact_phone VARCHAR(32) NULL COMMENT '联系电话', contact_email VARCHAR(128) NULL COMMENT '联系邮箱', contact_wechat VARCHAR(64) NULL COMMENT '联系微信', sales_owner_name VARCHAR(64) NULL COMMENT '销售负责人姓名', payment_term_days SMALLINT UNSIGNED NULL COMMENT '账期天数', enterprise_type VARCHAR(64) NULL COMMENT '企业类型', established_date DATE NULL COMMENT '成立日期', registered_capital DECIMAL(18,2) NULL COMMENT '注册资本', registered_capital_currency CHAR(3) NULL COMMENT '注册资本币种 ISO 4217', registered_address VARCHAR(500) NULL COMMENT '注册地址文本', internal_remark VARCHAR(1000) NULL COMMENT '平台内部备注', approved_at DATETIME(3) NULL COMMENT '审核通过时间', approved_by BIGINT NULL COMMENT '审核人ID', reject_reason VARCHAR(500) NULL COMMENT '驳回原因', created_by BIGINT NULL COMMENT '创建人ID', created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', updated_by BIGINT NULL COMMENT '最后修改人ID', updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间', deleted TINYINT NOT NULL DEFAULT 0 COMMENT '逻辑删除标记', version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号', PRIMARY KEY (id), UNIQUE KEY uk_iam_tenant_code (tenant_code), UNIQUE KEY uk_iam_tenant_credit (unified_social_credit_code), KEY idx_iam_tenant_status (status, created_at) ) ENGINE=InnoDB COMMENT='企业租户主表:作为SaaS数据隔离边界,保存商户企业资料、审核结果和启停状态'; CREATE TABLE IF NOT EXISTS iam_tenant_review ( id BIGINT NOT NULL COMMENT '审核记录ID', tenant_id BIGINT NOT NULL COMMENT '被审核租户ID', review_type VARCHAR(20) NOT NULL DEFAULT 'REGISTER' COMMENT '审核类型', status VARCHAR(20) NOT NULL DEFAULT 'PENDING' COMMENT '审核状态', reviewer_id BIGINT NULL COMMENT '审核人ID', review_comment VARCHAR(500) NULL COMMENT '审核意见', reviewed_at DATETIME(3) NULL COMMENT '审核完成时间', created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '进入审核队列时间', PRIMARY KEY (id), KEY idx_review_queue (status, created_at), KEY idx_review_tenant (tenant_id) ) ENGINE=InnoDB COMMENT='租户审核记录表:保存企业注册、资料变更等审核过程和审核意见'; CREATE TABLE IF NOT EXISTS iam_tenant_address ( id BIGINT NOT NULL COMMENT '租户地址ID', tenant_id BIGINT NOT NULL COMMENT '所属租户ID', address_type VARCHAR(20) NOT NULL COMMENT '地址类型', country_code CHAR(2) NOT NULL DEFAULT 'CN' COMMENT '国家二字码', province VARCHAR(64) NULL COMMENT '省/州', city VARCHAR(64) NULL COMMENT '城市', district VARCHAR(64) NULL COMMENT '区县', detail VARCHAR(255) NOT NULL COMMENT '详细地址', postal_code VARCHAR(16) NULL COMMENT '邮政编码', is_default TINYINT NOT NULL DEFAULT 0 COMMENT '是否默认地址', created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间', deleted TINYINT NOT NULL DEFAULT 0 COMMENT '逻辑删除标记', PRIMARY KEY (id), KEY idx_address_tenant (tenant_id, address_type) ) ENGINE=InnoDB COMMENT='租户地址表:保存企业注册地址、办公地址等租户级资料'; CREATE TABLE IF NOT EXISTS iam_tenant_qualification ( id BIGINT NOT NULL COMMENT '资质记录ID', tenant_id BIGINT NOT NULL COMMENT '所属租户ID', qualification_type VARCHAR(32) NOT NULL COMMENT '资质类型', certificate_no VARCHAR(128) NULL COMMENT '证书编号', document_url VARCHAR(500) NULL COMMENT '资质文件存储地址', valid_from DATE NULL COMMENT '有效期开始日期', valid_to DATE NULL COMMENT '有效期结束日期', status VARCHAR(20) NOT NULL DEFAULT 'PENDING' COMMENT '资质审核状态', review_comment VARCHAR(500) NULL COMMENT '审核意见', created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间', deleted TINYINT NOT NULL DEFAULT 0 COMMENT '逻辑删除标记', PRIMARY KEY (id), KEY idx_qualification_tenant (tenant_id, status) ) ENGINE=InnoDB COMMENT='租户资质表:保存企业证照、有效期、文件地址和审核状态'; CREATE TABLE IF NOT EXISTS iam_user ( id BIGINT NOT NULL COMMENT 'IAM用户资料ID', auth_user_id BIGINT NOT NULL COMMENT '认证服务账号逻辑ID', user_type VARCHAR(20) NOT NULL DEFAULT 'ENTERPRISE' COMMENT '用户类型', display_name VARCHAR(64) NOT NULL COMMENT '用户展示名称', phone VARCHAR(32) NULL COMMENT '手机号', email VARCHAR(128) NULL COMMENT '邮箱', status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE' COMMENT '用户资料状态', created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间', deleted TINYINT NOT NULL DEFAULT 0 COMMENT '逻辑删除标记', version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号', PRIMARY KEY (id), UNIQUE KEY uk_iam_user_auth (auth_user_id), KEY idx_iam_user_status (status) ) ENGINE=InnoDB COMMENT='IAM用户资料表:连接统一认证账号与业务身份资料,不保存密码'; CREATE TABLE IF NOT EXISTS iam_membership ( id BIGINT NOT NULL COMMENT '租户成员关系ID', tenant_id BIGINT NOT NULL COMMENT '所属租户ID', user_id BIGINT NOT NULL COMMENT 'IAM用户资料ID', member_type VARCHAR(20) NOT NULL DEFAULT 'EMPLOYEE' COMMENT '成员类型', member_no VARCHAR(64) NULL COMMENT '租户内部成员编号', status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE' COMMENT '成员状态', joined_at DATETIME(3) NULL COMMENT '加入租户时间', left_at DATETIME(3) NULL COMMENT '离开租户时间', created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间', deleted TINYINT NOT NULL DEFAULT 0 COMMENT '逻辑删除标记', version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号', PRIMARY KEY (id), UNIQUE KEY uk_membership_tenant_user (tenant_id, user_id), UNIQUE KEY uk_membership_tenant_no (tenant_id, member_no), KEY idx_membership_user (user_id, status), KEY idx_membership_tenant (tenant_id, status) ) ENGINE=InnoDB COMMENT='租户成员关系表:表示一个用户在某个企业租户中的成员身份,是分配商户端角色的主体'; CREATE TABLE IF NOT EXISTS iam_role ( id BIGINT NOT NULL COMMENT '角色ID', tenant_id BIGINT NOT NULL DEFAULT 0 COMMENT '角色所属租户;0表示平台预置角色', app_code VARCHAR(20) NOT NULL COMMENT '应用端:MERCHANT或PLATFORM', role_code VARCHAR(64) NOT NULL COMMENT '作用域内唯一角色编码', role_name VARCHAR(128) NOT NULL COMMENT '角色名称', role_type VARCHAR(20) NOT NULL DEFAULT 'CUSTOM' COMMENT '角色类型:SYSTEM或CUSTOM', status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE' COMMENT '角色状态', description VARCHAR(255) NULL COMMENT '角色用途说明', created_by BIGINT NULL COMMENT '创建人ID', created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', updated_by BIGINT NULL COMMENT '更新人ID', updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间', deleted TINYINT NOT NULL DEFAULT 0 COMMENT '逻辑删除标记', version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号', PRIMARY KEY (id), UNIQUE KEY uk_role_scope_code (tenant_id, app_code, role_code), KEY idx_role_tenant (tenant_id, app_code, status) ) ENGINE=InnoDB COMMENT='角色表:按租户和应用端隔离商户端、平台后台两套角色体系'; CREATE TABLE IF NOT EXISTS iam_membership_role ( membership_id BIGINT NOT NULL COMMENT '租户成员关系ID', role_id BIGINT NOT NULL COMMENT '角色ID', tenant_id BIGINT NOT NULL COMMENT '冗余租户ID,用于租户隔离校验和查询', created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '授权时间', PRIMARY KEY (membership_id, role_id), KEY idx_mr_tenant (tenant_id) ) ENGINE=InnoDB COMMENT='成员角色关联表:将租户成员分配到对应应用端的一个或多个角色'; CREATE TABLE IF NOT EXISTS iam_permission ( id BIGINT NOT NULL COMMENT '权限资源ID', tenant_id BIGINT NOT NULL DEFAULT 0 COMMENT '权限所属租户;0表示平台预置权限', app_code VARCHAR(20) NOT NULL COMMENT '所属应用端:MERCHANT或PLATFORM', permission_type VARCHAR(20) NOT NULL COMMENT '权限类型:MENU、PAGE、BUTTON或API', parent_id BIGINT NOT NULL DEFAULT 0 COMMENT '父权限ID,用于构造菜单和页面树', permission_code VARCHAR(128) NOT NULL COMMENT '鉴权使用的唯一权限码', permission_name VARCHAR(128) NOT NULL COMMENT '权限名称', route_path VARCHAR(255) NULL COMMENT '前端路由或API路径', http_method VARCHAR(16) NULL COMMENT 'API权限对应的HTTP方法', sort_no INT NOT NULL DEFAULT 0 COMMENT '同级显示顺序', status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE' COMMENT '权限状态', built_in TINYINT NOT NULL DEFAULT 0 COMMENT '是否为系统预置权限;预置权限不可通过管理接口修改', created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间', deleted TINYINT NOT NULL DEFAULT 0 COMMENT '逻辑删除标记', PRIMARY KEY (id), UNIQUE KEY uk_permission_scope_code (tenant_id, app_code, permission_code), KEY idx_permission_parent (parent_id), KEY idx_permission_api (http_method, route_path) ) ENGINE=InnoDB COMMENT='统一权限资源表:支持商户端和平台后台两套菜单、页面、按钮及API权限,权限最细可控制到按钮'; CREATE TABLE IF NOT EXISTS iam_role_permission ( role_id BIGINT NOT NULL COMMENT '角色ID', permission_id BIGINT NOT NULL COMMENT '权限资源ID', tenant_id BIGINT NOT NULL COMMENT '冗余租户ID,用于隔离校验和查询', created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '授权时间', PRIMARY KEY (role_id, permission_id), KEY idx_rp_tenant (tenant_id) ) ENGINE=InnoDB COMMENT='角色权限关联表:定义角色可访问的菜单、页面、按钮和API资源'; CREATE TABLE IF NOT EXISTS iam_data_scope ( id BIGINT NOT NULL COMMENT '数据范围规则ID', role_id BIGINT NOT NULL COMMENT '角色ID', tenant_id BIGINT NOT NULL COMMENT '规则所属租户ID', scope_type VARCHAR(20) NOT NULL DEFAULT 'SELF' COMMENT '范围类型:SELF、DEPARTMENT、TENANT或CUSTOM', scope_expression JSON NULL COMMENT '自定义数据范围表达式', created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', PRIMARY KEY (id), UNIQUE KEY uk_scope_role (role_id) ) ENGINE=InnoDB COMMENT='角色数据范围表:在功能权限之外限制角色可查看和操作的租户内数据集合'; -- 存量数据库重复执行初始化脚本时,不重复创建审核状态索引。 SET @review_status_index_sql = IF( EXISTS(SELECT 1 FROM information_schema.statistics WHERE table_schema = DATABASE() AND table_name = 'iam_tenant_review' AND index_name = 'idx_tenant_review_status'), 'SELECT 1', 'CREATE INDEX idx_tenant_review_status ON iam_tenant_review (tenant_id, status)' ); PREPARE review_status_index_stmt FROM @review_status_index_sql; EXECUTE review_status_index_stmt; DEALLOCATE PREPARE review_status_index_stmt;