feat(skeleton): T1 后端工程骨架——fork flow-center 模板
build / build-push (push) Successful in 44s

- 包 com.yunhai.formcenter:config / controller(api|oapi) / entity / enums / model / repository / service / common
- pom:剥 aviator、加 easyexcel 3.3.2、finalName=form-center、surefire 收 *Test+*IT(CI 不跑单测→本地 mvn test 是门禁)
- FormBaseController 平移 FlowBaseController:/api/base/GetUserInfo + GetUserMod,新增可选 target appCode(H4 未上线→空树+warn,不回落本应用树)
- CORS 与 yml 分层照搬:jar 内只留本地最小默认,端口/ctx/DB/SSO/redis 由 projman env 注入;notice 的 upload-path 容器锚定教训注释原样抄入,FILE_PATH 本地兜底键保留
- 自验:mvn -o clean package BUILD SUCCESS + 7 单测全绿 + 本地启动 /actuator/health 200(/api/* 302 CAS 墙、/oapi/* 401 验签墙)
- docs/T1-report.md:产出说明 + 13 条问题单
This commit is contained in:
chenxing
2026-10-14 12:21:10 +08:00
parent c62f5d9187
commit 8c218b7271
15 changed files with 792 additions and 0 deletions
+113
View File
@@ -0,0 +1,113 @@
# T1 执行说明 · 表单中心工程骨架
> 任务书:《表单中心任务书-Qoder-20261014.md》v1.1 §T1|执行日期:2026-10-14|执行方:Qoder
> 前置事实:H1(projman 建项目)已完成——两仓已由 projman 注入 CI 与(后端)Dockerfile。
---
## 1. 做了什么
### 1.1 仓库与目录
| 仓 | 本地路径 | 远端 |
| --- | --- | --- |
| 后端 | `D:\SoftProject\yunhai\form-center\service` | `form-center/form-center-service.git` |
| 前端 | `D:\SoftProject\yunhai\form-center\front` | `form-center/form-center-front.git` |
两仓均为 **clone 既有远端仓**(非本地 init),projman 注入的 `.gitea/workflows/build.yml`、
`docker/Dockerfile`、`README.md` 天然在工作树与历史中,未被覆盖、未被删除。
### 1.2 后端(fork flow-center/service 骨架)
- **包结构** `com.yunhai.formcenter`:
- `config/FormCorsConfiguration`(平移 `FlowCorsConfiguration`,键名换 `form-center.cors.allowed-origins`)
- `controller/api/FormBaseController`(见下)
- `controller/oapi`(T4 落契约 §9 两个读端点,本任务先声明包)
- `entity/BaseEntity`(自增主键 + 审计四件套;`id` 绝不外露,对外身份是 uuid/code——契约 §1)
- `common/FormCenterAuditListener`、`enums`、`model`、`repository`、`service`
- 空包以 `package-info.java` 声明(javadoc 里写明该包 T2/T4 装什么、受哪条契约约束)
- **pom**:照 flow-center 模板(Boot 2.7.18 / JDK8 / `yh-platform-dependencies` BOM /
`yh-spring-boot-starter` 聚合 / `yh-appearance-spring-boot-starter` / data-redis / cas-client-core 3.5.1 /
mysql-connector-j / lombok / starter-test);**剥 aviator**;**加 `com.alibaba:easyexcel:3.3.2`**;
`finalName=form-center`;surefire 收 `*Test.java` + `*IT.java`(CI 不跑单测→本地 `mvn test` 是门禁)。
- **FormBaseController**:`GET /api/base/GetUserInfo`(会话用户)、`GET /api/base/GetUserMod`(本应用授权模块树,
经 SDK `YschBaseOpenApi.getUserModule`,只做字段改名不组树,与其他子应用同口径),
**新增可选 `appCode` 参数**:等于本应用/缺省→本应用树;指向其它应用→**空树 + warn 日志**(H4 未上线,见问题单 P3)。
- **application.yml 分层**(jar 内只留本地最小默认,生产值全部由 projman env 注入并被 env 压过):
- `server.port: 8086` 仅本地;不写 context-path(生产 `CONTEXT_PATH=/form-center`)
- datasource 指向本地 `bsch_formcenter`;`open-in-view: false`、`MySQL5InnoDBDialect`、时区 Asia/Shanghai
- **上传路径教训注释原样抄入**(notice/service 的「Linux 容器把 `D:/data/upload` 锚定成
`/app/D:/data/upload` 写进可写层,每次部署附件全丢」)+ 本地兜底键 `file.upload-path: D:/data/upload`
**未删**,并注明 T3 的读取形态 `${FILE_PATH:${FILE_UPLOAD_PATH:${file.upload-path:/data/upload}}}`
- `yh.sso`/`yh.app-auth`(本地占位身份 100021 + 带引号 secret + `/oapi/*` 强制验签 + trust-registry)/
`yh.open`(base-host 本地 UserBase;**明确禁止把 `services.userbase` 写进 jar**,沿用 2026-09-18 事故纪律)
- `management.health.redis.enabled: false`(Redis 抖动不得把 `/actuator/health` 拉 DOWN)
### 1.3 前端(仅工程壳)
`vite ^5` + `vue ^3.4` + TypeScript 最小壳:`index.html` / `src/main.ts` / `src/App.vue`(占位页)/
`src/env.d.ts` / `vite.config.ts`(`base: "./"`、dev 端口 8089)/ `tsconfig{,.node}.json` /
`.npmrc`(npmmirror)/ `.gitignore` / **`package-lock.json`**(CI 用 `npm ci`,必须有锁文件)。
脚本:`build = vite build`(CI 执行项)、`type-check = vue-tsc --noEmit`。
A 类 loader / view-ui-plus 1.3.24 / alova / router / layout 属 **T5**,本任务刻意未接。
### 1.4 环境动作(本机副作用,供知悉)
- 本机 MySQL 8.0.45(`D:\BaiduNetdiskDownload\mysql-8.0.45-winx64`)此前未运行,为完成「本地能启动」门禁
**已拉起**(`--defaults-file=my.ini`,端口 3306),并 **新建库 `bsch_formcenter`**(utf8mb4 / utf8mb4_general_ci)。
两者均为本地开发环境常规动作;服务验证完未关,如需释放内存自行停止即可。
- 未启动 CAS(8443)/UserBase(8060)/Redis,未触碰 160 共享环境(只做过一次只读可达性探测)。
---
## 2. 自验证据
| # | 门禁 | 命令 | 结果 |
| --- | --- | --- | --- |
| 1 | 后端编译+打包+单测 | `mvn -B -o clean package`(离线,本地仓库 `D:\SoftProject\yunhai\.m2`) | **BUILD SUCCESS**,`target/form-center.jar`(finalName 生效);`Tests run: 7, Failures: 0, Errors: 0` |
| 2 | 本地启动 | `java -jar target/form-center.jar --server.port=8086` | `Started FormCenterApplication in 9.472 seconds`;HikariPool-1 Start completed;`Initialized JPA EntityManagerFactory` |
| 3 | 健康探活 | `curl --noproxy '*' http://localhost:8086/actuator/health` | **HTTP 200** `{"status":"UP"}` |
| 4 | 鉴权墙(用户面) | `curl http://localhost:8086/api/base/GetUserInfo` | HTTP 302 → `http://localhost:8443/login?service=...%2Fapi%2Fbase%2FGetUserInfo`(`yh.sso.url-pattern=/api/*` 生效,`/api/appearance` 同墙) |
| 5 | 验签墙(对外面) | `curl http://localhost:8086/oapi/form/schema` | HTTP **401**(`yh.app-auth.server.enforce-patterns: [/oapi/*]` 生效) |
| 6 | 前端构建 | `npm run build` | **✓ built**,`dist/index.html` + `dist/assets/*`(zip 根含 index.html,满足 projman 前端发布要求) |
| 7 | 前端类型检查 | `npm run type-check`(vue-tsc --noEmit) | 无报错 |
| 8 | CI | 见 §4(推送后回填) | — |
单测覆盖(`FormBaseControllerTest`,7 条,全部脱网/脱库可跑):
`toFrontendTree` 保层级与字段改名 / `modId` 取数字 custom_id / `children` 恒为数组 / 非数字 customId
(`fc:scope:all` 权限锚点,path 为空)回退主键且不炸 / null 与空入参不抛 NPE /
`isForeignTarget` 判定(null·空白·本应用·大小写·其它 appCode)/
**target appCode 命中时返回空树且不触碰 SDK**(单测里 SDK 静态客户端未装配,误走本应用分支会直接抛异常)。
未达成项:**「GetUserInfo 返回会话用户」的登录态冒烟**——本地 CAS(8443) 与 UserBase(8060) 未启动,
且 GetUserMod 出树还依赖 H2(UserBase 的 form-center 应用行 + 模块行,用户侧待办)。
按任务书 §0.1 规则①记缺口继续,取证改由上表 #3/#4/#5 + 单测承担 → 问题单 P1。
---
## 3. 问题单(本轮登记,供执行手册 §5 裁决)
| # | 问题 | 本轮取值(最保守解读) | 影响面 |
| --- | --- | --- | --- |
| P1 | 任务书 T1 自验含「GetUserInfo 返回会话用户」,本地无 CAS/UserBase 实例,且 H2 应用行未建 | 不停顿;以 health 200 + `/api/*` 302 CAS 墙 + `/oapi/*` 401 墙 + 7 条单测替代取证。一键脚本已核实存在:`D:\c\脚本执行\cas\start-server.bat`、`D:\c\脚本执行\userbase\start-jar.bat`(jar 已构建),需要登录态时在 T2/T5 联调轮补跑 | 仅取证强度,不改设计 |
| P2 | target 参数名口径不一:执行手册 §1 写「可选 target **appKey**」,任务书 T1 与 H4 任务书写「**appCode**」 | 取 **appCode**(与 H4 的 UserBase `/oapi/user/modules` 参数、契约 §1 归属列 `app_code` 一致) | 参数名,前端 T8 需按此对齐 |
| P3 | SDK 无目标应用形态:`javap` 实测 `YschBaseOpenApi` 只有 `getUserModule(int userId, Integer schId)` | H4 未上线前,`appCode` 指向其它应用一律**空树 + warn**,不回落本应用树(回落会把「要 A 的菜单」伪装成「A 就这些菜单」);H4 上线后消费范式=`YschOpenCall.raw()` 直调(SDK 不动) | 快应用上下文 T8/T9 前置 |
| P4 | `appCode` 只加在 GetUserMod:GetUserInfo 无「树」语义,任务书把两端的参数写在一起 | 只 GetUserMod 加参数(T8 原文「模块树经 FormBaseController 带 target appCode」与此一致) | 无 |
| P5 | `entity/BaseEntity` 审计四件套含 `create_by/update_by`,契约 §10 DDL 草案九表只列 `create_time/update_time` | 保留基类形态(任务书 §0.4「实体继承 BaseEntity」+ 模板平移纪律);`ddl-auto=update` 会在自动建表时多两列 | 若 DDL 草案为唯一权威,T2 前需裁决:补列 or 精简基类 |
| P6 | 端口/身份号未在文档中为 form-center 定死(生产容器端口只从注入的 Dockerfile `EXPOSE 10020` 可见) | 本地 dev:service **8086**、front **8089**(顺延 notice 8101/8077、svc-hall 8087、flow-center 8085/8088);yml 不写生产端口,由 `SERVER_PORT`/`CONTEXT_PATH` env 注入 | 仅本地联调约定 |
| P7 | 本地占位 appKey 号段:100018=svc-hall、100019=flow-center、100020=work-leave(实测各仓 yml) | 取 **100021** + `app-secret: "form-center-dev-secret-100021"`(带引号防八进制解析);真实身份需 UserBase 注册后由 projman 注入,仓库内不落真凭据 | 上线前替换项 |
| P8 | `trusted-apps` 本地白名单暂无内容可列 | 先列 svc-hall/flow-center 两号(与 flow-center 本地兜底同口径);本应用 `/oapi` 的真实消费方在 T4 出现时补 | T4 |
| P9 | maven-compiler-plugin 3.10.1 对「只含 package-info.java 的包」打印 `[WARNING] Error creating missing package info classes`(NoSuchFileException,非致命,BUILD SUCCESS) | 不为此升插件版本(CI 用 `maven:3.6.3-jdk-8`,插件升级有依赖解析风险);T2 起这些包落入真实类即消失 | 观感/日志噪声 |
| P10 | 本地 MySQL 是 8.0.45,方案 §7 要求 **MySQL 5.7 兼容 SQL** | 用 `MySQL5InnoDBDialect` + utf8mb4;本地 8.0 跑通**不能**证明 5.7 兼容,T2 起 DDL/查询需按 5.7 复核(160 生产版本仍待核,见手册 §4.3) | T2~T4 |
| P11 | 前端壳未接平台约定(A 类 loader / view-ui-plus 1.3.24 / alova / router / layout) | 属 T5 范围,T1 只保 `npm ci + npm run build` 绿;`base: "./"` 已按 notice/flow-center 口径设好,保证 `/form-center/` 挂载可取静态资源 | T5 |
| P12 | 上传相关 yml 只落键、未落 `spring.servlet.multipart` 上限 | 属 T3 上传模块范围;**记档**:Spring 默认 `max-file-size=1MB` 会挡住契约 §3 的 ≤50MB 附件,T3 必须显式配 | T3 |
| P13 | 首推纪律写的是 `git merge origin/main --allow-unrelated-histories`(适用于本地 init 后合入注入文件) | 实际采用 clone,注入提交已在历史里,merge 为 `Already up to date` 空操作;**未用** `git reset` / `git add -A`,暂存按显式路径 | 无 |
---
## 4. 推送与 CI(回填位)
| 仓 | 提交 | 推送 | CI run | 结论 |
| --- | --- | --- | --- | --- |
| form-center-service | 待回填 | 待回填 | 待回填 | 待回填 |
| form-center-front | 待回填 | 待回填 | 待回填 | 待回填 |