暂存提交
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
server:
|
||||
port: ${IAM_PORT:9201}
|
||||
spring:
|
||||
application:
|
||||
name: iam-service
|
||||
config:
|
||||
import:
|
||||
- optional:nacos:baiyue-common.yml?group=BAIYUE&refreshEnabled=true
|
||||
- optional:nacos:${spring.application.name}.yml?group=BAIYUE&refreshEnabled=true
|
||||
cloud:
|
||||
nacos:
|
||||
server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848}
|
||||
username: ${NACOS_USERNAME:nacos}
|
||||
password: ${NACOS_PASSWORD:nacos}
|
||||
discovery:
|
||||
enabled: ${NACOS_DISCOVERY_ENABLED:true}
|
||||
register-enabled: ${NACOS_REGISTER_ENABLED:true}
|
||||
group: ${NACOS_GROUP:BAIYUE}
|
||||
namespace: ${NACOS_NAMESPACE:public}
|
||||
config:
|
||||
namespace: ${NACOS_NAMESPACE:public}
|
||||
datasource:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: ${IAM_DB_URL:jdbc:mysql://127.0.0.1:3306/baiyue_iam?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true}
|
||||
username: ${IAM_DB_USERNAME:root}
|
||||
password: ${IAM_DB_PASSWORD:123456}
|
||||
baiyue:
|
||||
clients:
|
||||
auth:
|
||||
url: ${AUTH_SERVICE_URL:}
|
||||
security:
|
||||
jwt-secret: ${JWT_SECRET:change-me-to-at-least-32-bytes-long-before-start}
|
||||
internal-service-token: ${INTERNAL_SERVICE_TOKEN:change-me-to-an-internal-token-at-least-32-bytes-long}
|
||||
management.endpoints.web.exposure.include: health,info,prometheus
|
||||
@@ -0,0 +1,199 @@
|
||||
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 '联系邮箱',
|
||||
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 '权限状态',
|
||||
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;
|
||||
@@ -0,0 +1,185 @@
|
||||
-- Phase-one administrator identities and RBAC seed data.
|
||||
-- Scope is intentionally limited to first-level menus, second-level menus and buttons.
|
||||
-- PAGE and API permission resources are not part of phase one.
|
||||
USE baiyue_iam;
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
-- Keep the role table aligned with the shared BaseEntity audit fields.
|
||||
SET @ddl = IF(
|
||||
EXISTS(SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE() AND table_name = 'iam_role' AND column_name = 'created_by'),
|
||||
'SELECT 1',
|
||||
'ALTER TABLE iam_role ADD COLUMN created_by BIGINT NULL AFTER description'
|
||||
);
|
||||
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
SET @ddl = IF(
|
||||
EXISTS(SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE() AND table_name = 'iam_role' AND column_name = 'updated_by'),
|
||||
'SELECT 1',
|
||||
'ALTER TABLE iam_role ADD COLUMN updated_by BIGINT NULL AFTER created_at'
|
||||
);
|
||||
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
INSERT INTO iam_tenant (
|
||||
id, tenant_code, tenant_name, tenant_type, status, legal_name,
|
||||
unified_social_credit_code, contact_name, contact_phone, contact_email,
|
||||
approved_at, approved_by, created_by, deleted, version
|
||||
) VALUES
|
||||
(0, 'PLATFORM', '虫虫出海平台', 'PLATFORM', 'ACTIVE', '虫虫出海平台',
|
||||
NULL, '平台管理员', NULL, NULL, NOW(3), 1000001, 1000001, 0, 0),
|
||||
(10001, 'PHASE1_DEMO', '一期演示企业', 'MERCHANT', 'ACTIVE', '一期演示企业有限公司',
|
||||
'91310000PHASE10001', '企业管理员', '13800000000', 'merchant@example.com',
|
||||
NOW(3), 1000001, 1000001, 0, 0)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
tenant_name = VALUES(tenant_name), tenant_type = VALUES(tenant_type),
|
||||
status = 'ACTIVE', legal_name = VALUES(legal_name),
|
||||
contact_name = VALUES(contact_name), contact_phone = VALUES(contact_phone),
|
||||
contact_email = VALUES(contact_email), approved_at = COALESCE(approved_at, NOW(3)),
|
||||
approved_by = VALUES(approved_by), deleted = 0;
|
||||
|
||||
INSERT INTO iam_user (
|
||||
id, auth_user_id, user_type, display_name, phone, email, status, deleted, version
|
||||
) VALUES
|
||||
(2000001, 1000001, 'INTERNAL', '平台管理员', NULL, NULL, 'ACTIVE', 0, 0),
|
||||
(2000002, 1000002, 'ENTERPRISE', '一期演示企业管理员', '13800000000',
|
||||
'merchant@example.com', 'ACTIVE', 0, 0)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
display_name = VALUES(display_name), phone = VALUES(phone), email = VALUES(email),
|
||||
status = 'ACTIVE', deleted = 0;
|
||||
|
||||
INSERT INTO iam_membership (
|
||||
id, tenant_id, user_id, member_type, member_no, status, joined_at, deleted, version
|
||||
) VALUES
|
||||
(3000001, 0, 2000001, 'EMPLOYEE', 'PLATFORM-ADMIN-001', 'ACTIVE', NOW(3), 0, 0),
|
||||
(3000002, 10001, 2000002, 'OWNER', 'MERCHANT-OWNER-001', 'ACTIVE', NOW(3), 0, 0)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
member_type = VALUES(member_type), member_no = VALUES(member_no),
|
||||
status = 'ACTIVE', joined_at = COALESCE(joined_at, NOW(3)), left_at = NULL, deleted = 0;
|
||||
|
||||
INSERT INTO iam_role (
|
||||
id, tenant_id, app_code, role_code, role_name, role_type, status, description, deleted, version
|
||||
) VALUES
|
||||
(4000001, 0, 'PLATFORM', 'PLATFORM_ADMIN', '平台超级管理员', 'SYSTEM', 'ACTIVE', '一期平台全部菜单和按钮', 0, 0),
|
||||
(4000002, 0, 'PLATFORM', 'CUSTOMER_REVIEWER', '企业审核员', 'SYSTEM', 'ACTIVE', '企业资料与入驻审核', 0, 0),
|
||||
(4000003, 0, 'PLATFORM', 'ORDER_OPERATOR', '平台订单运营', 'SYSTEM', 'ACTIVE', '头程订单审核与履约处理', 0, 0),
|
||||
(4000101, 10001, 'MERCHANT', 'MERCHANT_OWNER', '企业管理员', 'SYSTEM', 'ACTIVE', '本企业一期全部菜单和按钮', 0, 0),
|
||||
(4000102, 10001, 'MERCHANT', 'MERCHANT_ORDER_MANAGER', '企业订单管理员', 'SYSTEM', 'ACTIVE', '本企业头程订单操作', 0, 0)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
role_name = VALUES(role_name), role_type = VALUES(role_type), status = 'ACTIVE',
|
||||
description = VALUES(description), deleted = 0;
|
||||
|
||||
-- Platform: level-one menus.
|
||||
INSERT INTO iam_permission
|
||||
(id, tenant_id, app_code, permission_type, parent_id, permission_code, permission_name, route_path, http_method, sort_no, status, deleted)
|
||||
VALUES
|
||||
(5100000, 0, 'PLATFORM', 'MENU', 0, 'platform:customer', '客户管理', '/customers', NULL, 10, 'ACTIVE', 0),
|
||||
(5101000, 0, 'PLATFORM', 'MENU', 0, 'platform:system', '系统管理', '/system', NULL, 20, 'ACTIVE', 0),
|
||||
(5102000, 0, 'PLATFORM', 'MENU', 0, 'platform:order', '头程订单', '/first-leg-orders', NULL, 30, 'ACTIVE', 0),
|
||||
(5103000, 0, 'PLATFORM', 'MENU', 0, 'platform:master-data', '基础资料', '/master-data', NULL, 40, 'ACTIVE', 0),
|
||||
(5104000, 0, 'PLATFORM', 'MENU', 0, 'platform:audit', '审计管理', '/audit', NULL, 50, 'ACTIVE', 0),
|
||||
-- Platform: level-two menus.
|
||||
(5100010, 0, 'PLATFORM', 'MENU', 5100000, 'platform:customer:list', '企业客户', '/customers/list', NULL, 10, 'ACTIVE', 0),
|
||||
(5100020, 0, 'PLATFORM', 'MENU', 5100000, 'platform:customer:review', '企业审核', '/customers/reviews', NULL, 20, 'ACTIVE', 0),
|
||||
(5101010, 0, 'PLATFORM', 'MENU', 5101000, 'platform:user:list', '内部用户', '/system/users', NULL, 10, 'ACTIVE', 0),
|
||||
(5101020, 0, 'PLATFORM', 'MENU', 5101000, 'platform:role:list', '角色管理', '/system/roles', NULL, 20, 'ACTIVE', 0),
|
||||
(5101030, 0, 'PLATFORM', 'MENU', 5101000, 'platform:permission:list', '菜单按钮', '/system/permissions', NULL, 30, 'ACTIVE', 0),
|
||||
(5102010, 0, 'PLATFORM', 'MENU', 5102000, 'platform:order:list', '订单列表', '/first-leg-orders/list', NULL, 10, 'ACTIVE', 0),
|
||||
(5103010, 0, 'PLATFORM', 'MENU', 5103000, 'platform:warehouse:list', '国内仓/FBA仓', '/master-data/warehouses', NULL, 10, 'ACTIVE', 0),
|
||||
(5103020, 0, 'PLATFORM', 'MENU', 5103000, 'platform:express:list', '快递公司', '/master-data/express', NULL, 20, 'ACTIVE', 0),
|
||||
(5103030, 0, 'PLATFORM', 'MENU', 5103000, 'platform:counterparty:list', '往来单位', '/master-data/counterparties', NULL, 30, 'ACTIVE', 0),
|
||||
(5104010, 0, 'PLATFORM', 'MENU', 5104000, 'platform:audit:list', '操作日志', '/audit/logs', NULL, 10, 'ACTIVE', 0),
|
||||
-- Platform: buttons.
|
||||
(5100021, 0, 'PLATFORM', 'BUTTON', 5100020, 'platform:customer:approve', '审核通过', NULL, NULL, 10, 'ACTIVE', 0),
|
||||
(5100022, 0, 'PLATFORM', 'BUTTON', 5100020, 'platform:customer:reject', '审核驳回', NULL, NULL, 20, 'ACTIVE', 0),
|
||||
(5101011, 0, 'PLATFORM', 'BUTTON', 5101010, 'platform:user:create', '新增用户', NULL, NULL, 10, 'ACTIVE', 0),
|
||||
(5101021, 0, 'PLATFORM', 'BUTTON', 5101020, 'platform:role:create', '新增角色', NULL, NULL, 10, 'ACTIVE', 0),
|
||||
(5101022, 0, 'PLATFORM', 'BUTTON', 5101020, 'platform:role:grant', '角色授权', NULL, NULL, 20, 'ACTIVE', 0),
|
||||
(5101031, 0, 'PLATFORM', 'BUTTON', 5101030, 'platform:permission:create', '新增菜单按钮', NULL, NULL, 10, 'ACTIVE', 0),
|
||||
(5102011, 0, 'PLATFORM', 'BUTTON', 5102010, 'platform:order:approve', '订单审核通过', NULL, NULL, 10, 'ACTIVE', 0),
|
||||
(5102012, 0, 'PLATFORM', 'BUTTON', 5102010, 'platform:order:reject', '订单驳回', NULL, NULL, 20, 'ACTIVE', 0),
|
||||
(5102013, 0, 'PLATFORM', 'BUTTON', 5102010, 'platform:order:accept', '订单受理', NULL, NULL, 30, 'ACTIVE', 0),
|
||||
(5102014, 0, 'PLATFORM', 'BUTTON', 5102010, 'platform:order:process', '开始处理', NULL, NULL, 40, 'ACTIVE', 0),
|
||||
(5102015, 0, 'PLATFORM', 'BUTTON', 5102010, 'platform:order:complete', '完成订单', NULL, NULL, 50, 'ACTIVE', 0),
|
||||
(5102016, 0, 'PLATFORM', 'BUTTON', 5102010, 'platform:order:cancel', '取消订单', NULL, NULL, 60, 'ACTIVE', 0),
|
||||
(5102017, 0, 'PLATFORM', 'BUTTON', 5102010, 'platform:order:note', '内部备注', NULL, NULL, 70, 'ACTIVE', 0),
|
||||
(5102018, 0, 'PLATFORM', 'BUTTON', 5102010, 'platform:order:fulfillment', '登记履约快递', NULL, NULL, 80, 'ACTIVE', 0),
|
||||
(5103011, 0, 'PLATFORM', 'BUTTON', 5103010, 'platform:warehouse:create', '新增仓库', NULL, NULL, 10, 'ACTIVE', 0),
|
||||
(5103012, 0, 'PLATFORM', 'BUTTON', 5103010, 'platform:warehouse:edit', '编辑仓库', NULL, NULL, 20, 'ACTIVE', 0),
|
||||
(5103013, 0, 'PLATFORM', 'BUTTON', 5103010, 'platform:warehouse:status', '启用停用', NULL, NULL, 30, 'ACTIVE', 0)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
permission_type = VALUES(permission_type), parent_id = VALUES(parent_id),
|
||||
permission_name = VALUES(permission_name), route_path = VALUES(route_path),
|
||||
http_method = NULL, sort_no = VALUES(sort_no), status = 'ACTIVE', deleted = 0;
|
||||
|
||||
-- Merchant: level-one menus, level-two menus and buttons.
|
||||
INSERT INTO iam_permission
|
||||
(id, tenant_id, app_code, permission_type, parent_id, permission_code, permission_name, route_path, http_method, sort_no, status, deleted)
|
||||
VALUES
|
||||
(5200000, 10001, 'MERCHANT', 'MENU', 0, 'merchant:enterprise', '企业管理', '/enterprise', NULL, 10, 'ACTIVE', 0),
|
||||
(5201000, 10001, 'MERCHANT', 'MENU', 0, 'merchant:order', '头程订单', '/first-leg-orders', NULL, 20, 'ACTIVE', 0),
|
||||
(5202000, 10001, 'MERCHANT', 'MENU', 0, 'merchant:master-data', '基础资料', '/master-data', NULL, 30, 'ACTIVE', 0),
|
||||
(5200010, 10001, 'MERCHANT', 'MENU', 5200000, 'merchant:profile:view', '企业资料', '/enterprise/profile', NULL, 10, 'ACTIVE', 0),
|
||||
(5200020, 10001, 'MERCHANT', 'MENU', 5200000, 'merchant:member:list', '企业成员', '/enterprise/members', NULL, 20, 'ACTIVE', 0),
|
||||
(5200030, 10001, 'MERCHANT', 'MENU', 5200000, 'merchant:role:list', '角色管理', '/enterprise/roles', NULL, 30, 'ACTIVE', 0),
|
||||
(5201010, 10001, 'MERCHANT', 'MENU', 5201000, 'merchant:order:list', '我的订单', '/first-leg-orders/list', NULL, 10, 'ACTIVE', 0),
|
||||
(5201020, 10001, 'MERCHANT', 'MENU', 5201000, 'merchant:order:create-page', '新建订单', '/first-leg-orders/create', NULL, 20, 'ACTIVE', 0),
|
||||
(5202010, 10001, 'MERCHANT', 'MENU', 5202000, 'merchant:warehouse:list', '收货仓选择', '/master-data/warehouses', NULL, 10, 'ACTIVE', 0),
|
||||
(5202020, 10001, 'MERCHANT', 'MENU', 5202000, 'merchant:counterparty:list', '往来单位', '/master-data/counterparties', NULL, 20, 'ACTIVE', 0),
|
||||
(5200011, 10001, 'MERCHANT', 'BUTTON', 5200010, 'merchant:profile:edit', '编辑企业资料', NULL, NULL, 10, 'ACTIVE', 0),
|
||||
(5200012, 10001, 'MERCHANT', 'BUTTON', 5200010, 'merchant:qualification:upload', '上传企业资质', NULL, NULL, 20, 'ACTIVE', 0),
|
||||
(5200021, 10001, 'MERCHANT', 'BUTTON', 5200020, 'merchant:member:create', '新增成员', NULL, NULL, 10, 'ACTIVE', 0),
|
||||
(5200022, 10001, 'MERCHANT', 'BUTTON', 5200020, 'merchant:member:grant-role', '分配角色', NULL, NULL, 20, 'ACTIVE', 0),
|
||||
(5200031, 10001, 'MERCHANT', 'BUTTON', 5200030, 'merchant:role:create', '新增角色', NULL, NULL, 10, 'ACTIVE', 0),
|
||||
(5200032, 10001, 'MERCHANT', 'BUTTON', 5200030, 'merchant:role:grant', '角色授权', NULL, NULL, 20, 'ACTIVE', 0),
|
||||
(5201011, 10001, 'MERCHANT', 'BUTTON', 5201010, 'merchant:order:view', '查看订单', NULL, NULL, 10, 'ACTIVE', 0),
|
||||
(5201012, 10001, 'MERCHANT', 'BUTTON', 5201010, 'merchant:order:cancel', '取消订单', NULL, NULL, 20, 'ACTIVE', 0),
|
||||
(5201021, 10001, 'MERCHANT', 'BUTTON', 5201020, 'merchant:order:create', '创建草稿', NULL, NULL, 10, 'ACTIVE', 0),
|
||||
(5201022, 10001, 'MERCHANT', 'BUTTON', 5201020, 'merchant:order:edit', '编辑草稿', NULL, NULL, 20, 'ACTIVE', 0),
|
||||
(5201023, 10001, 'MERCHANT', 'BUTTON', 5201020, 'merchant:order:submit', '提交订单', NULL, NULL, 30, 'ACTIVE', 0)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
permission_type = VALUES(permission_type), parent_id = VALUES(parent_id),
|
||||
permission_name = VALUES(permission_name), route_path = VALUES(route_path),
|
||||
http_method = NULL, sort_no = VALUES(sort_no), status = 'ACTIVE', deleted = 0;
|
||||
|
||||
INSERT INTO iam_membership_role (membership_id, role_id, tenant_id) VALUES
|
||||
(3000001, 4000001, 0),
|
||||
(3000002, 4000101, 10001)
|
||||
ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id);
|
||||
|
||||
-- Full administrator roles receive all phase-one permissions in their application scope.
|
||||
INSERT INTO iam_role_permission (role_id, permission_id, tenant_id)
|
||||
SELECT 4000001, id, 0 FROM iam_permission
|
||||
WHERE app_code = 'PLATFORM' AND tenant_id = 0 AND permission_type IN ('MENU', 'BUTTON')
|
||||
ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id);
|
||||
|
||||
INSERT INTO iam_role_permission (role_id, permission_id, tenant_id)
|
||||
SELECT 4000101, id, 10001 FROM iam_permission
|
||||
WHERE app_code = 'MERCHANT' AND tenant_id = 10001 AND permission_type IN ('MENU', 'BUTTON')
|
||||
ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id);
|
||||
|
||||
-- Limited platform and merchant operational roles.
|
||||
INSERT INTO iam_role_permission (role_id, permission_id, tenant_id)
|
||||
SELECT 4000002, id, 0 FROM iam_permission
|
||||
WHERE permission_code IN (
|
||||
'platform:customer', 'platform:customer:list', 'platform:customer:review',
|
||||
'platform:customer:approve', 'platform:customer:reject'
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id);
|
||||
|
||||
INSERT INTO iam_role_permission (role_id, permission_id, tenant_id)
|
||||
SELECT 4000003, id, 0 FROM iam_permission
|
||||
WHERE permission_code LIKE 'platform:order%'
|
||||
ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id);
|
||||
|
||||
INSERT INTO iam_role_permission (role_id, permission_id, tenant_id)
|
||||
SELECT 4000102, id, 10001 FROM iam_permission
|
||||
WHERE permission_code LIKE 'merchant:order%' OR permission_code IN ('merchant:master-data', 'merchant:warehouse:list')
|
||||
ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id);
|
||||
|
||||
INSERT INTO iam_data_scope (id, role_id, tenant_id, scope_type, scope_expression) VALUES
|
||||
(6000001, 4000001, 0, 'TENANT', NULL),
|
||||
(6000002, 4000002, 0, 'TENANT', NULL),
|
||||
(6000003, 4000003, 0, 'TENANT', NULL),
|
||||
(6000101, 4000101, 10001, 'TENANT', NULL),
|
||||
(6000102, 4000102, 10001, 'TENANT', NULL)
|
||||
ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id), scope_type = VALUES(scope_type), scope_expression = NULL;
|
||||
@@ -0,0 +1,38 @@
|
||||
SET NAMES utf8mb4;
|
||||
-- 企业成员管理按钮权限增量;部署后应将权限按需授予企业管理员角色。
|
||||
USE baiyue_iam;
|
||||
|
||||
-- 为存量数据库补齐企业内成员编号唯一约束,防止并发重复创建。
|
||||
SET @member_no_index_sql = IF(
|
||||
EXISTS(SELECT 1 FROM information_schema.statistics
|
||||
WHERE table_schema = DATABASE() AND table_name = 'iam_membership'
|
||||
AND index_name = 'uk_membership_tenant_no'),
|
||||
'SELECT 1',
|
||||
'ALTER TABLE iam_membership ADD UNIQUE KEY uk_membership_tenant_no (tenant_id, member_no)'
|
||||
);
|
||||
PREPARE member_no_index_stmt FROM @member_no_index_sql;
|
||||
EXECUTE member_no_index_stmt;
|
||||
DEALLOCATE PREPARE member_no_index_stmt;
|
||||
|
||||
INSERT INTO iam_permission
|
||||
(id, tenant_id, app_code, permission_type, parent_id, permission_code, permission_name, sort_no, status, deleted)
|
||||
VALUES
|
||||
(5200023, 10001, 'MERCHANT', 'BUTTON', 5200020, 'merchant:member:edit', '编辑成员', 30, 'ACTIVE', 0),
|
||||
(5200024, 10001, 'MERCHANT', 'BUTTON', 5200020, 'merchant:member:status', '启停成员', 40, 'ACTIVE', 0),
|
||||
(5200025, 10001, 'MERCHANT', 'BUTTON', 5200020, 'merchant:member:reset-password', '重置成员密码', 50, 'ACTIVE', 0),
|
||||
(5300023, 0, 'MERCHANT', 'BUTTON', 5300020, 'merchant:member:edit', '编辑成员', 30, 'ACTIVE', 0),
|
||||
(5300024, 0, 'MERCHANT', 'BUTTON', 5300020, 'merchant:member:status', '启停成员', 40, 'ACTIVE', 0),
|
||||
(5300025, 0, 'MERCHANT', 'BUTTON', 5300020, 'merchant:member:reset-password', '重置成员密码', 50, 'ACTIVE', 0)
|
||||
ON DUPLICATE KEY UPDATE permission_name = VALUES(permission_name), status = VALUES(status), deleted = 0;
|
||||
|
||||
INSERT INTO iam_role_permission (role_id, permission_id, tenant_id)
|
||||
SELECT 4000101, id, 10001 FROM iam_permission
|
||||
WHERE tenant_id = 10001 AND permission_code IN
|
||||
('merchant:member:edit', 'merchant:member:status', 'merchant:member:reset-password')
|
||||
ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id);
|
||||
|
||||
INSERT INTO iam_role_permission (role_id, permission_id, tenant_id)
|
||||
SELECT 4000100, id, 0 FROM iam_permission
|
||||
WHERE tenant_id = 0 AND permission_code IN
|
||||
('merchant:member:edit', 'merchant:member:status', 'merchant:member:reset-password')
|
||||
ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id);
|
||||
@@ -0,0 +1,71 @@
|
||||
-- Phase-one merchant onboarding state migration.
|
||||
USE baiyue_iam;
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
ALTER TABLE iam_tenant MODIFY COLUMN status VARCHAR(20) NOT NULL DEFAULT 'PROFILE_REQUIRED'
|
||||
COMMENT 'PROFILE_REQUIRED, PENDING, ACTIVE, REJECTED or DISABLED';
|
||||
DROP PROCEDURE IF EXISTS phase1_iam_add_column;
|
||||
DELIMITER $$
|
||||
CREATE PROCEDURE phase1_iam_add_column(
|
||||
IN p_table_name VARCHAR(64), IN p_column_name VARCHAR(64), IN p_definition VARCHAR(1000)
|
||||
)
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = p_table_name AND COLUMN_NAME = p_column_name
|
||||
) THEN
|
||||
SET @phase1_iam_sql = CONCAT('ALTER TABLE `', p_table_name, '` ADD COLUMN `',
|
||||
p_column_name, '` ', p_definition);
|
||||
PREPARE phase1_iam_stmt FROM @phase1_iam_sql;
|
||||
EXECUTE phase1_iam_stmt;
|
||||
DEALLOCATE PREPARE phase1_iam_stmt;
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
CALL phase1_iam_add_column('iam_tenant', 'approved_at', "DATETIME(3) NULL COMMENT 'Approval time'");
|
||||
CALL phase1_iam_add_column('iam_tenant', 'approved_by', "BIGINT NULL COMMENT 'Reviewer ID'");
|
||||
CALL phase1_iam_add_column('iam_tenant', 'reject_reason', "VARCHAR(500) NULL COMMENT 'Rejection reason'");
|
||||
CALL phase1_iam_add_column('iam_tenant_qualification', 'review_comment', "VARCHAR(500) NULL COMMENT 'Review comment'");
|
||||
CALL phase1_iam_add_column('iam_membership', 'created_by', "BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Creator ID'");
|
||||
CALL phase1_iam_add_column('iam_membership', 'updated_by', "BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Updater ID'");
|
||||
DROP PROCEDURE phase1_iam_add_column;
|
||||
|
||||
-- A global merchant owner template is assigned to newly registered enterprises.
|
||||
INSERT INTO iam_role (
|
||||
id, tenant_id, app_code, role_code, role_name, role_type, status,
|
||||
description, created_by, updated_by, deleted, version
|
||||
) VALUES (
|
||||
4000100, 0, 'MERCHANT', 'MERCHANT_OWNER', '企业管理员', 'SYSTEM', 'ACTIVE',
|
||||
'一期企业全部菜单和操作按钮模板', 1000001, 1000001, 0, 0
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE status='ACTIVE', deleted=0;
|
||||
|
||||
-- Clone the一期 merchant menu/button template into the global scope.
|
||||
INSERT INTO iam_permission (
|
||||
id, tenant_id, app_code, permission_type, parent_id, permission_code,
|
||||
permission_name, route_path, http_method, sort_no, status, deleted
|
||||
)
|
||||
SELECT id + 100000, 0, app_code, permission_type,
|
||||
CASE WHEN parent_id = 0 THEN 0 ELSE parent_id + 100000 END,
|
||||
permission_code, permission_name, route_path, NULL, sort_no, 'ACTIVE', 0
|
||||
FROM iam_permission
|
||||
WHERE tenant_id = 10001 AND app_code = 'MERCHANT'
|
||||
AND permission_type IN ('MENU', 'BUTTON')
|
||||
ON DUPLICATE KEY UPDATE
|
||||
permission_name=VALUES(permission_name), route_path=VALUES(route_path),
|
||||
parent_id=VALUES(parent_id), sort_no=VALUES(sort_no), status='ACTIVE', deleted=0;
|
||||
|
||||
INSERT IGNORE INTO iam_role_permission (role_id, permission_id, tenant_id)
|
||||
SELECT 4000100, id, 0
|
||||
FROM iam_permission
|
||||
WHERE app_code='MERCHANT' AND tenant_id=0
|
||||
AND permission_type IN ('MENU','BUTTON') AND status='ACTIVE' AND deleted=0;
|
||||
|
||||
-- Keep the phase-one demo merchant eligible for existing order acceptance tests.
|
||||
INSERT INTO iam_tenant_qualification (
|
||||
id, tenant_id, qualification_type, certificate_no, document_url, status, deleted
|
||||
) VALUES (
|
||||
7000101, 10001, 'BUSINESS_LICENSE', '91310000PHASE10001',
|
||||
'/phase1-seed/demo-business-license.jpg', 'APPROVED', 0
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE status='APPROVED', deleted=0;
|
||||
@@ -0,0 +1,44 @@
|
||||
SET NAMES utf8mb4;
|
||||
-- 角色管理闭环权限迁移,可重复执行。
|
||||
USE baiyue_iam;
|
||||
|
||||
INSERT INTO iam_permission
|
||||
(id, tenant_id, app_code, permission_type, parent_id, permission_code,
|
||||
permission_name, sort_no, status, deleted)
|
||||
VALUES
|
||||
(5100011, 0, 'PLATFORM', 'BUTTON', 5100010, 'platform:customer:create', '新增企业客户', 10, 'ACTIVE', 0),
|
||||
(5101023, 0, 'PLATFORM', 'BUTTON', 5101020, 'platform:role:edit', '编辑角色', 30, 'ACTIVE', 0),
|
||||
(5101024, 0, 'PLATFORM', 'BUTTON', 5101020, 'platform:role:status', '启停角色', 40, 'ACTIVE', 0),
|
||||
(5101025, 0, 'PLATFORM', 'BUTTON', 5101020, 'platform:role:delete', '删除角色', 50, 'ACTIVE', 0),
|
||||
(5101040, 0, 'PLATFORM', 'MENU', 5101000, 'platform:member:list', '平台成员', 40, 'ACTIVE', 0),
|
||||
(5101041, 0, 'PLATFORM', 'BUTTON', 5101040, 'platform:member:grant-role', '分配成员角色', 10, 'ACTIVE', 0),
|
||||
(5200033, 10001, 'MERCHANT', 'BUTTON', 5200030, 'merchant:role:edit', '编辑角色', 30, 'ACTIVE', 0),
|
||||
(5200034, 10001, 'MERCHANT', 'BUTTON', 5200030, 'merchant:role:status', '启停角色', 40, 'ACTIVE', 0),
|
||||
(5200035, 10001, 'MERCHANT', 'BUTTON', 5200030, 'merchant:role:delete', '删除角色', 50, 'ACTIVE', 0),
|
||||
(5300033, 0, 'MERCHANT', 'BUTTON', 5300030, 'merchant:role:edit', '编辑角色', 30, 'ACTIVE', 0),
|
||||
(5300034, 0, 'MERCHANT', 'BUTTON', 5300030, 'merchant:role:status', '启停角色', 40, 'ACTIVE', 0),
|
||||
(5300035, 0, 'MERCHANT', 'BUTTON', 5300030, 'merchant:role:delete', '删除角色', 50, 'ACTIVE', 0)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
permission_type = VALUES(permission_type), parent_id = VALUES(parent_id),
|
||||
permission_name = VALUES(permission_name), sort_no = VALUES(sort_no),
|
||||
status = 'ACTIVE', deleted = 0;
|
||||
|
||||
-- 示例管理员获得新增权限;其他角色仍由管理员按需授权。
|
||||
INSERT INTO iam_role_permission (role_id, permission_id, tenant_id)
|
||||
SELECT 4000001, id, 0 FROM iam_permission
|
||||
WHERE tenant_id = 0 AND app_code = 'PLATFORM'
|
||||
AND permission_code IN ('platform:role:edit', 'platform:role:status', 'platform:role:delete',
|
||||
'platform:member:list', 'platform:member:grant-role', 'platform:customer:create')
|
||||
ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id);
|
||||
|
||||
INSERT INTO iam_role_permission (role_id, permission_id, tenant_id)
|
||||
SELECT 4000101, id, 10001 FROM iam_permission
|
||||
WHERE tenant_id = 10001 AND app_code = 'MERCHANT'
|
||||
AND permission_code IN ('merchant:role:edit', 'merchant:role:status', 'merchant:role:delete')
|
||||
ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id);
|
||||
|
||||
INSERT INTO iam_role_permission (role_id, permission_id, tenant_id)
|
||||
SELECT 4000100, id, 0 FROM iam_permission
|
||||
WHERE tenant_id = 0 AND app_code = 'MERCHANT'
|
||||
AND permission_code IN ('merchant:role:edit', 'merchant:role:status', 'merchant:role:delete')
|
||||
ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id);
|
||||
@@ -0,0 +1,391 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: Baiyue IAM API / 百悦身份与权限 API
|
||||
description: Tenant, member, role, menu, page, button and API permission management. / 租户、成员、角色、菜单、页面、按钮和 API 权限管理。
|
||||
version: 1.0.1
|
||||
servers:
|
||||
- url: /
|
||||
security:
|
||||
- bearerAuth: []
|
||||
tags:
|
||||
- name: Platform Tenant / 平台租户
|
||||
description: Enterprise registration and review / 企业注册与审核
|
||||
- name: Merchant Tenant / 商户企业
|
||||
description: Current tenant profile and members / 当前企业资料与成员
|
||||
- name: IAM Resources / IAM 资源
|
||||
description: Internal users, addresses and qualifications / 内部用户、地址与资质
|
||||
- name: RBAC
|
||||
description: Platform and merchant role-permission management / 平台端与商户端角色权限管理
|
||||
paths:
|
||||
/api/platform/v1/iam/tenants:
|
||||
post:
|
||||
tags: [Platform Tenant / 平台租户]
|
||||
summary: Register enterprise tenant / 创建企业租户
|
||||
description: Create a pending enterprise tenant and review task. Platform identity is required. / 创建待审核企业租户及审核任务,要求平台端身份。
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: '#/components/schemas/RegisterRequest'}
|
||||
responses:
|
||||
'200': {$ref: '#/components/responses/Success'}
|
||||
'400': {$ref: '#/components/responses/BadRequest'}
|
||||
'403': {$ref: '#/components/responses/Forbidden'}
|
||||
'409': {$ref: '#/components/responses/Conflict'}
|
||||
/api/platform/v1/iam/reviews:
|
||||
get:
|
||||
tags: [Platform Tenant / 平台租户]
|
||||
summary: List pending tenant reviews / 查询待审核企业
|
||||
description: Return enterprise registrations waiting for a platform decision. / 返回等待平台处理的企业注册审核记录。
|
||||
responses:
|
||||
'200': {$ref: '#/components/responses/Success'}
|
||||
'403': {$ref: '#/components/responses/Forbidden'}
|
||||
/api/platform/v1/iam/reviews/{id}/approve:
|
||||
post:
|
||||
tags: [Platform Tenant / 平台租户]
|
||||
summary: Approve enterprise registration / 审核通过企业注册
|
||||
description: Approve a pending review and activate the tenant. / 通过待审核申请并激活企业租户。
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/Id'}
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: '#/components/schemas/ReviewRequest'}
|
||||
responses:
|
||||
'200': {$ref: '#/components/responses/Success'}
|
||||
'403': {$ref: '#/components/responses/Forbidden'}
|
||||
'404': {$ref: '#/components/responses/NotFound'}
|
||||
'409': {$ref: '#/components/responses/Conflict'}
|
||||
/api/platform/v1/iam/reviews/{id}/reject:
|
||||
post:
|
||||
tags: [Platform Tenant / 平台租户]
|
||||
summary: Reject enterprise registration / 驳回企业注册
|
||||
description: Reject a pending registration and save the review comment. / 驳回待审核注册申请并保存审核意见。
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/Id'}
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: '#/components/schemas/ReviewRequest'}
|
||||
responses:
|
||||
'200': {$ref: '#/components/responses/Success'}
|
||||
'403': {$ref: '#/components/responses/Forbidden'}
|
||||
'404': {$ref: '#/components/responses/NotFound'}
|
||||
'409': {$ref: '#/components/responses/Conflict'}
|
||||
/api/platform/v1/iam/internal-users:
|
||||
get:
|
||||
tags: [IAM Resources / IAM 资源]
|
||||
summary: List platform internal users / 查询平台内部用户
|
||||
responses:
|
||||
'200': {$ref: '#/components/responses/Success'}
|
||||
'403': {$ref: '#/components/responses/Forbidden'}
|
||||
post:
|
||||
tags: [IAM Resources / IAM 资源]
|
||||
summary: Create platform internal user / 新增平台内部用户
|
||||
description: Create an IAM profile linked to an existing authentication account. / 创建关联已有认证账号的 IAM 用户资料。
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: '#/components/schemas/CreateIamUserRequest'}
|
||||
responses:
|
||||
'200': {$ref: '#/components/responses/Success'}
|
||||
'400': {$ref: '#/components/responses/BadRequest'}
|
||||
'403': {$ref: '#/components/responses/Forbidden'}
|
||||
'409': {$ref: '#/components/responses/Conflict'}
|
||||
/api/merchant/v1/iam/tenant/profile:
|
||||
get:
|
||||
tags: [Merchant Tenant / 商户企业]
|
||||
summary: Get current tenant profile / 查询当前企业资料
|
||||
description: Tenant ID comes only from the verified JWT. / 租户 ID 仅取自已验证 JWT。
|
||||
responses:
|
||||
'200': {$ref: '#/components/responses/Success'}
|
||||
'401': {$ref: '#/components/responses/Unauthorized'}
|
||||
'403': {$ref: '#/components/responses/Forbidden'}
|
||||
'404': {$ref: '#/components/responses/NotFound'}
|
||||
put:
|
||||
tags: [Merchant Tenant / 商户企业]
|
||||
summary: Update current tenant profile / 更新当前企业资料
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: '#/components/schemas/UpdateProfileRequest'}
|
||||
responses:
|
||||
'200': {$ref: '#/components/responses/Success'}
|
||||
'400': {$ref: '#/components/responses/BadRequest'}
|
||||
'403': {$ref: '#/components/responses/Forbidden'}
|
||||
'404': {$ref: '#/components/responses/NotFound'}
|
||||
/api/merchant/v1/iam/members:
|
||||
get:
|
||||
tags: [Merchant Tenant / 商户企业]
|
||||
summary: List enterprise members / 查询企业成员
|
||||
responses:
|
||||
'200': {$ref: '#/components/responses/Success'}
|
||||
'403': {$ref: '#/components/responses/Forbidden'}
|
||||
post:
|
||||
tags: [Merchant Tenant / 商户企业]
|
||||
summary: Add enterprise member / 新增企业成员
|
||||
description: Attach an existing IAM user to the current tenant. / 将已有 IAM 用户加入当前企业。
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: '#/components/schemas/CreateMemberRequest'}
|
||||
responses:
|
||||
'200': {$ref: '#/components/responses/Success'}
|
||||
'400': {$ref: '#/components/responses/BadRequest'}
|
||||
'403': {$ref: '#/components/responses/Forbidden'}
|
||||
'409': {$ref: '#/components/responses/Conflict'}
|
||||
/api/merchant/v1/iam/tenant/addresses:
|
||||
get:
|
||||
tags: [IAM Resources / IAM 资源]
|
||||
summary: List tenant addresses / 查询企业地址
|
||||
responses:
|
||||
'200': {$ref: '#/components/responses/Success'}
|
||||
'403': {$ref: '#/components/responses/Forbidden'}
|
||||
post:
|
||||
tags: [IAM Resources / IAM 资源]
|
||||
summary: Add tenant address / 新增企业地址
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: '#/components/schemas/AddressRequest'}
|
||||
responses:
|
||||
'200': {$ref: '#/components/responses/Success'}
|
||||
'400': {$ref: '#/components/responses/BadRequest'}
|
||||
'403': {$ref: '#/components/responses/Forbidden'}
|
||||
/api/merchant/v1/iam/tenant/qualifications:
|
||||
get:
|
||||
tags: [IAM Resources / IAM 资源]
|
||||
summary: List tenant qualifications / 查询企业资质
|
||||
responses:
|
||||
'200': {$ref: '#/components/responses/Success'}
|
||||
'403': {$ref: '#/components/responses/Forbidden'}
|
||||
post:
|
||||
tags: [IAM Resources / IAM 资源]
|
||||
summary: Add tenant qualification / 新增企业资质
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: '#/components/schemas/QualificationRequest'}
|
||||
responses:
|
||||
'200': {$ref: '#/components/responses/Success'}
|
||||
'400': {$ref: '#/components/responses/BadRequest'}
|
||||
'403': {$ref: '#/components/responses/Forbidden'}
|
||||
/api/{app}/v1/iam/roles:
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/App'}
|
||||
get:
|
||||
tags: [RBAC]
|
||||
summary: List roles / 查询角色
|
||||
description: List roles in the selected application and tenant scope. / 查询指定应用及租户范围内的角色。
|
||||
responses:
|
||||
'200': {$ref: '#/components/responses/Success'}
|
||||
'403': {$ref: '#/components/responses/Forbidden'}
|
||||
post:
|
||||
tags: [RBAC]
|
||||
summary: Create role / 新增角色
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: '#/components/schemas/CreateRoleRequest'}
|
||||
responses:
|
||||
'200': {$ref: '#/components/responses/Success'}
|
||||
'400': {$ref: '#/components/responses/BadRequest'}
|
||||
'403': {$ref: '#/components/responses/Forbidden'}
|
||||
'409': {$ref: '#/components/responses/Conflict'}
|
||||
/api/{app}/v1/iam/members/roles:
|
||||
put:
|
||||
tags: [RBAC]
|
||||
summary: Assign roles to member / 设置成员角色
|
||||
description: Replace member role assignments in the same tenant and application. / 在同一租户和应用域内替换成员角色。
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/App'}
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: '#/components/schemas/AssignRolesRequest'}
|
||||
responses:
|
||||
'200': {$ref: '#/components/responses/Success'}
|
||||
'400': {$ref: '#/components/responses/BadRequest'}
|
||||
'403': {$ref: '#/components/responses/Forbidden'}
|
||||
/api/{app}/v1/iam/permissions:
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/App'}
|
||||
get:
|
||||
tags: [RBAC]
|
||||
summary: List menu, page, button and API permissions / 查询菜单、页面、按钮和 API 权限
|
||||
responses:
|
||||
'200': {$ref: '#/components/responses/Success'}
|
||||
'403': {$ref: '#/components/responses/Forbidden'}
|
||||
post:
|
||||
tags: [RBAC]
|
||||
summary: Create permission / 新增权限
|
||||
description: Create a MENU, PAGE, BUTTON or API permission node. / 创建 MENU、PAGE、BUTTON 或 API 权限节点。
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: '#/components/schemas/CreatePermissionRequest'}
|
||||
responses:
|
||||
'200': {$ref: '#/components/responses/Success'}
|
||||
'400': {$ref: '#/components/responses/BadRequest'}
|
||||
'403': {$ref: '#/components/responses/Forbidden'}
|
||||
'409': {$ref: '#/components/responses/Conflict'}
|
||||
/api/{app}/v1/iam/roles/permissions:
|
||||
put:
|
||||
tags: [RBAC]
|
||||
summary: Grant permissions to role / 设置角色权限
|
||||
description: Replace role permissions; cross-tenant and cross-application grants are rejected. / 替换角色权限,拒绝跨租户和跨应用授权。
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/App'}
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: '#/components/schemas/GrantPermissionsRequest'}
|
||||
responses:
|
||||
'200': {$ref: '#/components/responses/Success'}
|
||||
'400': {$ref: '#/components/responses/BadRequest'}
|
||||
'403': {$ref: '#/components/responses/Forbidden'}
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
parameters:
|
||||
Id:
|
||||
name: id
|
||||
in: path
|
||||
required: true
|
||||
description: Resource ID / 资源 ID
|
||||
schema: {type: integer, format: int64}
|
||||
example: 190000000000000001
|
||||
App:
|
||||
name: app
|
||||
in: path
|
||||
required: true
|
||||
description: Application domain / 应用域
|
||||
schema: {type: string, enum: [platform, merchant]}
|
||||
example: platform
|
||||
responses:
|
||||
Success: {description: Operation succeeded / 操作成功, content: {application/json: {schema: {$ref: '#/components/schemas/ApiResponse'}}}}
|
||||
BadRequest: {description: Invalid request / 请求参数错误, content: {application/json: {schema: {$ref: '#/components/schemas/ApiResponse'}}}}
|
||||
Unauthorized: {description: Authentication required / 需要登录, content: {application/json: {schema: {$ref: '#/components/schemas/ApiResponse'}}}}
|
||||
Forbidden: {description: Permission or tenant scope rejected / 权限或租户范围不匹配, content: {application/json: {schema: {$ref: '#/components/schemas/ApiResponse'}}}}
|
||||
NotFound: {description: Resource not found / 资源不存在, content: {application/json: {schema: {$ref: '#/components/schemas/ApiResponse'}}}}
|
||||
Conflict: {description: Resource conflict / 资源冲突, content: {application/json: {schema: {$ref: '#/components/schemas/ApiResponse'}}}}
|
||||
schemas:
|
||||
ApiResponse:
|
||||
type: object
|
||||
required: [code, message, timestamp]
|
||||
properties:
|
||||
code: {type: string, example: '00000'}
|
||||
message: {type: string, example: Success}
|
||||
data: {}
|
||||
requestId: {type: string}
|
||||
traceId: {type: string}
|
||||
timestamp: {type: string, format: date-time}
|
||||
RegisterRequest:
|
||||
type: object
|
||||
required: [tenantName, legalName, unifiedSocialCreditCode, contactName, contactPhone]
|
||||
properties:
|
||||
tenantName: {type: string, example: 深圳虫虫出海科技有限公司}
|
||||
legalName: {type: string, example: 张三}
|
||||
unifiedSocialCreditCode: {type: string, pattern: '^[0-9A-Z]{18}$', example: 91440300MA5ABCDE12}
|
||||
contactName: {type: string, example: 李四}
|
||||
contactPhone: {type: string, example: '13800138000'}
|
||||
contactEmail: {type: string, format: email, example: contact@example.com}
|
||||
UpdateProfileRequest:
|
||||
type: object
|
||||
required: [tenantName, legalName, contactName, contactPhone]
|
||||
properties:
|
||||
tenantName: {type: string}
|
||||
legalName: {type: string}
|
||||
contactName: {type: string}
|
||||
contactPhone: {type: string}
|
||||
contactEmail: {type: string, format: email}
|
||||
ReviewRequest:
|
||||
type: object
|
||||
properties:
|
||||
comment: {type: string, description: Review comment or rejection reason / 审核意见或驳回原因}
|
||||
CreateIamUserRequest:
|
||||
type: object
|
||||
required: [authUserId, userType, displayName]
|
||||
properties:
|
||||
authUserId: {type: integer, format: int64}
|
||||
userType: {type: string, enum: [PLATFORM, ENTERPRISE]}
|
||||
displayName: {type: string}
|
||||
phone: {type: string}
|
||||
email: {type: string, format: email}
|
||||
CreateMemberRequest:
|
||||
type: object
|
||||
required: [username, password, displayName, memberType]
|
||||
properties:
|
||||
username: {type: string, minLength: 4, maxLength: 64}
|
||||
password: {type: string, format: password, minLength: 8, maxLength: 64}
|
||||
displayName: {type: string, maxLength: 64}
|
||||
phone: {type: string, maxLength: 32}
|
||||
email: {type: string, format: email, maxLength: 128}
|
||||
memberType: {type: string, enum: [OWNER, ADMIN, EMPLOYEE]}
|
||||
memberNo: {type: string}
|
||||
roleIds: {type: array, items: {type: integer, format: int64}}
|
||||
AddressRequest:
|
||||
type: object
|
||||
required: [addressType, detail]
|
||||
properties:
|
||||
addressType: {type: string, enum: [OPERATING, BILLING, RETURN]}
|
||||
countryCode: {type: string, example: CN}
|
||||
province: {type: string}
|
||||
city: {type: string}
|
||||
district: {type: string}
|
||||
detail: {type: string}
|
||||
postalCode: {type: string}
|
||||
isDefault: {type: boolean}
|
||||
QualificationRequest:
|
||||
type: object
|
||||
required: [qualificationType, documentUrl]
|
||||
properties:
|
||||
qualificationType: {type: string, example: BUSINESS_LICENSE}
|
||||
certificateNo: {type: string}
|
||||
documentUrl: {type: string, format: uri}
|
||||
validFrom: {type: string, format: date}
|
||||
validTo: {type: string, format: date}
|
||||
CreateRoleRequest:
|
||||
type: object
|
||||
required: [roleCode, roleName]
|
||||
properties:
|
||||
roleCode: {type: string, example: ORDER_OPERATOR}
|
||||
roleName: {type: string, example: 订单操作员}
|
||||
description: {type: string}
|
||||
CreatePermissionRequest:
|
||||
type: object
|
||||
required: [type, code, name]
|
||||
properties:
|
||||
type: {type: string, enum: [MENU, PAGE, BUTTON, API], example: BUTTON}
|
||||
code: {type: string, example: 'order:firstleg:submit'}
|
||||
name: {type: string, example: 提交头程订单}
|
||||
parentId: {type: integer, format: int64, example: 0}
|
||||
routePath: {type: string}
|
||||
httpMethod: {type: string, enum: [GET, POST, PUT, PATCH, DELETE]}
|
||||
sortNo: {type: integer, example: 10}
|
||||
AssignRolesRequest:
|
||||
type: object
|
||||
required: [membershipId, roleIds]
|
||||
properties:
|
||||
membershipId: {type: integer, format: int64}
|
||||
roleIds: {type: array, items: {type: integer, format: int64}}
|
||||
GrantPermissionsRequest:
|
||||
type: object
|
||||
required: [roleId, permissionIds]
|
||||
properties:
|
||||
roleId: {type: integer, format: int64}
|
||||
permissionIds: {type: array, items: {type: integer, format: int64}}
|
||||
Reference in New Issue
Block a user