feat: 新增语音转文字(ASR)功能

- 后端:新增 /api/audio/transcribe 接口,调用 Ollama whisper 进行语音识别
- 前端:新增 AudioTranscribePage.vue 页面,支持 MP3/WAV/M4A/OGG/FLAC 等格式
- 注册路由、工具卡片、智能助手欢迎语更新

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
eaiadmin
2026-09-14 00:53:36 +08:00
co-authored by Claude Code
parent 752c7837ef
commit 0455f064ac
299 changed files with 1588 additions and 432 deletions
+8 -5
View File
@@ -1,4 +1,4 @@
# eaisalestrain_app 博昇内部培训平台 — 编码与调试最高准则
# eai_agentplatform_app 博昇内部培训平台 — 编码与调试最高准则
> **版本:V1.0**
> **日期:2026-08-15**
@@ -16,7 +16,7 @@
# 第一部分:通用开发规则
> **适用范围**:适用于 eaisalestrain_app 及 EAIHub 下其他涉及 FastAPI/Vue3/AI 的项目。
> **适用范围**:适用于 eai_agentplatform_app 及 EAIHub 下其他涉及 FastAPI/Vue3/AI 的项目。
> **使用方式**:新任务开始前应先通读本部分;项目专用规则(P)在遵守本部分基础上叠加。
## 索引
@@ -112,10 +112,13 @@
## G06 原则:AI 助手行为规范
1. **任务启动预读**:AI 助手在接收到新任务后的第一步操作中,必须读取本项目根目录下的 `CODING_RULES.md` 与 `eaisalestrain_app/CLAUDE.md`。
1. **任务启动预读**:AI 助手在接收到新任务后的第一步操作中,必须读取本项目根目录下的 `CODING_RULES.md` 与 `eai_agentplatform_app/CLAUDE.md`。
2. **持续追踪**:直到问题完全解决并经由日志或接口验证通过前,不得结束任务。
3. **新对话启动仪式**:新对话必须先读 `eaisalestrain_app/PROJECT_STATE.md` → `CODING_RULES.md`,再开始干活。
3. **新对话启动仪式**:新对话必须先读 `eai_agentplatform_app/PROJECT_STATE.md` → `CODING_RULES.md`,再开始干活。
4. **发现规则与实现冲突时**,优先提醒并修正,不得静默忽略。
5. **Git 同步状态必须用 `-sb` 显式确认**:首次执行 git 相关操作时,必须使用 `git status -sb` 或 `git status -v` 而非简短版本,确保能清晰看到本地与远端的 ahead/behind 关系。禁止依赖 `git diff HEAD origin/HEAD` 单条链式命令判断,因其 `&&` 链在中间出错时会导致后续输出丢失。
6. **Git 检查必须指定分支名**:使用 `origin/<branch>`(如 `origin/main`)而非 `origin/HEAD`,避免 `origin/HEAD` 歧义。
7. **验证输出后再总结**:在给出 git 状态结论前,必须确认所有关键信息(ahead/behind、clean/dirty、branch)均已成功读取,不得在未确认完整性的情况下返回结论。
---
@@ -138,7 +141,7 @@
---
# 第二部分:eaisalestrain_app 项目专用规则
# 第二部分:eai_agentplatform_app 项目专用规则
> **适用范围**:仅适用于博昇内部培训平台项目。
> **使用方式**:本部分在通用规则之上叠加。若两者看似冲突,应先检查是否为项目专用规则对通用规则的场景化收敛。
@@ -55,22 +55,22 @@
### 品牌与布局
- `eaisalestrain_app/frontend/src/layout/SideNav.vue`
- `eaisalestrain_app/frontend/src/layout/SectionTabs.vue`
- `eaisalestrain_app/frontend/src/views/Login.vue`
- `eaisalestrain_app/frontend/src/views/home/HomePage.vue`
- `eaisalestrain_app/frontend/src/views/exam/MyCertificates.vue`
- `eai_agentplatform_app/frontend/src/layout/SideNav.vue`
- `eai_agentplatform_app/frontend/src/layout/SectionTabs.vue`
- `eai_agentplatform_app/frontend/src/views/Login.vue`
- `eai_agentplatform_app/frontend/src/views/home/HomePage.vue`
- `eai_agentplatform_app/frontend/src/views/exam/MyCertificates.vue`
### 导航与路由
- `eaisalestrain_app/frontend/src/config/navigation.js`
- `eaisalestrain_app/frontend/src/router/index.js`
- `eai_agentplatform_app/frontend/src/config/navigation.js`
- `eai_agentplatform_app/frontend/src/router/index.js`
### 系统配置页面
- `eaisalestrain_app/frontend/src/views/system/CompanyConfigPage.vue`
- `eaisalestrain_app/frontend/src/views/system/SystemConfigPage.vue`
- `eaisalestrain_app/frontend/src/views/system/AiUsage.vue`
- `eai_agentplatform_app/frontend/src/views/system/CompanyConfigPage.vue`
- `eai_agentplatform_app/frontend/src/views/system/SystemConfigPage.vue`
- `eai_agentplatform_app/frontend/src/views/system/AiUsage.vue`
## 当前状态
@@ -12,7 +12,7 @@
## 1. 项目定位
**eaisalestrain_app**(博昇内部培训平台)是一个纯内网本地化部署的内部专属员工培训系统,并以此为基础演进为知识库中心化的智能体平台。
**eai_agentplatform_app**(博昇内部培训平台)是一个纯内网本地化部署的内部专属员工培训系统,并以此为基础演进为知识库中心化的智能体平台。
**核心价值(V1 已交付):**
- 新人快速了解公司文化和业务
@@ -19,8 +19,8 @@
相关参考文档:
- [SY03_Knowledge_Centric_Agent_Platform_Strategy.md](file:///home/eaiadmin/eaifiles/codebase/pj0231-eaisalestraining/docs/01_System_Overall/SY03_Knowledge_Centric_Agent_Platform_Strategy.md)
- [09_Research/wechat/叶小钗](file:///home/eaiadmin/eaifiles/codebase/pj0231-eaisalestraining/docs/09_Research/wechat/%E5%8F%B6%E5%B0%8F%E9%92%97)(专家/专家团、任务系统、生产级 Agent 工程清单)
- [SY03_Knowledge_Centric_Agent_Platform_Strategy.md](file:///home/eaiadmin/eaifiles/codebase/pj0231-eai_agentplatforming/docs/01_System_Overall/SY03_Knowledge_Centric_Agent_Platform_Strategy.md)
- [09_Research/wechat/叶小钗](file:///home/eaiadmin/eaifiles/codebase/pj0231-eai_agentplatforming/docs/09_Research/wechat/%E5%8F%B6%E5%B0%8F%E9%92%97)(专家/专家团、任务系统、生产级 Agent 工程清单)
- [SY15_Terminology_Benchmark_Ontology_Semantic_Layer_Object_Layer.md](file:///home/eaiadmin/eaifiles/codebase/pj0235-eai_agentplatform/docs/01_System_Overall/SY15_Terminology_Benchmark_Ontology_Semantic_Layer_Object_Layer.md)
- [SY16_Ontology_Generalizes_Data_Actions_And_Workflows.md](file:///home/eaiadmin/eaifiles/codebase/pj0235-eai_agentplatform/docs/01_System_Overall/SY16_Ontology_Generalizes_Data_Actions_And_Workflows.md)
@@ -339,6 +339,6 @@ SY03 在业务方向上提出“知识底座 + 智能体矩阵 + 半定制工坊
- 本文档:SY04(平台升级分析、分层、UI、落地路线)
- 研究材料已入库:
- [09_Research/wechat/叶小钗](file:///home/eaiadmin/eaifiles/codebase/pj0231-eaisalestraining/docs/09_Research/wechat/%E5%8F%B6%E5%B0%8F%E9%92%97)
- [生产级Agent实践指南/PAG00](file:///home/eaiadmin/eaifiles/codebase/pj0231-eaisalestraining/docs/09_Research/wechat/%E5%8F%B6%E5%B0%8F%E9%92%97/%E7%94%9F%E4%BA%A7%E7%BA%A7Agent%E5%AE%9E%E8%B7%B5%E6%8C%87%E5%8D%97/PAG00_%E5%90%88%E9%9B%86%E6%80%BB%E8%A7%88_%E6%91%98%E8%A6%81%E4%B8%8E%E5%B7%A5%E7%A8%8B%E6%A3%80%E6%9F%A5%E5%8D%95_01-14.md)
- [PAG14](file:///home/eaiadmin/eaifiles/codebase/pj0231-eaisalestraining/docs/09_Research/wechat/%E5%8F%B6%E5%B0%8F%E9%92%97/%E7%94%9F%E4%BA%A7%E7%BA%A7Agent%E5%AE%9E%E8%B7%B5%E6%8C%87%E5%8D%97/PAG14_%E7%AC%AC14%E7%AF%87_%E5%A4%9AAagent%E7%BC%96%E6%8E%92%E4%B8%8E%E4%BB%BB%E5%8A%A1%E7%B3%BB%E7%BB%9F_%E4%BB%8E%E4%B8%80%E6%AC%A1%E5%A7%94%E6%B4%BE%E5%88%B0%E4%BB%BB%E5%8A%A1%E5%B7%A5%E4%BD%9C%E6%B5%81.md)
- [09_Research/wechat/叶小钗](file:///home/eaiadmin/eaifiles/codebase/pj0231-eai_agentplatforming/docs/09_Research/wechat/%E5%8F%B6%E5%B0%8F%E9%92%97)
- [生产级Agent实践指南/PAG00](file:///home/eaiadmin/eaifiles/codebase/pj0231-eai_agentplatforming/docs/09_Research/wechat/%E5%8F%B6%E5%B0%8F%E9%92%97/%E7%94%9F%E4%BA%A7%E7%BA%A7Agent%E5%AE%9E%E8%B7%B5%E6%8C%87%E5%8D%97/PAG00_%E5%90%88%E9%9B%86%E6%80%BB%E8%A7%88_%E6%91%98%E8%A6%81%E4%B8%8E%E5%B7%A5%E7%A8%8B%E6%A3%80%E6%9F%A5%E5%8D%95_01-14.md)
- [PAG14](file:///home/eaiadmin/eaifiles/codebase/pj0231-eai_agentplatforming/docs/09_Research/wechat/%E5%8F%B6%E5%B0%8F%E9%92%97/%E7%94%9F%E4%BA%A7%E7%BA%A7Agent%E5%AE%9E%E8%B7%B5%E6%8C%87%E5%8D%97/PAG14_%E7%AC%AC14%E7%AF%87_%E5%A4%9AAagent%E7%BC%96%E6%8E%92%E4%B8%8E%E4%BB%BB%E5%8A%A1%E7%B3%BB%E7%BB%9F_%E4%BB%8E%E4%B8%80%E6%AC%A1%E5%A7%94%E6%B4%BE%E5%88%B0%E4%BB%BB%E5%8A%A1%E5%B7%A5%E4%BD%9C%E6%B5%81.md)
+1 -1
View File
@@ -81,7 +81,7 @@ from fastapi import FastAPI
from app.api import auth, company_train, product, sales_train
from app.api import exam, media, ai_chat, system
app = FastAPI(title="eaisalestrain_app", version="1.1.0")
app = FastAPI(title="eai_agentplatform_app", version="1.1.0")
# 异常处理器
@app.exception_handler(AppError)
+4 -4
View File
@@ -80,7 +80,7 @@ location /api/ {
# 媒体文件预览(仅内部)
location /media/ {
alias /opt/eaisalestrain/backend/data/media/;
alias /opt/eai_agentplatform/backend/data/media/;
internal;
}
@@ -95,8 +95,8 @@ services:
mysql:
image: mysql:8.0
environment:
MYSQL_DATABASE: eaisalestrain
MYSQL_USER: eaisalestrain
MYSQL_DATABASE: eai_agentplatform
MYSQL_USER: eai_agentplatform
MYSQL_PASSWORD: ${DB_PASSWORD}
volumes:
- mysql_data:/var/lib/mysql
@@ -104,7 +104,7 @@ services:
backend:
build: ./backend
environment:
DATABASE_URL: mysql+pymysql://eaisalestrain:${DB_PASSWORD}@mysql:3306/eaisalestrain
DATABASE_URL: mysql+pymysql://eai_agentplatform:${DB_PASSWORD}@mysql:3306/eai_agentplatform
JWT_SECRET: ${JWT_SECRET}
LLM_BASE_URL: http://llm-server:11434/v1
volumes:
@@ -22,7 +22,7 @@
## 2. 完整目录结构(定稿)
```
eaisalestrain_app/
eai_agentplatform_app/
├── docs/
│ └── knowledge_source/ # 知识源文档(权威源,纳入 git 版本管理)
│ ├── README.md # 格式契约 + 答案契约 + 审批状态机
@@ -1,7 +1,7 @@
# 工作流画布交互设计调研报告
> **版本:V2.0 | 最后更新:2026-08-17**
> **目标产品:eaisalestrain-app · 数字员工平台 · 工坊(Studio)**
> **目标产品:eai_agentplatform-app · 数字员工平台 · 工坊(Studio)**
---
+4 -4
View File
@@ -11,10 +11,10 @@
## 已整理
- [RE01_AgentScope_WorkBuddy_专家与专家团机制_2026-08-12.md](file:///home/eaiadmin/eaifiles/codebase/pj0231-eaisalestraining/docs/09_Research/wechat/%E5%8F%B6%E5%B0%8F%E9%92%97/RE01_AgentScope_WorkBuddy_%E4%B8%93%E5%AE%B6%E4%B8%8E%E4%B8%93%E5%AE%B6%E5%9B%A2%E6%9C%BA%E5%88%B6_2026-08-12.md)
- [RE02_mini-openclaw_多Agent编排与任务系统_delegate_task_2026-08-15.md](file:///home/eaiadmin/eaifiles/codebase/pj0231-eaisalestraining/docs/09_Research/wechat/%E5%8F%B6%E5%B0%8F%E9%92%97/RE02_mini-openclaw_%E5%A4%9AAagent%E7%BC%96%E6%8E%92%E4%B8%8E%E4%BB%BB%E5%8A%A1%E7%B3%BB%E7%BB%9F_delegate_task_2026-08-15.md)
- [RE03_WorkBuddy培训复盘_业务团队崛起产研紧张_日期未提供.md](file:///home/eaiadmin/eaifiles/codebase/pj0231-eaisalestraining/docs/09_Research/wechat/%E5%8F%B6%E5%B0%8F%E9%92%97/RE03_WorkBuddy%E5%9F%B9%E8%AE%AD%E5%A4%8D%E7%9B%98_%E4%B8%9A%E5%8A%A1%E5%9B%A2%E9%98%9F%E5%B4%9B%E8%B5%B7%E4%BA%A7%E7%A0%94%E7%B4%A7%E5%BC%A0_%E6%97%A5%E6%9C%9F%E6%9C%AA%E6%8F%90%E4%BE%9B.md)
- [RE01_AgentScope_WorkBuddy_专家与专家团机制_2026-08-12.md](file:///home/eaiadmin/eaifiles/codebase/pj0231-eai_agentplatforming/docs/09_Research/wechat/%E5%8F%B6%E5%B0%8F%E9%92%97/RE01_AgentScope_WorkBuddy_%E4%B8%93%E5%AE%B6%E4%B8%8E%E4%B8%93%E5%AE%B6%E5%9B%A2%E6%9C%BA%E5%88%B6_2026-08-12.md)
- [RE02_mini-openclaw_多Agent编排与任务系统_delegate_task_2026-08-15.md](file:///home/eaiadmin/eaifiles/codebase/pj0231-eai_agentplatforming/docs/09_Research/wechat/%E5%8F%B6%E5%B0%8F%E9%92%97/RE02_mini-openclaw_%E5%A4%9AAagent%E7%BC%96%E6%8E%92%E4%B8%8E%E4%BB%BB%E5%8A%A1%E7%B3%BB%E7%BB%9F_delegate_task_2026-08-15.md)
- [RE03_WorkBuddy培训复盘_业务团队崛起产研紧张_日期未提供.md](file:///home/eaiadmin/eaifiles/codebase/pj0231-eai_agentplatforming/docs/09_Research/wechat/%E5%8F%B6%E5%B0%8F%E9%92%97/RE03_WorkBuddy%E5%9F%B9%E8%AE%AD%E5%A4%8D%E7%9B%98_%E4%B8%9A%E5%8A%A1%E5%9B%A2%E9%98%9F%E5%B4%9B%E8%B5%B7%E4%BA%A7%E7%A0%94%E7%B4%A7%E5%BC%A0_%E6%97%A5%E6%9C%9F%E6%9C%AA%E6%8F%90%E4%BE%9B.md)
## 合集
- 生产级 Agent 实践指南:[README.md](file:///home/eaiadmin/eaifiles/codebase/pj0231-eaisalestraining/docs/09_Research/wechat/%E5%8F%B6%E5%B0%8F%E9%92%97/%E7%94%9F%E4%BA%A7%E7%BA%A7Agent%E5%AE%9E%E8%B7%B5%E6%8C%87%E5%8D%97/README.md)
- 生产级 Agent 实践指南:[README.md](file:///home/eaiadmin/eaifiles/codebase/pj0231-eai_agentplatforming/docs/09_Research/wechat/%E5%8F%B6%E5%B0%8F%E9%92%97/%E7%94%9F%E4%BA%A7%E7%BA%A7Agent%E5%AE%9E%E8%B7%B5%E6%8C%87%E5%8D%97/README.md)
@@ -15,7 +15,7 @@
## 清单
- [PAG00_合集总览_摘要与工程检查单_01-14.md](file:///home/eaiadmin/eaifiles/codebase/pj0231-eaisalestraining/docs/09_Research/wechat/%E5%8F%B6%E5%B0%8F%E9%92%97/%E7%94%9F%E4%BA%A7%E7%BA%A7Agent%E5%AE%9E%E8%B7%B5%E6%8C%87%E5%8D%97/PAG00_%E5%90%88%E9%9B%86%E6%80%BB%E8%A7%88_%E6%91%98%E8%A6%81%E4%B8%8E%E5%B7%A5%E7%A8%8B%E6%A3%80%E6%9F%A5%E5%8D%95_01-14.md)
- [PAG00_合集总览_摘要与工程检查单_01-14.md](file:///home/eaiadmin/eaifiles/codebase/pj0231-eai_agentplatforming/docs/09_Research/wechat/%E5%8F%B6%E5%B0%8F%E9%92%97/%E7%94%9F%E4%BA%A7%E7%BA%A7Agent%E5%AE%9E%E8%B7%B5%E6%8C%87%E5%8D%97/PAG00_%E5%90%88%E9%9B%86%E6%80%BB%E8%A7%88_%E6%91%98%E8%A6%81%E4%B8%8E%E5%B7%A5%E7%A8%8B%E6%A3%80%E6%9F%A5%E5%8D%95_01-14.md)
- PAG01_第01篇_Agent的定义与环境搭建_2026-05-31.md
- PAG02_第02篇_一次LLM_API调用_2026-06-02.md
- PAG03_第03篇_FunctionCalling原理_2026-06-06.md
@@ -29,4 +29,4 @@
- PAG11_第11篇_上下文压缩_长会话持续工作.md
- PAG12_第12篇_Agent记忆_长期记忆与短期记忆.md
- PAG13_第13篇_多Agent_协作原理与任务委派实现.md
- [PAG14_第14篇_多Agent编排与任务系统_从一次委派到任务工作流.md](file:///home/eaiadmin/eaifiles/codebase/pj0231-eaisalestraining/docs/09_Research/wechat/%E5%8F%B6%E5%B0%8F%E9%92%97/%E7%94%9F%E4%BA%A7%E7%BA%A7Agent%E5%AE%9E%E8%B7%B5%E6%8C%87%E5%8D%97/PAG14_%E7%AC%AC14%E7%AF%87_%E5%A4%9AAagent%E7%BC%96%E6%8E%92%E4%B8%8E%E4%BB%BB%E5%8A%A1%E7%B3%BB%E7%BB%9F_%E4%BB%8E%E4%B8%80%E6%AC%A1%E5%A7%94%E6%B4%BE%E5%88%B0%E4%BB%BB%E5%8A%A1%E5%B7%A5%E4%BD%9C%E6%B5%81.md)
- [PAG14_第14篇_多Agent编排与任务系统_从一次委派到任务工作流.md](file:///home/eaiadmin/eaifiles/codebase/pj0231-eai_agentplatforming/docs/09_Research/wechat/%E5%8F%B6%E5%B0%8F%E9%92%97/%E7%94%9F%E4%BA%A7%E7%BA%A7Agent%E5%AE%9E%E8%B7%B5%E6%8C%87%E5%8D%97/PAG14_%E7%AC%AC14%E7%AF%87_%E5%A4%9AAagent%E7%BC%96%E6%8E%92%E4%B8%8E%E4%BB%BB%E5%8A%A1%E7%B3%BB%E7%BB%9F_%E4%BB%8E%E4%B8%80%E6%AC%A1%E5%A7%94%E6%B4%BE%E5%88%B0%E4%BB%BB%E5%8A%A1%E5%B7%A5%E4%BD%9C%E6%B5%81.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# eaisalestrain_app 博昇内部培训平台 — 产品需求文档
# eai_agentplatform_app 博昇内部培训平台 — 产品需求文档
> **版本:V1.1 最终版(V1 培训底座基线)| 纯本地化部署 | 极简架构 | 全功能闭环**
> **最后更新:2026-08-15**
+2 -2
View File
@@ -1,4 +1,4 @@
# eaisalestrain_app — API 文档
# eai_agentplatform_app — API 文档
> **版本:V1.1 | 协议:HTTP/JSON | 认证:JWT Bearer**
> **最后更新:2026-08-15**
@@ -570,7 +570,7 @@ data: {"type": "done"}
```json
{
"status": "ok",
"service": "eaisalestrain-app",
"service": "eai_agentplatform-app",
"version": "1.1.0"
}
```
+4 -4
View File
@@ -1,4 +1,4 @@
# eaisalestrain_app — 变更日志
# eai_agentplatform_app — 变更日志
> **最后更新:2026-08-16**
@@ -122,9 +122,9 @@
**目录重构 + 全功能联调测试 + 修复 1 个缺陷。**
### 变更
- `docs/`(设计文档)从 `eaisalestrain_app/` 移出到仓库根 `pj0231-eaisalestraining/docs/`,与 `CODING_RULES.md` 平级
- `docs/`(设计文档)从 `eai_agentplatform_app/` 移出到仓库根 `pj0231-eai_agentplatforming/docs/`,与 `CODING_RULES.md` 平级
- `knowledge_source/`(知识源运行时数据)从 `docs/` 移入 `backend-go/knowledge_source/`,归后端
- 后端 `KNOWLEDGE_SOURCE_DIR` 默认值 `../docs/knowledge_source` → `knowledge_source`;部署路径 `/opt/eaisalestrain/knowledge_source`
- 后端 `KNOWLEDGE_SOURCE_DIR` 默认值 `../docs/knowledge_source` → `knowledge_source`;部署路径 `/opt/eai_agentplatform/knowledge_source`
- 前后端全功能联调测试通过(认证/权限边界/产品/课程/考试/素材审批/知识入库/AI)
- 素材存储目录 `data/media` → `data/kb_data`,子目录三态化:`approved/`(已审批公开)、
`pending/`(待审批)、`rejected/`(已驳回);环境变量 `MEDIA_DIR` → `KB_DATA_DIR`。
@@ -145,7 +145,7 @@
- 旧 Python 后端目录 `backend/` 已整体删除,Go 后端为唯一后端
- 认证:JWT(golang-jwt)+ bcrypt;文档转换:LibreOffice + pdftotext(裸进程)
- 部署:裸进程 + systemd + Clonezilla 整盘克隆,Go 单二进制交付(无 Docker、无源码交付)
- 文件存储路径:`backend/data/media` → `data/media`(Go 后端工作目录下,部署为 `/opt/eaisalestrain/data/media`)
- 文件存储路径:`backend/data/media` → `data/media`(Go 后端工作目录下,部署为 `/opt/eai_agentplatform/data/media`)
### 说明
- `docs/` 下历史设计文档(SY/AR/BE/设计稿)中残留的 `backend/`、`backend/data/media`、
+1 -1
View File
@@ -1,4 +1,4 @@
# eaisalestrain_app — 数据库 Schema
# eai_agentplatform_app — 数据库 Schema
> **版本:V1.2 | 引擎:MySQL 8.0(关系数据)+ FAISS(向量检索)| ORM:GORM**
> **最后更新:2026-08-16**
+23 -23
View File
@@ -1,4 +1,4 @@
# eaisalestrain_app — 部署文档
# eai_agentplatform_app — 部署文档
> **版本:V1.2 | 部署模式:纯本地离线 · Go 单二进制 · MySQL 8.0 + FAISS · systemd · Clonezilla 整盘克隆**
> **最后更新:2026-08-16**
@@ -25,7 +25,7 @@
│ │
┌─────▼──────────────┐ ┌──────▼───────┐
│ Go 单二进制 │ │ Vue 静态打包 │
│ eaisalestrain- │ │ /usr/share/ │
│ eai_agentplatform- │ │ /usr/share/ │
│ server :8080 │ │ nginx/html │
│ (Gin + GORM) │ └──────────────┘
└──┬─────┬─────┬─────┘
@@ -55,7 +55,7 @@
| 服务 | 端口 | 说明 |
|------|------|------|
| Nginx | 80/443 | HTTP 反代 + 前端静态资源托管 |
| eaisalestrain-server | 8080 | Go 单二进制后端(Gin + GORM) |
| eai_agentplatform-server | 8080 | Go 单二进制后端(Gin + GORM) |
| MySQL | 3306 | MySQL 8.0 关系数据(systemd 托管 mysqld) |
| FAISS | 内嵌 | 向量索引,由 Go 后端 cgo 内嵌,索引文件 `data/faiss/` |
| LibreOffice + pdftotext | 进程内调用 | 裸进程,非容器,文档转文本 |
@@ -68,8 +68,8 @@
## 目录布局
```
/opt/eaisalestrain/
├── eaisalestrain-server # 单二进制(CGO 关闭,静态链接,约 38MB)
/opt/eai_agentplatform/
├── eai_agentplatform-server # 单二进制(CGO 关闭,静态链接,约 38MB)
├── .env # JWT 密钥、LLM 配置等
├── data/
│ ├── faiss/ # FAISS 向量索引(embedding 向量)
@@ -93,9 +93,9 @@ apt update && apt install -y nginx mysql-server libreoffice poppler-utils
> MySQL 初始化库与账号(FAISS 向量索引内嵌于后端,无需独立服务):
>
> ```sql
> CREATE DATABASE eaisalestrain DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_unicode_ci;
> CREATE USER 'eaisalestrain'@'127.0.0.1' IDENTIFIED BY '<随机密码>';
> GRANT ALL PRIVILEGES ON eaisalestrain.* TO 'eaisalestrain'@'127.0.0.1';
> CREATE DATABASE eai_agentplatform DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_unicode_ci;
> CREATE USER 'eai_agentplatform'@'127.0.0.1' IDENTIFIED BY '<随机密码>';
> GRANT ALL PRIVILEGES ON eai_agentplatform.* TO 'eai_agentplatform'@'127.0.0.1';
> FLUSH PRIVILEGES;
> ```
@@ -103,37 +103,37 @@ apt update && apt install -y nginx mysql-server libreoffice poppler-utils
```bash
# 2.1 拷贝二进制 + 建服务账号
sudo install -m 0755 eaisalestrain-server /opt/eaisalestrain/eaisalestrain-server
sudo useradd -r -s /usr/sbin/nologin eaisalestrain
sudo mkdir -p /opt/eaisalestrain/data/kb_data /opt/eaisalestrain/docs/knowledge_source
sudo chown -R eaisalestrain:eaisalestrain /opt/eaisalestrain
sudo install -m 0755 eai_agentplatform-server /opt/eai_agentplatform/eai_agentplatform-server
sudo useradd -r -s /usr/sbin/nologin eai_agentplatform
sudo mkdir -p /opt/eai_agentplatform/data/kb_data /opt/eai_agentplatform/docs/knowledge_source
sudo chown -R eai_agentplatform:eai_agentplatform /opt/eai_agentplatform
# 2.2 生成 .env(JWT 密钥随机)
sudo -u eaisalestrain cp deploy/eaisalestrain.env /opt/eaisalestrain/.env
sudo -u eai_agentplatform cp deploy/eai_agentplatform.env /opt/eai_agentplatform/.env
NEW_SECRET=$(python3 -c "import secrets; print(secrets.token_urlsafe(48))")
sudo sed -i "s|^JWT_SECRET=.*|JWT_SECRET=$NEW_SECRET|" /opt/eaisalestrain/.env
sudo sed -i "s|^JWT_SECRET=.*|JWT_SECRET=$NEW_SECRET|" /opt/eai_agentplatform/.env
# 2.3 安装 systemd 单元并启动
sudo install -m 0644 deploy/eaisalestrain.service /etc/systemd/system/eaisalestrain.service
sudo install -m 0644 deploy/eai_agentplatform.service /etc/systemd/system/eai_agentplatform.service
sudo systemctl daemon-reload
sudo systemctl enable --now eaisalestrain
sudo systemctl enable --now eai_agentplatform
# 2.4 验证
curl http://127.0.0.1:8080/api/health # {"status":"ok","service":"eaisalestrain-app",...}
curl http://127.0.0.1:8080/api/health # {"status":"ok","service":"eai_agentplatform-app",...}
```
`.env` 关键项:
```bash
PORT=8080
DB_DSN=eaisalestrain:<随机密码>@tcp(127.0.0.1:3306)/eaisalestrain?charset=utf8mb4&parseTime=True&loc=Local
DB_DSN=eai_agentplatform:<随机密码>@tcp(127.0.0.1:3306)/eai_agentplatform?charset=utf8mb4&parseTime=True&loc=Local
JWT_SECRET=<48 字符随机串,交付前生成>
LLM_BASE_URL=http://127.0.0.1:11434/v1
LLM_MODEL=qwen2.5:7b
EMBED_MODEL=bge-m3
FAISS_INDEX_DIR=data/faiss
KB_DATA_DIR=data/kb_data
KNOWLEDGE_SOURCE_DIR=/opt/eaisalestrain/docs/knowledge_source
KNOWLEDGE_SOURCE_DIR=/opt/eai_agentplatform/docs/knowledge_source
LIBREOFFICE_BIN=/usr/bin/libreoffice
PDFTOTEXT_BIN=/usr/bin/pdftotext
```
@@ -205,10 +205,10 @@ python -m vllm.entrypoints.openai.api_server \
## 启动/停止
```bash
sudo systemctl restart eaisalestrain # 重启
sudo systemctl stop eaisalestrain # 停止
sudo systemctl status eaisalestrain # 状态 / 日志
journalctl -u eaisalestrain -f # 实时日志
sudo systemctl restart eai_agentplatform # 重启
sudo systemctl stop eai_agentplatform # 停止
sudo systemctl status eai_agentplatform # 状态 / 日志
journalctl -u eai_agentplatform -f # 实时日志
```
---
+2 -2
View File
@@ -1,4 +1,4 @@
eaisalestrain_app 博昇内部培训平台
eai_agentplatform_app 博昇内部培训平台
最终完整定稿 PRD(可直接交付 AI 生成前后端代码)
版本:V1.1 最终版 | 纯本地化部署 | 极简架构 | 全功能闭环
@@ -71,7 +71,7 @@ V1.0 → V1.1(修复内部不自洽):
2. 项目目录结构(最终强制规范)
plaintext
eaisalestrain_app/ # 项目根目录(所有代码集中此处)
eai_agentplatform_app/ # 项目根目录(所有代码集中此处)
├── docs/ # 独立文档目录(只放文档,不放代码)
│ ├── PRD.md
│ ├── db_schema.md
@@ -1,4 +1,4 @@
# pj0231-eaisalestraining 完整分析报告(对比 + 差距 + 路线图 + 设计稿)
# pj0231-eai_agentplatforming 完整分析报告(对比 + 差距 + 路线图 + 设计稿)
> 版本:V1.0 | 日期:2026-08-16
> 对比对象:pj006-zhilianyuan2(智练猿)
@@ -47,7 +47,7 @@
## A3. 重要前提:pj0231 文档已过时
- `docs/PRD.md` 写「FastAPI + MySQL + 不做向量检索」;实际代码是 **Go + Gin + GORM + SQLite**,检索已实现**向量(brute-force 余弦 + bge-m3)**。
- 本项目权威信息以 `eaisalestrain_app/CLAUDE.md` 与**实际代码**为准。
- 本项目权威信息以 `eai_agentplatform_app/CLAUDE.md` 与**实际代码**为准。
---
@@ -1,4 +1,4 @@
# pj0231-eaisalestraining vs pj006-zhilianyuan2 能力对比分析
# pj0231-eai_agentplatforming vs pj006-zhilianyuan2 能力对比分析
> 生成日期:2026-08-16
> 范围:知识库能力、考试能力、测试/自测能力、岗位与知识对应能力
@@ -132,10 +132,10 @@
## 7. 关键文件索引(证据)
**pj0231**(本项,实际代码为准):
- 数据模型:`eaisalestrain_app/backend-go/internal/model/`(11 张表)
- 检索:`eaisalestrain_app/backend-go/internal/ai/retrieve.go`(混合检索)
- 考试:`eaisalestrain_app/backend-go/internal/api/exam.go`(组卷 / 判分 / 存档)
- AI 聊天:`eaisalestrain_app/backend-go/internal/api/ai_chat.go`(PathCoach + 3 快捷动作)
- 数据模型:`eai_agentplatform_app/backend-go/internal/model/`(11 张表)
- 检索:`eai_agentplatform_app/backend-go/internal/ai/retrieve.go`(混合检索)
- 考试:`eai_agentplatform_app/backend-go/internal/api/exam.go`(组卷 / 判分 / 存档)
- AI 聊天:`eai_agentplatform_app/backend-go/internal/api/ai_chat.go`(PathCoach + 3 快捷动作)
**pj006**(对比项):
- 数据模型:`zlyapp/backend/app/db/schema.py`(v23,40+ 表,含 `orgs` 多租户根)
@@ -0,0 +1,771 @@
# 一个超级智能体,顶一个办公团队——数据永远不出门
> 来源:微信公众号「微趣私有AI」
> 作者:上海微趣网络科技有限公司(原创)
> 发布日期:2026年6月11日 13:09 · 上海
> 修改于:2026年6月11日
---
**政企私有化AI · 标准化产品 · 开箱即用**
## 让您的单位拥有自己的 AI 大脑
订阅 AI 软件服务,算力硬件由我们提供并部署到您单位。
开箱即用,数据永远不出门。
- **01 算力机硬件**
- **02 AI 大模型**
- **03 AI 系统平台**
- **04 智能体应用**
上海微趣网络科技有限公司 · 2011年成立 · 深耕政企服务十余年
---
## 您是不是也遇到了这四个问题?
很多单位想用 AI,但一动手就卡住了。不是不想用,是确实有顾虑。
### 🚫 不敢用
用公网 AI,合同、人事数据要上传到别人的服务器。数据一旦外泄,后果不是效率问题,而是**合规风险**。
> ✅ 我们的 AI 装在您自己的机房里,数据从始至终不出门。
### 💰 用不起
自己建 AI 团队,算力设备几十万、工程师年薪几十万、开发周期半年起。算下来百万起步,预算批不下来。
> ✅ 我们提供年度订阅服务,费用远低于自建成本,算力硬件由我们提供部署,您无需单独采购。
### 😰 用不好
员工不会用 AI,免费大模型只支持十几种格式,不支持 WPS,处理不了合同 PDF 和会议录音。跟实际工作脱节。
> ✅ 内置几十种办公场景智能体,100+ 种格式通吃,说句话就能用。
### 🏃 跟不上
AI 技术迭代飞快,竞争对手和兄弟单位已经开始用 AI 提效。再不上车,不是赶不上的问题,而是被甩开的问题。
> ✅ 订阅即用,快速上线。同行已经验证的成熟方案,您可以直接复用。
---
## 十余年深耕,最懂政企的 AI 团队
不是互联网公司转型做政企,而是从第一天起就在为您服务。
- **2011** 年成立,持续服务至今
- **10+** 年政企服务经验
- **唯一** WAIC2024 私有化实机参展
### 🏆 国家王选新闻科技技术奖
以中国计算机汉字激光照排创始人命名的国家级科技大奖。也就是说,我们的技术经过了**国家最高级别的认可**。
### 📋 国家行业标准制定者
我们参与了国家行业标准 **SJ/T 11615.2-2016** 的制定。也就是说,**行业的规则是我们参与写的**。
### 🔒 权威安全认证全覆盖
华为鲲鹏技术认证、海光适配认证。也就是说,**国产芯片、信创环境完美兼容**,您不用操心适配问题。
### 🌟 WAIC2024 唯一实机参展
世界人工智能大会上,唯一以私有化部署实机参展的企业。也就是说,**我们的产品经得起公开检验**。
---
### 他们已经在用微趣 AI+
- 国家级安全机关
- 公安部直属研究所
- 直辖市网信主管部门
- 大型航空制造央企
- 全国性证券机构
- 大型建工集团
- 直辖市委组织部门
- 省级公安机关
- 部队及军工单位
- 省级产业研究院
---
## 数据不出门,合规无忧
AI 算力机就放在您自己的机房里,所有运算都在本地完成。
- **100%** 数据本地存储
- **0** 数据上传公网
- **∞** 安心使用无顾虑
- **10+** 年安全运行记录
> "您的数据就像放在自家保险柜里,钥匙只有您自己有。AI 在您家里工作,从不'出门上网'。"
---
## 一套标准产品,四层 AI 能力
就像订阅一个全能 AI 员工——平台、能力、工具全配齐,算力硬件我们带过来部署好,开通即用。
### 01 算力机硬件 — AI 的"发动机" ⚡
由我们提供的专用 AI 算力硬件,内置 GPU 算力。支持华为鲲鹏、海光等国产芯片。部署到您机房,**插上电源和网络就能用**,您无需单独采购。
### 02 AI 大模型 — AI 的"大脑" 🧠
预装基座大模型+垂直小模型,上下文 12 万字,能读懂文本、能看图、能听音频视频。**模型已调好,开机即用**。
### 03 AI 系统平台 — AI 的"操作系统" 🖥️
智能助手、知识库、文档处理、工作流引擎、用户管理……**全员可用的 AI 工作平台**,有界面、有权限、有协作。
### 04 智能体应用 — AI 的"即战力" 🚀
公文写作、合同审查、会议分析、简历筛选、发票对账、PPT 制作、报告生成……**20+ 种场景开箱即用**,持续更新。
---
## 标准化产品,开箱即用
这不是定制开发,不是 AI 咨询,而是一台装好一切的标准产品。
### 📦 订阅即用,快速上线
订阅服务后,我们将算力硬件部署到您机房,接上电源和网络即可使用。**不需要等开发、不需要排期。**
### 🔄 像手机系统一样升级
我们持续迭代产品,新版本免费推送。**不需要您自己维护**,就像手机收到系统更新。
### ✅ 数十家政企客户验证
从国家级安全机关到大型央企,**最高安全等级的客户都在用**,稳定可靠。
### 🖥️ 算力硬件,我们提供
您不需要单独采购 GPU 服务器,**算力硬件由我们提供并部署到您机房**,省去大额硬件投入。
> "您不需要花半年找团队定制开发,也不需要把数据交给公网。订阅我们的 AI 服务,我们将算力硬件部署到您单位,快速上线。"
---
## 年度订阅,降低预算门槛
不用买算力、不用招 AI 工程师、不用外包开发。订阅服务,全部到位。
### ❌ 自建 AI 团队
- 算力设备 **30 万+**
- AI 工程师年薪 **40 万+/人**
- 开发周期 **3–6 个月**
- 运维费用 **持续投入**
### ✅ 微趣 AI+ 订阅服务
- 算力硬件 **我们提供**
- 大模型 **已预装**
- AI 平台 **已部署**
- 智能体应用 **开箱即用**
> "不是让您花百万自建 AI 团队、自己采购算力硬件,而是通过年度订阅服务费,直接拥有一个 AI 全能员工——算力硬件我们提供,数据安全有保障。"
---
## 100+ 种格式,职场文件通吃
- **100+** 种文件格式
- **不限** 文件数量
- **不限** 文件大小
### 📄 文档类
Word · PDF · Excel · PPT · WPS · TXT · Markdown
### 🖼️ 图片类
扫描件 · 长图 · 手写 · 证件照 · 产品截图
### 🎵 音视频类
会议录音 · 培训视频 · MP3 · MP4 · WAV
### 📦 压缩包及其他
ZIP · RAR · 7Z · 邮件 · 网页 · 数据库
> "不管您的材料是什么格式——PDF 合同、扫描件、录音、视频、压缩包——拖进来就能用。"
---
## 一个指令,智能体自动搞定
您只需要说一句话,智能体会自己拆解任务、调用工具、验证结果、交付文件。
### 📊 78 份文件 → 3 分钟出表
把 78 份处罚决定书丢给智能体,**3 分钟自动提取**处罚时间、被处罚者、金额,汇总成 Excel。
### 🔍 文件比对 → 自动找差异
上传新旧两份合同,**自动标注修改、删除、新增内容**,并排高亮差异,便于法务快速审核确认。
### 🎤 一段录音 → 5 分钟出 PPT
上传一段会议录音,智能体自动转文字、提炼要点、**生成 6 页 PPT**,下载就能用。
### 📋 日报汇总 → 一键周报
把一周的日报丢给智能体,**自动归纳重点工作、进展与下周计划**,生成结构化周报,直接提交。
> "您只需要说一句话,剩下的它自己拆解、自己执行、自己验证、自己交付——这就是智能体的力量。"
---
## AI 超级会议室
不只是记录会议,而是让每一次对话变成可搜索、可追溯、可复用的知识资产。
### 🌐 多语言同声传译
中/英/日/韩四语互译,**2–3 秒出结果**。跨国会议不再需要翻译人员。
### 📝 AI 自动总结 + 待办
会议进行中,AI 实时提炼要点、提取待办事项、**指定负责人和截止日期**。
### ⚠️ 合规风险实时预警
自动识别过度承诺、敏感信息,**高/中/低分级预警**,防患于未然。
### 💾 一键导出知识沉淀
会议内容结构化存储,可检索可追溯。一键导出 Word/TXT,**单语/双语并排**。
> "以前的会议,开完就散了。现在的会议,开完就变成可搜索、可追溯、可复用的知识资产。"
---
## 无缝嵌入,零学习成本
### 📝 Office/WPS 内嵌
在 Word、Excel、WPS 里直接调出 AI 侧边栏,**不用换工具**,就像用输入法一样自然。
### 💬 说话就能用
自然语言交互,**会用微信就会用**。不需要学编程,不需要写提示词。
### 🔌 API 对接现有系统
提供 OpenAI 兼容接口,**改一行配置**就能接入您现有的 OA/ERP 系统。
### 👤 界面简洁,上手即会
每个智能体应用入口清晰明了,**打开就知道该点哪里**。没有复杂菜单和多余按钮,领导员工都能轻松上手。
---
## 看看它都能做什么
每个场景都是经过实测试验证的真实能力,不是概念演示。
### 01 简历批量筛选 `HR/人事`
收到几百份简历,HR 再也不用一份份打开。把简历批量导入知识库,一句话说出筛选条件,3 分钟筛选出符合条件的候选人名单。支持按毕业院校、工作年限、特定经历等多条件组合筛选。
⚡ 效率提升 **20 倍**
### 02 合同批量审查与提取 `法务/采购`
几十份合同,自动提取甲方、乙方、金额、付款方式等关键字段,一键汇总成 Excel 总表。还能按条件筛选"百万以上合同"或"涉及公路运输的合同",并自动归纳违约金条款。
⚡ 1 天工作量 → **10 分钟**
### 03 发票批量识别与对账 `财务`
打包一个 ZIP 里 8 张发票 PDF,直接上传,自动逐张识别、汇总金额、分类统计。金额精确到分。还能跨库对账:同时勾选"发票库"和"合同库",自动找出哪些合同没开发票、哪些发票没对应合同。
⚡ 半天工作量 → **5 分钟**
### 04 会议纪要自动生成 `办公室/行政`
上传一小时会议录音,自动转写文字、识别发言人、提炼决策要点、提取待办事项,**连思维导图都自动画好**。支持点击文字回听原声,确保关键决策有据可查。
⚡ 2 小时整理 → **5 分钟**
### 05 公文起草与校对 `机关/国企办公室`
选择公文类型(通知/报告/函件/工作总结等)、填写要点,AI 自动生成符合规范的完整初稿,支持水印、页眉页脚、公章等正式要素。还能自动校对错别字、语序、甚至领导排序,避免原则性错误。
⚡ 半天写稿 → **15 分钟**
### 06 一键生成 PPT 汇报 `各部门通用`
上传一份材料或一段录音,说"做 8 页 PPT",自动生成演示文稿。每页标题清晰、要点不重复,下载就能直接汇报。支持指定语言(中文/英文/日文等)。
⚡ 2 小时制作 → **5 分钟**
### 07 知识库搭建与问答 `各业务部门`
把制度文件、历史合同、项目资料上传到知识库,AI 自动学习。之后直接提问,秒级回答,**附带原文引用,有据可查**。回答仅基于您上传的文件,不会凭空编造。支持跨部门共享,知识持续增值。
⚡ 翻资料 1 小时 → **即问即答**
### 08 跨语言会议实时翻译 `外事/国际合作`
开会时 AI 实时转录翻译,2–3 秒出结果,支持中英日韩四语。AI 还会智能润色口语化表达,提升文本可读性。会后自动生成双语纪要,一键导出 Word,单语/双语并排。
⚡ 不再需要翻译人员随行
### 09 文档翻译保留排版 `国际业务`
英文合同、日文报告,整份翻译成中文,**排版、表格、图片位置完全保留**。双语对照模式,左右同步滚动,遇到专业术语随时核对原文。支持 Word/PDF/PPT/Excel 全格式。
⚡ 翻译+排版 1 天 → **10 分钟**
### 10 工作流自动化 `重复性办公任务`
把重复性工作定义成"工作流":7 份日报自动汇总成周报、发票按类型分类统计、合同印章识别+校验一致性……**定义一次,永远自动运行**。每步中间结果可见,失败自动重试。
⚡ 重复劳动 → **一键执行**
### 11 长文档/年报快速摘要 `领导/管理层`
50 页年报、合同、研报,没时间读全文。5 分钟拿到结构化摘要:业绩亮点、主要风险、战略方向,分块整齐。百页 PDF 也能 1 分钟内开始提问。
⚡ 2 小时通读 → **5 分钟掌握要点**
### 12 文档版本对比 `合同管理/法务`
新旧两版合同、方案、政策文件,自动高亮标注被修改、删除或新增的内容,并排对照视图。支持跨格式对比(Word vs PDF),不用手动转换格式。
⚡ 逐字校对 2 小时 → **3 分钟**
### 13 视频课程/培训材料转文字 `培训/教育`
培训视频、讲座录像,自动提取文字内容。英文原声也能高精度捕捉。转出的文字可以进一步翻译、总结、做成学习材料。把"看视频"变成"读文档"。
⚡ 听写 2 小时 → **5 分钟出稿**
### 14 Excel 数据分析与可视化 `各部门通用`
不会写公式、不会 Pandas?把 Excel 拖进去,用自然语言说"统计每个区域的成交金额"或"画一张收入趋势折线图",**智能体在沙箱里写 Python 精确计算**,返回表格+图表。
⚡ 写公式 1 小时 → **一句话出结果**
### 15 图片/证件识别提取 `行政/人事/财务`
营业执照、身份证、发票、表单截图、手写考勤表——拖进来直接提问。AI 自动识别文字字段,物体计数、文字提取、字段结构化一次到位。
⚡ 手工录入 → **一键识别**
### 16 法律条文智能问答 `法务/合规`
将法律法规、行业规章上传到知识库,遇到合规问题直接提问,AI 精准定位相关法条、给出依据和解读,还可结合本单位合同自动识别潜在法律风险。
⚡ 翻法条 2 小时 → **秒级精准答复**
---
## 三种 AI 路线,您选哪个?
很多单位想上 AI,但不知道该走哪条路。帮您算清楚这笔账。
| 对比维度 | 自建 AI 团队 | 公网大模型 | **微趣 AI+** ✅ |
|---|---|---|---|
| 数据安全 | ✅ 安全 | ❌ 上传公网 | ✅ 私有化部署 |
| 落地周期 | ❌ 3–6 个月 | ✅ 即开即用 | ✅ 当天可用 |
| 总体成本 | ❌ 百万起步 | ✅ 免费/低价 | ✅ 年度订阅 |
| 文件格式 | — 需开发 | ❌ 10 多种,限 50 文件 | ✅ 100+ 种,不限量 |
| 办公场景 | — 需开发 | ❌ 不贴业务 | ✅ 20+ 场景预装 |
| 团队协作 | — 需开发 | ❌ 不支持 | ✅ 共享+权限 |
| 成果交付 | — 需开发 | ❌ 仅文本 | ✅ Excel/PDF/PPT |
| 信创兼容 | — 需适配 | ❌ 不支持 | ✅ 鲲鹏/海光 |
| 运维服务 | ❌ 自建团队 | ❌ 无 | ✅ 专业技术支撑 |
> 自建太贵太慢,公网不安全不好用,标准化产品刚好。
---
## 客户常问的问题
### "免费的 DeepSeek 不就够用了吗?"
确实,免费大模型越来越强。但您把单位的合同、人事数据、会议录音上传到公网,合规审查能过吗?我们的模型能力不比公网的弱,但**数据安全、100+ 种文件格式、20+ 办公场景**全部到位——这是免费产品给不了的。
### "我们 IT 部门说可以自己搭一套。"
贵单位 IT 团队能力一定很强。但自己搭需要解决模型选型、部署调优、应用开发、持续运维等一系列问题,周期至少 3–6 个月。我们做的是标准化产品,省去的就是这个"自己搭"的过程——**到货当天就能用**。
### "我们的数据比较敏感,真的安全吗?"
正因为敏感,所以更要私有化部署。我们的产品经过**国家级安全机关、公安等部门最高安全等级客户**的验证,数据从始至终在您自己的机器上,AI 运算全部在本地完成,不上传任何一个字节到公网。
### "员工不会用怎么办?"
我们的产品交互方式就是"说话"——自然语言对话,**会用微信就会用**。而且 AI 助手直接嵌入 Word、WPS,员工不需要切换工具。我们还提供完整的培训材料和现场培训。
### "价格能不能再便宜点?"
理解,预算控制很重要。但请算一笔总账:如果自建,算力设备+AI 工程师+开发+运维,**三年总成本至少是标准化产品的 5–10 倍**。我们做的是标准化产品,已经是同能力方案中最具性价比的选择。
### "你们的产品能对接我们现有的 OA 系统吗?"
我们提供 **OpenAI 兼容 API 接口**,贵单位现有系统只需改一行配置就能接入,不需要额外开发。标准化产品已经考虑了对接需求,而且我们还有 Office/WPS 插件,可以在不改变现有工作流的情况下使用。
### "AI 这个东西太新了,我们不急着上。"
谨慎是对的。但您的同行、兄弟单位已经开始用了。AI 不是噱头,而是实实在在帮人省时间、降成本的工具。我们可以先做一个小范围试点,几个核心部门先用起来,看到效果再决定推广范围。
### "算力机的性能够用吗?会不会卡顿?"
我们的算力机是针对大模型推理专门优化的,支持高并发,集中算力按需分配,完全满足一个单位的日常使用。实际已部署的客户中,**最大并发上百人同时使用,运行稳定**。
---
## 准备好让 AI 为您工作了吗?
订阅 AI 服务,开箱即用。
我们提供算力硬件到您单位部署,让您的单位拥有自己的 AI 大脑。
📞 **联系我们,预约产品演示**
上海微趣网络科技有限公司 · 2011 年成立 · 深耕政企服务十余年
---
> 上海微趣网络科技有限公司 | 国家王选新闻科技技术奖 | 国家行业标准制定者 | WAIC2024 唯一私有化部署实机参展企业
>
> © 2026 上海微趣网络科技有限公司 · 保留所有权利
>
> 公众号 · 微趣私有AI
---
---
# 第二部分:MyGPT 完整产品手册(34 页功能介绍)
> 来源:微信公众号「微趣MyGPT一体机」
> 产品名:**MyGPT**(一体机形态,私有化部署)
> 形态:Web 应用(浏览器访问 MyGPT 地址,账号密码登录),支持白标
---
## 产品定位
**MyGPT**——20+ 能力覆盖对话、文档、知识库、数据分析、工作流全场景。
让 AI 真正为您工作。不上云、不外发、不依赖公网。
---
## 一、智能对话与知识问答(5 个能力)
### 1. 智能助手
说句话,复杂任务自动完成。
- **适用人群**:项目经理、部门主管、分析师、法务人员
- **操作**:打开「智能助手」,用自然语言描述目标 → 可拖入多份文件、关联知识库 → 助手自动拆解为「计划→执行→验证→交付」,全程可见可控
- **效果对比**:
| 任务 | 传统方式 | MyGPT |
|---|---|---|
| 翻译+校对+摘要 | 40 分钟 | **3 分钟** |
| 对比两年数据出报告 | 半天 | **5 分钟** |
| 10 份文件批量处理 | 一整天 | **30 分钟** |
### 2. 知识库问答
让 AI 读懂您公司的所有文件。
- **适用人群**:企业管理层、项目经理、研究人员、行政文秘
- **操作**:创建知识库,文件批量拖入 → 等待系统完成学习(通常几分钟)→ 自然语言提问,回答附带原文引用
- **效果对比**:
| 任务 | 传统方式 | MyGPT |
|---|---|---|
| 查找合同条款 | 20–40 分钟翻阅 | **10 秒精准定位** |
| 梳理多份报告风险点 | 2–3 小时逐页阅读 | **1 分钟汇总** |
| 跨文件信息整合 | 手工摘录 | **自动关联引用** |
### 3. 知识库表格视图
几十份文件秒变一张表。
- **适用人群**:财务人员、行政文秘、采购专员
- **操作**:所有文件拖入知识库 → 切换到「表格视图」,AI 自动发现共有字段 → 自动生成表格,可排序、编辑、一键导出 Excel
- **效果对比**:
| 任务 | 传统方式 | MyGPT |
|---|---|---|
| 20 份发票汇总 | 2 小时手工录入 | **2 分钟自动生成** |
| 字段列名 | 手动建表头 | **AI 自动识别命名** |
| 新增文件 | 重新手动录入 | **拖入即自动补充** |
### 4. PDF 大文件即时问答
百页文档,30 秒找到答案。
- **适用人群**:律师、投行分析师、审计师、采购经理
- **操作**:把 PDF 直接拖进聊天框 → 几秒钟后用自然语言提问 → 回答附带原文段落引用,精准定位
- **效果对比**:
| 任务 | 传统方式 | MyGPT |
|---|---|---|
| 144 页查付款条款 | 5–10 分钟翻阅 | **10 秒精准回答** |
| 200 页风险分析 | 2–3 小时逐页阅读 | **1 分钟结构化总结** |
| 定位原文 | 靠记忆和书签 | **点击引用直接跳转** |
### 5. 图片/扫描件智能识别
拍照即提取,长图也能问。
- **适用人群**:前台行政、财务人员、质检人员
- **操作**:把图片拖进聊天框(JPG/PNG/长图/扫描件均可)→ 用自然语言描述要提取什么 → AI 自动识别内容并结构化输出
- **效果对比**:
| 任务 | 传统方式 | MyGPT |
|---|---|---|
| 提取营业执照信息 | 3–5 分钟抄写 | **5 秒自动提取** |
| 长图公司列表 | 逐条辨认录入 | **一次识别全部** |
| 手写考勤表数字化 | 30 分钟+核对 | **1 分钟自动整理** |
---
## 二、AI 员工自动交付(4 个能力)
### 6. 一键生成报告
聊完天,PDF/Word 报告就写好了。
- **适用人群**:管理层、项目经理、市场人员、分析师
- **操作**:在「智能助手」中上传资料或讨论要点 → 说"帮我做成 PDF 报告"或"整理成 Word" → AI 自动生成结构化内容,排版为正式文档,一键下载
- **效果对比**:
| 任务 | 传统方式 | MyGPT |
|---|---|---|
| 10 页产品手册 | 1–2 天 | **15 分钟初稿** |
| 会议讨论→正式报告 | 2–3 小时 | **5 分钟** |
| 含图表分析报告 | 半天 | **10 分钟** |
### 7. 一键生成 PPT
从资料到演示文稿,一步到位。
- **适用人群**:管理层、销售经理、培训讲师
- **操作**:在「智能助手」中上传资料或录音 → 说"基于这份资料生成一份 8 页 PPT" → 下载 .pptx 文件,每页标题清晰、要点完整
- **效果对比**:
| 任务 | 传统方式 | MyGPT |
|---|---|---|
| 8 页汇报 PPT | 3–4 小时 | **5 分钟** |
| 多语言版本 | 每版本额外 2 小时 | **指定语言即可** |
| 录音→PPT | 半天 | **10 分钟** |
### 8. 批量字段提取 → Excel
上百份文件的关键信息,自动汇表。
- **适用人群**:法务人员、审计师、合规专员
- **操作**:在「智能助手」中选择目标知识库 → 用自然语言告诉 AI 需要哪些字段 → AI 自动遍历每份文件,逐项提取,保存为 Excel
- **效果对比**:
| 任务 | 传统方式 | MyGPT |
|---|---|---|
| 78 份文件提取 | 2 个工作日 | **20 分钟** |
| 字段遗漏风险 | 高(人工疲劳) | **极低(AI 逐份遍历)** |
| 结果格式 | 手动整理 Excel | **直接下载 .xlsx** |
### 9. Excel 数据分析与可视化
说句话就能做统计、画图表。
- **适用人群**:业务主管、运营人员、数据分析师
- **操作**:把 Excel/CSV 拖进「智能助手」→ 用自然语言描述需求 → AI 自动完成计算并返回表格+图表,可下载
- **效果对比**:
| 任务 | 传统方式 | MyGPT |
|---|---|---|
| 按区域统计排序 | 30–60 分钟手工 | **30 秒自动完成** |
| 画趋势折线图 | 15 分钟调格式 | **10 秒生成** |
| 跨表关联查询 | 不会公式就没法做 | **一句话搞定** |
---
## 三、工作流自动化(2 个能力)
### 10. 工作流引擎
重复工作,定义一次,永久复用。
- **适用人群**:行政人员、运营主管、财务主管
- **操作**:在「工作流」中用自然语言写下每步逻辑 → 上传样本文件,单步运行并确认,锁定步骤 → 发布后每次换新文件,一键运行
- **效果对比**:
| 任务 | 传统方式 | MyGPT |
|---|---|---|
| 7 份日报→周报 | 每周 2 小时 | **定义一次,之后 5 分钟** |
| 上百张发票分类 | 每月 1 天 | **定义一次,之后 10 分钟** |
| 80 份合同印章校验 | 人工逐份检查 | **工作流自动遍历** |
### 11. 兼容 API
无缝接入您现有的业务系统。
- **适用人群**:IT 部门、技术负责人
- **操作**:在用户中心生成 API 密钥 → 将现有系统接口地址指向 MyGPT(改一行配置)→ 完全兼容原有调用方式,业务系统零改造上线
- **效果对比**:
| 任务 | 传统方式 | MyGPT |
|---|---|---|
| 系统迁移改造 | 2–3 周开发 | **改一行配置,5 分钟** |
| 代码修改量 | 大量接口适配 | **客户端代码无需修改** |
| 部署方式 | 依赖外部云服务 | **企业内网私有化** |
---
## 四、办公工具直接使用(4 个能力)
### 12. 文档翻译
整份翻译,排版原封不动。
- **适用人群**:外贸人员、法务人员、研究人员
- **操作**:打开「文档翻译」,上传文件(Word/PDF/PPT/Excel)→ 选择目标语言 → 下载译文——排版、表格、图片位置全部保留
- **效果对比**:
| 任务 | 传统方式 | MyGPT |
|---|---|---|
| 30 页手册翻译 | 1 天(含重新排版) | **10 分钟** |
| 双语对照 | 手动逐段对照 | **自动生成双语版** |
| 日文合同翻译 | 专业翻译 3–5 天 | **15 分钟** |
### 13. 文案校对
错别字、语病,一键标出。
- **适用人群**:文秘人员、市场编辑、行政主管
- **操作**:打开「文案校对」,上传文档 → AI 自动逐句检查,标注错别字、语法问题 → 返回带高亮修订版 + 修改建议,可一键采纳
- **效果对比**:
| 任务 | 传统方式 | MyGPT |
|---|---|---|
| 50 页报告校对 | 1–2 小时 | **2 分钟** |
| 遗漏率 | 人工疲劳易漏 | **AI 逐句覆盖,无遗漏** |
| 修改建议 | 靠个人经验 | **智能建议,一键采纳** |
### 14. 会议音频分析
一小时录音,自动出纪要。
- **适用人群**:行政文秘、项目助理、管理层
- **操作**:打开「会议音频分析」,上传音频(MP3/M4A/WAV)→ AI 自动转写(带说话人标签)→ 同时输出纪要 + 待办清单 + 思维导图
- **效果对比**:
| 任务 | 传统方式 | MyGPT |
|---|---|---|
| 1 小时会议纪要 | 1–2 小时整理 | **5 分钟自动产出** |
| 说话人识别 | 手动标注 | **自动区分说话人** |
| 待办事项 | 人工回忆梳理 | **自动提取列出** |
| 思维导图 | 额外花时间制作 | **自动生成** |
### 15. AI 会议室
开会实时字幕,会后自动摘要。
- **适用人群**:跨国团队、外贸人员、政府外事人员
- **操作**:打开「AI 会议室」,创建或加入房间 → 多人同时说话,实时字幕,可选目标语言翻译 → 会后自动生成会议摘要
- **效果对比**:
| 任务 | 传统方式 | MyGPT |
|---|---|---|
| 跨语言会议 | 依赖翻译人员或猜测 | **实时字幕+实时翻译** |
| 会议纪要 | 会后手工整理 1–2 小时 | **会后自动生成** |
| 翻译人员成本 | 每场 1000–3000 元 | **零额外成本** |
---
## 五、行业专业助手(5 个能力)
### 16. 财经研报分析助理
53 万份研报,一问即达。
- **适用人群**:投资经理、研究员、基金经理
- **操作**:打开「财经研报分析助理」→ 用自然语言提问 → AI 从 **53 万份研报、970 万份公告**中检索并给出带引用的精准回答
### 17. 法律案例研究助理
按案由、法院、时间检索判决书。
- **适用人群**:律师、法务人员、合规专员
- **操作**:打开「法律案例研究助理」→ 按案由、法院、时间等维度组合检索 → AI 提供裁判规则分析、法律适用建议
- **效果对比**:
| 任务 | 传统方式 | MyGPT |
|---|---|---|
| 类案检索 | 1–2 小时搜索+筛选 | **10 秒精准检索** |
| 裁判倾向分析 | 逐案阅读后人工总结 | **AI 自动分析** |
| 法律适用建议 | 依赖个人经验 | **AI 基于案例给出建议** |
### 18. 招聘简历助手
自然语言筛简历,多人对比。
- **适用人群**:HR 招聘专员、部门负责人
- **操作**:打开「招聘简历助手」,上传简历文件 → 用自然语言描述岗位需求 → AI 逐条匹配,自动生成多人对比表
- **效果对比**:
| 任务 | 传统方式 | MyGPT |
|---|---|---|
| 200 份简历初筛 | 1 整天 | **20 分钟** |
| 候选人对比 | 手动做对比表 | **自动生成对比表** |
| 匹配准确度 | 主观判断 | **逐条对标岗位要求** |
### 19. 公文辅助写作
通知、报告、函,一键起草。
- **适用人群**:政府机关文秘、国企行政人员
- **操作**:选择「公文辅助写作」→ 用自然语言描述公文内容 → AI 自动生成符合规范的公文初稿,字体字号符合标准
- **效果对比**:
| 任务 | 传统方式 | MyGPT |
|---|---|---|
| 起草一份通知 | 2–3 小时 | **3 分钟初稿** |
| 格式规范调整 | 反复调整排版 | **自动符合规范** |
| 不同类型公文 | 每种需查模板 | **AI 自动识别类型匹配格式** |
### 20. 离境退税客服
三角色严格基于知识库答疑。
- **适用人群**:政务窗口人员、税务工作人员
- **操作**:打开「离境退税客服」助手 → 选择角色身份或直接提问 → AI 严格基于知识库政策文件回答,不编造不偏题
- **效果对比**:
| 任务 | 传统方式 | MyGPT |
|---|---|---|
| 政策咨询响应 | 翻文件 5–10 分钟 | **10 秒精准回答** |
| 回答准确性 | 依赖个人记忆 | **严格基于政策文件** |
| 多角色覆盖 | 需熟悉不同角色政策 | **一站式覆盖三方需求** |
---
## 六、基础能力
- **跨会话记忆**:智能助手能记住您之前的对话,下次问"上次那份报告的结论是什么",它真的能回答
- **压缩包直接上传**:把 .zip 直接拖入聊天框或知识库,系统自动解压处理所有文件,几十份文件打包一次搞定
- **拼写/语法检查服务**:编辑器内一键触发,错误行内高亮显示,每处附带修改建议,与文案校对互补
- **品牌定制(白标)**:后台可自定义产品名称、助手名称、Logo、欢迎页面。支持白标部署,客户看到完全是您的品牌
---
## 七、安全承诺
**您的数据,始终在您手里。不上云、不外发、不依赖公网。**
| 维度 | 承诺 |
|---|---|
| 数据完全自主可控 | 所有文件、对话、知识库数据均存储在您的服务器上,我们无法访问 |
| 网络完全内网隔离 | 可在无互联网环境下正常运行,不依赖任何外部服务 |
| 权限完全自主管理 | 用户管理、角色权限、数据隔离,全部由您自主配置 |
| 操作完全可追溯 | 完整的审计日志,谁在什么时间做了什么操作,一目了然 |
**适配政企要求**:
- 支持国产化服务器和操作系统
- 支持私有网络部署,满足等保要求
- 支持品牌定制,可替换产品名称、Logo、欢迎页
---
## 八、快速上手指南
3 步开始使用 MyGPT,5 分钟体验第一个场景。
**第一步:登录**
打开浏览器,访问您的 MyGPT 地址,输入账号密码登录。
**第二步:选一个场景,立即体验**
| 您想做什么 | 怎么操作 |
|---|---|
| 随便问个问题 | 首页点击「极速 GPT」,直接输入问题 |
| 让 AI 处理一份文件 | 把文件拖进聊天框,说"帮我总结" |
| 查询公司文件 | 创建知识库 → 拖入文件 → 提问 |
| 翻译一份文档 | 打开「文档翻译」→ 上传 → 选语言 |
| 分析 Excel 数据 | 拖入 Excel → 说"按区域统计成交额" |
**第三步:看到效果,逐步深入**
先用最简单的场景建立信心 → 再尝试知识库、智能助手等进阶能力 → 最后搭建工作流,把重复工作交给 AI。
---
## 九、产品封底
**MyGPT —— 让 AI 真正为您工作**
20+ 能力 · 覆盖对话、文档、知识库、数据分析、工作流全场景
上海微趣网络科技有限公司
> 公众号 · 微趣MyGPT一体机
---
---
# 第三部分:架构对比分析(AionUi vs 博昇 pj0235 vs MyGPT)
## 一、结论
**博昇 pj0235 架构比 AionUi 强,但离 MyGPT 更远。**
原因:AionUi 是桌面壳,博昇是企业级 Web 服务。博昇底座已经够企业交付,但上面没跑 MyGPT 那 20 个办公场景。
```
AionUi = 强场景 + 弱底座(桌面玩具,不能卖企业)
博昇 = 强底座 + 弱场景(企业级地基,但房子没盖办公那层)
MyGPT = 强底座 + 强场景(博昇的底座 + AionUi 的场景)
```
## 二、架构逐项对比
| 维度 | AionUi | 博昇 pj0235 | MyGPT(微趣) | 谁强 |
|---|---|---|---|---|
| **产品形态** | Electron 桌面应用 | **Web 服务**(浏览器访问) | Web 一体机 | 博昇 ≈ MyGPT |
| **前端** | React + Arco Design | Vue3 + Vite + Element Plus | 未公开 | 平 |
| **后端** | Node.js 主进程(几乎无后端) | **Go + Gin + GORM** | 未公开 | 博昇碾压 AionUi |
| **数据库** | 文件系统 | **SQLite**(接口留 MySQL) | 未公开 | 博昇碾压 AionUi |
| **多用户** | ❌ 单用户 | ✅ JWT + 部门 + 角色 | ✅ 多用户+权限 | 博昇 ≈ MyGPT |
| **知识库/RAG** | ❌ 没有 | ✅ 向量+关键词混合检索 | ✅ 核心能力 | 博昇 ≈ MyGPT |
| **交付形态** | Electron 安装包 | **Go 单二进制 + systemd + 整盘克隆** | 硬件送机房 | 博昇 ≈ MyGPT |
| **连接器** | MCP 协议 | **金蝶 ERP**(已落地) | 未公开 | 博昇 |
| **Agent 架构** | Cowork 多 Agent 并行 + Cron + 远程触发 | PathCoach 单助手 | 智能助手自动拆任务 | AionUi |
| **内置办公场景** | **21 个**(PPT/Word/Excel/Pitch Deck/财务模型…) | ❌ 几乎没有 | 20+ | AionUi ≈ MyGPT |
| **Office 文件生成** | 调 OfficeCLI(10.8k Star) | ❌ 没有 | ✅ 原生 .pptx/.docx/.xlsx | AionUi ≈ MyGPT |
| **远程/移动端** | WebUI + Telegram/飞书/钉钉/微信 | ❌ 未做 | Web | AionUi |
| **技术栈重量** | Electron(重,~200MB) | Go 单二进制(轻) | 一体机 | 博昇 |
| **白标/等保/国产化** | ❌ | ❌(但交付形态支持) | ✅ | MyGPT |
## 三、AionUi 源码实读结果
- **技术栈**:Electron + React + Arco Design + TypeScript + Bun,v2.2.2,Apache-2.0
- **monorepo**:desktop(Electron)/ web-host(Web 远程)/ web-cli / shared-scripts
- **21 个内置助手**:Cowork、PPT/Morph PPT/Morph PPT 3D(3个)、Pitch Deck、仪表板、Word/Word表单/Excel、学术论文、财务模型、3D游戏、UI/UX、文件规划、HUMAN教练、社交招聘、moltbook、Mermaid、OpenClaw设置、故事角色扮演、Butler
- **关键发现**:
- 助手规则用 Markdown 写,定义在姊妹仓库 AionCore(Rust),不在本仓库
- Office 文件生成靠外挂 **OfficeCLI**(iOfficeAI/OfficeCLI,10.8k Star)
- 内置技能只有 5 个:pptx / docx / pdf / xlsx / mermaid
- **没有知识库/RAG、没有会议转写、没有多用户、没有行业垂直**
## 四、博昇 pj0235 实读结果
- **当前产品名**:eai_agentplatform_app(博昇内部员工培训平台)
- **技术栈**:Vue3 + Vite + Element Plus / Go + Gin + GORM + SQLite / Ollama bge-m3 / LibreOffice + pdftotext
- **已落地模块**:
- 知识库全套(上传→审批→摄入→混合检索→导出)
- 培训考试(岗位组卷/错题本/简答题 LLM 评分/证书/能力雷达)
- 公众号内容工作流(热点→文章→配图→分发)
- 金蝶 ERP 连接器
- PathCoach AI 助教
- 积分/排行榜/部门/站内通知
- **关键决策 D20**:第一批 4 个通用数字员工——知识运营、培训考试、内容生成、任务推进
- **交付形态**:Go 单二进制 + systemd + Clonezilla 整盘克隆,无源码交付
## 五、博昇 vs MyGPT 功能差距
| 能力 | 博昇当前 | 微趣 MyGPT |
|---|---|---|
| 知识库/RAG | ✅ 已落地 | ✅ |
| 培训考试 | ✅ **比微趣强** | ❌ |
| 公众号内容生成 | ✅ **比微趣强** | ❌ |
| ERP 连接器 | ✅ 金蝶 | ❌ |
| PPT 生成 | ❌ | ✅ |
| 会议转写/纪要 | ❌ | ✅ |
| 文档翻译/校对 | ❌ | ✅ |
| 公文写作 | ❌ | ✅ |
| 多语言实时字幕 | ❌ | ✅ |
| 行业垂直(研报/法律/退税) | ❌ | ✅ |
| 多用户/权限 | ⚠️ 两级,无 RBAC | ✅ |
| 白标 | ❌ | ✅ |
## 六、下一步建议
底座已经够了,缺的是把办公场景作为"场景包"接到现有 Go 后端:
1. **PPT/Word/Excel 生成**:直接拿 OfficeCLI(AionUi 那个开源项目),不用自研
2. **会议转写**:接 Meetily(本地 Whisper + 说话人分离)
3. **办公助手规则**:参考 AionUi 的 21 个 Markdown 助手,挑需要的移植
4. **不要换技术栈**:AionUi 的 Electron 对博昇是倒退,博昇的 Go Web 底座已经赢了
> 核心判断:博昇不是要成为 AionUi,而是要成为"有 AionUi 场景包的企业级 MyGPT"。
@@ -154,7 +154,7 @@ CREATE INDEX IF NOT EXISTS idx_pk_domain ON position_knowledge(domain);
### 4.3 改动:`user` 加岗位列
在 [user.go](eaisalestrain_app/backend-go/internal/model/user.go) 的 `User` 中追加:
在 [user.go](eai_agentplatform_app/backend-go/internal/model/user.go) 的 `User` 中追加:
```go
PositionID *uint `gorm:"index" json:"position_id"` // 所属岗位,可空(历史用户/管理员可为空)
@@ -162,7 +162,7 @@ CREATE INDEX IF NOT EXISTS idx_pk_domain ON position_knowledge(domain);
### 4.4 改动:`exam_paper` 加岗位列
在 [exam_paper.go](eaisalestrain_app/backend-go/internal/model/exam_paper.go) 的 `ExamPaper` 中追加:
在 [exam_paper.go](eai_agentplatform_app/backend-go/internal/model/exam_paper.go) 的 `ExamPaper` 中追加:
```go
PositionID *uint `gorm:"index" json:"position_id"` // 关联岗位考试,可空;设置后按岗位知识映射抽题
@@ -238,7 +238,7 @@ var validLevels = map[string]bool{LevelL1: true, LevelL2: true, LevelL3: true, L
## 6. 岗位驱动考试组卷(核心算法改动)
修改 [exam.go](eaisalestrain_app/backend-go/internal/api/exam.go) 的 `pickQuestions`,在原有 `domain` 抽题之前,先判断 `p.PositionID` 是否为空:
修改 [exam.go](eai_agentplatform_app/backend-go/internal/api/exam.go) 的 `pickQuestions`,在原有 `domain` 抽题之前,先判断 `p.PositionID` 是否为空:
```go
// pickQuestions 按 paper 抽题:优先按岗位知识映射圈定题池,否则回退 domain 抽题
@@ -1,4 +1,4 @@
# eaisalestrain_app 博昇内部培训平台
# eai_agentplatform_app 博昇内部培训平台
纯内网本地化、内部专属员工培训系统。
用于新人入职培训、公司认知、产品知识学习、销售能力培训、统一考试验收。
@@ -18,7 +18,7 @@
## 目录结构
```
pj0231-eaisalestraining/ # 工作区根(仓库根)
pj0231-eai_agentplatforming/ # 工作区根(仓库根)
├── CODING_RULES.md # 编码与调试最高准则
├── start_dev_10231_10232.sh # 开发启动脚本
├── docs/ # 设计文档(项目级,与代码分离)
@@ -33,9 +33,9 @@ pj0231-eaisalestraining/ # 工作区根(仓库根)
│ ├── api.md # API 文档
│ ├── deploy.md # 部署文档
│ ├── changelog.md # 变更日志
│ ├── eaisalestrain_app设计稿.md # 完整 PRD 中文原稿
│ ├── eai_agentplatform_app设计稿.md # 完整 PRD 中文原稿
│ └── 博昇产品与渠道合作表.md # 知识源权威数据
└── eaisalestrain_app/ # 应用代码
└── eai_agentplatform_app/ # 应用代码
├── backend-go/ # Go 后端(正式,唯一后端)
│ ├── cmd/ internal/ # Go 源码
│ ├── knowledge_source/ # 知识源 Markdown(运行时数据)
@@ -5,7 +5,7 @@
## 1. 项目是什么
**eaisalestrain_app** — 博昇内部培训平台。
**eai_agentplatform_app** — 博昇内部培训平台。
纯内网本地化、内部专属员工培训系统,用于新人入职培训、公司认知、产品知识学习、
销售能力培训、统一考试验收。配套全局 AI 助教 PathCoach。
@@ -68,7 +68,7 @@
| 文档 | 路径 | 说明 |
|------|------|------|
| PRD | `../docs/PRD.md` | 产品需求文档(V1.1 最终版) |
| 设计稿 | `../docs/eaisalestrain_app设计稿.md` | 完整 PRD 中文原稿 |
| 设计稿 | `../docs/eai_agentplatform_app设计稿.md` | 完整 PRD 中文原稿 |
| DB Schema | `../docs/db_schema.md` | 9 张核心表字段设计 |
| API 文档 | `../docs/api.md` | API 接口定义 |
| 部署文档 | `../docs/deploy.md` | 部署架构与步骤 |
@@ -81,7 +81,7 @@
## 5. 目录结构(当前)
```
pj0231-eaisalestraining/ # 工作区根(仓库根)
pj0231-eai_agentplatforming/ # 工作区根(仓库根)
├── CODING_RULES.md # 编码与调试最高准则
├── start_dev_10231_10232.sh # 开发启动脚本
├── docs/ # 设计文档(项目级,与代码分离)
@@ -92,9 +92,9 @@ pj0231-eaisalestraining/ # 工作区根(仓库根)
│ ├── 06_Product_Lines/ # 产品线与前端设计
│ ├── 08_Design_Rules/ # UI/UX 设计规范
│ ├── PRD.md / db_schema.md / api.md / deploy.md / changelog.md
│ ├── eaisalestrain_app设计稿.md # 完整 PRD 中文原稿
│ ├── eai_agentplatform_app设计稿.md # 完整 PRD 中文原稿
│ └── 博昇产品与渠道合作表.md # 知识源权威数据
└── eaisalestrain_app/ # 应用代码
└── eai_agentplatform_app/ # 应用代码
├── backend-go/ # Go 后端(正式,唯一后端,已完成)
│ ├── cmd/ internal/ # Go 源码
│ ├── knowledge_source/ # 知识源 Markdown(运行时数据)
@@ -47,7 +47,7 @@ func main() {
resetStuck := flag.Bool("reset-stuck", false, "reset stuck running state for the given task")
flag.Parse()
dbPath := `d:\traecode\pj0235-eai_agentplatform\eai_ap_app\backend-go\data\eaisalestrain.db`
dbPath := `d:\traecode\pj0235-eai_agentplatform\eai_ap_app\backend-go\data\eai_agentplatform.db`
db, err := sql.Open("sqlite", dbPath)
if err != nil {
log.Fatal(err)
@@ -6,11 +6,11 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/api"
"eaisalestrain/backend/internal/auth"
"eaisalestrain/backend/internal/config"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eai_agentplatform/backend/internal/api"
"eai_agentplatform/backend/internal/auth"
"eai_agentplatform/backend/internal/config"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
)
func main() {
@@ -36,16 +36,16 @@ func main() {
api.RegisterRoutes(r, cfg)
log.Printf("eaisalestrain 后端启动,端口 :%s", cfg.Port)
log.Printf("eai_agentplatform 后端启动,端口 :%s", cfg.Port)
if err := r.Run(":" + cfg.Port); err != nil {
log.Fatalf("启动失败: %v", err)
}
}
// resetAdmin 交付前重置管理员密码:eaisalestrain-server -reset-admin <新密码>
// resetAdmin 交付前重置管理员密码:eai_agentplatform-server -reset-admin <新密码>
func resetAdmin(args []string) {
if len(args) < 1 || args[0] == "" {
log.Fatal("用法: eaisalestrain-server -reset-admin <新密码>")
log.Fatal("用法: eai_agentplatform-server -reset-admin <新密码>")
}
cfg := config.Load()
if _, err := store.Init(cfg.DBPath); err != nil {
@@ -1 +1 @@
{"agent_routes": {"embed_gen": "embed_route_openrouter_text_v3", "image_gen": "image_route_openrouter_gpt_image_2", "path_coach": "chat_route_openrouter_deepseek_v4_flash", "title_gen": "chat_route_openrouter_deepseek_v4_flash"}, "chat_routes": {"chat_route_ollama_qwen": {"description": "本地 Ollama Qwen2.5:7b", "endpoint": "/chat/completions", "max_tokens": 2048, "model": "qwen2.5:7b", "provider": "ollama", "temperature": 0.7}, "chat_route_ollama_qwen_fast": {"description": "本地快速对话 (Ollama Qwen2.5:7b 轻量)", "endpoint": "/chat/completions", "max_tokens": 512, "model": "qwen2.5:7b", "provider": "ollama", "temperature": 0.3}, "chat_route_openrouter_deepseek_v3": {"description": "DeepSeek V3.2 (OpenRouter)", "endpoint": "/chat/completions", "max_tokens": 4096, "model": "deepseek/deepseek-v3.2", "provider": "openrouter", "temperature": 0.6}, "chat_route_openrouter_deepseek_v4_flash": {"description": "DeepSeek V4 Flash (OpenRouter)", "endpoint": "/chat/completions", "max_tokens": 4096, "model": "deepseek/deepseek-v4-flash", "provider": "openrouter", "temperature": 0.7}, "chat_route_openrouter_gpt_5": {"description": "GPT 5.4 (OpenRouter)", "endpoint": "/chat/completions", "max_tokens": 8192, "model": "openai/gpt-5.4", "provider": "openrouter", "temperature": 0.7}, "chat_route_openrouter_grok_4": {"description": "Grok 4.20 (OpenRouter)", "endpoint": "/chat/completions", "max_tokens": 4096, "model": "x-ai/grok-4.20", "provider": "openrouter", "temperature": 0.6}}, "default_embed_route": "embed_route_openrouter_text_v3", "default_route": "chat_route_openrouter_deepseek_v4_flash", "description": "eaisalestrain AI 路由配置 — 按场景分类定义多条路由,支持 provider/模型切换", "embed_routes": {"embed_route_ollama_bge_m3": {"description": "本地 Ollama bge-m3", "endpoint": "/embeddings", "model": "bge-m3", "provider": "ollama"}, "embed_route_openrouter_text_v3": {"description": "OpenAI text-embedding-3-small (OpenRouter)", "endpoint": "/embeddings", "model": "openai/text-embedding-3-small", "provider": "openrouter"}}, "fallback_routes": {"chat_route_openrouter_deepseek_v3": ["chat_route_openrouter_grok_4", "chat_route_ollama_qwen"], "chat_route_openrouter_deepseek_v4_flash": ["chat_route_openrouter_deepseek_v3", "chat_route_openrouter_grok_4", "chat_route_ollama_qwen"], "chat_route_openrouter_grok_4": ["chat_route_ollama_qwen"], "embed_route_ollama_bge_m3": ["embed_route_openrouter_text_v3"], "embed_route_openrouter_text_v3": ["embed_route_ollama_bge_m3"]}, "image_routes": {"image_route_ollama_llava": {"description": "本地 Ollama LLaVA", "endpoint": "/chat/completions", "max_tokens": 2048, "model": "llava", "provider": "ollama", "temperature": 0.7}, "image_route_openrouter_flux": {"description": "FLUX 1.1 Pro (OpenRouter)", "endpoint": "/images/generations", "max_tokens": 1024, "model": "black-forest-labs/flux-1.1-pro", "provider": "openrouter", "temperature": 1}, "image_route_openrouter_gpt_image_2": {"description": "GPT 5.4 Image 2 (OpenRouter)", "endpoint": "/images/generations", "max_tokens": 4096, "model": "openai/gpt-5.4-image-2", "provider": "openrouter", "temperature": 1}}, "version": "2.1.0"}
{"agent_routes": {"embed_gen": "embed_route_openrouter_text_v3", "image_gen": "image_route_openrouter_gpt_image_2", "path_coach": "chat_route_openrouter_deepseek_v4_flash", "title_gen": "chat_route_openrouter_deepseek_v4_flash"}, "chat_routes": {"chat_route_ollama_qwen": {"description": "本地 Ollama Qwen2.5:7b", "endpoint": "/chat/completions", "max_tokens": 2048, "model": "qwen2.5:7b", "provider": "ollama", "temperature": 0.7}, "chat_route_ollama_qwen_fast": {"description": "本地快速对话 (Ollama Qwen2.5:7b 轻量)", "endpoint": "/chat/completions", "max_tokens": 512, "model": "qwen2.5:7b", "provider": "ollama", "temperature": 0.3}, "chat_route_openrouter_deepseek_v3": {"description": "DeepSeek V3.2 (OpenRouter)", "endpoint": "/chat/completions", "max_tokens": 4096, "model": "deepseek/deepseek-v3.2", "provider": "openrouter", "temperature": 0.6}, "chat_route_openrouter_deepseek_v4_flash": {"description": "DeepSeek V4 Flash (OpenRouter)", "endpoint": "/chat/completions", "max_tokens": 4096, "model": "deepseek/deepseek-v4-flash", "provider": "openrouter", "temperature": 0.7}, "chat_route_openrouter_gpt_5": {"description": "GPT 5.4 (OpenRouter)", "endpoint": "/chat/completions", "max_tokens": 8192, "model": "openai/gpt-5.4", "provider": "openrouter", "temperature": 0.7}, "chat_route_openrouter_grok_4": {"description": "Grok 4.20 (OpenRouter)", "endpoint": "/chat/completions", "max_tokens": 4096, "model": "x-ai/grok-4.20", "provider": "openrouter", "temperature": 0.6}}, "default_embed_route": "embed_route_openrouter_text_v3", "default_route": "chat_route_openrouter_deepseek_v4_flash", "description": "eai_agentplatform AI 路由配置 — 按场景分类定义多条路由,支持 provider/模型切换", "embed_routes": {"embed_route_ollama_bge_m3": {"description": "本地 Ollama bge-m3", "endpoint": "/embeddings", "model": "bge-m3", "provider": "ollama"}, "embed_route_openrouter_text_v3": {"description": "OpenAI text-embedding-3-small (OpenRouter)", "endpoint": "/embeddings", "model": "openai/text-embedding-3-small", "provider": "openrouter"}}, "fallback_routes": {"chat_route_openrouter_deepseek_v3": ["chat_route_openrouter_grok_4", "chat_route_ollama_qwen"], "chat_route_openrouter_deepseek_v4_flash": ["chat_route_openrouter_deepseek_v3", "chat_route_openrouter_grok_4", "chat_route_ollama_qwen"], "chat_route_openrouter_grok_4": ["chat_route_ollama_qwen"], "embed_route_ollama_bge_m3": ["embed_route_openrouter_text_v3"], "embed_route_openrouter_text_v3": ["embed_route_ollama_bge_m3"]}, "image_routes": {"image_route_ollama_llava": {"description": "本地 Ollama LLaVA", "endpoint": "/chat/completions", "max_tokens": 2048, "model": "llava", "provider": "ollama", "temperature": 0.7}, "image_route_openrouter_flux": {"description": "FLUX 1.1 Pro (OpenRouter)", "endpoint": "/images/generations", "max_tokens": 1024, "model": "black-forest-labs/flux-1.1-pro", "provider": "openrouter", "temperature": 1}, "image_route_openrouter_gpt_image_2": {"description": "GPT 5.4 Image 2 (OpenRouter)", "endpoint": "/images/generations", "max_tokens": 4096, "model": "openai/gpt-5.4-image-2", "provider": "openrouter", "temperature": 1}}, "version": "2.1.0"}
@@ -1,6 +1,6 @@
{
"name": "博昇内部培训平台",
"short_name": "eaisalestrain",
"short_name": "eai_agentplatform",
"version": "1.1.0",
"build_time": "2026-08-15",
"company": "博昇",
@@ -9,11 +9,11 @@
| 文件 | 说明 |
|------|------|
| `eaisalestrain-server` | 单二进制(CGO 关闭,静态链接,约 38MB,无任何运行时依赖) |
| `eaisalestrain.service` | systemd 单元文件 |
| `eaisalestrain.env` | 环境变量样例 |
| `eai_agentplatform-server` | 单二进制(CGO 关闭,静态链接,约 38MB,无任何运行时依赖) |
| `eai_agentplatform.service` | systemd 单元文件 |
| `eai_agentplatform.env` | 环境变量样例 |
| `clonezilla-cleanup.sh` | 克隆前清理脚本(DRY-RUN 默认) |
| `data/eaisalestrain.db` | SQLite 数据库(首启自动建表) |
| `data/eai_agentplatform.db` | SQLite 数据库(首启自动建表) |
| `data/kb_data/` | 已审批素材目录 |
| `knowledge_source/` | 知识源 Markdown(待入库,由管理员审批) |
@@ -24,11 +24,11 @@
## 1. 目录布局(客户机器最终形态)
```
/opt/eaisalestrain/
├── eaisalestrain-server # 单二进制
/opt/eai_agentplatform/
├── eai_agentplatform-server # 单二进制
├── .env # JWT 密钥等(交付前生成,勿提交源码库)
├── data/
│ ├── eaisalestrain.db # SQLite(首启自动建)
│ ├── eai_agentplatform.db # SQLite(首启自动建)
│ └── kb_data/ # 素材 + 提取缓存
├── knowledge_source/ # 知识源 Markdown
└── (前端静态资源由 Nginx 托管,见 ../docs/deploy.md)
@@ -41,24 +41,24 @@
```bash
# 2.1 构建静态二进制(开发机执行,产物拷贝到原型机)
export PATH=$HOME/go-sdk/go/bin:$PATH CGO_ENABLED=0 GOPROXY=https://goproxy.cn,direct
go build -o bin/eaisalestrain-server ./cmd/server
go build -o bin/eai_agentplatform-server ./cmd/server
# 校验:file 输出应为 "statically linked",ldd 应为 "not a dynamic executable"
# 2.2 拷贝到原型机 + 建账号 + 装 systemd 单元
sudo install -m 0755 eaisalestrain-server /opt/eaisalestrain/eaisalestrain-server
sudo useradd -r -s /usr/sbin/nologin eaisalestrain
sudo mkdir -p /opt/eaisalestrain/data/kb_data /opt/eaisalestrain/knowledge_source
sudo chown -R eaisalestrain:eaisalestrain /opt/eaisalestrain
sudo install -m 0644 deploy/eaisalestrain.service /etc/systemd/system/eaisalestrain.service
sudo install -m 0755 eai_agentplatform-server /opt/eai_agentplatform/eai_agentplatform-server
sudo useradd -r -s /usr/sbin/nologin eai_agentplatform
sudo mkdir -p /opt/eai_agentplatform/data/kb_data /opt/eai_agentplatform/knowledge_source
sudo chown -R eai_agentplatform:eai_agentplatform /opt/eai_agentplatform
sudo install -m 0644 deploy/eai_agentplatform.service /etc/systemd/system/eai_agentplatform.service
# 2.3 生成 .env(含随机 JWT 密钥)
sudo -u eaisalestrain cp deploy/eaisalestrain.env /opt/eaisalestrain/.env
sudo -u eai_agentplatform cp deploy/eai_agentplatform.env /opt/eai_agentplatform/.env
NEW_SECRET=$(python3 -c "import secrets; print(secrets.token_urlsafe(48))")
sudo sed -i "s|^JWT_SECRET=.*|JWT_SECRET=$NEW_SECRET|" /opt/eaisalestrain/.env
sudo sed -i "s|^JWT_SECRET=.*|JWT_SECRET=$NEW_SECRET|" /opt/eai_agentplatform/.env
# 2.4 启动验证
sudo systemctl daemon-reload
sudo systemctl enable --now eaisalestrain
sudo systemctl enable --now eai_agentplatform
curl http://127.0.0.1:8080/api/health # {"status":"ok",...}
```
@@ -82,8 +82,8 @@ sudo bash clonezilla-cleanup.sh --confirm # 确认后真实清理
| # | 动作 | 命令 |
|---|------|------|
| A | **重置管理员密码** | `sudo -u eaisalestrain /opt/eaisalestrain/eaisalestrain-server -reset-admin '<强密码>'` |
| B | **确认 JWT 密钥随机** | `grep -c '__CHANGE_ME__' /opt/eaisalestrain/.env`(应为 0) |
| A | **重置管理员密码** | `sudo -u eai_agentplatform /opt/eai_agentplatform/eai_agentplatform-server -reset-admin '<强密码>'` |
| B | **确认 JWT 密钥随机** | `grep -c '__CHANGE_ME__' /opt/eai_agentplatform/.env`(应为 0) |
| C | **清空测试数据** | Web 后台删除演示用户/素材/考试记录,或用 sqlite3(见第 4 节) |
> 默认种子账号为 `admin / admin123`,**克隆前必须改密**(A 项),否则客户拿到默认口令。
@@ -94,7 +94,7 @@ sudo bash clonezilla-cleanup.sh --confirm # 确认后真实清理
```bash
# 若需彻底清库只保留结构 + admin:
sqlite3 /opt/eaisalestrain/data/eaisalestrain.db <<'SQL'
sqlite3 /opt/eai_agentplatform/data/eai_agentplatform.db <<'SQL'
-- 先停服务
DELETE FROM exam_record;
DELETE FROM knowledge_chunk;
@@ -125,9 +125,9 @@ SQL
## 6. 交付红线(每次克隆前过一遍)
- [ ] `ldd eaisalestrain-server` 输出 `not a dynamic executable`
- [ ] `find /opt/eaisalestrain -name '*.go' -o -name 'go.mod'` 无结果
- [ ] `/opt/eaisalestrain/.env` 无 `__CHANGE_ME__`
- [ ] `ldd eai_agentplatform-server` 输出 `not a dynamic executable`
- [ ] `find /opt/eai_agentplatform -name '*.go' -o -name 'go.mod'` 无结果
- [ ] `/opt/eai_agentplatform/.env` 无 `__CHANGE_ME__`
- [ ] 管理员密码非 `admin123`
- [ ] `.bash_history` 已清空、无 `.git`
- [ ] 测试账号(zhangsan 等)、演示素材、演示考试记录已删除
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
# ============================================================
# eaisalestrain — Clonezilla 整盘克隆前的清理脚本
# eai_agentplatform — Clonezilla 整盘克隆前的清理脚本
# 目标:交付给客户的设备上「无源代码、无开发痕迹、无测试数据、无默认口令」。
#
# 用法(在交付原型机上以 root 执行):
@@ -11,7 +11,7 @@
# ============================================================
set -euo pipefail
APP_DIR="/opt/eaisalestrain"
APP_DIR="/opt/eai_agentplatform"
CONFIRM="${1:-}"
log() { echo -e "\033[1;32m[OK]\033[0m $*"; }
@@ -45,7 +45,7 @@ echo " - 提示:测试用户 zhangsan / 演示素材 / 演示考试记录等
echo " 或在克隆前用 sqlite3 执行(见 DELIVERY.md 第 4 节)。脚本不自动清库,避免误删正式数据。"
step "4. 清空日志与 shell 历史"
for f in "$APP_DIR/logs" "$APP_DIR"/*.log /var/log/eaisalestrain*.log; do
for f in "$APP_DIR/logs" "$APP_DIR"/*.log /var/log/eai_agentplatform*.log; do
if compgen -G "$f" >/dev/null 2>&1; then
echo " 将清空: $f"
[[ $DRY -eq 0 ]] && find "$f" -type f -name '*.log' -exec truncate -s 0 {} \; 2>/dev/null || true
@@ -61,11 +61,11 @@ done
step "5. 提示:以下必须手工完成(脚本无法替你决定口令)"
cat <<'EOF'
[A] 重置管理员密码:
sudo -u eaisalestrain /opt/eaisalestrain/eaisalestrain-server -reset-admin '<新强密码>'
[B] 重新生成 JWT 密钥(写回 /opt/eaisalestrain/.env):
sudo -u eai_agentplatform /opt/eai_agentplatform/eai_agentplatform-server -reset-admin '<新强密码>'
[B] 重新生成 JWT 密钥(写回 /opt/eai_agentplatform/.env):
python3 -c "import secrets; print('JWT_SECRET='+secrets.token_urlsafe(48))"
[C] 确认 .env 内无 __CHANGE_ME__ 占位符:
grep -n '__CHANGE_ME__' /opt/eaisalestrain/.env && echo '!! 存在未替换占位符' || echo '无占位符'
grep -n '__CHANGE_ME__' /opt/eai_agentplatform/.env && echo '!! 存在未替换占位符' || echo '无占位符'
EOF
step "6. 移除本清理脚本自身(交付物不含脚本)"
@@ -1,11 +1,11 @@
# eaisalestrain 后端环境变量(交付样例,实际值在 Clonezilla 清理时生成)
# eai_agentplatform 后端环境变量(交付样例,实际值在 Clonezilla 清理时生成)
# systemd 通过 EnvironmentFile 读取;system_config 表可覆盖 LLM 相关字段。
# 监听端口(Nginx 反代到 127.0.0.1:8080)
PORT=8080
# SQLite 数据文件(相对 WorkingDirectory=/opt/eaisalestrain)
DB_PATH=data/eaisalestrain.db
# SQLite 数据文件(相对 WorkingDirectory=/opt/eai_agentplatform)
DB_PATH=data/eai_agentplatform.db
# JWT 签名密钥 —— 交付前必须随机生成(见 DELIVERY.md)
JWT_SECRET=__CHANGE_ME__GENERATE_48_CHARS_RANDOM__
@@ -19,7 +19,7 @@ EMBED_MODEL=bge-m3
# 数据目录
KB_DATA_DIR=data/kb_data
KNOWLEDGE_SOURCE_DIR=/opt/eaisalestrain/knowledge_source
KNOWLEDGE_SOURCE_DIR=/opt/eai_agentplatform/knowledge_source
# 上传大小限制(字节)
FILE_MAX_SIZE_DOC=209715200
@@ -1,15 +1,15 @@
[Unit]
Description=eaisalestrain 博昇内部培训平台后端
Description=eai_agentplatform 博昇内部培训平台后端
After=network.target
Wants=network.target
[Service]
Type=simple
User=eaisalestrain
Group=eaisalestrain
WorkingDirectory=/opt/eaisalestrain
EnvironmentFile=-/opt/eaisalestrain/.env
ExecStart=/opt/eaisalestrain/eaisalestrain-server
User=eai_agentplatform
Group=eai_agentplatform
WorkingDirectory=/opt/eai_agentplatform
EnvironmentFile=-/opt/eai_agentplatform/.env
ExecStart=/opt/eai_agentplatform/eai_agentplatform-server
Restart=always
RestartSec=3
@@ -17,7 +17,7 @@ RestartSec=3
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/eaisalestrain/data
ReadWritePaths=/opt/eai_agentplatform/data
PrivateTmp=true
PrivateDevices=true
ProtectKernelTunables=true
@@ -1,4 +1,4 @@
module eaisalestrain/backend
module eai_agentplatform/backend
go 1.25.0
@@ -5,8 +5,8 @@ import (
"gorm.io/gorm"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
)
// ──────────────────────────────────────────────
@@ -9,7 +9,7 @@ import (
"strings"
"time"
"eaisalestrain/backend/internal/config"
"eai_agentplatform/backend/internal/config"
)
type KnowledgeClassifyResult struct {
@@ -10,9 +10,9 @@ import (
"strings"
"time"
"eaisalestrain/backend/internal/config"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eai_agentplatform/backend/internal/config"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
)
// ──────────────────────────────────────────────
@@ -5,9 +5,9 @@ import (
"sort"
"strings"
"eaisalestrain/backend/internal/config"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eai_agentplatform/backend/internal/config"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
)
// Retrieve 混合检索:向量 brute-force 余弦 + 关键词兜底,去重合并取 topK
@@ -6,8 +6,8 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/config"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/config"
"eai_agentplatform/backend/internal/web"
)
// ──────────────────────────────────────────────
@@ -9,11 +9,11 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/ai"
"eaisalestrain/backend/internal/config"
"eaisalestrain/backend/internal/middleware"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/ai"
"eai_agentplatform/backend/internal/config"
"eai_agentplatform/backend/internal/middleware"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/web"
)
// checkBalance 调用前校验用户算力点余额(不扣点的能力直接放行)
@@ -6,10 +6,10 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/middleware"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/middleware"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
// ──────────────────────────────────────────────
@@ -0,0 +1,183 @@
package api
import (
"bytes"
"encoding/json"
"fmt"
"io"
"mime/multipart"
"net/http"
"strings"
"time"
"github.com/gin-gonic/gin"
"eai_agentplatform/backend/internal/ai"
"eai_agentplatform/backend/internal/config"
"eai_agentplatform/backend/internal/middleware"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
// AudioTranscribeResult 语音转录结果
type AudioTranscribeResult struct {
Text string `json:"text"` // 转录文字
Language string `json:"language"` // 语言
Duration float64 `json:"duration"` // 时长(秒)
CreatedAt string `json:"created_at"` // 时间
}
// TranscribeAudio POST /api/audio/transcribe —— 语音转文字
func TranscribeAudio(c *gin.Context) {
user := middleware.CurrentUser(c)
if user == nil {
web.Fail(c, web.NewAuthError("未登录"))
return
}
// 解析 multipart 表单
file, fileHeader, err := c.Request.FormFile("file")
if err != nil {
web.Fail(c, web.NewBadRequest("请上传音频文件"))
return
}
// 检查扩展名
ext := extractExt(fileHeader.Filename)
if ext == "" {
ext = "mp3"
}
allowedExt := map[string]bool{
"mp3": true, "wav": true, "m4a": true,
"ogg": true, "flac": true, "aac": true, "wma": true,
}
if !allowedExt[ext] {
web.Fail(c, web.NewBadRequest("不支持的音频格式,仅支持 MP3/WAV/M4A/OGG/FLAC"))
return
}
language := c.PostForm("language")
if language == "" {
language = "zh" // 默认中文
}
// 读取文件内容
fileData, err := io.ReadAll(file)
if err != nil {
web.Fail(c, web.NewBadRequest("读取音频文件失败"))
return
}
file.Close()
result := transcribeAudio(fileData, ext, language)
logTranscription(user.ID, fileHeader.Filename, result)
web.OK(c, result)
}
// extractExt 从文件名提取扩展名
func extractExt(filename string) string {
for i := len(filename) - 1; i >= 0; i-- {
if filename[i] == '.' {
return strings.ToLower(filename[i+1:])
}
}
return ""
}
// transcribeAudio 调用 Ollama whisper 进行语音转录
func transcribeAudio(fileData []byte, ext, language string) AudioTranscribeResult {
// 尝试从路由配置获取 LLM baseURL,降级到 Ollama 默认
baseURL := "http://127.0.0.1:11434"
if r, err := config.GetRoute("title_gen"); err == nil && r != nil && r.BaseURL != "" {
baseURL = r.BaseURL
// 去掉 /v1 后缀,确保路径正确
baseURL = strings.TrimSuffix(baseURL, "/v1")
}
// 调用 Ollama /v1/audio/transcriptions
url := baseURL + "/v1/audio/transcriptions"
// 构建 multipart body
buf := bytes.NewBuffer(nil)
w := multipart.NewWriter(buf)
// model field
modelField, _ := w.CreateFormField("model")
modelField.Write([]byte("whisper"))
// language field
langField, _ := w.CreateFormField("language")
langField.Write([]byte(language))
// audio file
filePart, _ := w.CreateFormFile("file", "audio."+ext)
filePart.Write(fileData)
w.Close()
req, err := http.NewRequest("POST", url, buf)
if err != nil {
return AudioTranscribeResult{
Text: "请求构建失败",
CreatedAt: time.Now().Format("2006-01-02 15:04:05"),
}
}
req.Header.Set("Content-Type", w.FormDataContentType())
req.Header.Set("Authorization", "Bearer placeholder") // Ollama 通常不需要 key
client := &http.Client{Timeout: 120 * time.Second}
resp, err := client.Do(req)
if err != nil {
return AudioTranscribeResult{
Text: fmt.Sprintf("Ollama 服务不可达 (%s),请确认 whisper 模型已加载", baseURL),
CreatedAt: time.Now().Format("2006-01-02 15:04:05"),
}
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return AudioTranscribeResult{
Text: "读取响应失败",
CreatedAt: time.Now().Format("2006-01-02 15:04:05"),
}
}
if resp.StatusCode != http.StatusOK {
return AudioTranscribeResult{
Text: fmt.Sprintf("转录失败 (HTTP %d): %s", resp.StatusCode, string(body)),
CreatedAt: time.Now().Format("2006-01-02 15:04:05"),
}
}
// 解析 {"text": "..."}
var out struct {
Text string `json:"text"`
}
if err := json.Unmarshal(body, &out); err != nil {
return AudioTranscribeResult{
Text: "响应解析失败",
CreatedAt: time.Now().Format("2006-01-02 15:04:05"),
}
}
return AudioTranscribeResult{
Text: out.Text,
Language: language,
Duration: 0, // Ollama whisper 不返回时长
CreatedAt: time.Now().Format("2006-01-02 15:04:05"),
}
}
// logTranscription 记录语音转录日志
func logTranscription(userID uint, filename string, result AudioTranscribeResult) {
store.DB.Create(&model.AiCallLog{
UserID: userID,
Capability: "audio_transcribe",
Status: "success",
})
_ = filename
_ = ai.GenerateWithFallback
_ = result
}
@@ -3,11 +3,11 @@ package api
import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/auth"
"eaisalestrain/backend/internal/middleware"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/auth"
"eai_agentplatform/backend/internal/middleware"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
type loginRequest struct {
@@ -7,11 +7,11 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/ai"
"eaisalestrain/backend/internal/middleware"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/ai"
"eai_agentplatform/backend/internal/middleware"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
// BatchExtractRequest POST /api/batch/extract —— 批量字段提取请求
@@ -6,10 +6,10 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/middleware"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/middleware"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
// issueCertificate 正式考试通过后颁发证书(幂等:同一 exam_record 只发一张)。
@@ -9,10 +9,10 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/middleware"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/middleware"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
// GetCompanyTrain GET /api/company-train
@@ -6,8 +6,8 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/connector"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/connector"
"eai_agentplatform/backend/internal/web"
)
// ListConnectors GET /api/connectors
@@ -6,11 +6,11 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/ai"
"eaisalestrain/backend/internal/middleware"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/ai"
"eai_agentplatform/backend/internal/middleware"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
// ContractReviewRequest POST /api/contract/review
@@ -7,10 +7,10 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/middleware"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/middleware"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
// CopyProofreadingRequest POST /api/copy/proofread 文案校对请求
@@ -5,9 +5,9 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
// courseView 课程详情视图(含绑定产品)
@@ -7,9 +7,9 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
// ListDepartments GET /api/departments?status= —— 部门字典列表(含成员数)
@@ -10,12 +10,12 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/ai"
"eaisalestrain/backend/internal/config"
"eaisalestrain/backend/internal/middleware"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/ai"
"eai_agentplatform/backend/internal/config"
"eai_agentplatform/backend/internal/middleware"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
// DocumentTranslateRequest POST /api/document/translate 文档翻译请求
@@ -6,8 +6,8 @@ import (
"strings"
"time"
"eaisalestrain/backend/internal/ai"
"eaisalestrain/backend/internal/config"
"eai_agentplatform/backend/internal/ai"
"eai_agentplatform/backend/internal/config"
)
// gradeEssay 调 LLM 按评分标准对简答题作答打分,返回 0~1 得分率与一句话评语。
@@ -13,11 +13,11 @@ import (
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt/v5"
"eaisalestrain/backend/internal/auth"
"eaisalestrain/backend/internal/middleware"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/auth"
"eai_agentplatform/backend/internal/middleware"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
// Option 题目选项
@@ -5,7 +5,7 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/web"
)
// parseID 解析路径中的 uint id,失败返回 false 并已写入错误响应
@@ -11,10 +11,10 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/middleware"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/middleware"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
// ============ 扫描 ============
@@ -9,9 +9,9 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
// ============ 知识库导出 ============
@@ -7,9 +7,9 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
// ListKnowledgeFAQs GET /api/knowledge/faqs?knowledge_space_key=&status=&keyword=&page=&size=
@@ -6,10 +6,10 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/ai"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/ai"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
var knowledgeIndexRebuildLock sync.Mutex
@@ -9,10 +9,10 @@ import (
"gorm.io/gorm"
"eaisalestrain/backend/internal/ai"
"eaisalestrain/backend/internal/config"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eai_agentplatform/backend/internal/ai"
"eai_agentplatform/backend/internal/config"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
)
const (
@@ -8,9 +8,9 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
type spaceMetrics struct {
@@ -5,10 +5,10 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/middleware"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/middleware"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
var validItemTypes = map[string]bool{"company": true, "product": true, "course": true}
@@ -16,10 +16,10 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/middleware"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/middleware"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
var allowedExt = map[string]bool{
@@ -6,10 +6,10 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/middleware"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/middleware"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
var validNoteItemTypes = map[string]bool{"company": true, "product": true, "course": true}
@@ -5,10 +5,10 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/middleware"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/middleware"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
// notifyUser 给单个用户发站内通知(userID=0 忽略)。
@@ -6,8 +6,8 @@ import (
"sort"
"strings"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
)
func loadOfficialAccountArticle(taskID uint) (*model.OfficialAccountArticle, error) {
@@ -13,11 +13,11 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/ai"
"eaisalestrain/backend/internal/config"
"eaisalestrain/backend/internal/middleware"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/ai"
"eai_agentplatform/backend/internal/config"
"eai_agentplatform/backend/internal/middleware"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/web"
)
type officialAccountSection struct {
@@ -10,10 +10,10 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/config"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/config"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
func officialAccountGeneratedImageDir() string {
@@ -17,8 +17,8 @@ import (
"golang.org/x/net/html/charset"
"gorm.io/gorm/clause"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
)
type officialAccountFetchedHotspot struct {
@@ -9,12 +9,12 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/ai"
"eaisalestrain/backend/internal/config"
"eaisalestrain/backend/internal/middleware"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/ai"
"eai_agentplatform/backend/internal/config"
"eai_agentplatform/backend/internal/middleware"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
const (
@@ -6,10 +6,10 @@ import (
"github.com/gin-gonic/gin"
"gorm.io/gorm"
"eaisalestrain/backend/internal/middleware"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/middleware"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
// —— 积分规则(游戏化成长值,集中一处便于调整,见 docs/changelog.md 待确认项)——
@@ -5,10 +5,10 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/middleware"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/middleware"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
// ============ 岗位 CRUD(管理员) ============
@@ -3,9 +3,9 @@ package api
import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
// ListProducts GET /api/products?category=&status=
@@ -5,10 +5,10 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/middleware"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/middleware"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
// domainLabels 能力雷达维度(正式考试按域聚合的掌握度)。
@@ -8,12 +8,12 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/ai"
"eaisalestrain/backend/internal/config"
"eaisalestrain/backend/internal/middleware"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/ai"
"eai_agentplatform/backend/internal/config"
"eai_agentplatform/backend/internal/middleware"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
// ReportGenRequest POST /api/report/generate 报告生成请求
@@ -6,8 +6,8 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/config"
"eaisalestrain/backend/internal/middleware"
"eai_agentplatform/backend/internal/config"
"eai_agentplatform/backend/internal/middleware"
)
// Cfg 全局配置,RegisterRoutes 时注入
@@ -28,7 +28,7 @@ func RegisterRoutes(r *gin.Engine, cfg *config.Config) {
if p, err := config.LoadPlatformConfig(); err == nil {
ver = p.Version
}
c.JSON(200, gin.H{"status": "ok", "service": "eaisalestrain-app", "version": ver})
c.JSON(200, gin.H{"status": "ok", "service": "eai_agentplatform-app", "version": ver})
})
auth := r.Group("/api/auth")
@@ -135,6 +135,9 @@ func RegisterRoutes(r *gin.Engine, cfg *config.Config) {
r.POST("/api/batch/files", middleware.Auth(cfg), ExtractFromFiles)
r.POST("/api/assistant/chat", middleware.Auth(cfg), Chat)
// 语音工具
r.POST("/api/audio/transcribe", middleware.Auth(cfg), TranscribeAudio)
// 管理员维护
admin := r.Group("/api")
admin.Use(middleware.Auth(cfg), middleware.RequireAdmin())
@@ -1,8 +1,8 @@
package api
import (
"eaisalestrain/backend/internal/config"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/config"
"eai_agentplatform/backend/internal/web"
"github.com/gin-gonic/gin"
)
@@ -5,11 +5,11 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/ai"
"eaisalestrain/backend/internal/middleware"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/ai"
"eai_agentplatform/backend/internal/middleware"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
// SmartAssistantRequest POST /api/assistant/chat —— 智能助手请求
@@ -5,10 +5,10 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/middleware"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/middleware"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
// ListSpecialists GET /api/specialists?tier=&state=&market_tag=
@@ -6,9 +6,9 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
// round1 保留 1 位小数
@@ -9,10 +9,10 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/auth"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/auth"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
// ============ 用户管理(管理员) ============
@@ -7,10 +7,10 @@ import (
"github.com/gin-gonic/gin"
"gorm.io/gorm"
"eaisalestrain/backend/internal/middleware"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/middleware"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
func WorkbenchOverview(c *gin.Context) {
@@ -10,13 +10,13 @@ import (
"github.com/gin-gonic/gin"
"gorm.io/gorm"
"eaisalestrain/backend/internal/ai"
"eaisalestrain/backend/internal/config"
"eaisalestrain/backend/internal/connector"
"eaisalestrain/backend/internal/middleware"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/ai"
"eai_agentplatform/backend/internal/config"
"eai_agentplatform/backend/internal/connector"
"eai_agentplatform/backend/internal/middleware"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
type workerTaskReq struct {
@@ -46,7 +46,7 @@ func Load() *Config {
return &Config{
Port: getenv("PORT", "8080"),
DBPath: getenv("DB_PATH", filepath.Join(baseDir, "data", "eaisalestrain.db")),
DBPath: getenv("DB_PATH", filepath.Join(baseDir, "data", "eai_agentplatform.db")),
JWTSecret: getenv("JWT_SECRET", "change-this-to-a-strong-secret-in-production"),
JWTExpireMin: getenvInt("JWT_EXPIRE_MINUTES", 480),
@@ -12,7 +12,7 @@ import (
"strings"
"time"
"eaisalestrain/backend/internal/config"
"eai_agentplatform/backend/internal/config"
)
type KingdeeConnector struct {
@@ -4,7 +4,7 @@ import (
"context"
"testing"
"eaisalestrain/backend/internal/config"
"eai_agentplatform/backend/internal/config"
)
func TestKingdeeDefinitionDefaultsToDemo(t *testing.T) {
@@ -6,7 +6,7 @@ import (
"strings"
"time"
"eaisalestrain/backend/internal/config"
"eai_agentplatform/backend/internal/config"
)
var ErrConnectorNotFound = errors.New("connector not found")
@@ -4,7 +4,7 @@ import (
"context"
"strings"
"eaisalestrain/backend/internal/config"
"eai_agentplatform/backend/internal/config"
)
type Definition struct {
@@ -9,11 +9,11 @@ import (
"github.com/gin-gonic/gin"
"eaisalestrain/backend/internal/auth"
"eaisalestrain/backend/internal/config"
"eaisalestrain/backend/internal/model"
"eaisalestrain/backend/internal/store"
"eaisalestrain/backend/internal/web"
"eai_agentplatform/backend/internal/auth"
"eai_agentplatform/backend/internal/config"
"eai_agentplatform/backend/internal/model"
"eai_agentplatform/backend/internal/store"
"eai_agentplatform/backend/internal/web"
)
// Auth 解析 JWT → 校验用户 → 注入 current_user

Some files were not shown because too many files have changed in this diff Show More