Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
47 changes: 47 additions & 0 deletions .agents/ACCEPTANCE_CHECKLIST.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# 后续验收清单(本次未执行)

## A. 练习管理

- [ ] 列表加载、名称搜索、一级类别和细分方向筛选正确。
- [ ] 新建/生成练习可从资料管理选择文件,自动带入类别和文件类型。
- [ ] 编辑、删除、批量删除与刷新行为正确。
- [ ] 生成题目、题目列表、题目关键词/题型筛选、新增/编辑/删除题目正确。
- [ ] 加载、空数据、生成中和失败提示明确且不丢失用户输入。

## B. 考试管理

- [ ] 考试名称、状态、一级类别、细分方向筛选正确。
- [ ] 新建、编辑、预览、删除和批量删除正确。
- [ ] 普通分类考试只选择对应类别的练习;混合考试满足已确认的跨类别规则。
- [ ] 题目来源、题型组成、数量、分值、总分、时长、及格线与考试规则正确。
- [ ] 草稿、已发布、已结束状态与发布流程符合后端契约。

## C. 左侧菜单和路由

- [ ] 培训中心显示练习管理和考试管理,顺序与产品确认一致。
- [ ] 考试管理直接访问、刷新和浏览器前进/后退均正常。
- [ ] 未授权用户不看到或不能访问受限入口,已有菜单和深链接不回归。

## D. 分类筛选

- [ ] 数据来自已确认的正式来源,而非 `reference-ui/category-filter.js` 的原型常量。
- [ ] 一级类别切换会正确重置/加载二级方向。
- [ ] 练习和考试使用相同字段语义,混合考试筛选行为明确。

## E. API 和异常提示

- [ ] 请求路径、方法、鉴权头、分页参数和响应适配与后端契约一致。
- [ ] 401、4xx/5xx、超时、空数据、重复提交和部分批量失败可理解且可恢复。
- [ ] Nginx 环境变量代理链与部署目标一致。

## F. 权限

- [ ] 菜单权限、路由权限、页面按钮权限和后端接口权限使用同一已确认规则。
- [ ] 无权限访问不会泄露数据;超级管理员特殊规则不回归。

## G. 页面风格一致性

- [ ] 使用现有 Vue/Element Plus 组件和布局,不嵌入或直接覆盖参考 HTML。
- [ ] 表格、表单、抽屉/弹窗、分页、提示、空状态和响应式布局与管理端一致。
- [ ] 中文、英文、泰文 i18n 文案完整;键名不影响现有页面。

86 changes: 86 additions & 0 deletions .agents/ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# 架构与调用关系

## 前端结构(已确认)

```text
D:\PL\eap-chat\src
├─ main.js / App.vue Vue、Router、Pinia、I18n、Element Plus 入口
├─ router\index.js 静态路由与 token 路由守卫
├─ stores\modules\auth.ts 静态左侧菜单数据及显示过滤
├─ layouts\LayoutVertical\index.vue 管理端双栏布局与左侧菜单渲染
├─ layouts\components\Menu\SubMenu.vue
├─ pages\LicenseAdmin.vue 当前“练习管理”实际路由页面
├─ components\exam\ReviewDialog.vue 题目复核、编辑、删除组件
└─ services\ Axios 服务封装
```

构建流程为 `src` → Vite `dist` → Docker 第二阶段 `/usr/share/nginx/html` → Nginx。`/eap` 另有静态目录回退至 `/eap/index.html`,与当前 Vue 管理端构建输出无直接调用关系。

## 浏览器、Nginx 与后端

