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);0保留为平台技术作用域', tenant_code VARCHAR(64) NOT NULL COMMENT '全局唯一客户编码', tenant_name VARCHAR(128) NOT NULL COMMENT '客户企业名称', tenant_type VARCHAR(20) NOT NULL DEFAULT 'MERCHANT' COMMENT '主体类型:MERCHANT企业客户', status VARCHAR(20) NOT NULL DEFAULT 'PROFILE_REQUIRED' COMMENT '客户状态:PROFILE_REQUIRED待完善资料、PENDING待审核、ACTIVE正常、REJECTED已驳回、DISABLED已停用、ARCHIVED已归档', dimension_initialization_status VARCHAR(16) NOT NULL DEFAULT 'READY' COMMENT '默认尺寸初始化状态:PENDING待处理、READY已就绪、FAILED失败', legal_name VARCHAR(128) NULL COMMENT '企业法定名称', legal_representative VARCHAR(64) 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 '联系邮箱', service_package VARCHAR(64) NOT NULL DEFAULT '基础版' 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='客户企业主档表:保存企业资料、审核结果和启停状态;ID同时作为客户数据隔离键'; CREATE TABLE IF NOT EXISTS iam_customer_dimension_initialization_task ( tenant_id BIGINT NOT NULL COMMENT '客户ID及任务聚合ID', operator_id BIGINT NOT NULL COMMENT '触发初始化的操作人ID;系统补偿为0', initialization_key VARCHAR(128) NOT NULL COMMENT '稳定初始化幂等键:iam-customer-create:{tenantId}', action VARCHAR(16) NOT NULL DEFAULT 'INITIALIZE' COMMENT '目标动作:INITIALIZE初始化、COMPENSATE补偿', status VARCHAR(16) NOT NULL DEFAULT 'PENDING' COMMENT '投递状态:PENDING待投递、SENDING投递中、READY已就绪、FAILED失败、CANCELLED已补偿', attempt_count INT NOT NULL DEFAULT 0 COMMENT '当前动作已失败尝试次数', next_retry_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '下次允许投递时间', lease_owner VARCHAR(128) NULL COMMENT '当前任务租约持有者', lease_until DATETIME(3) NULL COMMENT '当前任务租约截止时间', last_error_code VARCHAR(32) NULL COMMENT '最后下游错误码', last_error_message VARCHAR(1000) NULL COMMENT '最后诊断错误,不保存敏感凭证', remote_config_id BIGINT NULL COMMENT 'Firstleg返回的首条默认尺寸配置ID', task_version INT 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 '任务更新时间', completed_at DATETIME(3) NULL COMMENT 'READY或CANCELLED完成时间', PRIMARY KEY (tenant_id), KEY idx_customer_dimension_task_dispatch (status,next_retry_at,lease_until), KEY idx_customer_dimension_task_diagnosis (status,updated_at) ) ENGINE=InnoDB COMMENT='IAM客户默认尺寸可靠后台初始化任务及诊断状态'; 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 '审核类型:REGISTER注册审核等', status VARCHAR(20) NOT NULL DEFAULT 'PENDING' COMMENT '审核状态:PENDING待审核、APPROVED已通过、REJECTED已驳回', 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 '是否默认地址:0否、1是', 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 '资质审核状态:PENDING待审核、APPROVED已通过、REJECTED已驳回', 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 '用户类型:ENTERPRISE企业用户、PLATFORM平台用户', 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 '用户资料状态:ACTIVE正常、DISABLED停用', 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 '成员类型:EMPLOYEE企业员工等', member_no VARCHAR(64) NULL COMMENT '客户企业内部成员编号', overseas_warehouse_id BIGINT NULL COMMENT '海外仓PDA操作员绑定的唯一实际海外仓ID', status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE' COMMENT '成员状态:ACTIVE在职、DISABLED停用、LEFT已离开', 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为平台预置模板,正数为客户ID和数据隔离键', 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 '角色状态:ACTIVE启用、DISABLED停用', 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为平台预置权限,正数为客户ID和数据隔离键', 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 '权限状态:ACTIVE启用、DISABLED停用', built_in TINYINT NOT NULL DEFAULT 0 COMMENT '是否为系统预置权限:0否、1是;预置权限不可通过管理接口修改', 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或平台作用域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 '规则作用域:0为平台,正数为客户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;