Skip to content

后台管理系统(admin 管理端)项目说明书

项目根目录:w:\AI-Pet-Project\xhs-miniapp-saas 管理端代码目录:admin/;后端管理 API 代码目录:backend/app/routers/admin.pybackend/app/services/admin_service.pybackend/app/models/admin.py 等 线上地址:https://admin.jvguang.com(仅内网 WiFi 可访问,公网返回 403)


1. 项目概述

后台管理系统是「小红书 SaaS 多租户内容运营平台」的管理控制台,用于平台运营方(Admin)对入驻商家(Merchant)、平台规则(RAG 知识库)、LLM 模型配置、AI 聊天会话与记忆进行统一管理。

核心定位:

  • 运营侧一站式管理:用户(商家)管理、平台规范管理、公司知识库管理、模型配置热切换、全局知识库、AI 记忆库、会话管理(人工客服接管)。
  • 与小程序端、Web 端共享同一套后端 API 与数据库(PostgreSQL),通过 RLS(Row Level Security)行级隔离 + Admin 专用无 RLS 数据库会话 实现双模式访问。
  • 安全要求(硬性约束):仅内网可访问、所有页面与接口返回 noindex, nofollow, noarchive 响应头防止搜索引擎收录、页面标题为「后台管理系统」且不含任何「小红书 / XHS」字样。

