docs: add AI handover guide (env snapshot & module dev SOP)
CI/CD Deploy (Web) / 构建前端镜像并部署 (push) Successful in 25s

This commit is contained in:
张家训
2026-09-03 19:01:58 +08:00
parent 4223822f29
commit 1741a35107
+235
View File
@@ -0,0 +1,235 @@
# Freedom(KPI 绩效考核系统)AI 开发接手指南
> - 生成/更新日期:2026-09-03(请留意后续变更,环境信息随时间会过期)
> - 存放位置:`freedom-admin/docs/AI-开发接手指南.md` 与 `freedom-web/docs/AI-开发接手指南.md`(两仓库同步维护同一份内容)
> - 用途:当新的 AI 编码代理(如小龙虾 / openclaw)接手本项目、开发新功能模块时,**先完整阅读本文件**即可快速建立上下文。第 1 节是可整体复制给代理的 Prompt 模板,第 2 节之后是明细资料。
---
## 1. 接手 Prompt(可直接复制给 openclaw / 任意编码 Agent)
```
你是 Freedom(KPI 绩效考核系统)项目的开发工程师。项目为前后端分离架构,由两个独立 git 仓库组成:
freedom-admin(Spring Boot 2.7.10 / Java 8 / MyBatis-Plus / MySQL)与 freedom-web(Vue2 + iView(view-design) 后台)。
请先阅读各仓库 docs/AI-开发接手指南.md,了解环境、目录结构与开发 SOP 后再动手。
本次任务要求:
1. 明确需求范围与验收标准,拆解为前后端改造点;涉及数据库变更必须先给出 SQL 脚本并说明执行方式。
2. 后端新增接口:仿照 freedom-admin 现有 TSysDept/TSysUser 模块的 entity→mapper→service→controller 分层;
注意 controller 不带 /api 前缀、POST 参数按表单(POJO)接收、统一返回 Result{code,message,data}。
3. 前端新增页面:在 src/view 下建 .vue,在 src/api 对应目录建请求封装;新菜单/按钮权限登记在后端权限树
(t_sys_permission / 系统-权限管理界面),component 字段填写相对 src/view 的路径(无 .vue、无前导斜杠)。
4. 提交与验证:本地构建通过(mvn package / npm run build),提交信息规范,push master 会自动触发
Gitea Actions 构建并 docker compose 部署到生产(无独立预览环境,涉及生产数据变更务必谨慎并在提交说明中提示)。
5. 禁止把数据库密码/邮箱授权码等敏感信息写入代码或文档;一律引用 /opt/freedom/deploy/.env 或询问部署人。
环境速记:页面入口(公网) http://124.221.214.237:8880,后端直连 http://124.221.214.237:8800;
仓库远端 gitlab.jiaxun.site/yiciheng/freedom-*;内网 Gitea 192.168.1.158:3000(yiciheng/freedom-*) 跑 Actions。
项目现状与缺口(后端仅 RBAC、KPI 前端页面存在但后端接口缺失、api/basic 为已删生成器残留)见指南第 4/8 节,
动手前先与需求方核对,不要凭假设补全业务规则。
```
---
## 2. 项目定位与总体架构
- 前后端分离的 **KPI 绩效考核管理系统**,目前生产可用的部分是「系统管理/RBAC」(用户、角色、部门、权限/菜单树),另有已写完前端但后端尚未落地的 KPI 业务页面。
- 一套源码同时维护 **2 个独立 git 仓库**(`freedom-admin`、`freedom-web`),根工作区同时还有辅助目录(`deploy/`、`docs/`、`_ci-test/`、`scripts/`、`act-runner-src-tmp/`、`logs/`),这些属于运维/CI 资产,不入业务仓库。
- 请求链路:
```
浏览器(Vue SPA, 端口 8880 对外)
↓ /api/xxx(nginx 去掉 /api 前缀)
freedom-web nginx 容器 (80) ──proxy_pass──▶ freedom-admin(Spring Boot, 8800) ──▶ MySQL freedom_db
页面静态资源由 nginx 直接托管;Excel 模板目录 /excelTemplate → nginx alias
```
---
## 3. 当前环境快照(2026-09-03 实测)
### 3.1 代码托管与 CI/CD
| 项 | 值 | 说明 |
|---|---|---|
| 工作区远端 remote(实测) | `http://gitlab.jiaxun.site/yiciheng/freedom-admin.git`、`freedom-web.git`(HTTPS,需凭据) | 日常工作 push 到此 |
| 内网 Gitea | `http://192.168.1.158:3000`,仓库 `yiciheng/freedom-admin`、`yiciheng/freedom-web` | **Gitea Actions 实际在此触发** |
| 域名与内网关系 | `gitlab.jiaxun.site` 在办公网可能走内网 DNS/hosts;在公网 DNS 下可能解析到失效的拦截页。**依赖 git remote 的操作请在办公网环境验证**,若线上未更新,优先到内网 Gitea 看仓库提交与 Actions 运行记录 | 环境差异,勿假设 |
| Gitea Actions Runner | `local-runner`(act_runner v0.6.1,labels `ubuntu-latest`,宿主 `/etc/act_runner/runner-config.yml`) | docker socket 自动挂载 |
| 部署卷白名单 | `/opt/freedom`(runner `container.valid_volumes`) | |
| 工作流 | 各仓库 `.gitea/workflows/deploy.yml`;触发 `push master`(支持手动 `workflow_dispatch`) | |
| CI 注意事项 | act_runner **不会自动 clone 代码**,workflow 里是手动 `git clone`(oauth2 token + `host.docker.internal:3000`),克隆目录 `/opt/freedom/workspace-admin|web` | |
### 3.2 生产服务器(部署拓扑)
- 部署目录:`/opt/freedom/deploy/`,内含 `docker-compose.yml` + `.env`(`DB_URL / DB_USERNAME / DB_PASSWORD / IMAGE_TAG`)
- 容器(网络 `freedom-net`):
| 容器 | 镜像 | 服务名 | 宿主端口 | 说明 |
|---|---|---|---|---|
| `freedom-web` | `freedom-web:latest` | nginx | `8880` | 页面入口;`/api` → 后端(nginx 去前缀);`/excelTemplate` alias |
| `freedom-admin` | `freedom-admin:latest` | Spring Boot | `8800` | 后端;日志 `/app/logs` 映射宿主 `deploy/logs/backend` |
- 公网访问:`http://124.221.214.237:8880`(frp 映射)。后端 8800 也映射了公网,一般不直接用。
- 数据库:MySQL,库 `freedom_db`;凭据由 `deploy/.env` 注入容器(后端 `application.yml` 中引用 `DB_URL` 等环境变量),**不要硬编码在镜像/代码里**。
- 容器内 `docker compose` 操作统一在 `/opt/freedom/deploy` 下执行。
### 3.3 本地开发环境
- 后端:JDK 8 + Maven(推荐 3.6.x);启动类 `com.freedom.admin.FreedomAdminApplication`;本地端口 `8800`;连库 `freedom_db`(DB 信息在 `application.yml` / 部署机 `.env`)。
- 前端:**Node 16**(高版本 Node 可能构建失败);建议 `npm config set registry https://registry.npmmirror.com`;`npm run serve` 默认 8080,dev `baseUrl = http://localhost:8800`(src/config/index.js)。
- 不想起后端时,可把 dev `baseUrl` 指到 `http://124.221.214.237:8800` 联调远程接口(接口不带 /api 前缀)。
---
## 4. 技术栈速览
### 后端 freedom-admin
- Spring Boot 2.7.10(Web / Security / Thymeleaf / Mail / Test)、**JDK 8**
- **MyBatis-Plus**(`BaseMapper`、`QueryWrapper`、`Page`)+ XML(`resources/mapper`)
- **Spring Security + JWT(jjwt)+ BCrypt**;自定义 `@PermitAll` 注解(忽略鉴权)
- Lombok、commons-lang3/collections4、beetl(历史遗留,谨慎使用)、guava、fastjson
- 登录/登出统一由 Security Handler 输出 JSON(已修复跨域重定向问题,见 §6)
### 前端 freedom-web
- Vue 2.x + vue-router + vuex + **iView4(`view-design`)** + less + echarts + mathjs + vue-particles(登录页粒子)
- 基于 iview-admin 模板改造;请求封装 `src/libs/axios.js` + `src/libs/api.request.js`
- **POST 请求体统一为表单编码**(axios `transformRequest` + `qs.stringify(data,{indices:false})`),后端按 POJO/form 绑定接收
- token:Cookie(`TOKEN_KEY`),`libs/util.js` 的 `getToken()`,每个请求放入 `Authorization` 头
---
## 5. 仓库结构(重要:先精读这些文件再动手)
### 5.1 后端(freedom-admin)
```
src/main/java/com/freedom/admin/
FreedomAdminApplication.java
common/ Result{code,message,data}+ok/error、ResultCode、MyException 等
base/ BaseController(含 getUsername() 取当前登录人)等
config/ WebSecurityConfig(Security/JWT 过滤器/CORS/permitAll 清单)、
MyAuthenticationSuccessHandler / MyAuthenticationFailureHandler(登录结果 JSON 化)
controller/ TSysUserController / TSysRoleController / TSysPermissionController / TSysDeptController
service/ TSysXxxService(接口)
service/impl/ TSysXxxServiceImpl(含用户-角色、角色-权限分配等事务)
entity/ TSysUser / TSysRole / TSysPermission / TSysDept / TSysUserRole / TSysRolePermission
mapper/ 接口 extends BaseMapper<TSysXxx>
src/main/resources/
application.yml 数据源/邮箱等(含敏感项,勿外泄)
mapper/*.xml 复杂 SQL
sql/init.sql 6 张 t_sys_* 建表 + 初始数据(默认管理员 admin)
Dockerfile maven3.6.3-jdk8(阿里云源) → openjdk8-jre
.gitea/workflows/deploy.yml
```
> ⚠️ `sql/init.sql` 可能滞后于生产库(尤其权限树数据),新建环境初始化后仍需要在「权限管理」界面补全菜单,或以生产库为准核对。
### 5.2 前端(freedom-web)
```
src/
config/index.js baseUrl:dev http://localhost:8800;prod /api
libs/ axios.js(拦截器/30s 超时/错误码)、api.request.js、util.js、router-util.js
router/routers.js 静态基础路由(/home /login 401 等);业务路由由后端权限树动态注册
store/module/user.js handleLogin / getUserInfo / 登出清 token
store/module/app.js updateMenuList:权限树 → 动态 addRoutes(业务路由)
api/ 按业务域组织:sys/、kpi/、basic/(basic 为已删除的代码生成器残留,勿用)
view/ login/、home/、sys/(sys-user|sys-role|sys-dept|sys-permission)、kpi/(7 个页面)
components/login-form/
nginx.conf /api 反代后端、history 路由 try_files、/excelTemplate alias
Dockerfile node16 + npmmirror → nginx
.gitea/workflows/deploy.yml
```
- **动态菜单机制**:登录后 `getUserInfo` 拉取权限树 → `app.js` 先重置 matcher 再 `addRoutes`;
页面组件映射规则 = `@/view` + `component` 字段 + `.vue`。所以新增页面三件事缺一不可:
① `view/.../xxx.vue` 文件必须存在且路径一致;② 权限树登记(url=前端路由 path,component=相对 view 路径,无 `.vue` 无前导斜杠);③ 给角色勾选后重新登录。
### 5.3 现状缺口(接手前务必与需求方核对)
1. 后端目前只有 **RBAC 系统管理**模块(4 个 TSysXxx controller、6 张表)。
2. 前端 **kpi/ 7 个页面 + api/kpi** 已存在,调用 `system/kpi-staff/*` 等接口,**后端无对应实现**(controller/mapper/表均无)——需确认是从零实现 KPI 后端,还是有现成实现待合入。
3. `api/basic/*` 三个文件是已被移除的「代码生成器」残留(freedom-web 历史提交 `ec2fc97 remove code generator module`),前端 view 中无对应页面。若后续要重启代码生成方向(多数据源/项目路径替换),属于**新开发**而非修复。
4. freedom-admin 本地有备份分支 `backup/pre-sync`,合入 master 前请先 diff 确认。
---
## 6. 如何新增一个功能模块(SOP)
### 6.1 后端
1. **建表**:字段风格参考 `t_sys_dept/t_sys_user`(逻辑删除 `del_flag`、审计字段 `create_by/create_time/update_by/update_time`);DDL 落成 `sql/*.sql` 并更新 init.sql,不要只改库不留脚本。
2. **entity** `TSysXxx.java`:Lombok `@Data`、`@TableName`、`@TableId`、`@TableLogic`(参考 TSysUser)。
3. **mapper** `TSysXxxMapper extends BaseMapper<TSysXxx>`;复杂 SQL 放 `resources/mapper/TSysXxxMapper.xml`。
4. **service / impl**:参考 `TSysDeptService(Impl)` 分层,事务 `@Transactional`。
5. **controller** `TSysXxxController`:`@RequestMapping("xxx")` **不带 /api 前缀**;POST 用 POJO/表单参数接收(不要 @RequestBody JSON);统一返回 `Result.ok()/Result.error()`;需免登录的接口加 `@PermitAll`,否则保持默认(走 JWT 鉴权)。
6. 权限粒度:若要做按钮级权限,参考现有 `@RequiresPermission` 或权限树 permissionType 用法,与现有代码保持一致。
### 6.2 前端
1. `src/view/<域>/<页面>.vue`:结构参考 `view/sys/sys-dept.vue`(Card + 查询表单 + Table + 分页 + Modal 编辑),组件直接用 `view-design`(全局注册,无需 import)。
2. `src/api/<域>/<api>.js`:仿照 `api/sys/sys-user.js`,如
`export const addXxx = data => axios.request({ url: 'xxx/add', headers: { Authorization: getToken() }, data, method: 'post' })`。
3. **登记菜单/按钮**:在系统「权限管理」中新增(或直接改 `t_sys_permission`,注意与前端字段对应):
- 目录级:`url` 一般为前端路由前缀、`component` 留空;
- 页面级:`url = /<域>/<页面>`(vue-router path)、`component = <域>/<页面>`(相对 src/view,无 .vue、无前导斜杠);
- 按钮级:作为页面子节点登记(permissionType/编码约定参考现网数据)。
4. **授权**:角色-权限勾选 → 重新登录生效。
5. 请求错误码统一走 axios 拦截器(见 §7),页面一般只需处理 `code === 200`。
### 6.3 联调与提交
- 本地:`mvn spring-boot:run` + `npm run serve`;远端联调改 `config/index.js` dev baseUrl。
- 验证闭环:登录态 → 菜单出现 → 增删改查 → 权限不足被拦。
- 提交规范:`feat: / fix: / docs: / style: / refactor: / ci:` 前缀 + 中文说明。
- push master 即自动构建部署生产(无预览环境);涉及 SQL/权限变更时,在提交说明里写明需要人工执行的 SQL 与执行顺序。
---
## 7. 全局约定与易踩坑清单(务必遵守)
| # | 约定/坑 | 说明 |
|---|---|---|
| 1 | URL 无 /api 前缀 | `/api` 是 nginx 层的路径,后端 controller 不要写 /api |
| 2 | POST 表单编码 | 前端统一 qs.stringify;后端 POJO 绑定,别用 @RequestBody |
| 3 | 返回结构 | `Result{code,message,data}`;code:200 成功 / 415 账号或密码错误 / 511,512,513 token 相关问题 / 500 异常;前端会据此自动跳登录页 |
| 4 | 登录/登出是 JSON 流程 | Spring Security handler 直接输出 JSON(/login、/logout),**严禁改回 redirect**(会导致 CORS/跨域 302 与前端报错,历史已踩坑修复) |
| 5 | 登录失败文案 | `MyAuthenticationFailureHandler` 返回 code 415 + “账号或密码错误” |
| 6 | 动态路由 | 页面文件路径必须与权限树 component 完全一致,否则菜单点击无路由(白屏/跳 home) |
| 7 | 敏感信息 | DB/邮箱密码一律走部署机 `.env` 注入容器;禁止写进代码/提交/文档 |
| 8 | init.sql 可能滞后 | 权限树/菜单以生产库与「权限管理」界面为准 |
| 9 | Node 版本 | 前端必须 Node 16 附近,高版本可能构建失败 |
| 10 | CI 无自动检出 | 改 workflow 时保留手动 clone 逻辑;不要假设 $GITHUB_WORKSPACE 已含代码 |
---
## 8. 常用命令速查
```bash
# 本地后端
cd freedom-admin && mvn spring-boot:run
# 本地前端
cd freedom-web && npm install && npm run serve
# 生产(SSH 到部署机后)
cd /opt/freedom/deploy
docker compose ps
docker compose logs -f backend web
docker compose up -d --force-recreate backend # 手工发布后端
docker compose up -d --force-recreate web # 手工发布前端
cat .env # 数据库凭据(勿外泄)
# CI 排查
docker logs -f act_runner # runner 日志
# Gitea Actions 页面:检查最近一次运行是否成功、失败步骤输出
```
---
## 9. 已知待办/需求池(开发前先确认)
1. (2026-09 完成)登录体验修复:登录错误 JSON 提示、登出 CORS/302 修复、登录页默认账号清空 + “海阔凭鱼跃,天高任鸟飞”诗句化、演示文案移除 —— 提交见 freedom-admin `59e796c/030916e`、freedom-web `7d07121/4223822`,**待线上验证**。
2. (口头需求,未开工)若重启代码生成方向:
- 系统内置多套 MyBatis 数据源信息(开发/SIT/生产等),生成时下拉选择,免手动填 `db_url/db_username/db_password`;
- 系统设置「项目管理」Tab 提供项目路径字符替换工具:快捷固定替换父目录(如 `D:/bestpay-srdcloud`)、替换账号(如 `srd17321104074`),支持对所有项目路径批量生效。
- 注意:旧代码生成模块曾存在后被移除(web `ec2fc97`),此需求属新建还是恢复需与用户确认。
3. (待确认)KPI 模块后端化:前端 7 个页面 + 6 个 API 已就绪,后端需补数据模型/表/接口,字段与业务流程请先访谈确认。
---
## 10. 附录:可参考的本地文档/文件
- `freedom-admin/docs/`:后端仓库内说明文档(含部署实录等)
- 工作区根 `docs/CICD-环境与进度.md`:环境与踩坑记录(含 runner、frp、镜像同步背景)
- `deploy/docker-compose.yml`、各仓库 `.gitea/workflows/deploy.yml`、`Dockerfile`、`nginx.conf`:发布链路一手配置