| 浏览器前缀 | 模板转发 | 运行容器变量(已确认) | 运行后端地址 | 前端调用示例 |
|---|---|---|---|---|
| `/sop-api/` | `http://$SOP_API_HOST/` | `SOP_API_HOST` | `118.196.142.69:6007` | `sop.api.js` |
| `/chatapi/` | `http://$CHAT_API_HOST/` | `CHAT_API_HOST` | `118.196.142.69:9010` | `chat.service.js` |
| `/companyapi/` | `http://$COMPANY_API_HOST/` | `COMPANY_API_HOST` | `118.196.142.69:8010` | `company.service.js` |
| `/chathistoryapi/` | `http://$CHAT_HISTORY_API_HOST/` | `CHAT_HISTORY_API_HOST` | `118.196.142.69:6022` | `chatHistory.service.js` |
| `/userapi/` | `http://$USER_API_HOST/` | `USER_API_HOST` | `118.196.142.69:9011` | `user.service.js` |
| `/dashboardapi/` | `http://$DASHBOARD_API_HOST/` | `DASHBOARD_API_HOST` | `118.196.142.69:6020` | `dashboard.service.js` |
| `/mobileapi/`、`/eap/mobileapi/` | `http://$MOBILE_API_HOST/` | `MOBILE_API_HOST` | `118.196.142.69:7010` | `mobile.service.js` |
| `/videoapi/` | `http://$VIDEO_API_HOST/` | `VIDEO_API_HOST` | `118.196.142.69:8000` | `video.service.js` |
| `/videoapiv2/` | `http://$VIDEO_API_HOST_V2/` | `VIDEO_API_HOST_V2` | `118.196.142.69:8001` | `videov2.service.js` |
| `/monitor-api/` | `http://153.35.82.15:8080/api/` | 无 | 固定地址 `153.35.82.15:8080` | `monitor.service.js` |
| `/api-153/` | `http://153.35.82.15:31117/` | 无 | 固定地址 `153.35.82.15:31117` | `license.service.js` |

模板中的 `proxy_pass` 尾部带 `/`,所以代理会去掉上述浏览器前缀。Vite 开发代理也去掉相同前缀,但其目标地址与当前 Docker 运行容器不同;不可把开发代理目标当作生产容器后端。

## 菜单、路由与权限

- 路由是 `src/router/index.js` 中的静态注册;未发现按后端接口返回菜单、动态 `addRoute` 或菜单数据库调用。
- 左侧菜单来自 Pinia `src/stores/modules/auth.ts` 的静态 `authMenuList`,经 `showMenuListGet` 和 `getShowMenuList` 过滤 `meta.isHide` 后,由 `LayoutVertical` / `SubMenu` 渲染。
- 培训中心静态父菜单为 `/trainingCenter`;其子项为学习管理与练习管理。
- 路由守卫只验证本地 token;`/system/modelSetting` 另以 `userInfo.name === 'superadmin'` 限制。未发现练习管理或考试管理的菜单权限码、角色码或后端权限菜单接口。
- `LicenseAdmin.vue` 使用了 `v-auth="'add'"`,但在本次扫描的应用入口与源码中未找到该指令注册位置;该按钮级权限是否生效为待确认。

## 练习管理现有链路(已确认到前端与代理)

`培训中心` → `auth.ts` 的“练习管理” → `/trainingCenter/practiceManagement` → `router/index.js` → `pages/LicenseAdmin.vue` → `ProTable`、`components/licenseAdmin/searchForm.vue`、`components/licenseAdmin/editDrawer.vue`、`components/exam/ReviewDialog.vue` → `services/sop.api.js` 与 `services/company.service.js` → `/sop-api`、`/companyapi` → Nginx 模板 → `SOP_API_HOST`、`COMPANY_API_HOST` → 运行容器后端地址。

当前页面的业务语义是 SOP/资料导入、异步生成 QA、题目复核及 SOP 元数据编辑;它并不存在与参考 HTML 一一对应的“练习实体”接口。后续改造前必须确认新练习的数据模型与后端接口。

## 考试能力现状

- 已有用户答题会话:`services/chat.service.js` 的 `/chatapi/v1/exams/start`、`/answer`、`/finish`,页面为独立路由 `/chat/exam` 的 `pages/ChatExam.vue`。
- 仪表盘存在考试统计调用:`dashboard.service.js` 的 `/dashboardapi/api/dashboard/department-exam` 等。
- `pages/testCenter/index.vue` 是未接入左侧菜单的占位页面;其路由在 `router/index.js` 中被注释,且使用用户列表 API,不可直接作为考试管理实现复用。
- 未发现考试管理列表、试卷、发布、考试记录、独立题库或考试权限码的正式 API 封装;SOP 的 QA 列表与保存接口可作为题目数据线索,但是否可复用为题库待确认。

