diff --git a/Docs/前后端调试说明/API接口文档.md b/Docs/前后端调试说明/API接口文档.md index a30d003..b49fd30 100644 --- a/Docs/前后端调试说明/API接口文档.md +++ b/Docs/前后端调试说明/API接口文档.md @@ -1,7 +1,7 @@ # taiji-AI-PAD API 接口文档 -**版本**: v2.2.0 -**更新时间**: 2025年12月25日 +**版本**: v2.5.0 +**更新时间**: 2025年12月26日 **基础URL**: - Data Ingestion 服务: `http://localhost:8001` (容器内8000→主机8001) - MCP Server 服务: `http://localhost:8002` (容器内8000→主机8002) @@ -964,17 +964,45 @@ ws.onmessage = (event) => { ### 权限角色 -系统支持七种角色: +系统支持以下角色: -| 角色 | 说明 | 登录路径 | -|------|------|---------| -| user | 租户用户 | POST /api/auth/login (role=user) | -| channel_admin | 渠道管理员 | POST /api/auth/login (role=channel) | -| billing_admin | 计费管理员 | POST /api/auth/login (role=billing_admin) | -| operations_admin | 运营管理员 | POST /api/auth/login (role=operations_admin) | -| admin | 管理员 | POST /api/auth/login (role=admin) | -| super_admin | 超级管理员 | POST /api/auth/login (role=super_admin) | -| provider_admin | 供应商管理员 | POST /api/auth/login (role=provider) | +| 角色 | 说明 | 登录role参数 | +|------|------|-------------| +| super_admin | 超级管理员 | super_admin | +| billing_admin | 计费管理员 | billing_admin | +| operations_admin | 运维管理员 | operations_admin | +| channel_admin | 渠道管理员 | channel | +| provider_admin | 供应商管理员 | provider | +| user | 租户用户 | user | + +### 权限矩阵 + +| 操作 | super_admin | billing_admin | operations_admin | channel_admin | +|------|:-----------:|:-------------:|:----------------:|:-------------:| +| **管理员管理** | +| 查看管理员列表 | ✅ | ❌ | ❌ | ❌ | +| 创建管理员 | ✅ | ❌ | ❌ | ❌ | +| 删除管理员 | ✅ | ❌ | ❌ | ❌ | +| **渠道管理** | +| 查看渠道列表 | ✅ | ✅ | ✅ | ❌ | +| 创建渠道 | ✅ | ✅ | ❌ | ❌ | +| 编辑渠道 | ✅ | ✅ | ❌ | ❌ | +| 删除渠道 | ✅ | ✅ | ❌ | ❌ | +| **资源管理** | +| 查看资源 | ✅ | ✅ | ✅ | ✅ | +| 分配资源 | ✅ | ✅ | ❌ | ✅ | +| 配置Agent | ✅ | ✅ | ❌ | ❌ | +| **计费管理** | +| 查看计费记录 | ✅ | ✅ | ✅ | ✅ | +| 执行充值 | ✅ | ✅ | ❌ | ✅ | +| **监控** | +| 查看系统监控 | ✅ | ✅ | ✅ | ❌ | +| 查看Agent状态 | ✅ | ✅ | ✅ | ❌ | +| **申请审批** | +| 查看申请 | ✅ | ✅ | ✅ | ❌ | +| 审批申请 | ✅ | ✅ | ❌ | ❌ | + +> **权限层级**: super_admin > billing_admin > operations_admin > channel_admin > user ### 示例 @@ -1959,9 +1987,135 @@ curl -s -X PUT "http://localhost:8002/api/channel/tenants/${TENANT_ID}/credit" \ --- +### 管理员管理相关 + +> **权限说明**: 以下接口仅超级管理员(super_admin)可用 + +#### 2. 获取管理员列表 + +**GET** `/api/admin/admins` + +**响应示例**: +```json +{ + "success": true, + "data": { + "admins": [ + { + "id": "admin-uuid-1", + "name": "计费管理员", + "email": "billing@taiji-ai.com", + "role": "billing_admin", + "status": "active", + "createdAt": "2025-12-01T00:00:00Z" + }, + { + "id": "admin-uuid-2", + "name": "运维管理员", + "email": "ops@taiji-ai.com", + "role": "operations_admin", + "status": "active", + "createdAt": "2025-12-01T00:00:00Z" + } + ] + } +} +``` + +--- + +#### 3. 创建管理员 + +**POST** `/api/admin/admins/create` + +**请求体**: +```json +{ + "name": "新计费管理员", + "email": "newadmin@taiji-ai.com", + "password": "Admin@123456", + "role": "billing_admin" +} +``` + +**请求参数说明**: +- `name` (string, 必需): 管理员名称 +- `email` (string, 必需): 管理员邮箱,用于登录 +- `password` (string, 必需): 管理员密码 +- `role` (string, 可选): 角色类型,默认为 `billing_admin` + +**role可选值**: +| 角色 | 说明 | 权限范围 | +|------|------|----------| +| `billing_admin` | 计费管理员 | **完整写入权限**:创建渠道、管理租户、资源分配、计费操作、审批申请 | +| `operations_admin` | 运维管理员 | **只读权限**:查看概览、渠道、租户、资源、计费、监控等 | + +**curl示例**: +```bash +# 使用超级管理员token创建计费管理员 +curl -s -X POST "http://localhost:8002/api/admin/admins/create" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $SUPER_ADMIN_TOKEN" \ + -d '{ + "name": "新计费管理员", + "email": "newadmin@taiji-ai.com", + "password": "Admin@123456", + "role": "billing_admin" + }' +``` + +**响应示例**: +```json +{ + "success": true, + "data": { + "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "name": "新计费管理员", + "email": "newadmin@taiji-ai.com", + "role": "billing_admin" + }, + "message": "管理员创建成功" +} +``` + +> **注意**: +> - 计费管理员(billing_admin)可使用 `role=billing_admin` 登录,拥有完整写入权限 +> - 运维管理员(operations_admin)可使用 `role=operations_admin` 登录,只有只读权限 + +--- + +#### 4. 删除管理员 + +**DELETE** `/api/admin/admins/{admin_id}` + +删除管理员(软删除,仅标记为不活跃)。 + +**curl示例**: +```bash +curl -X DELETE "http://localhost:8002/api/admin/admins/admin-uuid-1" \ + -H "Authorization: Bearer $SUPER_ADMIN_TOKEN" +``` + +**响应示例**: +```json +{ + "success": true, + "data": { + "id": "admin-uuid-1" + }, + "message": "管理员已删除" +} +``` + +--- + ### 渠道管理相关 -#### 2. 获取渠道列表 +> **权限说明**: +> - **查看接口 (GET)**: super_admin、billing_admin、operations_admin 都可使用 +> - **写入接口 (POST/PUT/DELETE)**: 仅 super_admin 和 billing_admin 可使用 + +#### 5. 获取渠道列表 **GET** `/api/admin/channels` @@ -1989,7 +2143,7 @@ curl -s -X PUT "http://localhost:8002/api/channel/tenants/${TENANT_ID}/credit" \ --- -#### 3. 创建渠道 +#### 6. 创建渠道 **POST** `/api/admin/channels/create` @@ -2040,7 +2194,7 @@ curl -s -X POST "http://localhost:8002/api/admin/channels/create" \ --- -#### 4. 更新渠道信息 +#### 7. 更新渠道信息 **PUT** `/api/admin/channels/{channel_id}` @@ -2090,7 +2244,7 @@ curl -X PUT "http://localhost:8002/api/admin/channels/channel-uuid-1" \ --- -#### 5. 删除渠道 +#### 8. 删除渠道 **DELETE** `/api/admin/channels/{channel_id}` @@ -2122,7 +2276,7 @@ curl -X DELETE "http://localhost:8002/api/admin/channels/channel-uuid-1" \ --- -#### 6. 统一管理渠道资源 +#### 9. 统一管理渠道资源 **PUT** `/api/admin/channels/{channel_id}/resources` @@ -2156,7 +2310,7 @@ curl -X DELETE "http://localhost:8002/api/admin/channels/channel-uuid-1" \ ### 申请审批相关 -#### 7. 获取所有申请 +#### 10. 获取所有申请 **GET** `/api/admin/channels/applications` @@ -2187,7 +2341,7 @@ curl -X DELETE "http://localhost:8002/api/admin/channels/channel-uuid-1" \ --- -#### 8. 审批申请 +#### 11. 审批申请 **PUT** `/api/admin/channels/applications/{application_id}/review` @@ -2211,7 +2365,7 @@ curl -X DELETE "http://localhost:8002/api/admin/channels/channel-uuid-1" \ ### 资源管理相关 -#### 9. 获取所有模型供应商 +#### 12. 获取所有模型供应商 **GET** `/api/admin/resources/models` @@ -2239,7 +2393,7 @@ curl -X DELETE "http://localhost:8002/api/admin/channels/channel-uuid-1" \ --- -#### 10. 获取所有Agent资源 +#### 13. 获取所有Agent资源 **GET** `/api/admin/resources/agents` @@ -2265,7 +2419,7 @@ curl -X DELETE "http://localhost:8002/api/admin/channels/channel-uuid-1" \ --- -#### 11. 删除Agent资源 +#### 14. 删除Agent资源 **DELETE** `/api/admin/resources/agents/{agent_id}` @@ -2291,7 +2445,7 @@ curl -X DELETE "http://localhost:8002/api/admin/resources/agents/agent-uuid-1" \ --- -#### 12. 更新Agent资源配置 +#### 15. 更新Agent资源配置 **PUT** `/api/admin/resources/agents/{agent_id}/config` @@ -2342,7 +2496,7 @@ curl -X PUT "http://localhost:8002/api/admin/resources/agents/agent-uuid-1/confi ### 监控相关 -#### 13. 监控Agent健康状态 +#### 16. 监控Agent健康状态 **GET** `/api/admin/monitoring/agents` @@ -2371,7 +2525,7 @@ curl -X PUT "http://localhost:8002/api/admin/resources/agents/agent-uuid-1/confi ### 计费相关(三维度) -#### 14. 获取三维度计费统计 +#### 17. 获取三维度计费统计 **GET** `/api/admin/billing/overview` @@ -2398,6 +2552,88 @@ curl -X PUT "http://localhost:8002/api/admin/resources/agents/agent-uuid-1/confi --- +### 前端集成补充接口 + +为了保证前端在轻量集成场景下可以持续迭代,`services/mcp-server/app/routes/frontend_integration.py` 还暴露了一组直接以 `/api` 前缀对外的超级管理员辅助接口,数据保存在内存 store 中,适合 UI 预览与模拟,调用仍需超级管理员身份。 + +#### 18. 获取可用角色列表 + +**GET** `/api/admin/roles` + +返回当前前端可选择的管理员角色列表: + +**响应示例**: +```json +{ + "items": ["billing_admin", "operations_admin", "super_admin"] +} +``` + +#### 19. 创建管理员记录(前端模拟,已废弃) + +**POST** `/api/admin/admins/create` + +该接口会在内存 store 中记录一个管理员条目,并返回 `id`、`createdAt` 与客户端提交的字段(`name` / `email` / `role` / `permissions` 等)。仅用于展示和调试,数据不会持久化: + +**请求体示例**: +```json +{ + "name": "平台管理员", + "email": "admin@example.com", + "role": "super_admin", + "permissions": ["billing", "agent_management"] +} +``` + +**响应示例**: +```json +{ + "id": "4f1d2c1d-8c9a-4f4b-a045-6c1b0f2b5f7a", + "name": "平台管理员", + "email": "admin@example.com", + "role": "super_admin", + "permissions": ["billing", "agent_management"], + "createdAt": "2025-12-25T05:00:00Z" +} +``` + +#### 20. 供应商统计(展示用) + +**GET** `/api/admin/providers/stats` + +读取当前 `ProviderModel` 表,返回供应商数量与模型信息,便于管理台展示: + +**响应示例**(实际数据会根据数据库变动): +```json +{ + "providers": 2, + "models": [ + { + "id": "provider-uuid-1", + "name": "OpenAI", + "apiUrl": "https://api.openai.com/v1", + "supportedModels": ["gpt-4", "gpt-4o-mini"] + } + ] +} +``` + +#### 21. 后台简易渠道统计 + +**GET** `/api/admin/channels/backend/stats` + +从内存 store 中读取渠道数量与资源申请数,用于管理台快速绘图: + +**响应示例**: +```json +{ + "channels": 3, + "applications": 1 +} +``` + +--- + ## 供应商管理 API **基础URL**: `http://localhost:8002/api/providers` @@ -2690,8 +2926,8 @@ def get_dashboard(token: str): --- -**文档版本**: v2.3.0 -**最后更新**: 2025年12月25日 +**文档版本**: v2.5.0 +**最后更新**: 2025年12月26日 **维护者**: taiji-AI-PAD 项目组 ## 完整 API 测试流程 @@ -2807,16 +3043,33 @@ echo "=== API测试完成 ===" 系统初始化时会创建以下测试账号: -| 角色 | 邮箱 | 密码 | 登录role参数 | -|------|------|------|-------------| -| 超级管理员 | superadmin@taiji-ai.com | Admin@123456 | super_admin | -| 渠道 | default@channel.com | Channel@123456 | channel | -| 测试用户 | user@test.com | User@123456 | user | +| 角色 | 邮箱 | 密码 | 登录role参数 | 可执行操作 | +|------|------|------|-------------|-----------| +| 超级管理员 | superadmin@taiji-ai.com | Admin@123456 | super_admin | 创建管理员、创建渠道、全部管理 | +| 计费管理员 | billing@taiji-ai.com | Admin@123456 | billing_admin | 创建渠道、管理租户、计费操作(完整写入权限) | +| 运维管理员 | ops@taiji-ai.com | Admin@123456 | operations_admin | 查看概览、监控、计费(只读权限) | +| 渠道 | default@channel.com | Channel@123456 | channel | 创建租户、管理租户资源 | +| 测试用户 | user@test.com | User@123456 | user | 使用平台服务 | + +> **权限层级**: super_admin > billing_admin > operations_admin > channel_admin > user --- ## 更新日志 +- **v2.5.0** (2025-12-26): **权限系统重构** + - ✅ 重新设计权限系统,区分计费管理员和运维管理员 + - ✅ billing_admin(计费管理员):完整写入权限(创建渠道、管理租户、计费操作、审批申请) + - ✅ operations_admin(运维管理员):只读权限(仅查看和监控) + - ✅ 更新权限矩阵表格 + - ✅ 更新接口权限验证逻辑 + - ✅ 更新预置测试账号说明 +- **v2.4.0** (2025-12-26): **新增管理员管理接口** + - ✅ 添加 GET /api/admin/admins - 获取管理员列表(仅超级管理员可用) + - ✅ 添加 POST /api/admin/admins/create - 创建管理员(支持billing_admin/operations_admin角色) + - ✅ 添加 DELETE /api/admin/admins/{admin_id} - 删除管理员(软删除) + - ✅ 区分 super_admin(超级管理员)权限 + - ✅ 更新超级管理员API接口编号 - **v2.3.0** (2025-12-25): **新增管理接口** - ✅ 添加 PUT /api/admin/channels/{channel_id} - 更新渠道信息 - ✅ 添加 DELETE /api/admin/channels/{channel_id} - 删除渠道(软删除) diff --git a/Docs/项目文档/项目工作流程.md b/Docs/项目文档/项目工作流程.md index c69861b..e7217cf 100644 --- a/Docs/项目文档/项目工作流程.md +++ b/Docs/项目文档/项目工作流程.md @@ -22,7 +22,7 @@ - **本地基础 URL**: - Data Ingestion: `http://localhost:8001` - - MCP Server: `http://localhost:8000` + - MCP Server: `http://localhost:8002` - MCP Server API: `http://localhost:8000/api` - **认证**: - ✅ 已启用完整的JWT + API Key双认证机制 diff --git a/services/mcp-server/app/permissions.py b/services/mcp-server/app/permissions.py index 4b738ee..34183eb 100644 --- a/services/mcp-server/app/permissions.py +++ b/services/mcp-server/app/permissions.py @@ -1,76 +1,120 @@ """ 权限管理辅助模块 + +权限层级设计: +- super_admin(超级管理员): 全部权限,可创建任何管理员 +- billing_admin(计费管理员): 完整写入权限,可创建渠道、管理租户、计费操作 +- operations_admin(运维管理员): 只读权限,仅查看和监控 +- channel_admin(渠道管理员): 管理自己渠道下的租户 +- provider_admin(供应商管理员): 管理模型供应商 +- user(用户): 普通用户权限 """ from typing import List, Set # 权限定义 PERMISSIONS = { + # 查看权限(只读) "view:overview": "查看概览", - "manage:tenants": "管理租户", - "manage:resources": "管理资源", - "view:billing": "查看计费", - "manage:billing": "管理计费(含充值)", - "manage:settings": "管理设置", - "approve:applications": "审批申请", - "manage:channels": "管理渠道", - "manage:providers": "管理供应商", + "view:channels": "查看渠道列表", + "view:tenants": "查看租户列表", + "view:resources": "查看资源", + "view:agents": "查看Agent", + "view:billing": "查看计费记录", "view:monitoring": "查看监控", + "view:applications": "查看申请", + "view:admins": "查看管理员列表", + + # 管理权限(写入) + "manage:channels": "管理渠道(增删改)", + "manage:tenants": "管理租户(增删改)", + "manage:resources": "管理资源分配", + "manage:agents": "管理Agent配置", + "manage:billing": "管理计费(充值、设置)", + "manage:settings": "管理系统设置", + "manage:providers": "管理供应商", + "manage:admins": "管理管理员(仅super_admin)", + + # 审批权限 + "approve:applications": "审批资源申请", } # 角色权限映射 ROLE_PERMISSIONS = { - # 租户用户 + # 租户用户 - 仅查看自己的数据 "user": [ "view:overview", "view:billing", ], - # 渠道管理员 + # 渠道管理员 - 管理自己渠道下的租户 "channel_admin": [ "view:overview", + "view:tenants", + "view:resources", + "view:billing", "manage:tenants", "manage:resources", - "view:billing", "manage:billing", ], - # 计费管理员(渠道或平台的计费管理) + # 计费管理员 - 完整写入权限(可创建渠道、管理租户、计费操作) "billing_admin": [ "view:overview", + "view:channels", + "view:tenants", + "view:resources", + "view:agents", "view:billing", - "manage:billing", + "view:monitoring", + "view:applications", + "manage:channels", # 可创建/编辑/删除渠道 + "manage:tenants", # 可管理租户 + "manage:resources", # 可管理资源分配 + "manage:agents", # 可管理Agent配置 + "manage:billing", # 可执行计费操作(充值等) + "approve:applications", # 可审批申请 ], - # 运营管理员(渠道或平台的运营管理) + # 运维管理员 - 只读权限(仅查看和监控) "operations_admin": [ "view:overview", - "manage:tenants", - "manage:resources", + "view:channels", + "view:tenants", + "view:resources", + "view:agents", "view:billing", - ], - - # 管理员(平台管理员,权限低于超级管理员) - "admin": [ - "view:overview", - "manage:tenants", - "manage:resources", - "view:billing", - "manage:billing", - "manage:settings", "view:monitoring", + "view:applications", + # 无任何 manage: 权限,只能查看 ], - # 超级管理员(全部权限) + # 超级管理员 - 全部权限 "super_admin": list(PERMISSIONS.keys()), # 供应商管理员 "provider_admin": [ "view:overview", + "view:resources", "manage:providers", ], } +# 角色层级(用于判断角色大小) +ROLE_HIERARCHY = { + "super_admin": 100, + "billing_admin": 80, + "operations_admin": 70, + "channel_admin": 50, + "provider_admin": 40, + "user": 10, +} + + +def get_role_level(role: str) -> int: + """获取角色层级""" + return ROLE_HIERARCHY.get(role, 0) + def get_role_permissions(role: str) -> List[str]: """ diff --git a/services/mcp-server/app/routes/admin.py b/services/mcp-server/app/routes/admin.py index 2956b41..2138e4b 100644 --- a/services/mcp-server/app/routes/admin.py +++ b/services/mcp-server/app/routes/admin.py @@ -17,6 +17,7 @@ from models import ( from app.auth import require_auth, get_password_hash from app.schemas import ( SuccessResponse, + CreateAdminRequest, CreateChannelRequest, UpdateChannelRequest, UpdateAgentConfigRequest, @@ -26,20 +27,187 @@ from app.schemas import ( ReviewApplicationRequest, AdminBillingResponse, ) +from app.permissions import has_permission, get_role_permissions router = APIRouter(prefix="/api/admin", tags=["超级管理员"]) -def _verify_admin_permission(principal: dict): - """验证超级管理员权限""" - role = principal.get("claims", {}).get("role") - if role not in ["super_admin", "admin"]: +def _get_role(principal: dict) -> str: + """从principal获取角色""" + return principal.get("claims", {}).get("role", "") + + +def _verify_permission(principal: dict, permission: str): + """验证是否拥有指定权限""" + role = _get_role(principal) + if not has_permission(role, permission): + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail=f"需要权限: {permission}" + ) + + +def _verify_super_admin_permission(principal: dict): + """验证超级管理员权限(仅 super_admin 可管理管理员)""" + role = _get_role(principal) + if role != "super_admin": raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="需要超级管理员权限" ) +def _verify_write_permission(principal: dict): + """验证写入权限(super_admin 或 billing_admin)""" + role = _get_role(principal) + # 只有 super_admin 和 billing_admin 有写入权限 + if role not in ["super_admin", "billing_admin"]: + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail="需要写入权限(super_admin 或 billing_admin)" + ) + + +def _verify_read_permission(principal: dict): + """验证读取权限(super_admin, billing_admin, operations_admin)""" + role = _get_role(principal) + if role not in ["super_admin", "billing_admin", "operations_admin"]: + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail="需要管理员权限" + ) + + +# ============= 管理员管理 ============= + +@router.get("/admins", response_model=SuccessResponse) +async def list_admins( + principal: dict = Depends(require_auth), + db: AsyncSession = Depends(get_db) +): + """ + 获取管理员列表(仅超级管理员可用) + """ + _verify_super_admin_permission(principal) + + # 查询所有管理员角色的用户 + result = await db.execute( + select(User).where( + User.role.in_(["billing_admin", "operations_admin"]) + ) + ) + admins = result.scalars().all() + + data = [ + { + "id": str(admin.id), + "name": admin.name or admin.full_name, + "email": admin.email, + "role": admin.role, + "status": admin.status, + "createdAt": admin.created_at.isoformat() if admin.created_at else None, + } + for admin in admins + ] + + return SuccessResponse(data={"admins": data}) + + +@router.post("/admins/create", response_model=SuccessResponse) +async def create_admin( + req: CreateAdminRequest, + principal: dict = Depends(require_auth), + db: AsyncSession = Depends(get_db) +): + """ + 创建管理员(仅超级管理员可用) + + 可创建的角色: + - billing_admin: 计费管理员(完整写入权限,可创建渠道、管理租户、计费操作) + - operations_admin: 运维管理员(只读权限,仅查看和监控) + """ + _verify_super_admin_permission(principal) + + # 检查邮箱是否已存在 + result = await db.execute( + select(User).where(User.email == req.email) + ) + if result.scalar_one_or_none(): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="邮箱已被使用" + ) + + # 创建管理员用户 + password_hash = get_password_hash(req.password) + admin = User( + name=req.name, + email=req.email, + password_hash=password_hash, + hashed_password=password_hash, # 兼容 + username=req.email.split("@")[0], + full_name=req.name, + role=req.role, + status="active", + balance=0, + credit_limit=0, + ) + + db.add(admin) + await db.commit() + await db.refresh(admin) + + return SuccessResponse( + data={ + "id": str(admin.id), + "name": admin.name, + "email": admin.email, + "role": admin.role, + }, + message=f"管理员创建成功" + ) + + +@router.delete("/admins/{admin_id}", response_model=SuccessResponse) +async def delete_admin( + admin_id: str, + principal: dict = Depends(require_auth), + db: AsyncSession = Depends(get_db) +): + """ + 删除管理员(仅超级管理员可用,软删除) + """ + _verify_super_admin_permission(principal) + + # 验证管理员存在 + result = await db.execute( + select(User).where(User.id == admin_id) + ) + admin = result.scalar_one_or_none() + + if not admin: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="管理员不存在" + ) + + # 检查是否是管理员角色 + if admin.role not in ["billing_admin", "operations_admin"]: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="只能删除管理员角色的用户" + ) + + # 软删除:标记为不活跃 + admin.status = "inactive" + await db.commit() + + return SuccessResponse( + data={"id": str(admin.id)}, + message="管理员已删除" + ) + + # ============= 概览 ============= @router.get("/dashboard/stats", response_model=SuccessResponse) @@ -48,9 +216,9 @@ async def get_admin_dashboard_stats( db: AsyncSession = Depends(get_db) ): """ - 获取平台全局统计 + 获取平台全局统计(所有管理员可查看) """ - _verify_admin_permission(principal) + _verify_read_permission(principal) # 渠道总数 channels_count = await db.execute(select(func.count(Channel.id))) @@ -94,12 +262,12 @@ async def list_channels( db: AsyncSession = Depends(get_db) ): """ - 获取所有渠道列表 + 获取所有渠道列表(所有管理员可查看) Args: include_inactive: 是否包含已删除的渠道,默认False只返回活跃的 """ - _verify_admin_permission(principal) + _verify_read_permission(principal) # 默认只返回活跃的渠道,除非明确请求包含已删除的 if include_inactive: @@ -135,9 +303,9 @@ async def create_channel( db: AsyncSession = Depends(get_db) ): """ - 创建渠道 + 创建渠道(super_admin 和 billing_admin 可用) """ - _verify_admin_permission(principal) + _verify_write_permission(principal) # 检查邮箱是否已存在 result = await db.execute( @@ -184,9 +352,9 @@ async def update_channel( db: AsyncSession = Depends(get_db) ): """ - 更新渠道信息 + 更新渠道信息(super_admin 和 billing_admin 可用) """ - _verify_admin_permission(principal) + _verify_write_permission(principal) # 验证渠道存在 result = await db.execute( @@ -247,9 +415,9 @@ async def delete_channel( db: AsyncSession = Depends(get_db) ): """ - 删除渠道(软删除,标记为不活跃) + 删除渠道(软删除,super_admin 和 billing_admin 可用) """ - _verify_admin_permission(principal) + _verify_write_permission(principal) # 验证渠道存在 result = await db.execute( @@ -299,9 +467,9 @@ async def allocate_channel_resources( db: AsyncSession = Depends(get_db) ): """ - 统一管理渠道资源 + 统一管理渠道资源(super_admin 和 billing_admin 可用) """ - _verify_admin_permission(principal) + _verify_write_permission(principal) # 验证渠道 result = await db.execute( @@ -366,9 +534,9 @@ async def list_applications( db: AsyncSession = Depends(get_db) ): """ - 获取所有渠道申请 + 获取所有渠道申请(所有管理员可查看) """ - _verify_admin_permission(principal) + _verify_read_permission(principal) result = await db.execute( select(Application, Channel) @@ -413,9 +581,9 @@ async def review_application( db: AsyncSession = Depends(get_db) ): """ - 审批申请 + 审批申请(super_admin 和 billing_admin 可用) """ - _verify_admin_permission(principal) + _verify_write_permission(principal) user_id = principal.get("user_id") # 查询申请 @@ -494,9 +662,9 @@ async def list_model_providers( db: AsyncSession = Depends(get_db) ): """ - 获取所有模型供应商 + 获取所有模型供应商(所有管理员可查看) """ - _verify_admin_permission(principal) + _verify_read_permission(principal) result = await db.execute(select(ModelProvider)) providers = result.scalars().all() @@ -531,7 +699,7 @@ async def list_all_agents( Args: include_inactive: 是否包含已删除的Agent,默认False只返回活跃的 """ - _verify_admin_permission(principal) + _verify_read_permission(principal) # 默认只返回活跃的Agent,除非明确请求包含已删除的 if include_inactive: @@ -565,9 +733,9 @@ async def delete_agent_resource( db: AsyncSession = Depends(get_db) ): """ - 删除Agent资源(软删除,标记为不活跃) + 删除Agent资源(软删除,super_admin 和 billing_admin 可用) """ - _verify_admin_permission(principal) + _verify_write_permission(principal) # 验证Agent存在 result = await db.execute( @@ -599,9 +767,9 @@ async def update_agent_config( db: AsyncSession = Depends(get_db) ): """ - 更新Agent资源配置(CPU、内存、最大实例数) + 更新Agent资源配置(super_admin 和 billing_admin 可用) """ - _verify_admin_permission(principal) + _verify_write_permission(principal) # 验证Agent存在 result = await db.execute( @@ -646,9 +814,9 @@ async def monitor_agents( db: AsyncSession = Depends(get_db) ): """ - 监控Agent健康状态和性能指标 + 监控Agent健康状态和性能指标(所有管理员可查看) """ - _verify_admin_permission(principal) + _verify_read_permission(principal) result = await db.execute( select(Agent).where(Agent.type == "platform") @@ -687,9 +855,9 @@ async def get_billing_overview( db: AsyncSession = Depends(get_db) ): """ - 获取三维度计费统计(渠道/租户/调用) + 获取三维度计费统计(所有管理员可查看) """ - _verify_admin_permission(principal) + _verify_read_permission(principal) # 解析时间 start_dt = datetime.fromisoformat(startTime.replace("Z", "+00:00")) diff --git a/services/mcp-server/app/schemas.py b/services/mcp-server/app/schemas.py index 2ed41a2..81c73f2 100644 --- a/services/mcp-server/app/schemas.py +++ b/services/mcp-server/app/schemas.py @@ -454,6 +454,19 @@ class ModelProviderInfo(BaseModel): # ============= 其他 ============= +class CreateAdminRequest(BaseModel): + """创建管理员请求 + + 可创建的角色: + - billing_admin: 计费管理员(完整写入权限,可创建渠道、管理租户、计费操作) + - operations_admin: 运维管理员(只读权限,仅查看和监控) + """ + name: str + email: EmailStr + password: str + role: str = Field("billing_admin", pattern="^(billing_admin|operations_admin)$") + + class CreateChannelRequest(BaseModel): """创建渠道请求""" name: str