注意:本文档中的"管理端"指的是 admin/ 前端 + 后端 /api/admin/* 路由族;其余租户端(小程序/Web)功能不在本文档范围内,但管理端会跨租户查看这些端产生的数据(文章、聊天、记忆、知识库等)。


2. 技术栈

层次技术说明
前端框架React 18 + TypeScript 5admin/ 目录
UI 组件Ant Design 5 (antd ^5.16) + @ant-design/icons表单/表格/抽屉/消息提示
路由react-router-dom v6BrowserRouter + 手写 RequireAuth 守卫
HTTPaxios ^1.6统一拦截器,自动注入 Authorization: Bearer
构建Vite 5dev 代理 /api 到后端 8000 端口
样式自定义 editorial.css编辑部风格(editorial)视觉体系
后端框架Python FastAPI + asyncpg + pgvector/api/admin/* 路由族
数据库PostgreSQL 16 + pgvector 扩展17 张表,10 张租户表启用 RLS
部署Nginx(HTTPS)→ uvicorn(FastAPI :8000)backend/deploy/nginx-admin-intranet.conf

3. 整体架构图

mermaid
flowchart TB
    classDef net fill:#e3f2fd,stroke:#1565c0,stroke-width:2px,color:#0d47a1
    classDef mw  fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px,color:#1b5e20
    classDef svc fill:#f3e5f5,stroke:#6a1b9a,stroke-width:2px,color:#4a148c
    classDef db  fill:#fff8e1,stroke:#ef6c00,stroke-width:2px,color:#e65100

    ADMIN_BROWSER["🖥️ 管理员浏览器<br/>https://admin.jvguang.com"]
    NGINX["🛡️ Nginx · 443 SSL"]
    INTRANET_MW["✅ AdminIntranetMiddleware<br/>内网IP白名单 + noindex"]
    ADMIN_ROUTER["📦 routers/admin.py"]
    AUTH["🔑 /api/admin/login<br/>写死账号签发 admin JWT"]
    ADMIN_SVC["⚙️ admin_service.py<br/>dashboard/CRUD/配置缓存/热切换"]
    CHAT_SVC["💬 chat_service.py<br/>全局知识库/记忆/会话"]
    CHAT_WS["🔌 chat_ws.py<br/>AI自动回复/人工客服"]
    ENC["🔐 encryption.py<br/>Fernet 加密APIKey"]
    USERS["👥 merchants / merchant_profiles"]
    RULES["📏 platform_rules (无RLS)"]
    KNOW["📚 merchant_knowledge_chunks (RLS)"]
    LLM_CFG["🧠 llm_function_configs / cover_ai_configs (无RLS)"]
    CHAT_TB["💬 chat_conversations / chat_messages /<br/>chat_memory_docs (RLS)"]
    GLOBAL["🌍 global_knowledge_docs (无RLS)"]
    COVER_TB["🎨 cover_projects / cover_images /<br/>cover_styles / cover_covers (RLS)"]

    ADMIN_BROWSER -->|"443 HTTPS"| NGINX
    NGINX -->|"proxy_pass 127.0.0.1:8000"| INTRANET_MW
    INTRANET_MW --> ADMIN_ROUTER
    ADMIN_ROUTER --> AUTH
    ADMIN_ROUTER --> ADMIN_SVC
    ADMIN_ROUTER --> CHAT_SVC
    ADMIN_ROUTER --> CHAT_WS
    ADMIN_SVC --> ENC
    ADMIN_SVC -->|"AdminDb"| USERS
    ADMIN_SVC -->|"AdminDb"| RULES
    ADMIN_SVC -->|"AdminDb"| KNOW
    ADMIN_SVC -->|"AdminDb + Fernet"| LLM_CFG
    ADMIN_SVC -->|"AdminDb"| COVER_TB
    CHAT_SVC -->|"AdminDb"| GLOBAL
    CHAT_SVC -->|"AdminDb"| CHAT_TB
    CHAT_WS --> CHAT_TB

    class ADMIN_BROWSER,NGINX net
    class INTRANET_MW mw
    class AUTH,ADMIN_ROUTER,ADMIN_SVC,CHAT_SVC,CHAT_WS,ENC svc
    class USERS,RULES,KNOW,LLM_CFG,CHAT_TB,GLOBAL,COVER_TB db

图例:🟦 蓝 = 接入层 · 🟩 绿 = 安全中间件 · 🟪 紫 = 后端服务 · 🟧 橙 = 数据库表(底部横向排布,经 AdminDb 无 RLS 跨租户访问)

关键隔离模型:

  • 商家/租户端访问走 DbSessiondeps.py 注入 app.current_merchant_id 会话变量,触发 RLS 策略)。
  • Admin 端访问走 AdminDbdeps.py::get_admin_db),不注入 RLS 上下文,依赖 CurrentAdmin(role=admin JWT)保证只有管理员可用,实现跨租户全量读写。
  • platform_rulesllm_function_configscover_ai_configsglobal_knowledge_docs 四张表故意不启用 RLS(全局共享)。

4. 目录结构总览

admin/
├── index.html                    # Vite 入口 HTML(标题:后台管理系统)
├── package.json / package-lock.json
├── tsconfig.json
├── vite.config.ts                # dev 代理 /api → http://127.0.0.1:8000
├── .gitignore
└── src/
    ├── main.tsx                  # React 挂载入口
    ├── App.tsx                   # 路由表 + RequireAuth 登录守卫
    ├── vite-env.d.ts
    ├── api/
    │   ├── client.ts             # axios 实例 + token 存取(记住我)
    │   ├── admin.ts              # 全部 /api/admin/* 接口封装
    │   └── types.ts              # 接口 TS 类型定义
    ├── components/
    │   └── MessageBridge.tsx     # antd message 桥接组件
    ├── hooks/
    │   └── useMessage.ts         # 非组件环境获取 message 的 hook
    ├── layouts/
    │   └── AdminLayout.tsx       # 侧边栏 + 顶栏 + 内容区布局
    ├── pages/
    │   ├── Login.tsx             # 登录页
    │   ├── Dashboard.tsx         # 仪表盘
    │   ├── Users.tsx             # 用户(商家)管理
    │   ├── Rules.tsx             # 平台规范管理
    │   ├── KnowledgeBase.tsx     # 公司知识库管理
    │   ├── ModelConfig.tsx       # 模型配置(LLM 功能级 + 封面 AI)
    │   ├── GlobalKnowledge.tsx   # 全局知识库管理
    │   ├── MemoryDocs.tsx        # AI 记忆库管理
    │   └── ChatSessions.tsx      # 会话管理(人工客服)
    ├── styles/
    │   └── editorial.css         # 编辑部风格全局样式
    └── utils/
        └── messageBridge.ts      # message API 桥接(脱离 React 上下文)

5. 前端文件详解

5.1 入口与配置

文件作用(控制的功能)关联文件影响
index.html页面骨架;<title> 为「后台管理系统」,不出现「小红书/XHS」字样;引入字体与根样式src/main.tsx修改标题影响浏览器标签与 SEO 标题
vite.config.tsdev 服务器配置;server.proxy['/api'] 指向 http://127.0.0.1:8000,解决开发跨域.env(后端)改代理目标影响本地联调后端地址
src/main.tsxReact 18 挂载 App#rootsrc/App.tsx挂载点
src/vite-env.d.tsVite 环境变量类型声明全局

5.2 路由与全局守卫

文件作用关联文件影响
src/App.tsx定义全部路由:/login 公开;/ 及其子路由(dashboard/users/rules/knowledge/model/global-knowledge/memory-docs/chat-sessions)包裹在 RequireAuth 守卫内;* 重定向到 /dashboardapi/client.ts(getToken)、layouts/AdminLayout.tsx、全部 pages新增页面需在此注册路由;守卫逻辑影响整个后台的访问控制
src/layouts/AdminLayout.tsx后台主框架:可折叠侧边栏(8 个导航项:仪表盘/用户管理/平台规范/公司知识库/模型配置/全局知识库/AI 记忆库/会话管理)、品牌区「管理 Admin Console」、顶栏退出按钮;内容区渲染 Outlet全部 pages、api/client.ts(clearToken)导航菜单与布局改动影响所有管理页面的外观

5.3 API 层

文件作用关联后端影响
src/api/client.tsaxios 实例(baseURL /api,60s 超时);请求拦截自动注入 Authorization: Bearer {token};响应拦截:401 清 token 并跳转 /login,其余错误统一 toast;Token 存取按「记住我」偏好分流到 localStorage/sessionStorage(key:xhs_admin_token / xhs_admin_remember后端所有 /api/*改 baseURL/超时/拦截器会影响全部接口请求;token 存储策略影响登录持久性
src/api/admin.ts封装后端 /api/admin/* 全部接口(见下表)backend/app/routers/admin.py新增后台功能需在此补充接口函数
src/api/types.ts定义接口请求/响应的 TypeScript 类型(AdminToken、User、Rule、LLMConfig、CoverAIConfig、GlobalKnowledgeDoc、MemoryDoc、AdminConversation、AdminMessage 等)backend/app/models/admin.pymodels/chat.py类型与后端 schema 不一致会导致编译错误或运行期数据缺失

admin.ts 中封装的接口函数与后端路由对应关系:

前端函数后端端点功能
loginPOST /api/admin/login管理员登录(写死账号校验)
getStatsGET /api/admin/stats仪表盘统计
listUsers / getUser / createUser / updateUser / deleteUserGET /api/admin/usersGET/POST /api/admin/usersPUT/DELETE /api/admin/users/{id}商家 CRUD
listRules / createRule / updateRule / toggleRule / deleteRule / reindexRules / uploadPlatformMarkdownGET/POST /api/admin/rulesPUT/DELETE /api/admin/rules/{id}PATCH .../togglePOST .../reindexPOST .../upload平台规则 CRUD + 向量重建 + Markdown 上传
listUserKnowledge / uploadUserMarkdown / deleteUserKnowledgeGET /api/admin/users/{id}/knowledgePOST .../knowledge/uploadDELETE .../knowledge/{chunkId}公司知识库管理
getLLMConfig / updateLLMConfig / testLLMGET/PUT /api/admin/llm/configPOST /api/admin/llm/test全局 LLM 配置(内存热切换)
listLLMFunctionConfigs / updateLLMFunctionConfig / testLLMFunctionGET /api/admin/llm/function-configsPUT .../{function_key}POST /api/admin/llm/function-testLLM 功能级配置(持久化到 DB)
listCoverAIConfigs / updateCoverAIConfigGET /api/admin/cover-ai/configsPUT .../{function_key}封面 AI 配置 + 诊断
listGlobalKnowledgeDocs / create/update/deleteGlobalKnowledgeDoc / uploadGlobalMarkdown/api/admin/chat/global-knowledge/docs*/upload全局知识库管理
listMemoryDocs / deleteMemoryDocGET /api/admin/chat/memory/{merchantId}/docsDELETE .../docs/{docId}AI 记忆库管理
listConversations / listConversationMessagesGET /api/admin/chat/conversationsGET .../{merchantId}/messages会话列表/消息查看(跨租户)
getAutoReplyStatus / toggleAutoReplyGET /api/admin/chat/auto-reply/statusPOST .../toggleAI 自动回复开关
sendAdminChatMessage / generateAdminChatDraft / clearConversationPOST .../conversations/{merchantId}/messages.../ai-draft.../clear人工客服发消息 / AI 起草 / 清空会话