## 分类能力

- 正式练习页没有分类 API 或公共分类筛选组件;它的筛选为名称与公司/部门/岗位。
- 参考 `category-filter.js` 的“产品/运营/技术”及二级方向仅为本地原型数据,不能作为正式数据源。
- 现有 `courseManagement`、资料库中的静态课程类别与参考分类不同;正式分类接口与字段仍待确认。

## 本地参考 UI 分析(仅作目标,不可直接复用 HTML)

### `reference-ui/管理端-练习.html`

- 布局:双侧栏管理端外壳、顶部栏、筛选面板和列表面板;参考菜单含资料、练习、考试、题库、评价。
- 筛选:一级类别/细分方向标签、名称输入、查询和重置。表格展示名称、类别、版本、创建/更新时间,并支持多选、批量删除、刷新、编辑和删除。
- 生成/编辑:弹窗选择类别、细分方向、文件类型、版本、资料管理文件和描述;资料选择后自动带入类别和文件类型,并提示自动生成题目。
- 题目:编辑模式显示题目管理区,支持关键词、题型(选择题/回答题)筛选、题目数、新增、编辑、删除。
- 原型实现:数据保存在浏览器 `localStorage`(`bluedot_practices`、`bluedot_materials`),自动题目是 mock 函数,不是后端接口。因此只能借鉴交互目标,不能把其数据或函数迁入正式页面。

### `reference-ui/管理端-考试.html`

- 布局:同一管理端外壳;顶部有产品、技术、运营、混合考试统计卡,点击可筛选或开始相应类别的新建。
- 列表:考试名称搜索、状态(已发布/草稿/已结束)与共享分类筛选;支持新建、批量删除、预览、编辑、删除。
- 新建/编辑抽屉:四步——基础信息与题目来源练习、题型/数量/分值和规则、试卷预览、发布信息。
- 规则:普通类别考试选择同类别练习;混合考试原型要求至少选择两个不同类别练习;配置选择题/回答题数量与单题分值、时长、及格线、随机组卷等开关。
- 发布:原型展示草稿、已发布、已结束,并在最后一步配置起止时间;数据保存在 `bluedot_exams`,无网络请求。

### `reference-ui/category-filter.js`

- 原型一级类别:产品、运营、技术;二级方向:产品(AI Portal、AI Hub、BEAT、BAMS)、运营(公司章程)、技术(K8s)。
- 脚本提供标签 UI、值标准化和 `matches(record)` 本地过滤;仅处理原型记录字段 `primary` / `secondary`。
- 正式实现前必须以已确认的分类接口、字段、权限和空值规则替换这些常量;不能认定它们是生产数据。
16 changes: 16 additions & 0 deletions .agents/DECISIONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# 决策记录

| 决策 | 结论 | 依据/影响 |
|---|---|---|
| 协作文档位置 | `.agents` 固定在 `D:\PL\eap-chat\.agents` | 用户明确要求;根目录 `AGENTS.md` 作为入口规则。 |
| `docker.env` | 它是文件,不是目录 | Dockerfile 不读取它;运行态值与其一致,但注入命令待确认。 |
| Docker Compose | 不作假定 | 扫描未发现有效 Compose 配置,文档仅记录未发现。 |
| Docker/端口结论 | 必须同时参考 Dockerfile、Nginx、Docker inspect | 本次确认 `80` 容器内监听、`8080:80` 运行态映射。 |
| 改造顺序 | 先分析再修改 | 练习当前是 SOP/QA 流程,参考原型是练习实体管理,不能直接映射。 |
| 参考 HTML | 不直接覆盖正式页面 | 仅作为布局、字段、交互目标;正式实现沿用 Vue/Element Plus。 |
| 技术体系 | 沿用现有技术栈 | Vue 3、Vite、Router、Pinia、Element Plus、Axios;不新增依赖。 |
| 分类能力 | 优先确认正式数据源,之后再考虑共享 | 原型分类是 localStorage 静态数据,现有正式分类接口未找到。 |
| 数据库 | 当前阶段不修改 | 本次仅分析和文档;考试菜单数据库需求尚无证据。 |
| 正式页面 | 当前阶段不修改 | 不修改练习页,不新增正式考试页。 |
| 公共组件 | 暂不抽取 | 两个页面的正式字段和数据源尚未稳定;避免过早抽象。 |

