feat: 微信公众号技能包重命名(weixin_public_account)并增强功能
- 将 wechat_official_account 重命名为 weixin_public_account,符合中文命名规范 - 新增 DOCX 文档生成技能、聊天历史、请求 ID 中间件 - 增强工作流、热点服务、文章服务等模块功能 - 前端同步重命名组件和 API - 新增架构文档 AR13/AR14、专员文档更新 - 补充测试用例(seed_specialists_test, db_migration_test) Co-Authored-AI: yes
This commit is contained in:
@@ -323,7 +323,7 @@ API 路径**独立地**收敛到了同一条:
|
||||
|
||||
子系统前缀白名单(现有;新增须先登记到本表):
|
||||
|
||||
`task` · `knowledge` · `exam` · `official_account` · `ai` · `media` · `system` · `user` · `position`
|
||||
`task` · `knowledge` · `exam` · `weixin_public_account` · `ai` · `media` · `system` · `user` · `position`
|
||||
|
||||
**已知的一处不同构(登记,不强制回改)**:`specialist` 是裸名,而它的同位对象是 `skill_definition` / `xapp_definition` / `action_definition`。
|
||||
`_definition` 后缀标记的是"对象定义表",按此语义 `specialist` 应属同一族。但改表名牵动迁移与所有引用,收益不抵成本 —— 按 §6.4 的 P3 纪律**先登记,不顺手改**。
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,150 @@
|
||||
# AR14 — 跨项目技术选型对比分析
|
||||
|
||||
> **日期:** 2026-09-23
|
||||
> **状态:** 参考文件(记录 pj0235 与 pj0237 两项目的技术栈选型依据与结论)
|
||||
|
||||
---
|
||||
|
||||
## 1. 项目概览
|
||||
|
||||
### pj0235-eai_agentplatform(企业智能体平台)
|
||||
|
||||
| 维度 | 说明 |
|
||||
|------|------|
|
||||
| 项目类型 | 企业管理平台(培训、考试、知识管理、AI 助手) |
|
||||
| 当前语言 | Go 1.25 |
|
||||
| Web 框架 | Gin |
|
||||
| ORM | GORM |
|
||||
| 数据库 | SQLite(modernc 纯 Go 驱动) |
|
||||
| 前端 | Vue 3 + Vite + Element Plus |
|
||||
| 部署方式 | 静态二进制(38MB)+ systemd + Nginx |
|
||||
| 交付形态 | 单二进制部署,无需运行时依赖 |
|
||||
|
||||
### pj0237-mobwx_chatextr(微信聊天记录导出工具)
|
||||
|
||||
| 维度 | 说明 |
|
||||
|------|------|
|
||||
| 项目类型 | 桌面/移动端工具(微信数据采集、传输、解密、解析) |
|
||||
| 当前语言 | Rust |
|
||||
| 客户端框架 | Tauri 2(桌面端 + Android) |
|
||||
| 核心 crate | crates/core、crates/transfer、crates/ipc、crates/keywrap、crates/device、crates/desktop |
|
||||
| 传输协议 | SFTP(ssh2 crate,调用 libssh2) |
|
||||
| 前端 | JS(Tauri Webview 注入) |
|
||||
| 部署形态 | 多平台二进制(Windows / Linux / macOS / Android) |
|
||||
| 历史实现 | Go 实现已归档至 ahchive_goverson_ 目录 |
|
||||
|
||||
---
|
||||
|
||||
## 2. pj0235:为什么不选 Rust
|
||||
|
||||
### 2.1 当前 Go 方案已完全满足需求
|
||||
|
||||
| 需求 | Go 实现情况 |
|
||||
|------|------------|
|
||||
| 本地化部署 | `CGO_ENABLED=0 go build` 生成 38MB 静态二进制,无需任何运行时 |
|
||||
| 不泄露源码 | 静态链接二进制无法反编译回源码 |
|
||||
| 性能足够 | 企业级应用(CRUD + AI 调用),Go 性能绰绰有余 |
|
||||
| 生态成熟 | Gin + GORM + JWT + bcrypt 组合经过生产验证 |
|
||||
|
||||
### 2.2 重构成本与收益严重失衡
|
||||
|
||||
- 代码规模:Go 后端约 200+ 个文件(15-25 万行),前端约 100+ 个文件
|
||||
- 业务场景:培训管理、AI 对话、知识检索——不是需要 Rust 极致性能的场景
|
||||
- Rust 生态:ORM(Diesel/sea-orm)成熟度不及 GORM,JWT 等库需自行整合
|
||||
- 学习成本:团队需投入 Rust 异步运行时、所有权系统等学习时间
|
||||
|
||||
### 2.3 Go 二进制安全性已经足够
|
||||
|
||||
静态链接 + 无源码分发,逆向难度已经很高。Go 的运行时和反射机制使得反编译比 Rust 更困难。
|
||||
|
||||
---
|
||||
|
||||
## 3. pj0237:为什么 Rust 是正确选择
|
||||
|
||||
### 3.1 Tauri 框架天然绑定 Rust
|
||||
|
||||
Tauri 的核心(`tauri` crate)是 Rust 写的。使用 Tauri 意味着:
|
||||
- 核心逻辑用 Rust 可实现桌面端与移动端共享
|
||||
- 避免 JS 桥接层的开销和 bug
|
||||
- Rust 与 Tauri 的 FFI 是原生而非桥接
|
||||
|
||||
### 3.2 加密敏感场景需要内存安全
|
||||
|
||||
项目涉及:
|
||||
- 微信数据库密钥(`wrapped.key`,MWXK 私有格式)
|
||||
- SSH 私钥认证
|
||||
- 数据库解密(SQLCipher 兼容)
|
||||
|
||||
Rust 的编译时内存安全保证在这些场景下是真实收益。
|
||||
|
||||
### 3.3 跨平台二进制交付需求
|
||||
|
||||
输出需要覆盖四个平台:
|
||||
|
||||
| 平台 | 输出 |
|
||||
|------|------|
|
||||
| Windows | `mwx.exe` |
|
||||
| Linux | `mwx` |
|
||||
| macOS | `mwx` |
|
||||
| Android | `mwx-agent`(Go 实现) |
|
||||
|
||||
Rust 跨平台编译能力成熟,`Cargo` 一次定义、多平台构建。
|
||||
|
||||
### 3.4 与旧 Go 实现的对标
|
||||
|
||||
核心 `transfer` crate 实现了 SFTP 传输、断点续传、SHA256 完整性校验:
|
||||
- 完整的类型系统(`Manifest`、`FileEntry`、`UploadState`、`TransferError`)
|
||||
- 详尽的单元测试(1800+ 行测试)
|
||||
- `ssh2` crate 直接调用 libssh2,比 Go 的 `pkg/sftp` 更贴近底层
|
||||
|
||||
从归档目录看,旧 Go 实现已跑通 MVP,Rust 是在验证可行后的工程化升级。
|
||||
|
||||
---
|
||||
|
||||
## 4. 对比结论
|
||||
|
||||
### 4.1 决策矩阵
|
||||
|
||||
| 维度 | pj0235(企业平台) | pj0237(微信工具) |
|
||||
|------|-------------------|-------------------|
|
||||
| 项目类型 | 业务管理系统(SaaS) | 桌面/移动端工具(本地部署) |
|
||||
| 核心逻辑 | 业务 CRUD + AI 调用 | 加密 + SFTP 传输 + 数据库解析 |
|
||||
| 安全敏感度 | 中等(JWT + 角色权限) | 高(私钥 + 数据库密钥) |
|
||||
| 多端共享 | 无需(前端独立) | 必须(桌面 + 移动端共享核心) |
|
||||
| 交付平台 | Linux 服务器 | Windows + Linux + macOS + Android |
|
||||
| 性能瓶颈 | 无 | 文件 I/O + 加解密 |
|
||||
| 推荐语言 | Go(已选) | Rust(已选) |
|
||||
|
||||
### 4.2 核心原则
|
||||
|
||||
**项目类型决定技术栈,不是流行度决定。**
|
||||
|
||||
| 场景 | 推荐 | 原因 |
|
||||
|------|------|------|
|
||||
| 业务管理系统、微服务、SaaS | Go | 开发效率高,生态成熟,足够好用 |
|
||||
| 加密敏感、系统编程、FFI 调用多 | Rust | 编译时内存安全,贴近底层 |
|
||||
| Tauri 桌面应用 | Rust | 框架绑定,核心逻辑天然共享 |
|
||||
| 多平台二进制分发 | Rust 或 Go | 两者都支持,Rust 更统一 |
|
||||
| AI/LLM 调用密集型 | Go 或 Python | 不需要 Rust 的极致性能 |
|
||||
|
||||
### 4.3 GitHub Rust 项目多的误导性
|
||||
|
||||
GitHub 上 Rust 项目数量多、增长快,但这:
|
||||
1. 反映的是**增长率**,不是绝对总量(JS、Python 仍远超)
|
||||
2. 受社区开源文化影响(Rust 社区天然开源)
|
||||
3. 大量是工具库、框架、基础设施项目,而非业务应用
|
||||
|
||||
流行度 ≠ 技术选型正确性。两个项目都选对了各自的工具。
|
||||
|
||||
---
|
||||
|
||||
## 5. 对其他项目的参考
|
||||
|
||||
当评估新项目技术栈时,依次判断:
|
||||
|
||||
1. **是否需要内存安全保证?**(加密、驱动、协议解析 → 倾向 Rust)
|
||||
2. **是否绑定特定语言框架?**(Tauri → Rust,Spring → Java)
|
||||
3. **核心瓶颈在哪里?**(CPU/内存密集 → 可能 Rust,I/O 密集 → Go/Python 均可)
|
||||
4. **是否需要快速迭代?**(业务探索期 → Go/Python,稳定期 → 语言选择次要)
|
||||
5. **团队熟悉度如何?**(已有经验优先,除非有强技术理由)
|
||||
6. **交付形态是什么?**(容器化微服务 → Go/Java,单机二进制 → Go/Rust)
|
||||
@@ -10,6 +10,8 @@
|
||||
> `新建任务 / 项目 / 专员·技能·APP·连接器 / 长程APP / 知识库 / 后台管理 / 我的`
|
||||
> **`AR09` 是规范性文件(对象命名规范),不是设计稿。** 它约束新增代码的命名,并登记了当前已核实的命名问题与修复流程;与 `TOP_CODING_RULES.md` 的 G03 配套使用。
|
||||
> **`AR12` 是当前交互范式讨论的主文档。** 它定义“对话发起 + 结构化决策接管 + 对话继续推进”的混合交互架构,后续 Workbench 与专员工作流交互以此为依据。
|
||||
> **`AR13` 是公众号创作专员的正式多智能体架构定义。** 它定义双层工作流、步骤内角色智能体、共享任务上下文、裁决守门规则与对话回流协议,后续公众号创作专员执行器与右栏可视化以此为依据。
|
||||
> **`AR14` 是跨项目技术选型对比分析(参考文件)。** 记录了 pj0235(Go)与 pj0237(Rust)两项目的技术栈选型依据与结论,可作为其他项目技术选型的参考。
|
||||
> 当前正式对象目录请以 `docs/05_Object_Catalog/` 为准;本目录负责跨层架构契约,不再承担对象清单主仓职责。
|
||||
|
||||
## 文件清单
|
||||
@@ -31,4 +33,6 @@
|
||||
| `AR10_应用可删除封装规范.md` | XApp 可删除封装规范(面向一级业务包,目标是“删目录 + 删注册 + 跑卸载”) |
|
||||
| `AR11_技能专员连接器可删除封装规范.md` | Skill / Specialist / Connector 可删除封装规范(复用 AR10 思想,但区分能力包、策略定义包、连接插件包的边界) |
|
||||
| `AR12_对话驱动与结构化交互架构.md` | Workbench 交互范式主文档(对话发起 + 结构化决策接管 + 对话继续推进) |
|
||||
| `AR13_公众号创作专员双层多智能体架构定义.md` | 公众号创作专员多智能体架构主文档(双层工作流 + 步骤内角色智能体 + 共享任务上下文 + 裁决守门 + 对话回流) |
|
||||
| `AR14_跨项目技术选型对比分析.md` | 跨项目技术选型对比分析(参考文件:pj0235 Go vs pj0237 Rust 选型依据与结论) |
|
||||
| `Historical_Records/目录说明.md` | 架构迁移说明、历史清单、旧版 AR01–AR03 与阶段性记录索引 |
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
| `专01` | `EAI-S-01` | `contract-review` | 合同审查专员 | 条款风险、红线建议、审查交付 | active | 保留,后面再看是否补强法务数据面 |
|
||||
| `专02` | `EAI-S-02` | `solution-proposal` | 售前方案专员 | 客户需求澄清、方案草案、评审材料 | active | 保留,后面可补 CRM / 方案模板绑定 |
|
||||
| `专03` | `EAI-S-03` | `training-delivery` | 培训交付专员 | 培训计划、交付节点、归档闭环 | active | 继续观察是否需要拆出交付 xapp |
|
||||
| `专04` | `EAI-S-04` | `wechat-official-account` | 公众号创作专员 | 选题、提纲、正文、发布准备 | active | 继续包化公众号工作流与模型 |
|
||||
| `专04` | `EAI-S-04` | `weixin-public-account` | 公众号创作专员 | 选题、提纲、正文、发布准备 | active | 继续包化公众号工作流与模型 |
|
||||
| `专05` | `EAI-S-05` | `customer-followup` | 客户跟进专员 | 客户资料整理、意向分层、联系推进、会议预约 | active | 作为新口径继续打磨;详见 [客户跟进专员.md](./客户跟进专员.md) |
|
||||
| `专06` | `EAI-S-06` | `resume-processor` | 简历筛选与招聘专员 | 招聘入口归档、候选人筛选、面试推进 | active | 继续观察是否需要补独立招聘连接器 |
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ GW02 给出了"对话 vs 结构化 UI"的分界原则。本文件把它落到具
|
||||
|
||||
---
|
||||
|
||||
### 2.2 公众号创作专员(wechat-official-account)
|
||||
### 2.2 公众号创作专员(weixin-public-account)
|
||||
|
||||
| 维度 | 分析 |
|
||||
|---|---|
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
> 关联文档:
|
||||
> - `GW02_对话式AI工作台与传统UI分界判断.md`
|
||||
> - `GW03_专员工作交互形式分析.md`
|
||||
> - `docs/05_Object_Catalog/specialists/wechat-official-account/`(对象目录)
|
||||
> - `docs/05_Object_Catalog/specialists/weixin-public-account/`(对象目录)
|
||||
|
||||
---
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
| 层级 | 组件 | 说明 |
|
||||
|------|------|------|
|
||||
| Manifest | manifest.js (26行) | 专员定义 + InteractionCard |
|
||||
| API 封装 | officialAccount.js (33行) | 6个API函数 |
|
||||
| API 封装 | weixinPublicAccount.js (33行) | 6个API函数 |
|
||||
| 内置注册 | builtin.js 注册 | 作为第4个内置专员注册 |
|
||||
| 项目模板 | content-operations 绑定 | 绑定公众号创作专员 |
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
| 缺失项 | 级别 | 说明 |
|
||||
|--------|------|------|
|
||||
| **专属路由页面** | 必须 | `/apps/wechat-official-account` 无对应前端页面 |
|
||||
| **专属路由页面** | 必须 | `/apps/weixin-public-account` 无对应前端页面 |
|
||||
| **工作流配置页** | 必须 | 创建任务时输入业务域、关键词、受众、目标、语气等 |
|
||||
| **工作流步骤面板** | 必须 | 选题候选卡片选择、标题选择、提纲编辑、正文编辑 |
|
||||
| **配图管理 UI** | 必须 | 配图提示词查看、图片预览、图片重生成 |
|
||||
@@ -138,7 +138,7 @@
|
||||
需要实现的前端页面结构:
|
||||
|
||||
```
|
||||
/apps/wechat-official-account
|
||||
/apps/weixin-public-account
|
||||
├── 创建页:输入业务域、关键词、受众、目标、语气、字数要求
|
||||
├── 工作流页(主页面)
|
||||
│ ├── 左侧:步骤导航栏(9步进度条)
|
||||
@@ -305,14 +305,14 @@ AI 不仅给热度标签(爆热/高/中高/中),还给出预估阅读量
|
||||
|
||||
## 5. 已知 Bug
|
||||
|
||||
### 5.1 `isOfficialAccountStep` 缺少 `page_markdown` case
|
||||
### 5.1 `isWeixinPublicAccountStep` 缺少 `page_markdown` case
|
||||
|
||||
后端工作流引擎的 `isOfficialAccountStep` 函数(约第 919-924 行)的 switch 语句中缺少对 `officialAccountStepKeyPageMD` 的检查,而 `officialAccountNextStep` 函数(约第 950-968 行)会将其作为 `preview_export` 的下一步。这意味着执行分页 MD 步骤时会返回 "工作流步骤不存在" 错误。
|
||||
后端工作流引擎的 `isWeixinPublicAccountStep` 函数(约第 919-924 行)的 switch 语句中缺少对 `weixinPublicAccountStepKeyPageMD` 的检查,而 `weixinPublicAccountNextStep` 函数(约第 950-968 行)会将其作为 `preview_export` 的下一步。这意味着执行分页 MD 步骤时会返回 "工作流步骤不存在" 错误。
|
||||
|
||||
**修复方法:** 在 `isOfficialAccountStep` 的 switch 中添加:
|
||||
**修复方法:** 在 `isWeixinPublicAccountStep` 的 switch 中添加:
|
||||
|
||||
```go
|
||||
case officialAccountStepKeyPageMD:
|
||||
case weixinPublicAccountStepKeyPageMD:
|
||||
return true
|
||||
```
|
||||
|
||||
@@ -323,12 +323,12 @@ case officialAccountStepKeyPageMD:
|
||||
### 6.1 目录结构
|
||||
|
||||
```
|
||||
frontend/src/specialists/packages/wechat-official-account/
|
||||
frontend/src/specialists/packages/weixin-public-account/
|
||||
├── manifest.js ← 已存在,不需改
|
||||
├── views/
|
||||
│ ├── OfficialAccountCreatePage.vue ← 创建任务页
|
||||
│ ├── OfficialAccountWorkbenchPage.vue ← 工作流主页面(核心)
|
||||
│ └── OfficialAccountPreviewPage.vue ← 预览页(可选,可嵌入 Workbench)
|
||||
│ ├── WeixinPublicAccountCreatePage.vue ← 创建任务页
|
||||
│ ├── WeixinPublicAccountWorkbenchPage.vue ← 工作流主页面(核心)
|
||||
│ └── WeixinPublicAccountPreviewPage.vue ← 预览页(可选,可嵌入 Workbench)
|
||||
├── components/
|
||||
│ ├── WorkflowStepNav.vue ← 步骤导航(9步进度条)
|
||||
│ ├── TopicCandidateCard.vue ← 选题候选卡片
|
||||
@@ -340,16 +340,16 @@ frontend/src/specialists/packages/wechat-official-account/
|
||||
│ ├── PreviewPanel.vue ← 预览面板
|
||||
│ └── BottomPanel.vue ← 底部面板
|
||||
├── composables/
|
||||
│ ├── useOfficialAccountWorkflow.js ← 工作流状态管理
|
||||
│ └── useOfficialAccountExport.js ← 导出逻辑
|
||||
│ ├── useWeixinPublicAccountWorkflow.js ← 工作流状态管理
|
||||
│ └── useWeixinPublicAccountExport.js ← 导出逻辑
|
||||
└── api/
|
||||
└── officialAccount.js ← 已存在,不需改
|
||||
└── weixinPublicAccount.js ← 已存在,不需改
|
||||
```
|
||||
|
||||
### 6.2 核心交互流程伪代码
|
||||
|
||||
```javascript
|
||||
// OfficialAccountWorkbenchPage.vue
|
||||
// WeixinPublicAccountWorkbenchPage.vue
|
||||
<template>
|
||||
<div class="workbench">
|
||||
<!-- 左侧:步骤导航 -->
|
||||
@@ -421,12 +421,12 @@ frontend/src/specialists/packages/wechat-official-account/
|
||||
|
||||
```javascript
|
||||
// 1. 用户从专员市场或通用助手点击"公众号创作专员"
|
||||
// 2. 跳转到 /apps/wechat-official-account
|
||||
// 2. 跳转到 /apps/weixin-public-account
|
||||
// 3. 展示创建表单(或对话式启动)
|
||||
// 4. 填写表单 → 创建任务 → 跳转到工作流页
|
||||
|
||||
// 表单提交
|
||||
const task = await createOfficialAccountTask({
|
||||
const task = await createWeixinPublicAccountTask({
|
||||
business_domain: 'ai',
|
||||
keyword: '智能体',
|
||||
audience: '技术从业者',
|
||||
@@ -448,7 +448,7 @@ await fetchWorkflow(task.id)
|
||||
// 用户选择选题后,自动进入下一步
|
||||
async function handleSelectTopic(topic) {
|
||||
// 保存选题
|
||||
await updateOfficialAccountTask(taskId, { selected_topic: topic })
|
||||
await updateWeixinPublicAccountTask(taskId, { selected_topic: topic })
|
||||
// 执行下一步:标题生成
|
||||
await executeStep(taskId, 'title_generation', { topic })
|
||||
// 刷新工作流
|
||||
@@ -471,7 +471,7 @@ async function handleSelectTopic(topic) {
|
||||
| 组件 | 预估工作量 | 说明 |
|
||||
|------|-----------|------|
|
||||
| 创建表单 | 1天 | 业务域、关键词、受众、目标、语气、字数 |
|
||||
| 路由配置 | 0.5天 | `/apps/wechat-official-account` 路由 |
|
||||
| 路由配置 | 0.5天 | `/apps/weixin-public-account` 路由 |
|
||||
| 步骤导航 | 1天 | 9步进度条,状态指示 |
|
||||
| 选题卡片 | 1.5天 | 候选展示、选择、刷新热点 |
|
||||
| 标题卡片 | 0.5天 | 3个标题候选、选择 |
|
||||
|
||||
@@ -185,13 +185,13 @@ SpecialistPanel 是一个**只读面板**,它的职责是:
|
||||
- SpecialistPanel 根据 `currentStep` 动态渲染不同组件
|
||||
- 对话消息中展示工作流摘要
|
||||
- 面板中展示完整交互
|
||||
- 两个区域的同步通过 `fetchOfficialAccountWorkflow` API + 定时刷新
|
||||
- 两个区域的同步通过 `fetchWeixinPublicAccountWorkflow` API + 定时刷新
|
||||
|
||||
---
|
||||
|
||||
### 方案 B:独立工作台页面
|
||||
|
||||
**思路:** 用户从对话框点击"用公众号创作专员处理"后,跳转到 `/apps/wechat-official-account` 独立页面。
|
||||
**思路:** 用户从对话框点击"用公众号创作专员处理"后,跳转到 `/apps/weixin-public-account` 独立页面。
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────────────────────────────┐
|
||||
@@ -410,8 +410,8 @@ SpecialistPanel 是一个**只读面板**,它的职责是:
|
||||
|
||||
<!-- 新增:交互式步骤 -->
|
||||
<div v-if="tab === 'interactive'">
|
||||
<OfficialAccountStepInteractive
|
||||
v-if="currentSpecialistKey === 'wechat-official-account'"
|
||||
<WeixinPublicAccountStepInteractive
|
||||
v-if="currentSpecialistKey === 'weixin-public-account'"
|
||||
:step="currentStep"
|
||||
:workflow-state="workflowState"
|
||||
@select="handleStepSelect"
|
||||
@@ -443,7 +443,7 @@ messages.value.push({
|
||||
```
|
||||
|
||||
当用户点击卡片中的"选择这个"时:
|
||||
1. 调用 `executeOfficialAccountWorkflowStep(stepKey, { topic: selectedTopic })`
|
||||
1. 调用 `executeWeixinPublicAccountWorkflowStep(stepKey, { topic: selectedTopic })`
|
||||
2. 工作流自动推进到下一步
|
||||
3. 新的结果卡片出现在消息流中
|
||||
|
||||
|
||||
Reference in New Issue
Block a user