5.4 消息提示体系(MessageBridge)

文件作用关联文件影响
src/components/MessageBridge.tsx挂载在 App 根部的桥接组件:通过 App.useApp() 拿到 antd 的 message 实例,注入全局模块App.tsxutils/messageBridge.ts移除该组件会导致全局 toast 失效
src/utils/messageBridge.ts导出全局 messageApi(模块级引用,非 React 上下文),供 axios 拦截器等非组件代码调用api/client.ts
src/hooks/useMessage.ts提供 useMessage() hook,让页面组件在 React 上下文内安全获取 message 实例各 pages

5.5 页面详解

Login.tsx — 登录页

  • 功能:管理员登录表单(账号+密码),调用 login(),成功后按「记住我」偏好存储 token 并跳转 /dashboard;页面标题为「后台管理系统」。
  • 关联api/client.ts(setToken/getRememberMe)、api/admin.ts
  • 影响:登录流程的入口;若后端 ADMIN_USERNAME/ADMIN_PASSWORD 变更,此处无需改代码。

Dashboard.tsx — 仪表盘

  • 功能:调用 getStats() 展示平台总览(用户数、文章数、任务数等统计卡片)。
  • 关联api/admin.ts、后端 admin_service.dashboard_stats(查询 merchants/articles/tasks 等表 count)。
  • 影响:数据口径由后端 SQL 决定。