54 changes: 54 additions & 0 deletions .agents/DEVELOPMENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# 开发环境与运行方式

## 技术栈(已确认)

- 前端:Vue 3(SFC)、Vite 7、Vue Router 4、Pinia 3、Element Plus、Axios、Vue I18n、Sass。
- 包管理器:npm;锁文件为 `D:\PL\eap-chat\package-lock.json`。
- 脚本:`npm run dev`(Vite 开发服务器)、`npm run build`(`vite build`)、`npm run preview`(`vite preview`)。本次未执行。
- 前端入口:`D:\PL\eap-chat\src\main.js`;路由入口:`D:\PL\eap-chat\src\router\index.js`。

## 项目主结构扫描

```text
D:\PL\eap-chat
├─ Dockerfile / docker.env / entrypoint.sh / nginx.conf.template
├─ package.json / package-lock.json / vite.config.js / index.html / README.md
├─ src\ Vue 管理端源码
├─ public\ 静态资源(含 eap 子站静态产物)
├─ reference-ui\ 本地参考 HTML 与分类原型脚本
├─ .agents\ 协作文档(本次创建)
└─ AGENTS.md 协作规则(本次创建)
```

扫描发现:`Dockerfile`、`docker.env`、`nginx.conf`、`nginx.conf.template`、`nginx.generated.conf`、`entrypoint.sh`、`entrypoint.container.sh`、`package.json`、`package-lock.json`、`vite.config.js`、`src`、`public`、`README.md`。未发现 `.env`/`.env.*`、Docker Compose 配置、`pnpm-lock.yaml`、`yarn.lock`、`vue.config.*`、`next.config.*`、`webpack.config.*`、`Jenkinsfile`、`.gitlab-ci.yml`、`.github`、`deploy`、`start.sh`。

## Docker 与 Nginx(已确认)

- Dockerfile:`D:\PL\eap-chat\Dockerfile`,两阶段构建。
1. `registry.cn-hangzhou.aliyuncs.com/jilimoxing/test:node-20-alpine`:复制 `package*.json`,执行 `npm install --registry=https://registry.npmmirror.com`,复制源码,执行 `npm run build`。
2. `registry.cn-hangzhou.aliyuncs.com/jilimoxing/test:nginx1192`:把 `/app/dist` 复制至 `/usr/share/nginx/html`,复制 `nginx.conf.template` 和 `entrypoint.sh`,暴露 `80`,执行 `/entrypoint.sh`。
- 镜像是纯前端静态站点镜像;最终页面由 Nginx 提供。
- 启动脚本 `D:\PL\eap-chat\entrypoint.sh` 使用 `envsubst` 把指定环境变量写入 `/etc/nginx/nginx.conf`,然后以 `nginx -g 'daemon off;'` 启动。
- 镜像实际使用的模板为 `D:\PL\eap-chat\nginx.conf.template`;`nginx.conf` 与 `nginx.generated.conf` 是源码中的其他 Nginx 配置文件,Dockerfile 未复制它们。
- 模板确认:`listen 80`、静态根目录 `/usr/share/nginx/html`、入口 `index.html`、SPA 回退 `try_files $uri $uri/ /index.html`。

## 环境变量与 Compose

