Files
makemd/docs/用户层级架构说明.md
wurenzhi 1b14947e7b refactor: 优化代码结构和类型定义
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: 优化部门控制器代码
2026-03-30 01:20:57 +08:00

913 lines
32 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 用户层级架构说明
> **文档版本**: 1.2
> **最后更新**: 2026-03-29
> **更新内容**: 根据实际代码更新表名、字段定义、数据范围类型、服务方法签名、权限点设计,删除不存在的表和服务引用
> **适用范围**: Crawlful Hub 多租户用户管理体系
---
## 1. 多租户层级结构
Crawlful Hub 采用多层级的用户架构设计,确保数据隔离和权限控制:
```
平台Platform
商户/公司Tenant/Organization
组织结构Org Tree
├── 部门A主管
│ ├── 组A1组长
│ │ ├── 员工1
│ │ └── 员工2
│ └── 组A2组长
│ └── 员工3
└── 部门B主管
└── ...
```
### 1.1 层级关系说明
| 层级 | 英文 | 描述 | 数据隔离级别 |
|------|------|------|-------------|
| **平台** | Platform | 系统运营方,管理所有租户 | 全局管理 |
| **租户** | Tenant | 企业/商户,拥有独立数据空间 | 完全隔离 |
| **部门** | Department | 租户内的组织结构 | 层级隔离 |
| **店铺** | Shop | 具体电商平台的店铺 | 业务隔离 |
| **用户** | User | 系统使用者 | 权限控制 |
---
## 2. 核心层级模型
### 2.1 层级关系详解
#### 商户 (Merchant/Tenant)
- **定义**: 最高业务层级,代表一个独立的企业或组织
- **属性**: 商户ID、名称、认证状态、计费套餐、配额限制
- **管理**: 由平台管理员创建,商户管理员管理
- **数据**: 所有数据归属于特定租户,完全隔离
#### 部门 (Department)
- **定义**: 商户内的组织结构单元
- **属性**: 部门ID、名称、父部门ID、层级路径(path)、深度(depth)
- **管理**: 商户管理员创建和管理部门层级
- **特性**: 支持多级嵌套,形成树形结构
#### 店铺 (Shop)
- **定义**: 具体的电商平台店铺如Amazon、TikTok店铺
- **属性**: 店铺ID、平台类型、授权状态、所属部门
- **管理**: 可分配给特定部门或用户组
- **隔离**: 店铺间操作互不影响
#### 用户 (User)
- **定义**: 系统的实际使用者
- **属性**: 用户ID、用户名、邮箱、角色、所属租户/部门
- **状态**: active(活跃)、inactive(未激活)、suspended(暂停)、deleted(已删除)
### 2.2 数据隔离机制
#### 租户隔离
```sql
-- 所有业务表必须包含 tenant_id 字段
SELECT * FROM cf_products WHERE tenant_id = 'tenant_xxx';
SELECT * FROM cf_orders WHERE tenant_id = 'tenant_xxx';
```
#### 部门隔离
```sql
-- 通过部门路径实现层级数据访问
SELECT * FROM cf_user
WHERE tenant_id = 'tenant_xxx'
AND dept_path LIKE '/dept_a/%';
```
#### 店铺隔离
```sql
-- 店铺级别数据过滤
SELECT * FROM cf_products
WHERE tenant_id = 'tenant_xxx'
AND shop_id = 'shop_xxx';
```
---
## 3. 权限系统RBAC
### 3.1 系统级角色定义
| 角色 | 英文 | 描述 | 权限范围 |
|------|------|------|----------|
| **ADMIN** | 系统管理员 | 平台运营方 | 所有资源的所有操作 |
| **MANAGER** | 运营主管 | 租户内高级管理 | 租户内大部分资源的管理操作 |
| **OPERATOR** | 运营专员 | 日常运营人员 | 基础运营操作(商品、订单) |
| **FINANCE** | 财务主管 | 财务人员 | 财务相关操作(账单、结算) |
| **SOURCING** | 采购专家 | 采购人员 | 采购相关操作(供应商、选品) |
| **LOGISTICS** | 物流专家 | 物流人员 | 物流相关操作(发货、跟踪) |
| **ANALYST** | 数据分析师 | 数据分析人员 | 数据分析相关操作(报表、洞察) |
### 3.2 店铺级角色定义
| 角色 | 描述 | 权限范围 | 适用场景 |
|------|------|----------|----------|
| **owner** | 拥有者 | 删除店铺、管理授权、管理成员、所有权限 | 店铺创建者 |
| **admin** | 管理员 | 管理商品、管理价格、管理订单、不可删除店铺 | 店铺运营主管 |
| **operator** | 运营 | 刊登、改价、查看数据 | 日常运营人员 |
| **viewer** | 只读 | 查看数据、不可操作 | 仅查看报表人员 |
### 3.3 权限点设计
```typescript
// 权限对象结构
export interface Permission {
id: string; // 权限ID格式资源:操作
name: string; // 权限名称
description: string; // 权限描述
module: string; // 所属模块
action: 'READ' | 'WRITE' | 'DELETE' | 'EXECUTE'; // 操作类型
}
// 权限点定义(按模块划分)
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' },
// 库存权限
{ id: 'inventory:read', name: '查看库存', description: '允许查看库存数据', module: 'INVENTORY', action: 'READ' },
{ id: 'inventory:write', name: '编辑库存', description: '允许调整库存', module: 'INVENTORY', action: 'WRITE' },
{ id: 'inventory:sync', name: '库存同步', description: '允许执行跨平台库存同步', module: 'INVENTORY', action: 'EXECUTE' },
{ id: 'inventory:alert', name: '库存预警', description: '允许配置库存预警', module: 'INVENTORY', action: 'EXECUTE' },
// 财务权限
{ id: 'finance:read', name: '查看财务', description: '允许查看财务数据', module: 'FINANCE', action: 'READ' },
{ id: 'finance:recon', name: '财务对账', description: '允许执行自动化对账', module: 'FINANCE', action: 'EXECUTE' },
{ id: 'finance:settlement', name: '结算管理', description: '允许处理结算', module: 'FINANCE', action: 'EXECUTE' },
{ id: 'finance:report', name: '财务报表', description: '允许查看财务报表', module: 'FINANCE', action: 'READ' },
// 广告权限
{ id: 'ad:read', name: '查看广告', description: '允许查看广告数据', module: 'ADVERTISING', action: 'READ' },
{ id: 'ad:write', name: '编辑广告', description: '允许创建和修改广告', module: 'ADVERTISING', action: 'WRITE' },
{ id: 'ad:launch', name: '投放广告', description: '允许执行广告投放', module: 'ADVERTISING', action: 'EXECUTE' },
{ id: 'ad:optimize', name: '广告优化', description: '允许执行AI广告优化', module: 'ADVERTISING', action: 'EXECUTE' },
// 采购权限
{ id: 'sourcing:read', name: '查看采购', description: '允许查看采购数据', module: 'SOURCING', action: 'READ' },
{ id: 'sourcing:write', name: '编辑采购', description: '允许创建采购单', module: 'SOURCING', action: 'WRITE' },
{ id: 'sourcing:approve', name: '采购审批', description: '允许审批采购单', module: 'SOURCING', action: 'EXECUTE' },
// 物流权限
{ id: 'logistics:read', name: '查看物流', description: '允许查看物流数据', module: 'LOGISTICS', action: 'READ' },
{ id: 'logistics:write', name: '编辑物流', description: '允许配置物流', module: 'LOGISTICS', action: 'WRITE' },
{ id: 'logistics:track', name: '物流追踪', description: '允许追踪物流状态', module: 'LOGISTICS', action: 'EXECUTE' },
// AI权限
{ id: 'ai:read', name: '查看AI分析', description: '允许查看AI分析结果', module: 'AI', action: 'READ' },
{ id: 'ai:scoring', name: 'AI选品评分', description: '允许执行AI选品评分', module: 'AI', action: 'EXECUTE' },
{ id: 'ai:arbitrage', name: '套利识别', description: '允许执行套利机会识别', module: 'AI', action: 'EXECUTE' },
{ id: 'ai:pricing', name: '智能定价', description: '允许执行智能定价建议', module: 'AI', action: 'EXECUTE' },
{ id: 'ai:monitor', name: '价格监控', description: '允许配置竞争对手价格监控', module: 'AI', action: 'EXECUTE' },
// 采集权限
{ id: 'collection:read', name: '查看采集', description: '允许查看采集任务', module: 'COLLECTION', action: 'READ' },
{ id: 'collection:write', name: '编辑采集', description: '允许创建采集任务', module: 'COLLECTION', action: 'WRITE' },
{ id: 'collection:execute', name: '执行采集', description: '允许执行采集任务', module: 'COLLECTION', action: 'EXECUTE' },
// 用户权限
{ id: 'user:read', name: '查看用户', description: '允许查看用户列表', module: 'USER', action: 'READ' },
{ id: 'user:write', name: '编辑用户', description: '允许创建和修改用户', module: 'USER', action: 'WRITE' },
{ id: 'user:role', name: '角色管理', description: '允许分配用户角色', module: 'USER', action: 'EXECUTE' },
// 租户权限
{ id: 'tenant:read', name: '查看租户', description: '允许查看租户信息', module: 'TENANT', action: 'READ' },
{ id: 'tenant:write', name: '编辑租户', description: '允许修改租户配置', module: 'TENANT', action: 'WRITE' },
{ id: 'tenant:config', name: '租户配置', description: '允许配置租户设置', module: 'TENANT', action: 'EXECUTE' },
// 审计权限
{ id: 'audit:read', name: '查看审计', description: '允许查看审计日志', module: 'AUDIT', action: 'READ' },
{ id: 'audit:export', name: '导出审计', description: '允许导出审计日志', module: 'AUDIT', action: 'EXECUTE' },
];
```
---
## 4. 数据范围控制
### 4.1 数据范围类型
| 范围类型 | 英文 | 说明 | SQL过滤条件 | 适用角色 |
|---------|------|------|------------|---------|
| **OWN** | Own | 只看自己创建的数据 | `WHERE created_by = {userId}` | 普通员工 |
| **SHOP** | Shop | 看自己店铺的数据 | `WHERE shop_id IN ({userShops})` | 店铺管理员 |
| **DEPT** | Department | 看自己部门的数据 | `WHERE dept_id IN ({userDepts})` | 部门主管 |
| **ORG** | Organization | 看整个公司的数据 | `WHERE tenant_id = {tenantId}` | 高管 |
| **ALL** | All | 全平台数据(超管) | 无过滤 | 系统管理员 |
### 4.2 数据范围实现
```typescript
// 数据范围接口
export interface DataScope {
type: 'ALL' | 'ORG' | 'DEPT' | 'SHOP' | 'OWN';
departmentId?: string;
shopId?: string;
}
// 数据隔离服务
export class DataIsolationService {
static async getUserDataScope(userId: string): Promise<DataScope> {
const user = await UserService.getUserById(userId);
const role = user.role;
switch(role) {
case 'ADMIN':
return { type: 'ALL' };
case 'MANAGER':
return { type: 'ORG', tenantId: user.tenantId };
case 'DEPT_MANAGER':
const depts = await DepartmentService.getSubDepartments(user.deptId);
return { type: 'DEPT', deptIds: depts.map(d => d.id) };
default:
return { type: 'OWN', userId };
}
}
static applyDataScope(query: Knex.QueryBuilder, scope: DataScope): Knex.QueryBuilder {
switch(scope.type) {
case 'OWN':
return query.where('created_by', scope.userId);
case 'SHOP':
return query.whereIn('shop_id', scope.shopIds);
case 'DEPT':
return query.whereIn('dept_id', scope.deptIds);
case 'ORG':
return query.where('tenant_id', scope.tenantId);
case 'ALL':
default:
return query;
}
}
}
```
### 4.3 授权模型
**核心原则**
---
## 5. 技术实现
### 5.1 数据模型
#### 用户表 (`cf_user`)
```sql
CREATE TABLE cf_user (
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,
INDEX idx_tenant (tenant_id),
INDEX idx_email (email),
FOREIGN KEY (tenant_id) REFERENCES cf_tenant(id) ON DELETE CASCADE
);
```
#### 租户表 (`cf_tenant`)
```sql
CREATE TABLE cf_tenant (
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,
INDEX (domain),
INDEX (status)
);
```
#### 部门表 (`cf_department`)
```sql
CREATE TABLE cf_department (
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 ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (tenant_id) REFERENCES cf_tenant(id),
INDEX idx_tenant_path (tenant_id, path)
);
```
#### 角色权限表 (`cf_role_permission`)
```sql
CREATE TABLE cf_role_permission (
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
);
```
### 5.2 核心服务
#### HierarchyService - 层级服务
```typescript
export class HierarchyService {
// 初始化租户层级结构
static async initializeTenantHierarchy(tenantId: string): Promise<void>;
// 创建部门
static async createDepartment(
tenantId: string,
name: string,
parentId?: string,
managerId?: string
): Promise<Department>;
// 更新部门
static async updateDepartment(
departmentId: string,
updates: Partial<Department>
): Promise<void>;
// 删除部门
static async deleteDepartment(departmentId: string, tenantId: string): Promise<void>;
// 分配部门经理
static async assignDepartmentManager(
departmentId: string,
managerId: string,
tenantId: string
): Promise<void>;
// 获取部门经理
static async getDepartmentManager(departmentId: string, tenantId: string): Promise<any>;
// 获取部门统计
static async getDepartmentStats(departmentId: string, tenantId: string): Promise<any>;
// 创建店铺
static async createShop(
tenantId: string,
departmentId: string,
shopData: Partial<Shop>
): Promise<Shop>;
// 更新店铺
static async updateShop(shopId: string, updates: Partial<Shop>): Promise<void>;
// 删除店铺
static async deleteShop(shopId: string, tenantId: string): Promise<void>;
// 获取层级统计
static async getHierarchyStats(tenantId: string): Promise<HierarchyStats>;
// 获取部门树
static async getDepartmentTree(tenantId: string): Promise<HierarchyNode[]>;
// 获取部门下的店铺
static async getDepartmentShops(departmentId: string, tenantId: string): Promise<Shop[]>;
// 获取用户层级上下文
static async getUserHierarchyContext(userId: string): Promise<{
departmentId?: string;
departmentPath?: string;
shopIds: string[];
}>;
// 更新用户层级
static async updateUserHierarchy(
userId: string,
updates: { departmentId?: string; shopIds?: string[] }
): Promise<void>;
}
```
#### RBACService - 权限服务
```typescript
export class RBACService {
// 创建角色
static async createRole(roleData: RoleData): Promise<Role>;
// 为角色分配权限
static async assignPermissions(roleId: string, permissions: string[]): Promise<void>;
// 检查用户权限
static async checkPermission(userId: string, permission: string): Promise<boolean>;
// 获取用户所有权限
static async getUserPermissions(userId: string): Promise<string[]>;
// 权限审计
static async auditPermissionChange(auditData: AuditData): Promise<void>;
}
```
#### AuthService - 认证服务
```typescript
export class AuthService {
// 用户登录
static async login(input: LoginInput): Promise<LoginResult>;
// 用户注册
static async register(input: RegisterInput): Promise<RegisterResult>;
// 请求密码重置
static async requestPasswordReset(input: PasswordResetInput): Promise<PasswordResetResult>;
// 检查权限
static async checkPermission(input: PermissionCheckInput): Promise<PermissionCheckResult>;
// 获取用户权限列表
static async getUserPermissionsList(input: UserPermissionsInput): Promise<UserPermissionsResult>;
// 分配角色
static async assignRole(input: AssignRoleInput): Promise<AssignRoleResult>;
// 验证会话
static async validateSession(input: SessionValidationInput): Promise<SessionValidationResult>;
// 刷新Token
static async refreshToken(input: RefreshTokenInput): Promise<RefreshTokenResult>;
// 登出
static async logout(input: LogoutInput): Promise<LogoutResult>;
// 获取活跃会话
static async getActiveSessions(userId: string, tenantId: string): Promise<SessionInfo[]>;
// 初始化表
static async initializeTables(): Promise<void>;
}
```
### 5.3 权限检查中间件
```typescript
// Express 权限检查中间件
export function requirePermission(...permissions: string[]) {
return async (req: Request, res: Response, next: NextFunction) => {
const userId = req.user?.id;
if (!userId) {
return res.status(401).json({ error: 'Unauthorized' });
}
// 获取用户所有权限
const userPermissions = await RBACService.getUserPermissions(userId);
// 检查是否拥有所需权限
const hasPermission = permissions.some(p => userPermissions.includes(p));
if (!hasPermission) {
return res.status(403).json({
error: 'Permission denied',
required: permissions,
current: userPermissions
});
}
next();
};
}
// 数据范围中间件
export function applyDataScope(resourceType: string) {
return async (req: Request, res: Response, next: NextFunction) => {
const userId = req.user?.id;
const scope = await DataScopeService.getUserDataScope(userId);
// 将数据范围附加到请求对象
req.dataScope = scope;
next();
};
}
```
---
## 6. 安全考虑
### 6.1 安全原则
1. **最小权限原则**: 用户只获得完成工作所必需的最小权限
2. **权限分离**: 敏感操作需要多个权限组合
3. **定期审计**: 定期审查权限配置,清理无效权限
4. **数据加密**: 敏感数据加密存储和传输
5. **访问控制**: 严格的身份验证和访问控制
### 6.2 安全措施
| 安全措施 | 实现方式 | 状态 |
|---------|---------|------|
| **强密码策略** | 密码复杂度检查、定期更换 | ⚠️ 待实现 |
| **双因素认证(2FA)** | TOTP/短信验证码 | ✅ 已实现 |
| **登录异常检测** | 异常IP、时间、地点检测 | ⚠️ 待实现 |
| **权限边界检查** | 防止水平/垂直权限提升 | ✅ 已实现 |
| **敏感数据加密** | AES-256加密存储 | ✅ 已实现 |
| **审计日志** | 记录所有权限变更和数据访问 | ✅ 已实现 |
| **会话管理** | Token过期、单点登录限制 | ✅ 已实现 |
| **API限流** | 基于用户/租户的请求限流 | ✅ 已实现 |
### 6.3 审计日志
```typescript
// 审计日志记录
export class AuditService {
static async log(data: {
tenantId: string;
userId: string;
action: string;
resource: string;
resourceId?: string;
oldValue?: any;
newValue?: any;
ip?: string;
userAgent?: string;
}): Promise<void> {
await db('cf_audit_log').insert({
id: uuidv4(),
...data,
created_at: new Date()
});
}
}
```
---
## 7. 管理功能
### 7.1 后台管理系统架构
```
后台管理系统
├── 用户与权限管理
│ ├── 用户管理
│ │ ├── 用户列表
│ │ ├── 用户创建/编辑
│ │ ├── 用户禁用/启用
│ │ └── 用户登录日志
│ ├── 角色管理
│ │ ├── 角色列表
│ │ ├── 角色创建/编辑
│ │ ├── 权限分配
│ │ └── 角色成员
│ ├── 权限管理
│ │ ├── 权限列表
│ │ ├── 权限树
│ │ └── 权限分析
│ └── 部门管理
│ ├── 部门树
│ ├── 部门创建/编辑
│ ├── 部门成员
│ └── 部门统计
├── 租户管理
│ ├── 租户列表
│ ├── 租户创建/编辑
│ ├── 租户配置
│ ├── 配额管理
│ ├── 租户隔离
│ └── 租户数据备份
├── 店铺管理
│ ├── 我的店铺
│ │ ├── 店铺列表(卡片形式)
│ │ ├── 店铺状态(已连接/已过期/错误)
│ │ ├── 编辑店铺配置
│ │ ├── 刷新授权
│ │ ├── 管理成员
│ │ └── 删除店铺
│ ├── 店铺成员管理
│ │ ├── 侧边栏:我的店铺列表
│ │ ├── 主区域:当前店铺的成员列表
│ │ ├── 添加成员
│ │ ├── 修改成员角色
│ │ └── 移除成员
│ └── 用户店铺管理
│ ├── 查看用户拥有的店铺
│ ├── 添加用户到店铺
│ ├── 移除用户的店铺权限
│ └── 批量分配店铺
└── 系统监控
├── 审计日志
├── 登录日志
├── 操作日志
└── 系统告警
```
### 7.2 前端实现
| 功能页面 | 组件路径 | 状态 |
|---------|---------|------|
| 用户管理 | `pages/Settings/UserManagement.tsx` | ✅ 已实现 |
| 角色管理 | `pages/Settings/RoleManagement.tsx` | ✅ 已实现 |
| 部门管理 | `pages/Settings/DepartmentManagement.tsx` | ✅ 已实现 |
| 租户设置 | `pages/Settings/TenantSettings.tsx` | ✅ 已实现 |
| 订阅管理 | `pages/Settings/SubscriptionManage.tsx` | ✅ 已实现 |
| 我的店铺 | `pages/Settings/MyShops.tsx` | ✅ 已实现 |
| 店铺成员管理 | `pages/Settings/ShopMemberManagement.tsx` | ✅ 已实现 |
| 系统监控 | `pages/Monitoring/SystemStatus.tsx` | ✅ 已实现 |
| 操作日志 | `pages/OperationLogs/index.tsx` | ✅ 已实现 |
### 7.3 店铺管理流程
#### 7.3.1 店铺视角管理(我的店铺)
**页面路径**: `/dashboard/settings/my-shops`
**功能说明**:
- 显示用户拥有的所有店铺(卡片形式)
- 每个店铺卡片显示:
- 店铺名称
- 平台类型(带图标)
- 授权状态(已连接/已过期/错误)
- 成员数量
- 最后同步时间
- 操作按钮:
- **管理成员**:跳转到店铺成员管理页面
- **编辑配置**:修改店铺名称、平台配置
- **刷新授权**:刷新过期的店铺授权
- **删除店铺**:删除店铺及其成员关系
**使用场景**:
1. 用户登录系统
2. 进入"我的店铺"页面
3. 查看自己拥有的所有店铺
4. 点击某个店铺的"管理成员"按钮
5. 进入店铺成员管理页面
#### 7.3.2 店铺成员管理
**页面路径**: `/dashboard/settings/shop-members/:shopId`
**功能说明**:
- **左侧边栏**:我的店铺列表
- 显示用户拥有的所有店铺
- 当前选中的店铺高亮
- 显示每个店铺的成员数量
- 点击切换店铺
- **右侧主区域**:当前店铺的成员列表
- 显示成员信息(用户名、邮箱、角色、权限)
- 添加成员(选择用户,分配角色和权限)
- 修改成员角色(下拉选择)
- 移除成员
**使用场景**:
1. 从"我的店铺"页面点击"管理成员"
2. 进入店铺成员管理页面
3. 左侧边栏显示我的店铺列表
4. 选择要管理的店铺
5. 右侧显示该店铺的成员列表
6. 添加/修改/移除成员
#### 7.3.3 用户视角管理(用户店铺分配)
**页面路径**: `/dashboard/settings/user`
**功能说明**:
- 在用户管理页面,每个用户有"管理店铺"按钮
- 点击后弹出店铺分配模态框
- 模态框功能:
- 按平台分组显示所有店铺
- 支持平台级别全选
- 支持单个店铺选择
- 显示已分配店铺列表
- 保存分配结果
**使用场景**:
1. 管理员进入用户管理页面
2. 点击某个用户的"管理店铺"按钮
3. 在弹出的模态框中:
- 查看该用户当前拥有的店铺
- 添加新的店铺权限
- 移除现有的店铺权限
4. 保存分配结果
### 7.4 双向管理关系
#### 7.4.1 店铺 → 用户管理
**入口**: 我的店铺 → 店铺成员管理
**操作流程**:
```
我的店铺页面
选择店铺 → 点击"管理成员"
店铺成员管理页面
左侧边栏:我的店铺列表
选择要管理的店铺
右侧主区域:当前店铺的成员列表
添加/修改/移除成员
```
**特点**:
- 店铺拥有者可以管理自己店铺的成员
- 可以添加、修改、删除成员
- 可以分配不同的角色和权限
- 侧边栏支持快速切换店铺
#### 7.4.2 用户 → 店铺管理
**入口**: 用户管理 → 管理店铺
**操作流程**:
```
用户管理页面
选择用户 → 点击"管理店铺"
店铺分配模态框
查看该用户拥有的店铺
添加/删除店铺权限
保存分配结果
```
**特点**:
- 管理员可以管理任何用户的店铺权限
- 可以批量分配多个店铺
- 支持按平台分组显示
- 可以查看已分配的店铺列表
#### 7.4.3 数据关系
```
cf_shop店铺表
cf_shop_member店铺成员表
记录:用户-店铺-角色关系
cf_user用户表
通过cf_shop_member关联店铺
```
**关键约束**:
- 一个用户可以拥有多个店铺的权限
- 一个店铺可以有多个成员
- 成员角色owner拥有者、admin管理员、operator运营、viewer只读
- 权限可以自定义,也可以使用预设权限
### 7.5 店铺管理API
#### 7.5.1 店铺相关API
| API路径 | 方法 | 说明 | 权限要求 |
|---------|------|------|----------|
| `/api/shops/my-shops` | GET | 获取当前用户的店铺列表 | 登录用户 |
| `/api/shops/:id` | GET | 获取店铺详情 | 店铺成员 |
| `/api/shops` | POST | 创建店铺 | 店铺拥有者 |
| `/api/shops/:id` | PUT | 更新店铺信息 | 店铺拥有者 |
| `/api/shops/:id/refresh-auth` | POST | 刷新店铺授权 | 店铺拥有者 |
| `/api/shops/:id` | DELETE | 删除店铺 | 店铺拥有者 |
| `/api/shops/stats` | GET | 获取店铺统计信息 | 登录用户 |
#### 7.5.2 店铺成员相关API
| API路径 | 方法 | 说明 | 权限要求 |
|---------|------|------|----------|
| `/api/shops/:shopId/members` | GET | 获取店铺成员列表 | 店铺成员 |
| `/api/shops/user/:userId/shops` | GET | 获取用户拥有的店铺 | 管理员或用户本人 |
| `/api/shop-members` | POST | 添加店铺成员 | 店铺拥有者 |
| `/api/shop-members/:shopId/:userId` | DELETE | 移除店铺成员 | 店铺拥有者 |
| `/api/shop-members/:shopId/:userId` | PUT | 更新成员角色和权限 | 店铺拥有者 |
#### 7.5.3 数据源实现
**文件路径**: `dashboard/src/services/shopDataSource.ts`
**主要方法**:
- `getMyShops()`: 获取当前用户的店铺列表
- `getById(id)`: 获取店铺详情
- `getShopMembers(shopId)`: 获取店铺成员列表
- `getUserShops(userId)`: 获取用户拥有的店铺
- `createShop(data)`: 创建店铺
- `updateShop(id, data)`: 更新店铺信息
- `refreshAuth(id)`: 刷新店铺授权
- `deleteShop(id)`: 删除店铺
- `addMember(data)`: 添加店铺成员
- `removeMember(shopId, userId)`: 移除店铺成员
- `updateMemberRole(shopId, userId, role, permissions)`: 更新成员角色和权限
- `getStats()`: 获取店铺统计信息
---
## 8. 实现状态
### 8.1 已实现功能
| 功能模块 | 功能点 | 状态 | 实现位置 |
|---------|--------|------|---------|
| **用户管理** | 用户CRUD | ✅ | UserService.ts, UserManagement.tsx |
| | 用户状态管理 | ✅ | UserService.updateUserStatus |
| | 用户缓存 | ✅ | UserService (Redis缓存) |
| | 批量操作 | ✅ | UserService.batchCreateUsers |
| **角色管理** | 角色CRUD | ✅ | RBACService.ts, RoleManagement.tsx |
| | 权限分配 | ✅ | RBACService.assignPermissions |
| | 权限树 | ✅ | RoleManagement.tsx |
| **部门管理** | 部门CRUD | ✅ | HierarchyService.ts, DepartmentManagement.tsx |
| | 层级结构 | ✅ | HierarchyService (path + depth) |
| | 部门转移 | ✅ | HierarchyService.transferUser |
| **租户管理** | 租户CRUD | ✅ | SaasTenantService.ts |
| | 租户隔离 | ✅ | 所有表tenant_id字段 |
| | 配额管理 | ✅ | QuotaGovernance |
| **店铺管理** | 店铺CRUD | ✅ | ShopService.ts, MyShops.tsx |
| | 店铺成员管理 | ✅ | ShopMemberService.ts, ShopMemberManagement.tsx |
| | 店铺授权刷新 | ✅ | ShopService.refreshAuth |
| | 用户店铺分配 | ✅ | UserManagement.tsx |
| | 双向管理关系 | ✅ | 店铺视角 + 用户视角 |
| **认证授权** | 登录认证 | ✅ | AuthService.ts |
| | Token管理 | ✅ | JWT + Refresh Token |
| | 权限检查 | ✅ | requirePermission中间件 |
| **数据范围** | 范围控制 | ✅ | DataScopeService |
| | 部门过滤 | ✅ | dept_path字段 |
### 8.2 待实现功能
| 功能模块 | 功能点 | 优先级 | 计划时间 |
|---------|--------|--------|---------|
| **安全增强** | 强密码策略 | P1 | 待定 |
| | 登录异常检测 | P2 | 待定 |
| **用户体验** | 拖拽排序 | P2 | 待定 |
| **集成扩展** | SSO集成 | P2 | 待定 |
| | LDAP/AD集成 | P3 | 待定 |
| | Webhook通知 | P3 | 待定 |
| **测试覆盖** | 功能测试 | P1 | 待定 |
| | 安全测试 | P1 | 待定 |
| | 性能测试 | P2 | 待定 |
---
## 9. 相关文档
- [User_Tenant_Improvement_Checklist.md](./User_Tenant_Improvement_Checklist.md) - 用户租户改进清单
- [RBAC_Design.md](./archive/02_Backend/07_RBAC_Design.md) - RBAC详细设计
- [Governance_Standards.md](./archive/00_Business/Governance_Standards.md) - 治理规范
- [Security_Policy.md](./rules/security.md) - 安全策略
---
## 10. 总结
Crawlful Hub 的用户层级架构采用了**多租户 + 多层级 + RBAC** 的设计模式:
1. **多租户隔离**: 确保不同商户数据完全隔离,保障数据安全
2. **灵活的组织结构**: 支持多级部门,适应不同规模企业
3. **细粒度权限控制**: 基于角色的权限管理,支持自定义角色
4. **数据范围控制**: 从个人到全平台的多级数据访问控制
5. **完整的审计体系**: 记录所有操作,支持安全审计
该架构不仅满足了企业级应用的安全需求,也为不同规模的商户提供了灵活的组织管理能力,支持从初创企业到大型集团的业务场景。