Users.tsx — 用户(商家)管理

  • 功能:商家列表(分页+手机号搜索)、创建/编辑/删除商家;手机号遵循 ^1[3-9]\d{9}$,密码 8-64 位(与小程序/Web 统一规则);可查看单个商家的知识库详情。
  • 关联api/admin.tsmodels/admin.py(UserCreate/UserUpdate)、admin_service.create_user/update_user/delete_user(bcrypt 加密密码)。
  • 影响:创建/修改商家直接影响登录体系;删除商家级联删除其文章/任务/图片/会话/记忆等全部数据(外键 ON DELETE CASCADE)。

Rules.tsx — 平台规范管理

  • 功能:平台规则(限流词/发布规范/违禁词分类)CRUD、启停切换、向量重建(reindex)、Markdown 文件批量上传入库(uploadPlatformMarkdown 切块写入 platform_rules)。
  • 关联api/admin.tsadmin_service.list_rules/.../reindex_rulesrag/indexer.py(embedding 向量化)。
  • 影响:规则是文章生成流水线 rag_search 的召回来源(全局共享、无 RLS),修改直接影响所有商家生成文章的合规参考与内容。

KnowledgeBase.tsx — 公司知识库管理

  • 功能:选择某个商家,查看其专属知识切片(merchant_knowledge_chunks),支持上传该商家的 Markdown 规范文档(切块入库)与删除切片。
  • 关联api/admin.tsadmin_service.list_user_knowledge/upload_user_markdown/delete_user_knowledge
  • 影响:商家知识库被文章生成的主题推荐与聊天 AI 回复使用;上传后通过 invalidate_merchant_knowledge_cache 使该商家知识缓存失效(_knowledge_context.py)。

