feat(types): 添加express.d.ts类型引用 style: 格式化express.d.ts中的接口定义 refactor: 移除未使用的AntFC类型导入 chore: 删除自动生成的.umi-production文件 feat: 添加店铺管理相关表和初始化脚本 docs: 更新安全规则和交互指南文档 refactor: 统一使用FC类型替代React.FC perf: 优化图表组件导入方式 style: 添加.prettierrc配置文件 refactor: 调整组件导入顺序和结构 feat: 添加平台库存管理路由 fix: 修复订单同步时的库存检查逻辑 docs: 更新RBAC设计和租户管理文档 refactor: 优化部门控制器代码
15 KiB
15 KiB
用户层级架构文档与实际代码差异分析
分析日期: 2026-03-29 文档版本: 用户层级架构说明.md v1.1 代码版本: server/src
1. 表名差异
| 文档中的表名 | 实际代码中的表名 | 说明 |
|---|---|---|
cf_users |
cf_user |
复数/单数差异 |
cf_tenants |
cf_tenant |
复数/单数差异 |
cf_departments |
cf_department |
复数/单数差异 |
cf_role_permissions |
cf_role_permission |
复数/单数差异 |
cf_shop_auth |
不存在 | 文档中提到但代码中未实现 |
2. 用户表 (cf_user) 差异
文档中的字段
id VARCHAR(36) PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE,
password_hash VARCHAR(255) NOT NULL,
role VARCHAR(20) DEFAULT 'OPERATOR',
tenant_id VARCHAR(36) NOT NULL,
dept_id VARCHAR(36),
status ENUM('active', 'inactive', 'suspended') DEFAULT 'active',
last_login_at TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
实际代码中的字段
id VARCHAR(36) PRIMARY KEY,
tenant_id VARCHAR(36) NOT NULL,
username VARCHAR(64) NOT NULL UNIQUE,
email VARCHAR(128) NOT NULL UNIQUE,
password_hash VARCHAR(255) NOT NULL,
full_name VARCHAR(128) NOT NULL,
phone VARCHAR(32),
status ENUM('ACTIVE', 'INACTIVE', 'LOCKED') DEFAULT 'ACTIVE'),
role ENUM('ADMIN', 'MANAGER', 'OPERATOR', 'FINANCE', 'SOURCING', 'LOGISTICS', 'ANALYST') NOT NULL,
is_superadmin BOOLEAN DEFAULT FALSE,
last_login_by VARCHAR(36),
last_login_at TIMESTAMP,
created_by VARCHAR(36) NOT NULL,
updated_by VARCHAR(36) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
差异点
| 字段 | 文档 | 实际代码 | 差异说明 |
|---|---|---|---|
username |
VARCHAR(50) | VARCHAR(64) | 长度不同 |
email |
VARCHAR(100) | VARCHAR(128) | 长度不同 |
dept_id |
✅ 存在 | ❌ 不存在 | 实际代码中没有部门ID字段 |
full_name |
❌ 不存在 | ✅ 存在 | 实际代码中有全名字段 |
phone |
❌ 不存在 | ✅ 存在 | 实际代码中有电话字段 |
is_superadmin |
❌ 不存在 | ✅ 存在 | 实际代码中有超级管理员标识 |
created_by |
❌ 不存在 | ✅ 存在 | 实际代码中有创建人字段 |
updated_by |
❌ 不存在 | ✅ 存在 | 实际代码中有更新人字段 |
status |
小写枚举 | 大写枚举 | 命名风格不同 |
role |
字符串 | 枚举类型 | 类型定义不同 |
3. 租户表 (cf_tenant) 差异
文档中的字段
id VARCHAR(36) PRIMARY KEY,
name VARCHAR(100) NOT NULL,
type ENUM('SAAS', 'ENTERPRISE', 'TRIAL') DEFAULT 'SAAS',
status ENUM('ACTIVE', 'SUSPENDED', 'CANCELLED') DEFAULT 'ACTIVE',
plan_id VARCHAR(36),
quota_config JSON,
settings JSON,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
实际代码中的字段
id VARCHAR(36) PRIMARY KEY,
name VARCHAR(128) NOT NULL UNIQUE,
domain VARCHAR(128) NOT NULL UNIQUE,
contact_name VARCHAR(64) NOT NULL,
contact_email VARCHAR(128) NOT NULL UNIQUE,
contact_phone VARCHAR(32) NOT NULL,
address VARCHAR(255) NOT NULL,
status ENUM('ACTIVE', 'INACTIVE', 'SUSPENDED') DEFAULT 'ACTIVE'),
quota_limit DECIMAL(10, 2) DEFAULT 10000,
quota_used DECIMAL(10, 2) DEFAULT 0,
created_by VARCHAR(36) NOT NULL,
updated_by VARCHAR(36) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
差异点
| 字段 | 文档 | 实际代码 | 差异说明 |
|---|---|---|---|
name |
VARCHAR(100) | VARCHAR(128) | 长度不同 |
type |
✅ 存在 | ❌ 不存在 | 实际代码中没有租户类型字段 |
plan_id |
✅ 存在 | ❌ 不存在 | 实际代码中没有套餐ID字段 |
quota_config |
✅ 存在 | ❌ 不存在 | 实际代码中没有JSON配置字段 |
settings |
✅ 存在 | ❌ 不存在 | 实际代码中没有JSON设置字段 |
domain |
❌ 不存在 | ✅ 存在 | 实际代码中有域名字段 |
contact_name |
❌ 不存在 | ✅ 存在 | 实际代码中有联系人姓名字段 |
contact_email |
❌ 不存在 | ✅ 存在 | 实际代码中有联系人邮箱字段 |
contact_phone |
❌ 不存在 | ✅ 存在 | 实际代码中有联系人电话字段 |
address |
❌ 不存在 | ✅ 存在 | 实际代码中有地址字段 |
quota_limit |
❌ 不存在 | ✅ 存在 | 实际代码中有配额限制字段 |
quota_used |
❌ 不存在 | ✅ 存在 | 实际代码中有已用配额字段 |
created_by |
❌ 不存在 | ✅ 存在 | 实际代码中有创建人字段 |
updated_by |
❌ 不存在 | ✅ 存在 | 实际代码中有更新人字段 |
4. 部门表 (cf_department) 差异
文档中的字段
id VARCHAR(36) PRIMARY KEY,
tenant_id VARCHAR(36) NOT NULL,
parent_id VARCHAR(36),
name VARCHAR(100) NOT NULL,
manager_id VARCHAR(36),
path VARCHAR(500),
depth INT DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (tenant_id) REFERENCES cf_tenants(id),
INDEX idx_tenant_path (tenant_id, path)
实际代码中的字段(HierarchyService.ts中定义)
id VARCHAR(36) PRIMARY KEY,
tenant_id VARCHAR(36) NOT NULL,
name VARCHAR(128) NOT NULL,
parent_id VARCHAR(36),
path VARCHAR(500),
depth INT DEFAULT 0,
manager_id VARCHAR(36),
status ENUM('ACTIVE', 'INACTIVE') DEFAULT 'ACTIVE',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
差异点
| 字段 | 文档 | 实际代码 | 差异说明 |
|---|---|---|---|
name |
VARCHAR(100) | VARCHAR(128) | 长度不同 |
status |
❌ 不存在 | ✅ 存在 | 实际代码中有状态字段 |
updated_at |
❌ 不存在 | ✅ 存在 | 实际代码中有更新时间字段 |
5. 角色权限表 (cf_role_permission) 差异
文档中的字段
id VARCHAR(36) PRIMARY KEY,
role_key VARCHAR(50) NOT NULL,
permission_key VARCHAR(100) NOT NULL,
tenant_id VARCHAR(36),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY uk_role_perm (role_key, permission_key, tenant_id)
实际代码中的字段
id VARCHAR(36) PRIMARY KEY,
role_id VARCHAR(36) NOT NULL,
permission_id VARCHAR(36) NOT NULL,
created_by VARCHAR(36) NOT NULL,
updated_by VARCHAR(36) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uk_role_perm (role_id, permission_id),
FOREIGN KEY (role_id) REFERENCES cf_role(id) ON DELETE CASCADE,
FOREIGN KEY (permission_id) REFERENCES cf_permission(id) ON DELETE CASCADE
差异点
| 字段 | 文档 | 实际代码 | 差异说明 |
|---|---|---|---|
role_key |
✅ 存在 | ❌ 不存在 | 实际代码中是role_id |
permission_key |
✅ 存在 | ❌ 不存在 | 实际代码中是permission_id |
tenant_id |
✅ 存在 | ❌ 不存在 | 实际代码中没有租户ID字段 |
created_by |
❌ 不存在 | ✅ 存在 | 实际代码中有创建人字段 |
updated_by |
❌ 不存在 | ✅ 存在 | 实际代码中有更新人字段 |
updated_at |
❌ 不存在 | ✅ 存在 | 实际代码中有更新时间字段 |
6. 数据范围类型差异
文档中的数据范围类型
| 类型 | 说明 | SQL过滤条件 | 适用角色 |
|---|---|---|---|
| SELF | 只看自己创建的数据 | WHERE created_by = {userId} |
普通员工 |
| TEAM | 看自己组的数据 | WHERE team_id IN ({userTeams}) |
组长 |
| DEPT | 看自己部门的数据 | WHERE dept_id IN ({userDepts}) |
部门主管 |
| ORG | 看整个公司的数据 | WHERE tenant_id = {tenantId} |
高管 |
| ALL | 全平台数据(超管) | 无过滤 | 系统管理员 |
实际代码中的数据范围类型(RBACEngine.ts)
export interface DataScope {
type: 'ALL' | 'ORG' | 'DEPT' | 'SHOP' | 'OWN';
departmentId?: string;
shopId?: string;
}
差异点
| 文档类型 | 实际代码类型 | 差异说明 |
|---|---|---|
| SELF | OWN | 实际代码中是OWN而不是SELF |
| TEAM | SHOP | 实际代码中是SHOP而不是TEAM |
| DEPT | DEPT | 一致 |
| ORG | ORG | 一致 |
| ALL | ALL | 一致 |
7. 服务实现差异
DataScopeService
- 文档中: 提到
DataScopeService类,包含getUserDataScope和applyDataScope方法 - 实际代码: 不存在
DataScopeService类 - 实际实现: 数据隔离功能通过
DataIsolationService实现
HierarchyService
- 文档中的方法签名:
static async getUserHierarchyPath(userId: string): Promise<string[]>; static async getSubDepartments(deptId: string): Promise<Department[]>; static async getDepartmentUsers(deptId: string): Promise<User[]>; static async transferUser(userId: string, targetDeptId: string): Promise<void>; static async getDepartmentStats(deptId: string): Promise<DeptStats>; - 实际代码中的方法:
static async initializeTenantHierarchy(tenantId: string): Promise<void>; static async createDepartment(tenantId: string, name: string, parentId?: string): Promise<Department>; static async updateDepartment(deptId: string, updates: Partial<Department>): Promise<void>; static async deleteDepartment(deptId: string): Promise<void>; static async getDepartmentTree(tenantId: string): Promise<HierarchyNode[]>; static async getDepartmentStats(deptId: string): Promise<HierarchyStats>; static async transferUser(userId: string, targetDeptId: string): Promise<void>; static async createShop(tenantId: string, deptId: string, shopData: Partial<Shop>): Promise<Shop>; static async updateShop(shopId: string, updates: Partial<Shop>): Promise<void>; static async deleteShop(shopId: string): Promise<void>; static async getShopTree(tenantId: string): Promise<HierarchyNode[]>; static async assignUserToShop(userId: string, shopId: string): Promise<void>; static async removeUserFromShop(userId: string): Promise<void>;
AuthService
- 文档中的方法签名:
static async login(credentials: LoginCredentials): Promise<AuthResult>; static async verifyToken(token: string): Promise<TokenPayload>; static async refreshToken(refreshToken: string): Promise<AuthResult>; static async logout(userId: string): Promise<void>; - 实际代码中的方法:
static async login(input: LoginInput): Promise<LoginResult>; static async register(input: RegisterInput): Promise<RegisterResult>; static async passwordReset(input: PasswordResetInput): Promise<PasswordResetResult>; static async checkPermission(input: PermissionCheckInput): Promise<PermissionCheckResult>; static async getUserPermissions(input: UserPermissionsInput): Promise<UserPermissionsResult>; static async assignRole(input: AssignRoleInput): Promise<boolean>; static async removeRole(input: RemoveRoleInput): Promise<boolean>;
8. 权限点设计差异
文档中的权限点命名规范
const PERMISSIONS = {
'product:read': '查看商品',
'product:create': '创建商品',
'product:update': '更新商品',
'product:delete': '删除商品',
'product:export': '导出商品',
'product:import': '导入商品',
// ... 其他权限
};
实际代码中的权限点(RBACEngine.ts)
const PERMISSIONS: Permission[] = [
{ id: 'admin:all', name: '超级管理员', description: '拥有所有系统权限', module: 'SYSTEM', action: 'EXECUTE' },
{ id: 'product:read', name: '查看商品', description: '允许查看商品列表与详情', module: 'PRODUCT', action: 'READ' },
{ id: 'product:write', name: '编辑商品', description: '允许创建和修改商品信息', module: 'PRODUCT', action: 'WRITE' },
{ id: 'product:delete', name: '删除商品', description: '允许删除商品', module: 'PRODUCT', action: 'DELETE' },
{ id: 'product:publish', name: '发布商品', description: '允许执行商品刊登任务', module: 'PRODUCT', action: 'EXECUTE' },
{ id: 'product:score', name: '商品评分', description: '允许查看AI选品评分', module: 'PRODUCT', action: 'READ' },
{ id: 'order:read', name: '查看订单', description: '允许查看销售订单', module: 'ORDER', action: 'READ' },
{ id: 'order:write', name: '创建订单', description: '允许创建订单', module: 'ORDER', action: 'WRITE' },
{ id: 'order:cancel', name: '取消订单', description: '允许取消订单', module: 'ORDER', action: 'EXECUTE' },
{ id: 'order:refund', name: '退款处理', description: '允许处理退款', module: 'ORDER', action: 'EXECUTE' },
// ... 更多权限
];
差异点
| 差异 | 说明 |
|---|---|
| 权限结构 | 实际代码使用Permission对象数组,包含id、name、description、module、action字段 |
| 模块划分 | 实际代码按模块划分(PRODUCT、ORDER、INVENTORY、FINANCE、ADVERTISING、SOURCING、LOGISTICS、AI、COLLECTION、USER、TENANT、AUDIT) |
| 操作类型 | 实际代码使用READ、WRITE、DELETE、EXECUTE四种操作类型 |
| 权限数量 | 实际代码中定义了50+个权限点,比文档中更详细 |
9. 建议修正
9.1 表名统一
建议将文档中的表名统一为实际代码中的单数形式:
cf_users→cf_usercf_tenants→cf_tenantcf_departments→cf_departmentcf_role_permissions→cf_role_permission
9.2 字段定义更新
建议更新文档中的字段定义,与实际代码保持一致:
- 添加缺失的字段(如
full_name、phone、is_superadmin等) - 删除不存在的字段(如
dept_id、type、plan_id等) - 更新字段类型和长度(如
username从VARCHAR(50)改为VARCHAR(64))
9.3 数据范围类型更新
建议将文档中的数据范围类型更新为实际代码中的定义:
SELF→OWNTEAM→SHOP- 保持
DEPT、ORG、ALL不变
9.4 服务方法签名更新
建议更新文档中的服务方法签名,与实际代码保持一致:
HierarchyService方法签名更新AuthService方法签名更新- 删除不存在的
DataScopeService引用
9.5 权限点设计更新
建议更新文档中的权限点设计,与实际代码中的RBACEngine保持一致:
- 使用
Permission对象结构 - 按模块划分权限
- 使用READ、WRITE、DELETE、EXECUTE操作类型
9.6 店铺授权表
建议删除文档中关于cf_shop_auth表的描述,因为实际代码中不存在此表。
10. 总结
| 差异类型 | 数量 | 严重程度 |
|---|---|---|
| 表名不一致 | 5 | 🟡 中等 |
| 字段缺失 | 15+ | 🔴 严重 |
| 字段类型不一致 | 8 | 🟡 中等 |
| 数据范围类型不一致 | 2 | 🟡 中等 |
| 服务方法签名不一致 | 3 | 🟡 中等 |
| 权限点设计不一致 | 1 | 🟡 中等 |
总体评估: 文档与实际代码存在较多差异,建议尽快更新文档以保持一致性。