front/docs/小红书模块设计-063001.md
zzh c6723ab476
Some checks failed
Build and Deploy Front / deploy (push) Failing after 32m20s
chore: 前端部署去掉 nginx,静态由 serve,TLS 交 Traefik
生产不再内置 nginx/`__cos__`;镜像用 serve -s,HTTPS 由 Traefik+cert-manager;面单预览走 stream。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-23 12:24:36 +08:00

1240 lines
32 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

# 小红书模块 — 表结构与接口设计
> **代码基线**:`E:\oms0414`(前端)+ `C:\Users\wilso\Desktop\oms0414-back`(后端)+ `C:\Users\wilso\Desktop\LIKE AI`(本地 Agent 执行面)
> **关联文档**:`docs/oms系统设计-050801.md`(OMS 通用约定)、`docs/rbac系统设计-060801.md`(认证与菜单)
> **版本**:v0.1 · 2026-06-30
---
## 1 导读
### 1.1 这份文档解决什么问题?
将 **LIKE AI** 桌面端的核心内容运营能力迁入 **OMS Web**,形成独立业务模块「**小红书**」:
| 页面(菜单) | 说明 |
| --- | --- |
| 启动服务 | Agent 连接、Bridge/扩展/登录状态、引擎启停 |
| 内容分析 | 首页/搜索采集、笔记详情、AI 分析、互动留痕 |
| 爆款创作 | AI 辅助写稿、配图、即时/定时发布 |
| 发布记录 | 历史发布与定时任务状态 |
| 技能卡片 | 从找题到发布的一键技能配方 |
| 拟人设置 | 浏览器人类行为 + 防封号节奏(原 LIKE AI「系统设置」) |
**AI 助手**(ChatGPT / 豆包 / DeepSeek / 智谱 配置与对话)放在 **系统** 菜单下,不在「小红书」一级菜单内。
### 1.2 明确不在 OMS 范围内
以下能力 **不设计表、不设计接口、不做 Web 页面**,继续由 LIKE AI 本地 Agent 自行处理:
| 能力 | 说明 |
| --- | --- |
| 物流查价 | Agent 内部按需调用已有 `POST /order/price-check`,OMS 无感知 |
| 请求日志 | CLI/引擎调试日志仅存本机 |
| 授权 License | 独立激活码体系保留在 Agent,不走 OMS RBAC |
### 1.3 架构原则
```mermaid
flowchart LR
subgraph OMS["OMS(控制面)"]
Web["Vue 小红书模块"]
API["/xhs/* ApplicationService"]
DB[(MySQL t_xhs_*)]
Web --> API --> DB
end
subgraph Agent["LIKE AI Agent(执行面)"]
Bridge["Bridge + Chrome 扩展"]
Local["本地:License / 日志 / 查价"]
end
Web <-->|"HTTPS + JWT"| Agent
Agent --> Bridge
Agent --> Local
```
- **Web 编排任务、存业务数据**;**Agent 在本机 Chrome 执行**。
- Agent 使用用户 OMS **Access Token** 认证(`Authorization: Bearer`),与客户数据隔离规则同 OMS 其他模块。
### 1.4 后端实现约定(与 OMS 一致)
| 项 | 约定 |
| --- | --- |
| 框架 | .NET 8、Fake `ApplicationService` 自动映射 API |
| 数据访问 | SqlSugar + MySQL |
| 路由前缀 | **`/xhs/*`** |
| 分页 | `OmsPageResult<T>` → `{ items, total }`;默认 pageSize **30** |
| 客户隔离 | `OmsSessionHelper.ResolveListCustomerIdAsync` / `ResolveSessionCustomerAsync` |
| Swagger 分组 | `OMS-Xhs` |
---
## 2 前端菜单与路由
### 2.1 菜单结构
#### 一级菜单:小红书
| order | 菜单名 | path | name | component | permission |
| --- | --- | --- | --- | --- | --- |
| 4 | 启动服务 | `/xhs/startService` | `XhsStartService` | `views/xhs/startService/index.vue` | `Xhs.Agent.Query` |
| 5 | 内容分析 | `/xhs/analysis` | `XhsAnalysis` | `views/xhs/analysis/index.vue` | `Xhs.Analysis.Use` |
| 6 | 爆款创作 | `/xhs/creation` | `XhsCreation` | `views/xhs/creation/index.vue` | `Xhs.Creation.Use` |
| 7 | 发布记录 | `/xhs/publishHistory` | `XhsPublishHistory` | `views/xhs/publishHistory/index.vue` | `Xhs.Publish.Query` |
| 8 | 技能卡片 | `/xhs/skills` | `XhsSkills` | `views/xhs/skills/index.vue` | `Xhs.Skills.Query` |
| 9 | 拟人设置 | `/xhs/humanSettings` | `XhsHumanSettings` | `views/xhs/humanSettings/index.vue` | `Xhs.HumanSettings.Save` |
路由模块文件:`src/router/routes/newModules/xhs.ts`
```typescript
const XHS: AppRouteRecordRaw = {
path: '/xhs',
name: 'Xhs',
component: DEFAULT_LAYOUT,
meta: {
locale: 'menu.xhs',
icon: 'icon-book', // 或自定义小红书图标
requiresAuth: true,
order: 4,
},
children: [ /* 见上表 */ ],
};
export default XHS;
```
#### 系统菜单下:AI 助手
| 菜单名 | path | name | component | permission |
| --- | --- | --- | --- | --- |
| AI 助手 | `/system/xhsAiAssistant` | `SystemXhsAiAssistant` | `views/system/xhsAiAssistant/index.vue` | `Xhs.Ai.Use` |
追加到 `src/router/routes/newModules/system-management.ts` 的 `children` 末尾。
> **说明**:AI 接口仍走 `/xhs/ai/*`,仅 **菜单位置** 在「系统」下;客户门户若需使用 AI,通过 RBAC 分配 `Xhs.Ai.Use` 即可显示该菜单。
### 2.2 i18n 键名
```typescript
'menu.xhs': '小红书',
'menu.xhs.startService': '启动服务',
'menu.xhs.analysis': '内容分析',
'menu.xhs.creation': '爆款创作',
'menu.xhs.publishHistory': '发布记录',
'menu.xhs.skills': '技能卡片',
'menu.xhs.humanSettings': '拟人设置',
'menu.system.xhsAiAssistant': 'AI 助手',
```
### 2.3 Vite / SPA 规则
`/xhs/*` 为纯前端路由:
- `vite.config.ts` → `frontendRoutes` 增加 `'/xhs'`(开发 history fallback)
- 生产由前端容器 `serve -s` 回退 `index.html`;API 走分域名 `api.*`,无需站内 nginx
---
## 3 权限码
| PermissionCode | 说明 | 典型角色 |
| --- | --- | --- |
| `Xhs.Agent.Query` | 查看 Agent 状态、下载指引 | 客户主账号 |
| `Xhs.Agent.Control` | Web 远程启停引擎、触发登录 | 客户主账号 |
| `Xhs.Analysis.Use` | 内容分析页、创建分析任务 | 客户主账号 |
| `Xhs.Creation.Use` | 爆款创作、上传媒体、提交发布 | 客户主账号 |
| `Xhs.Publish.Query` | 发布记录列表 | 客户主账号 |
| `Xhs.Publish.Cancel` | 取消定时发布 | 客户主账号 |
| `Xhs.Skills.Query` | 技能卡片列表 | 客户主账号 |
| `Xhs.Skills.Save` | 增删改技能卡片 | 客户主账号 |
| `Xhs.Skills.Run` | 一键执行技能 | 客户主账号 |
| `Xhs.HumanSettings.Save` | 读写拟人/防封配置 | 客户主账号 |
| `Xhs.Ai.Use` | AI 助手页、对话与配置 | 客户 / 管理员 |
| `Xhs.Ai.Save` | 保存 AI 提供商密钥 | 客户 / 管理员 |
| `Xhs.Task.Query` | 任务列表(各页内嵌,可选独立页) | 客户主账号 |
管理员(`loginType=0`)列表接口 **不过滤** `CustomerId`,与订单模块当前实现一致;写操作须传 `customerId` 或使用 Agent 绑定关系校验。
---
## 4 数据表结构
命名前缀 **`t_xhs_`**,公共审计字段与 OMS 其他表一致。
### 4.1 Agent 设备表 `t_xhs_agent`
一台 Windows 本机 Agent 对应一条记录(按 `DeviceId` 唯一)。
```sql
CREATE TABLE `t_xhs_agent` (
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
`CustomerId` INT NOT NULL COMMENT '客户ID → t_customer.Id',
`DeviceId` VARCHAR(64) NOT NULL COMMENT 'Agent 本机设备标识(LIKE AI license.device_id 同源算法)',
`DeviceName` VARCHAR(128) NULL COMMENT '用户自定义名称,如「办公室电脑」',
`AgentVersion` VARCHAR(32) NULL COMMENT 'Agent 版本号',
`BridgePort` INT NOT NULL DEFAULT 9333 COMMENT 'Bridge WebSocket 端口',
`Status` VARCHAR(16) NOT NULL DEFAULT 'offline' COMMENT 'online/offline',
`EngineRunning` TINYINT NOT NULL DEFAULT 0 COMMENT 'Bridge 引擎是否运行',
`ExtensionConnected` TINYINT NOT NULL DEFAULT 0 COMMENT 'Chrome 扩展是否连上 Bridge',
`XhsLoggedIn` TINYINT NOT NULL DEFAULT 0 COMMENT '小红书是否已登录',
`LastHeartbeatTime` DATETIME NULL COMMENT '最后心跳时间',
`LastError` VARCHAR(512) NULL COMMENT '最近一次 Agent 上报错误摘要',
`IsDeleted` TINYINT NOT NULL DEFAULT 0,
`ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()),
`CreateUserId` INT NOT NULL DEFAULT 0,
`CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`UpdateUserId` INT NULL,
`UpdateTime` DATETIME NULL,
PRIMARY KEY (`Id`),
UNIQUE KEY `uk_xhs_agent_device` (`DeviceId`),
KEY `idx_xhs_agent_customer` (`CustomerId`, `Status`)
) COMMENT='小红书本地 Agent 设备表';
```
### 4.2 任务队列表 `t_xhs_task`
Web 创建 → Agent 拉取执行 → 回传结果。对应 LIKE AI `XhsBridgeService.call_tool` 及引擎控制。
```sql
CREATE TABLE `t_xhs_task` (
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
`CustomerId` INT NOT NULL COMMENT '客户ID',
`AgentId` INT NULL COMMENT '指定执行的 Agent;NULL 表示任意在线 Agent',
`TaskType` VARCHAR(32) NOT NULL COMMENT '任务类型,见 §4.2.1',
`ToolName` VARCHAR(64) NULL COMMENT 'LIKE AI 工具名,如 publish_content',
`Priority` INT NOT NULL DEFAULT 0 COMMENT '越大越优先',
`Status` VARCHAR(16) NOT NULL DEFAULT 'pending' COMMENT 'pending/claimed/running/succeeded/failed/cancelled',
`ArgumentsJson` JSON NOT NULL COMMENT '工具参数 JSON',
`ProgressText` VARCHAR(512) NULL COMMENT '执行过程摘要',
`ResultJson` JSON NULL COMMENT '成功时结构化结果',
`ErrorMessage` VARCHAR(1024) NULL COMMENT '失败原因',
`Source` VARCHAR(32) NOT NULL DEFAULT 'web' COMMENT 'web/schedule/skill',
`SourceRefId` VARCHAR(64) NULL COMMENT '来源关联,如 publish_record.Id、skill.Id',
`ScheduledTime` DATETIME NULL COMMENT '计划执行时间;NULL 表示立即',
`ClaimedAt` DATETIME NULL COMMENT 'Agent 认领时间',
`StartedAt` DATETIME NULL COMMENT '开始执行',
`FinishedAt` DATETIME NULL COMMENT '结束时间',
`IsDeleted` TINYINT NOT NULL DEFAULT 0,
`ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()),
`CreateUserId` INT NOT NULL DEFAULT 0,
`CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`UpdateUserId` INT NULL,
`UpdateTime` DATETIME NULL,
PRIMARY KEY (`Id`),
KEY `idx_xhs_task_poll` (`CustomerId`, `Status`, `ScheduledTime`, `Priority`),
KEY `idx_xhs_task_agent` (`AgentId`, `Status`),
KEY `idx_xhs_task_source` (`Source`, `SourceRefId`)
) COMMENT='小红书 Agent 任务队列表';
```
#### 4.2.1 TaskType 枚举
| TaskType | ToolName | 说明 |
| --- | --- | --- |
| `engine_start` | — | 启动 Bridge 引擎 |
| `engine_stop` | — | 停止 Bridge 引擎 |
| `browser_login` | `browser_login` | 打开 Chrome 扫码登录 |
| `clear_cookies` | `delete_cookies` | 清除登录 Cookie |
| `check_login` | `check_login_status` | 检查登录状态 |
| `browse` | `list_feeds` / `search_feeds` / `my_account_feeds` | 浏览采集 |
| `feed_detail` | `get_feed_detail` | 笔记详情 |
| `interact` | `post_comment_to_feed` 等 | 评论/点赞/收藏 |
| `publish` | `publish_content` / `publish_with_video` | 发布笔记 |
| `skill_pipeline` | — | 技能卡片编排(多步子任务,见 §4.5) |
`ArgumentsJson` 结构与 LIKE AI `skills_tool_adapter.build_cli_argv` 入参一致,例如:
```json
{
"keyword": "跨境物流",
"filters": { "sort_by": "最多点赞" },
"feed_id": "6a095abd0000000006030184",
"xsec_token": "ABIrq9ZLAO...",
"title": "笔记标题",
"content": "正文",
"images": ["https://oms.../uploads/xhs/1.jpg"],
"tags": ["生活"],
"visibility": "公开可见"
}
```
> **图片路径**:Web 上传至 OMS `/uploads/xhs/{customerId}/`,任务参数存 **HTTPS URL**;Agent 执行前下载到本机临时目录。
### 4.3 发布记录表 `t_xhs_publish_record`
对应 LIKE AI `.xhs_bridge/publish_history.json`。
```sql
CREATE TABLE `t_xhs_publish_record` (
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
`CustomerId` INT NOT NULL COMMENT '客户ID',
`TaskId` INT NULL COMMENT '关联 t_xhs_task.Id',
`ToolName` VARCHAR(64) NOT NULL COMMENT 'publish_content / publish_with_video',
`Title` VARCHAR(256) NOT NULL COMMENT '笔记标题',
`ContentPreview` VARCHAR(512) NULL COMMENT '正文摘要',
`ContentFull` TEXT NULL COMMENT '完整正文(可选存储)',
`MediaJson` JSON NULL COMMENT '图片/视频 URL 列表',
`TagsJson` JSON NULL COMMENT '标签数组',
`Visibility` VARCHAR(32) NULL COMMENT '公开可见/仅自己可见等',
`Status` VARCHAR(16) NOT NULL DEFAULT 'draft' COMMENT 'draft/scheduled/publishing/succeeded/failed/cancelled',
`Success` TINYINT NULL COMMENT '最终是否成功:0/1',
`ResultSummary` VARCHAR(1024) NULL COMMENT 'Agent 回传结果摘要',
`ScheduledTime` DATETIME NULL COMMENT '定时发布时间',
`PublishedTime` DATETIME NULL COMMENT '实际发布完成时间',
`SkillId` INT NULL COMMENT '若来自技能卡片',
`IsDeleted` TINYINT NOT NULL DEFAULT 0,
`ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()),
`CreateUserId` INT NOT NULL DEFAULT 0,
`CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`UpdateUserId` INT NULL,
`UpdateTime` DATETIME NULL,
PRIMARY KEY (`Id`),
KEY `idx_xhs_publish_customer_time` (`CustomerId`, `CreateTime`),
KEY `idx_xhs_publish_status_sched` (`CustomerId`, `Status`, `ScheduledTime`),
KEY `idx_xhs_publish_task` (`TaskId`)
) COMMENT='小红书发布记录表';
```
### 4.4 内容分析会话表 `t_xhs_analysis_session`
保存一次「采集 + 分析」会话,避免大 JSON 堆在任务表。
```sql
CREATE TABLE `t_xhs_analysis_session` (
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
`CustomerId` INT NOT NULL COMMENT '客户ID',
`SessionName` VARCHAR(128) NULL COMMENT '用户备注名',
`AnalysisType` VARCHAR(32) NOT NULL COMMENT 'home_feed/search/competitor/single_feed',
`Keyword` VARCHAR(128) NULL COMMENT '搜索关键词',
`TaskId` INT NULL COMMENT '采集任务 ID',
`FeedsJson` JSON NULL COMMENT '采集到的笔记列表(结构同 browse.partial.json)',
`SelectedFeedId` VARCHAR(64) NULL COMMENT '当前选中的笔记 ID',
`AiAnalysisMarkdown` MEDIUMTEXT NULL COMMENT 'AI 分析结果 Markdown',
`SkillId` INT NULL COMMENT '使用的技能配方 ID',
`IsDeleted` TINYINT NOT NULL DEFAULT 0,
`ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()),
`CreateUserId` INT NOT NULL DEFAULT 0,
`CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`UpdateUserId` INT NULL,
`UpdateTime` DATETIME NULL,
PRIMARY KEY (`Id`),
KEY `idx_xhs_analysis_customer` (`CustomerId`, `CreateTime`)
) COMMENT='小红书内容分析会话表';
```
### 4.5 技能卡片表 `t_xhs_skill`
对应 LIKE AI `.xhs_bridge/skills.json`。
```sql
CREATE TABLE `t_xhs_skill` (
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
`CustomerId` INT NOT NULL COMMENT '客户ID;0 表示系统预置模板',
`ExternalId` VARCHAR(32) NOT NULL COMMENT '对外稳定 ID(迁移自 LIKE AI skill.id)',
`Title` VARCHAR(256) NOT NULL COMMENT '技能名称',
`SkillType` VARCHAR(32) NOT NULL DEFAULT 'ai_create' COMMENT 'ai_create / analysis / ...',
`PresetId` VARCHAR(64) NULL COMMENT '内置预设标识',
`RecipeJson` JSON NOT NULL COMMENT '配方 JSON,结构同 LIKE AI skills.json.recipe',
`SortOrder` INT NOT NULL DEFAULT 0 COMMENT '排序',
`IsDeleted` TINYINT NOT NULL DEFAULT 0,
`ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()),
`CreateUserId` INT NOT NULL DEFAULT 0,
`CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`UpdateUserId` INT NULL,
`UpdateTime` DATETIME NULL,
PRIMARY KEY (`Id`),
UNIQUE KEY `uk_xhs_skill_external` (`CustomerId`, `ExternalId`),
KEY `idx_xhs_skill_customer` (`CustomerId`, `SortOrder`)
) COMMENT='小红书技能卡片表';
```
`RecipeJson` 示例(与 LIKE AI 一致):
```json
{
"formula": ["emotion", "utility", "visual", "social"],
"title_types": ["number", "question"],
"body": {
"domain": "物流知识",
"content_type": "干货教程",
"emotion": "生活场景",
"social": "知识炫耀"
},
"image_modes": ["cover_impact"],
"video_modes": [],
"notes": "讲解9610的简易申报..."
}
```
### 4.6 拟人配置表 `t_xhs_human_config`
每个客户一行,存储 **人类行为** + **防封号节奏** 完整 JSON(对应 `config.yaml` 的 `human_behavior` + `human_guard`)。
```sql
CREATE TABLE `t_xhs_human_config` (
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
`CustomerId` INT NOT NULL COMMENT '客户ID',
`BehaviorJson` JSON NOT NULL COMMENT 'human_behavior 完整配置',
`GuardJson` JSON NOT NULL COMMENT 'human_guard 完整配置',
`Version` INT NOT NULL DEFAULT 1 COMMENT '配置版本,Agent 拉取时比对',
`IsDeleted` TINYINT NOT NULL DEFAULT 0,
`ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()),
`CreateUserId` INT NOT NULL DEFAULT 0,
`CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`UpdateUserId` INT NULL,
`UpdateTime` DATETIME NULL,
PRIMARY KEY (`Id`),
UNIQUE KEY `uk_xhs_human_customer` (`CustomerId`)
) COMMENT='小红书拟人行为与防封配置表';
```
Agent 心跳或任务拉取时若 `Version` 变化,写入本机 `human_behavior.json` / guard 状态文件。
默认配置:首次访问「拟人设置」时,后端用 LIKE AI `human.py` / `human_guard.py` 内置默认值 INSERT。
### 4.7 AI 提供商表 `t_xhs_ai_provider`
对应 `.xhs_bridge/ai_providers.json`;**密钥加密存储**(AES,密钥来自 OMS 配置项)。
```sql
CREATE TABLE `t_xhs_ai_provider` (
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
`CustomerId` INT NOT NULL COMMENT '客户ID;管理员全局配置时可为 0',
`ProviderKey` VARCHAR(32) NOT NULL COMMENT 'ai_chatgpt / ai_zhipu 等',
`ProviderType` VARCHAR(32) NOT NULL COMMENT 'chatgpt/doubao/deepseek/zhipu',
`DisplayName` VARCHAR(64) NOT NULL COMMENT '展示名',
`BaseUrl` VARCHAR(512) NOT NULL COMMENT 'API Base URL',
`ApiKeyEnc` VARCHAR(512) NULL COMMENT '加密后的 API Key',
`ApiSecretEnc` VARCHAR(512) NULL COMMENT '加密后的 Secret/模型名',
`IsDefault` TINYINT NOT NULL DEFAULT 0 COMMENT '是否默认对话提供商',
`Enabled` TINYINT NOT NULL DEFAULT 1,
`IsDeleted` TINYINT NOT NULL DEFAULT 0,
`ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()),
`CreateUserId` INT NOT NULL DEFAULT 0,
`CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`UpdateUserId` INT NULL,
`UpdateTime` DATETIME NULL,
PRIMARY KEY (`Id`),
UNIQUE KEY `uk_xhs_ai_provider` (`CustomerId`, `ProviderKey`),
KEY `idx_xhs_ai_customer` (`CustomerId`, `Enabled`)
) COMMENT='小红书 AI 提供商配置表';
```
### 4.8 媒体文件表 `t_xhs_media`(可选,建议 v1 实现)
```sql
CREATE TABLE `t_xhs_media` (
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
`CustomerId` INT NOT NULL COMMENT '客户ID',
`FileName` VARCHAR(256) NOT NULL COMMENT '原始文件名',
`StoragePath` VARCHAR(512) NOT NULL COMMENT '相对路径 uploads/xhs/...',
`PublicUrl` VARCHAR(512) NOT NULL COMMENT '对外 HTTPS URL',
`MimeType` VARCHAR(64) NULL COMMENT 'image/jpeg 等',
`FileSizeBytes` BIGINT NULL COMMENT '字节数',
`IsDeleted` TINYINT NOT NULL DEFAULT 0,
`CreateUserId` INT NOT NULL DEFAULT 0,
`CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`Id`),
KEY `idx_xhs_media_customer` (`CustomerId`, `CreateTime`)
) COMMENT='小红书创作上传媒体表';
```
### 4.9 ER 关系概览
```mermaid
erDiagram
t_customer ||--o{ t_xhs_agent : owns
t_customer ||--o| t_xhs_human_config : has
t_customer ||--o{ t_xhs_ai_provider : configures
t_customer ||--o{ t_xhs_skill : owns
t_customer ||--o{ t_xhs_task : creates
t_customer ||--o{ t_xhs_publish_record : owns
t_customer ||--o{ t_xhs_analysis_session : owns
t_xhs_agent ||--o{ t_xhs_task : executes
t_xhs_task ||--o| t_xhs_publish_record : generates
t_xhs_skill ||--o{ t_xhs_publish_record : sources
t_xhs_skill ||--o{ t_xhs_analysis_session : uses
```
---
## 5 接口设计
所有接口需 **`[Authorize]`**;Swagger 组 **`OMS-Xhs`**。
Service 建议拆分:
| Service | 文件 | 职责 |
| --- | --- | --- |
| `XhsAgentService` | `Services/Xhs/XhsAgentService.cs` | Agent 注册、心跳、状态 |
| `XhsTaskService` | `Services/Xhs/XhsTaskService.cs` | 任务 CRUD、Agent 拉取/上报 |
| `XhsPublishService` | `Services/Xhs/XhsPublishService.cs` | 发布记录、定时调度 |
| `XhsAnalysisService` | `Services/Xhs/XhsAnalysisService.cs` | 分析会话 |
| `XhsSkillService` | `Services/Xhs/XhsSkillService.cs` | 技能卡片 |
| `XhsHumanConfigService` | `Services/Xhs/XhsHumanConfigService.cs` | 拟人设置 |
| `XhsAiService` | `Services/Xhs/XhsAiService.cs` | AI 提供商与对话 |
| `XhsMediaService` | `Services/Xhs/XhsMediaService.cs` | 媒体上传 |
---
### 5.1 Agent — 启动服务页
#### 5.1.1 注册 / 更新 Agent
Agent 首次启动或 Token 变更时调用;Web 也可展示已注册设备列表。
```
POST /xhs/agent/register
```
**Request**
```json
{
"deviceId": "A1B2C3D4-....",
"deviceName": "办公室电脑",
"agentVersion": "1.0.0",
"bridgePort": 9333
}
```
**Response**
```json
{
"agentId": 1,
"customerId": 100,
"deviceId": "A1B2C3D4-....",
"humanConfigVersion": 3
}
```
#### 5.1.2 心跳(Agent 每 30s)
```
POST /xhs/agent/heartbeat
```
**Request**
```json
{
"deviceId": "A1B2C3D4-....",
"engineRunning": true,
"extensionConnected": true,
"xhsLoggedIn": true,
"lastError": null
}
```
**Response**
```json
{
"ok": true,
"humanConfigVersion": 3,
"serverTime": "2026-06-30T12:00:00"
}
```
#### 5.1.3 查询 Agent 列表(Web)
```
POST /xhs/agent/list
```
**Request**
```json
{
"page": 1,
"pageSize": 30
}
```
**Response** `OmsPageResult<XhsAgentOutput>`
```json
{
"items": [
{
"id": 1,
"deviceId": "A1B2C3D4-....",
"deviceName": "办公室电脑",
"status": "online",
"engineRunning": true,
"extensionConnected": true,
"xhsLoggedIn": true,
"lastHeartbeatTime": "2026-06-30T12:00:00",
"agentVersion": "1.0.0"
}
],
"total": 1
}
```
> **在线判定**:`LastHeartbeatTime` 距今 ≤ 90s 且 `Status=online`。
#### 5.1.4 远程控制(Web → 创建任务)
```
POST /xhs/agent/control
```
**Request**
```json
{
"agentId": 1,
"action": "engine_start"
}
```
`action` 枚举:`engine_start` | `engine_stop` | `browser_login` | `clear_cookies` | `check_login`
**Response**
```json
{
"taskId": 101
}
```
---
### 5.2 任务 — Agent 拉取与上报
#### 5.2.1 Agent 拉取待执行任务
```
POST /xhs/task/claim
```
**Request**
```json
{
"deviceId": "A1B2C3D4-....",
"limit": 1
}
```
**Response**
```json
{
"items": [
{
"id": 101,
"taskType": "publish",
"toolName": "publish_content",
"arguments": { "title": "...", "images": ["https://..."] },
"humanConfigVersion": 3
}
]
}
```
认领后任务 `Status` → `claimed`;Agent 开始执行 → 调 `report` 置 `running`。
#### 5.2.2 Agent 上报进度/结果
```
POST /xhs/task/report
```
**Request**
```json
{
"taskId": 101,
"status": "succeeded",
"progressText": "正在发布…",
"result": { "summary": "发布成功" },
"errorMessage": null
}
```
`status`:`running` | `succeeded` | `failed`
#### 5.2.3 Web 查询任务(可选,调试)
```
POST /xhs/task/list
```
**Request**
```json
{
"page": 1,
"pageSize": 30,
"status": "pending",
"taskType": null,
"sourceRefId": null
}
```
#### 5.2.4 取消任务
```
POST /xhs/task/cancel
```
**Request**
```json
{
"taskId": 101
}
```
仅 `pending` / `claimed` 可取消。
---
### 5.3 内容分析
#### 5.3.1 创建分析会话并提交采集任务
```
POST /xhs/analysis/start
```
**Request**
```json
{
"analysisType": "search",
"keyword": "跨境物流",
"filters": {
"sort_by": "最多点赞",
"note_type": "图文"
},
"agentId": 1,
"skillId": 5
}
```
`analysisType`:`home_feed` | `search` | `my_feeds` | `feed_detail`
**Response**
```json
{
"sessionId": 20,
"taskId": 102
}
```
#### 5.3.2 会话列表
```
POST /xhs/analysis/list
```
**Response** `OmsPageResult<XhsAnalysisSessionOutput>`
#### 5.3.3 会话详情
```
POST /xhs/analysis/detail
```
**Request** `{ "sessionId": 20 }`
**Response** 含 `feedsJson`、`aiAnalysisMarkdown`
#### 5.3.4 AI 分析(基于已采集 feeds)
```
POST /xhs/analysis/run-ai
```
**Request**
```json
{
"sessionId": 20,
"skillId": 5,
"providerKey": "ai_zhipu",
"selectedFeedIds": ["6a095abd0000000006030184"]
}
```
**Response**
```json
{
"markdown": "## 爆款共性\n\n1. ..."
}
```
后端调用 `XhsAiService` 代理转发,**API Key 不出前端**。
#### 5.3.5 创建互动任务(评论/点赞)
```
POST /xhs/analysis/interact
```
**Request**
```json
{
"agentId": 1,
"action": "post_comment",
"feedId": "6a095abd0000000006030184",
"xsecToken": "ABIrq9ZLAO...",
"content": "写得太好了!"
}
```
---
### 5.4 爆款创作
#### 5.4.1 AI 生成笔记文案
```
POST /xhs/creation/generate
```
**Request**
```json
{
"skillId": 5,
"providerKey": "ai_zhipu",
"topic": "9610 简易申报入门",
"extraNotes": "面向外贸小白"
}
```
**Response**
```json
{
"title": "9610到底是什么?一文讲清",
"content": "正文...",
"tags": ["跨境", "物流"],
"imagePrompts": ["清关流程信息图风格"]
}
```
#### 5.4.2 上传图片
```
POST /xhs/media/upload
Content-Type: multipart/form-data
```
**Response**
```json
{
"mediaId": 1,
"publicUrl": "https://oms.nanafa.com/uploads/xhs/100/abc.jpg"
}
```
#### 5.4.3 提交发布(立即或定时)
```
POST /xhs/creation/publish
```
**Request**
```json
{
"agentId": 1,
"toolName": "publish_content",
"title": "笔记标题",
"content": "正文",
"mediaUrls": ["https://..."],
"tags": ["生活"],
"visibility": "公开可见",
"scheduledTime": "2026-06-30T18:00:00",
"skillId": null
}
```
`scheduledTime` 为空则立即创建 `pending` 任务;有值则 `publish_record.Status=scheduled`,由后台 **定时扫描**(或 Agent 心跳触发)生成任务。
**Response**
```json
{
"publishRecordId": 50,
"taskId": 103
}
```
---
### 5.5 发布记录
#### 5.5.1 分页列表
```
POST /xhs/publish/list
```
**Request**
```json
{
"page": 1,
"pageSize": 30,
"status": null,
"keyword": null
}
```
**Response** `OmsPageResult<XhsPublishRecordOutput>`
#### 5.5.2 取消定时发布
```
POST /xhs/publish/cancel
```
**Request** `{ "publishRecordId": 50 }`
仅 `scheduled` 可取消;关联 `pending` 任务一并 `cancelled`。
#### 5.5.3 重试失败发布
```
POST /xhs/publish/retry
```
**Request** `{ "publishRecordId": 50, "agentId": 1 }`
---
### 5.6 技能卡片
#### 5.6.1 列表
```
POST /xhs/skill/list
```
**Response** `OmsItemsResult<XhsSkillOutput>`(不分页,单客户通常 < 50 条)
#### 5.6.2 保存(新增/更新)
```
POST /xhs/skill/save
```
**Request**
```json
{
"id": null,
"title": "物流知识 · 干货教程",
"skillType": "ai_create",
"presetId": "",
"recipe": { "formula": ["emotion", "utility"], "body": { "domain": "物流知识" } }
}
```
#### 5.6.3 删除
```
POST /xhs/skill/delete
```
**Request** `{ "id": 5 }`
#### 5.6.4 一键执行技能
```
POST /xhs/skill/run
```
**Request**
```json
{
"skillId": 5,
"agentId": 1,
"runMode": "create_and_publish",
"providerKey": "ai_zhipu",
"topicOverride": null
}
```
`runMode`:`analyze_only` | `create_only` | `create_and_publish`
**Response**
```json
{
"taskIds": [104, 105],
"publishRecordId": 51
}
```
---
### 5.7 拟人设置
#### 5.7.1 获取配置
```
POST /xhs/human-config/get
```
**Response**
```json
{
"behavior": { "human_delay": { "min_ms": 300, "max_ms": 700 }, "home_browse_plan": { } },
"guard": {
"publish": { "max_per_day": 2, "min_interval_hours": 6 },
"browse": { "max_per_hour": 20 },
"quiet_hours": { "enabled": true, "start": "02:00", "end": "07:00" }
},
"version": 3
}
```
#### 5.7.2 保存配置
```
POST /xhs/human-config/save
```
**Request** 同上结构;保存后 `Version++`,Agent 下次心跳拉取新版本。
#### 5.7.3 Agent 拉取配置(内嵌 heartbeat 或独立)
```
POST /xhs/human-config/pull
```
**Request** `{ "deviceId": "...", "knownVersion": 2 }`
若版本一致返回 `{ "unchanged": true }`,否则返回完整 JSON。
---
### 5.8 AI 助手(系统菜单)
#### 5.8.1 提供商列表
```
POST /xhs/ai/provider/list
```
**Response**:`apiKey` / `apiSecret` **脱敏**(仅显示后四位)。
#### 5.8.2 保存提供商
```
POST /xhs/ai/provider/save
```
**Request**
```json
{
"providerKey": "ai_zhipu",
"providerType": "zhipu",
"displayName": "智谱 GLM",
"baseUrl": "https://open.bigmodel.cn/api/paas/v4",
"apiKey": "5fb9...",
"apiSecret": "glm-5.1",
"isDefault": true,
"enabled": true
}
```
#### 5.8.3 对话补全(Web AI 助手页)
```
POST /xhs/ai/chat
```
**Request**
```json
{
"providerKey": "ai_zhipu",
"model": null,
"messages": [
{ "role": "user", "content": "帮我写一个小红书标题" }
],
"scene": "assistant"
}
```
`scene`:`assistant` | `note_create` | `note_analysis` | `image_prompt` | `video_script`
**Response**
```json
{
"content": "......",
"usage": { "promptTokens": 100, "completionTokens": 200 }
}
```
#### 5.8.4 图片提示词 / 文生图(可选 v2)
```
POST /xhs/ai/image-prompt
POST /xhs/ai/image-generate
```
---
## 6 定时发布调度
LIKE AI 原 `publish_scheduler.process_due_scheduled` 逻辑迁移到 **OMS 后端**:
1. 后台 `IHostedService` 或 Hangfire 每分钟扫描:
```sql
SELECT * FROM t_xhs_publish_record
WHERE Status = 'scheduled'
AND ScheduledTime <= NOW()
AND IsDeleted = 0
LIMIT 10;
```
2. 每条创建 `t_xhs_task`(`Source=schedule`, `SourceRefId=publish_record.Id`),并将记录置 `publishing`。
3. Agent `claim` 后执行;`report` 回写 `publish_record` 最终状态。
---
## 7 Agent 对接契约(LIKE AI 改造要点)
### 7.1 启动参数
```bash
like_ai_agent.exe --oms-url https://oms.nanafa.com/admin --token <JWT> --device-id <GUID>
```
### 7.2 主循环伪代码
```python
while True:
heartbeat() # POST /xhs/agent/heartbeat
pull_human_config_if_needed()
tasks = claim_tasks(limit=1) # POST /xhs/task/claim
for task in tasks:
report(task.id, status="running")
result = service.call_tool(task.tool_name, task.arguments, check_license=True)
report(task.id, status="succeeded", result=result)
sleep(5)
```
### 7.3 不在 Agent 上报范围
- 物流查价记录
- CLI 请求日志
- License 激活状态(本地校验即可)
---
## 8 后端目录与迁移脚本
### 8.1 建议代码结构
```
Oms.Domain/XhsAggregate/Entities/
Oms.Domain/XhsAggregate/Repositories/
Oms.Application/Services/Xhs/
Oms.Application/Dtos/Xhs/
Oms.SqlSugarCore/Repositories/Xhs/
sql/migrate_t_xhs.sql # 本设计 DDL 汇总
```
### 8.2 迁移脚本位置
`C:\Users\wilso\Desktop\oms0414-back\sql\migrate_t_xhs.sql`(实现阶段从本文 §4 导出)
同步更新 `db.sql` 末尾追加 `t_xhs_*` 表定义。
---
## 9 前端 API 模块
```
src/api/xhs/
agent.ts
task.ts
analysis.ts
creation.ts
publish.ts
skill.ts
humanConfig.ts
ai.ts
media.ts
index.ts
```
统一使用 `@/api/rbac` 的 `axiosInstance`(Bearer Token)。
---
## 10 实施顺序建议
| 阶段 | 交付 |
| --- | --- |
| **P0** | DDL + `XhsAgentService` + `XhsTaskService` + Agent 心跳/拉取/上报 + 「启动服务」页 |
| **P1** | 发布记录 + 爆款创作 + 媒体上传 + 定时调度 |
| **P2** | 内容分析 + 技能卡片 |
| **P3** | 拟人设置 + AI 助手(系统菜单) |
| **P4** | RBAC 菜单种子数据、Agent 安装包下载页 |
---
## 11 接口路径速查
| 方法 | 路径 | 页面 |
| --- | --- | --- |
| POST | `/xhs/agent/register` | Agent |
| POST | `/xhs/agent/heartbeat` | Agent |
| POST | `/xhs/agent/list` | 启动服务 |
| POST | `/xhs/agent/control` | 启动服务 |
| POST | `/xhs/task/claim` | Agent |
| POST | `/xhs/task/report` | Agent |
| POST | `/xhs/task/list` | 调试 |
| POST | `/xhs/task/cancel` | 各页 |
| POST | `/xhs/analysis/start` | 内容分析 |
| POST | `/xhs/analysis/list` | 内容分析 |
| POST | `/xhs/analysis/detail` | 内容分析 |
| POST | `/xhs/analysis/run-ai` | 内容分析 |
| POST | `/xhs/analysis/interact` | 内容分析 |
| POST | `/xhs/creation/generate` | 爆款创作 |
| POST | `/xhs/creation/publish` | 爆款创作 |
| POST | `/xhs/media/upload` | 爆款创作 |
| POST | `/xhs/publish/list` | 发布记录 |
| POST | `/xhs/publish/cancel` | 发布记录 |
| POST | `/xhs/publish/retry` | 发布记录 |
| POST | `/xhs/skill/list` | 技能卡片 |
| POST | `/xhs/skill/save` | 技能卡片 |
| POST | `/xhs/skill/delete` | 技能卡片 |
| POST | `/xhs/skill/run` | 技能卡片 |
| POST | `/xhs/human-config/get` | 拟人设置 |
| POST | `/xhs/human-config/save` | 拟人设置 |
| POST | `/xhs/human-config/pull` | Agent |
| POST | `/xhs/ai/provider/list` | AI 助手 |
| POST | `/xhs/ai/provider/save` | AI 助手 |
| POST | `/xhs/ai/chat` | AI 助手 / 创作 / 分析 |
---
## 12 开放问题(实现前确认)
1. **子客户**是否允许绑定 Agent、操作小红书?默认与订单一致:子客户可用,数据 `CustomerId` 为子客户自身 Id。
2. **系统预置技能**(`CustomerId=0`)是否对所有客户只读可见?建议:只读 + 可复制到本客户。
3. **AI 密钥**:客户级 vs 租户级全局 — 当前设计为 **客户级**;管理员在系统菜单可配 `CustomerId=0` 作为全局默认 fallback。
4. **SignalR 推送**任务是否作为 v2 优化(当前 Agent 轮询 `claim`)。