ModelConfig.tsx — 模型配置

  • 功能:两大块——
    1. LLM 功能级配置/llm/function-configs):按 function_key(article_generate / compliance_check / title_tags / multimodal_kimi / multimodal_spark)配置 provider/model/api_key/base_url/temperature/max_tokens/is_enabled,持久化到数据库,保存后热生效(内存缓存刷新 + llm_client.reload())。
    2. 封面 AI 配置/cover-ai/configs):cover_vision / cover_text / cover_image 三个功能键,API Key 用 Fernet 加密enc:v1: 前缀)存储;含诊断面板(/cover-ai/diagnose)展示凭据来源、服务选择、环境变量是否配置等排障信息。
    • 按项目约定:隐藏 cover_visioncover_text 编辑入口,突出 multimodal_kimi 为统一模型(cover_vision/cover_text 自动回落到 multimodal_kimi)。
  • 关联api/admin.tsadmin_service.load_llm_function_configs_cache/get_function_config/update_llm_function_configllm/client.py(LLMClientProxy 按 signature 失效重建 provider)、security/encryption.py
  • 影响全局影响——模型配置变更会立即影响所有商家端(小程序/Web)的文章生成、合规检查、标题标签、封面神器等所有 AI 能力;改错 provider/api_key 可能导致全平台 AI 功能故障,因此提供 test 接口先行验证。

GlobalKnowledge.tsx — 全局知识库管理

  • 功能:全局知识文档(global_knowledge_docs,无 RLS,平台共享)CRUD + Markdown 上传(≤4000 字整篇存储,长文自动切片为 (i/N) 多篇)。
  • 关联api/admin.tschat_service.list_global_knowledge_docs/upload_global_markdown
  • 影响:全局知识被注入到所有商家的聊天 system prompt(chat_ai.build_system_prompt)与引导问题推荐;修改立即影响所有租户的 AI 助手回答。

MemoryDocs.tsx — AI 记忆库管理

  • 功能:查看指定商家的聊天记忆文档(chat_memory_docs,RLS 表但 Admin 跨租户访问),删除指定记忆。
  • 关联api/admin.tschat_service.list_memory_docs_by_merchant/delete_memory_doc
  • 影响:记忆是聊天 AI 的长期上下文;删除记忆会让 AI 忘记该商家的历史偏好与承诺信息。

ChatSessions.tsx — 会话管理(人工客服)

  • 功能:跨租户会话列表(以 merchants 表为主表 LEFT JOIN chat_conversations,保证所有商家都出现在列表,含无聊天记录的商家;支持 phone/company_name 模糊搜索);点击会话抽屉查看消息时间线(游标分页);AI 自动回复开关人工客服接管:查看最新商家消息、AI 起草回复(ai-draft,不落库)、编辑后发送(落库 + WS 推送 sender_role=admin 给商家);清空会话(删除消息 + 记忆 + 重置 last_msg_at)。
  • 关联api/admin.tschat_service.list_conversations_admin/list_messages_by_merchant_admin/clear_conversation_adminchat_ws.is_auto_reply_enabled/set_auto_reply_enabled/send_admin_message_to_merchantchat_ai.generate_admin_reply_draft
  • 影响:人工客服功能是「AI 自动回复」的接管机制;发送消息会通过 WebSocket 实时推送到商家端聊天页;关闭自动回复后,商家消息不再触发 AI 回复。

5.6 样式

文件作用影响
src/styles/editorial.css编辑部(editorial)视觉风格:品牌区、侧边栏(ed-sider)、导航项(ed-nav-label/caption)、卡片、表格等全局样式全站视觉;修改需注意与 antd 组件 class 的覆盖关系

6. 后端关联模块详解(管理端专属)

