Compare commits
2
Commits
b61db6684e
...
9de09dfa72
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9de09dfa72 | ||
|
|
0455f064ac |
+8
-5
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)**
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -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
@@ -1,4 +1,4 @@
|
||||
# eaisalestrain_app 博昇内部培训平台 — 产品需求文档
|
||||
# eai_agentplatform_app 博昇内部培训平台 — 产品需求文档
|
||||
|
||||
> **版本:V1.1 最终版(V1 培训底座基线)| 纯本地化部署 | 极简架构 | 全功能闭环**
|
||||
> **最后更新:2026-08-15**
|
||||
|
||||
+2
-2
@@ -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
@@ -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
@@ -1,4 +1,4 @@
|
||||
# eaisalestrain_app — 数据库 Schema
|
||||
# eai_agentplatform_app — 数据库 Schema
|
||||
|
||||
> **版本:V1.2 | 引擎:MySQL 8.0(关系数据)+ FAISS(向量检索)| ORM:GORM**
|
||||
> **最后更新:2026-08-16**
|
||||
|
||||
+23
-23
@@ -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 # 实时日志
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -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` 多租户根)
|
||||
|
||||
@@ -730,7 +730,7 @@ MyGPT = 强底座 + 强场景(博昇的底座 + AionUi 的场景)
|
||||
|
||||
## 四、博昇 pj0235 实读结果
|
||||
|
||||
- **当前产品名**:eaisalestrain_app(博昇内部员工培训平台)
|
||||
- **当前产品名**:eai_agentplatform_app(博昇内部员工培训平台)
|
||||
- **技术栈**:Vue3 + Vite + Element Plus / Go + Gin + GORM + SQLite / Ollama bge-m3 / LibreOffice + pdftotext
|
||||
- **已落地模块**:
|
||||
- 知识库全套(上传→审批→摄入→混合检索→导出)
|
||||
|
||||
@@ -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(运行时数据)
|
||||
+1
-1
@@ -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)
|
||||
+8
-8
@@ -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
@@ -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
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "博昇内部培训平台",
|
||||
"short_name": "eaisalestrain",
|
||||
"short_name": "eai_agentplatform",
|
||||
"version": "1.1.0",
|
||||
"build_time": "2026-08-15",
|
||||
"company": "博昇",
|
||||
+22
-22
@@ -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 等)、演示素材、演示考试记录已删除
|
||||
+6
-6
@@ -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. 移除本清理脚本自身(交付物不含脚本)"
|
||||
+4
-4
@@ -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
|
||||
+7
-7
@@ -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
|
||||
|
||||
+2
-2
@@ -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"
|
||||
)
|
||||
|
||||
// ──────────────────────────────────────────────
|
||||
+1
-1
@@ -9,7 +9,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"eaisalestrain/backend/internal/config"
|
||||
"eai_agentplatform/backend/internal/config"
|
||||
)
|
||||
|
||||
type KnowledgeClassifyResult struct {
|
||||
+3
-3
@@ -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"
|
||||
)
|
||||
|
||||
// ──────────────────────────────────────────────
|
||||
+3
-3
@@ -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
|
||||
+2
-2
@@ -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"
|
||||
)
|
||||
|
||||
// ──────────────────────────────────────────────
|
||||
+5
-5
@@ -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 调用前校验用户算力点余额(不扣点的能力直接放行)
|
||||
+4
-4
@@ -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
|
||||
}
|
||||
+5
-5
@@ -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 {
|
||||
+5
-5
@@ -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 —— 批量字段提取请求
|
||||
+4
-4
@@ -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 只发一张)。
|
||||
+4
-4
@@ -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
|
||||
+2
-2
@@ -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
|
||||
+5
-5
@@ -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
|
||||
+4
-4
@@ -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 文案校对请求
|
||||
+3
-3
@@ -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 课程详情视图(含绑定产品)
|
||||
+3
-3
@@ -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= —— 部门字典列表(含成员数)
|
||||
+6
-6
@@ -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 文档翻译请求
|
||||
+2
-2
@@ -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 得分率与一句话评语。
|
||||
+5
-5
@@ -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 题目选项
|
||||
+1
-1
@@ -5,7 +5,7 @@ import (
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"eaisalestrain/backend/internal/web"
|
||||
"eai_agentplatform/backend/internal/web"
|
||||
)
|
||||
|
||||
// parseID 解析路径中的 uint id,失败返回 false 并已写入错误响应
|
||||
+4
-4
@@ -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"
|
||||
)
|
||||
|
||||
// ============ 扫描 ============
|
||||
+3
-3
@@ -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"
|
||||
)
|
||||
|
||||
// ============ 知识库导出 ============
|
||||
+3
-3
@@ -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=
|
||||
+4
-4
@@ -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
|
||||
+4
-4
@@ -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 (
|
||||
+3
-3
@@ -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 {
|
||||
+4
-4
@@ -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}
|
||||
+4
-4
@@ -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{
|
||||
+4
-4
@@ -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}
|
||||
+4
-4
@@ -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 忽略)。
|
||||
+2
-2
@@ -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) {
|
||||
+5
-5
@@ -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 {
|
||||
+4
-4
@@ -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 {
|
||||
+2
-2
@@ -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 {
|
||||
+6
-6
@@ -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 (
|
||||
+4
-4
@@ -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 待确认项)——
|
||||
+4
-4
@@ -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
-3
@@ -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=
|
||||
+4
-4
@@ -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 能力雷达维度(正式考试按域聚合的掌握度)。
|
||||
+6
-6
@@ -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
-3
@@ -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())
|
||||
+2
-2
@@ -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
-5
@@ -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 —— 智能助手请求
|
||||
+4
-4
@@ -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=
|
||||
+3
-3
@@ -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 位小数
|
||||
+4
-4
@@ -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"
|
||||
)
|
||||
|
||||
// ============ 用户管理(管理员) ============
|
||||
+4
-4
@@ -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) {
|
||||
+7
-7
@@ -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 {
|
||||
+1
-1
@@ -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),
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"eaisalestrain/backend/internal/config"
|
||||
"eai_agentplatform/backend/internal/config"
|
||||
)
|
||||
|
||||
type KingdeeConnector struct {
|
||||
+1
-1
@@ -4,7 +4,7 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"eaisalestrain/backend/internal/config"
|
||||
"eai_agentplatform/backend/internal/config"
|
||||
)
|
||||
|
||||
func TestKingdeeDefinitionDefaultsToDemo(t *testing.T) {
|
||||
+1
-1
@@ -6,7 +6,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"eaisalestrain/backend/internal/config"
|
||||
"eai_agentplatform/backend/internal/config"
|
||||
)
|
||||
|
||||
var ErrConnectorNotFound = errors.New("connector not found")
|
||||
+1
-1
@@ -4,7 +4,7 @@ import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"eaisalestrain/backend/internal/config"
|
||||
"eai_agentplatform/backend/internal/config"
|
||||
)
|
||||
|
||||
type Definition struct {
|
||||
+5
-5
@@ -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
Reference in New Issue
Block a user