- `D:\PL\eap-chat\docker.env` 是文件。Dockerfile 不复制或读取它;它只能在容器运行时由外部传入。
- 启动脚本会替换:`SOP_API_HOST`、`CHAT_API_HOST`、`COMPANY_API_HOST`、`CHAT_HISTORY_API_HOST`、`USER_API_HOST`、`DASHBOARD_API_HOST`、`MOBILE_API_HOST`、`VIDEO_API_HOST`、`VIDEO_API_HOST_V2`。
- 当前项目未发现 Docker Compose 配置(未发现 `docker-compose.yml`、`docker-compose.yaml`、`compose.yml` 或 `compose.yaml`)。未执行任何 Compose 命令。
- 当前运行容器的九个变量值与 `docker.env` 一致,但 Docker inspect 无法证明其启动时是否使用了 `--env-file docker.env`;实际注入命令为待确认。

## 当前运行态(只读确认)

- 容器:`eap-chat`;镜像:`eap-chat:local`;状态:运行中。
- Dockerfile 声明端口、Nginx 监听端口、容器暴露端口均为 `80/tcp`。
- Docker inspect 端口绑定:`0.0.0.0:8080 -> 80/tcp` 和 `[::]:8080 -> 80/tcp`;本机访问端口为 `8080`。
- 启动链:镜像原生 Entrypoint `/docker-entrypoint.sh`,Cmd `/entrypoint.sh`;无挂载目录。

## 本次禁止的操作

- 不运行构建、预览、测试或自动化测试;测试由用户执行。
- 不启动、停止、删除、重建容器;不构建、删除、拉取镜像。
- 不修改数据库、不执行迁移、不修改 `docker.env`。
- 不使用 PowerShell 脚本。
33 changes: 33 additions & 0 deletions .agents/HANDOFF.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# 会话交接

## 定位信息

- 项目:`D:\PL\eap-chat`
- 技术栈:Vue 3、Vite、Vue Router、Pinia、Element Plus、Axios、Vue I18n、npm。
- Dockerfile:`D:\PL\eap-chat\Dockerfile`
- Nginx 模板:`D:\PL\eap-chat\nginx.conf.template`
- 运行容器:`eap-chat`;镜像:`eap-chat:local`;容器内/Nginx 端口 `80`;宿主端口 `8080`。
- 运行时变量值与 `docker.env` 一致;源码无自动加载逻辑,实际外部注入命令待确认。

## 页面链路

- 菜单文件:`D:\PL\eap-chat\src\stores\modules\auth.ts`
- 路由文件:`D:\PL\eap-chat\src\router\index.js`
- 左侧菜单渲染:`D:\PL\eap-chat\src\layouts\LayoutVertical\index.vue`、`src\layouts\components\Menu\SubMenu.vue`
- 练习管理页面:`D:\PL\eap-chat\src\pages\LicenseAdmin.vue`
- 子组件:`src\pages\components\licenseAdmin\searchForm.vue`、`editDrawer.vue`、`src\components\exam\ReviewDialog.vue`
- 练习 API:`D:\PL\eap-chat\src\services\sop.api.js`;组织筛选 API:`src\services\company.service.js`
- 练习浏览器前缀:`/sop-api`,由 `SOP_API_HOST` 转发至运行态 `118.196.142.69:6007`;组织选择经 `/companyapi`、`COMPANY_API_HOST` 至 `118.196.142.69:8010`。

## 参考与考试

- 练习参考:`D:\PL\eap-chat\reference-ui\管理端-练习.html`
- 考试参考:`D:\PL\eap-chat\reference-ui\管理端-考试.html`
- 分类原型:`D:\PL\eap-chat\reference-ui\category-filter.js`
- 考试会话残留:`src\services\chat.service.js`、`src\pages\ChatExam.vue`;未发现正式考试管理 API。
- 考试管理预计新增:`src\pages\examManagement\index.vue`(及必要局部组件)、`src\services\exam.service.js`、路由、auth 菜单和三份语言文件;先确认后端契约后再创建。

## 下一步

先确认:练习实体与分类字段、资料选择接口、题目保存契约、考试管理 API/权限/菜单来源。确认后从 `src/stores/modules/auth.ts` 和 `src/router/index.js` 做最小考试入口改动,再实施页面。

Loading