管理端依赖的 /api/admin/* 路由族与相关服务,本文档只描述管理端直接使用到的部分。

6.1 路由:backend/app/routers/admin.py

管理后台 API 聚合入口,包含以下区块:

区块端点说明
登录POST /api/admin/loginsecrets.compare_digest 恒时比较 ADMIN_USERNAME/ADMIN_PASSWORD,签发 role=admin 的 JWT;无注册入口
仪表盘GET /api/admin/statsadmin_service.dashboard_stats
用户管理GET/POST /api/admin/usersGET/PUT/DELETE /api/admin/users/{id}商家 CRUD
平台规则GET/POST /api/admin/rulesPUT/PATCH/DELETE /api/admin/rules/{id}POST /reindexPOST /upload规则管理 + 向量重建 + Markdown 上传
公司知识库GET /api/admin/users/{id}/knowledgePOST .../knowledge/uploadDELETE .../knowledge/{chunkId}单商家知识管理
全局 LLM 配置GET/PUT /api/admin/llm/configPOST /api/admin/llm/test内存级热切换(factory.set_overrides
LLM 功能级配置GET /api/admin/llm/function-configsPUT .../{function_key}POST /api/admin/llm/function-testDB 持久化配置 + 测试
封面 AI 配置GET /api/admin/cover-ai/configsPUT .../{function_key}GET /api/admin/cover-ai/diagnose封面 AI 配置 + 排障诊断
全局知识库/api/admin/chat/global-knowledge/docs* + /upload全局聊天知识 CRUD
AI 记忆库GET /api/admin/chat/memory/{merchantId}/docsDELETE .../docs/{docId}记忆管理
会话管理GET /api/admin/chat/conversationsGET .../{merchantId}/messagesPOST .../{merchantId}/messagesPOST .../ai-draftPOST .../clearGET/POST /api/admin/chat/auto-reply/*跨租户会话/客服

6.2 服务:backend/app/services/admin_service.py

函数功能关键逻辑
list_users / get_user / create_user / update_user / delete_user商家 CRUD密码用 pwd_context.hash(bcrypt);手机号唯一约束;删除级联
list_rules / create_rule / update_rule / toggle_rule / delete_rule / reindex_rules规则 CRUD + 向量重建新增/更新/重建时调 rag/indexer.py 生成 embedding(HNSW 向量索引)
dashboard_stats仪表盘统计跨表 COUNT(merchants/articles/tasks/chat 等)
get_llm_config / update_llm_config / test_llm全局 LLM 内存热切换factory.set_overrides() + llm_client.reload();test 用临时 provider 验证连通
load_llm_function_configs_cache / get_function_config / update_llm_function_config / test_llm_functionLLM 功能级配置缓存与热更新启动时(main.py lifespan)加载到内存;更新后 _refresh_cache_entry 刷新缓存并 llm_client.reload()
load_cover_ai_configs_cache / get_cover_ai_config / update_cover_ai_config封面 AI 配置缓存api_key 写入时用 encrypt_secret Fernet 加密,读取时解密
upload_platform_markdown / upload_user_markdown / list_user_knowledge / delete_user_knowledgeMarkdown 智能切块入库_split_markdown 按标题层级切块;user 知识写入 merchant_knowledge_chunks 并生成向量

6.3 安全中间件:backend/app/security/intranet.py

  • AdminIntranetMiddleware:拦截所有 /api/admin/* 请求——
    • ADMIN_INTRANET_ONLY=true 时校验客户端 IP 是否在 ADMIN_ALLOWED_CIDRS(默认内网网段)内,否则 403 INTRANET_ONLY
    • 永远注入 X-Robots-Tag: noindex, nofollow, noarchiveX-Content-Type-Options: nosniff(防搜索引擎收录 + 防 MIME 嗅探);
    • 通过 ADMIN_TRUSTED_PROXIES 信任 Nginx 的 X-Forwarded-For 获取真实 IP。
  • 影响:该中间件是「后台仅内网访问」的第一道闸;生产环境建议再叠加 Nginx 层 IP 白名单(deploy/nginx-admin-intranet.confallow/deny)。

6.4 模型:backend/app/models/admin.py

  • AdminLoginRequest/AdminTokenResponse:登录请求/响应。
  • UserCreate/UserUpdate/UserDetailResponse/UserListResponse/UserKnowledgeListResponse:商家与知识切片 schema。
  • RuleCreate/RuleUpdate/RuleListResponse/AdminRuleResponse/UploadResult:规则 schema。
  • LLMConfigResponse/LLMConfigUpdate/LLMFunctionConfig/LLMFunctionConfigUpdate/LLMConfigListResponse/LLMFunctionTestRequest/LLMTestRequest/LLMTestResponse/CoverAIConfig/CoverAIConfigUpdate/CoverAIConfigListResponse/CoverAIDiagnoseResponse:模型配置 schema(models/admin.pymodels/chat.py 均含会话管理相关 schema:AdminConversationResponseAdminMessageResponseGlobalKnowledgeDoc*MemoryDoc*AutoReply*AdminAiDraft*ConversationClearResponse 等)。
  • 约束UserCreate.phone 匹配 ^1[3-9]\d{9}$password 8-64 位(与 models/auth.py 统一)。

6.5 依赖注入:backend/app/deps.py

  • CurrentAdmin:解析 role=admin 的 JWT,非 admin 返回 403。
  • AdminDb:获取无 RLS 注入的数据库连接(管理员跨租户读写)。生产环境需使用 BYPASSRLS 数据库角色连接。

7. 数据库表关系(管理端视角)

mermaid
erDiagram
    merchants ||--o| merchant_profiles : "1:1 公司信息"
    merchants ||--o{ merchant_knowledge_chunks : "1:N 公司知识(RLS)"
    merchants ||--o{ articles : "1:N 文章(RLS)"
    merchants ||--o{ tasks : "1:N 生成任务(RLS)"
    merchants ||--o{ chat_conversations : "1:N 会话(RLS)"
    chat_conversations ||--o{ chat_messages : "1:N 消息(RLS)"
    merchants ||--o{ chat_memory_docs : "1:N AI记忆(RLS)"
    merchants ||--o{ cover_projects : "1:N 封面项目(RLS)"
    platform_rules : "全局共享(无RLS) 规则/限流词/违禁词"
    llm_function_configs : "全局共享(无RLS) 功能级LLM配置"
    cover_ai_configs : "全局共享(无RLS) 封面AI配置"
    global_knowledge_docs : "全局共享(无RLS) 聊天全局知识"

管理端对表的访问方式:全部通过 AdminDb(无 RLS)跨租户读写;platform_rules/llm_function_configs/cover_ai_configs/global_knowledge_docs 本身无 RLS。


8. 关键业务流程

8.1 管理员登录

  1. 浏览器访问 https://admin.jvguang.com → Nginx 443 → 中间件校验内网 IP。
  2. 前端 Login.tsx 提交账号密码 → POST /api/admin/login
  3. 后端 secrets.compare_digest 校验(写死账号来自 .envADMIN_USERNAME/ADMIN_PASSWORD)→ 签发 role=admin 的 access token(TTL 由 access_token_ttl_hours 控制)。
  4. 前端按「记住我」偏好存 token → 跳转 /dashboard;后续请求自动携带 Bearer

8.2 模型配置热切换(全局影响最大)

  1. ModelConfig.tsx 修改某个 function_key 的 provider/model/api_key → PUT /api/admin/llm/function-configs/{key}
  2. admin_service.update_llm_function_config:校验 + Fernet 加密 api_key 落库 → _refresh_cache_entry 更新内存缓存 → llm_client.reload()
  3. LLMClientProxyprovider:model:api_key:base_url signature 自动失效旧 provider、重建新 provider(HTTP 连接池同步切换)。
  4. 影响面:小程序/Web 端所有走 chat_for_function/chat_json_for_function 的 AI 功能(文章生成、合规、标题、封面、聊天)。

8.3 人工客服接管

  1. ChatSessions.tsx 列表(merchants LEFT JOIN chat_conversations)→ 选择商家 → 查看消息(游标分页)。
  2. 关闭「AI 自动回复」→ chat_ws.set_auto_reply_enabled(false) → 商家新消息不再触发 AI。
  3. 点击「AI 起草」→ POST .../ai-draftchat_ai.generate_admin_reply_draft(临时事务内注入该商家 RLS 上下文读取上下文,不落库)。
  4. 编辑后发送 → chat_ws.send_admin_message_to_merchant → 落库(sender_role=admin)+ 经 notify_merchant WS 推送商家端。

9. 部署与运维

9.1 构建

bash
cd admin
npm install
npm run build        # tsc && vite build → 产物 dist/

产物部署到服务器 admin/dist(Nginx root /opt/xhs-saas/admin/distlocation /admin/)。

9.2 Nginx(backend/deploy/nginx-admin-intranet.conf

  • admin.jvguang.com/admin/ 静态托管 + /api/admin//api/ 反代 127.0.0.1:8000 + /api/cover/uploads//health
  • api.jvguang.com/api/chat/ws 需配置 Upgrade/Connection 头支持 WebSocket;其余 /api/* 反代。
  • 建议在 Nginx 层再叠加 allow/deny IP 白名单(双重保险)。

9.3 关键环境变量(backend/.env

变量说明
ADMIN_USERNAME / ADMIN_PASSWORD后台登录账号密码(生产要求 ≥12 位)
ADMIN_INTRANET_ONLYtrue 时仅内网可访问
ADMIN_ALLOWED_CIDRS放行网段(默认内网三大段 + 127)
ADMIN_TRUSTED_PROXIES可信代理 IP(填 Nginx 内网 IP 才信任 X-Forwarded-For)
LLM_CONFIG_ENC_KEYFernet 加密密钥(生产必填,validate_runtime_security 校验)
CORS_ORIGINS需包含 https://admin.jvguang.com

注意:.env 修改后需重启后端(uvicorn)才生效。


10. 影响分析汇总

变更点影响范围风险级别
修改 LLM 功能级配置 / 封面 AI 配置全平台(小程序+Web 所有 AI 功能)
平台规范(Rules)增删改 / 重建向量所有商家的文章生成合规召回
全局知识库增删改所有商家聊天 AI 回答与引导问题
删除商家级联删除该商家全部数据(文章/任务/图片/会话/记忆/封面项目)
删除某商家记忆文档该商家 AI 遗忘历史偏好
关闭某商家 AI 自动回复该商家聊天由人工接管
修改 admin_intranet 相关配置后台可达性(改错可能锁死后台或暴露公网)
修改 deps.py::AdminDb / RLS 策略数据隔离边界,错误配置可能造成跨租户数据泄露

11. 常见问题

  1. 公网访问后台返回 403ADMIN_INTRANET_ONLY=true + 当前网络出口 IP 不在白名单。需将 WiFi 公网出口 IP 加入 ADMIN_ALLOWED_CIDRS;路由器重启后 IP 变化需重新配置。
  2. 模型配置保存后不生效:检查是否命中内存缓存(LLMClientProxy 按 signature 失效);修改后确认 llm_client.reload() 被调用;后端日志可见 LLM provider=... model=... 重建信息。
  3. 封面神器生成失败排查:使用 ModelConfig 的诊断面板(/api/admin/cover-ai/diagnose)查看 jimeng_credential_sourceselected_servicejimeng_has_access_key/secret_key 等。
  4. 聊天会话列表缺少商家:列表以 merchants 为主表 LEFT JOIN,理论上所有商家都应出现;若缺失说明 merchants 表数据异常或搜索条件过严。

基于 VitePress 构建 · 由 GitHub Actions 自动部署