Files

120 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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(推送后回填) | **两仓 main 各自 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 | `8c218b7` | `c62f5d9..8c218b7 main -> main` | [run 1456](http://192.168.10.160:3000/form-center/form-center-service/actions/runs/1456) | **completed / success**(6 步全绿:装 git-curl → 手动 clone 源码 → maven 容器构建 jar → docker build + push Nexus → 通知 projman 建档;「可选清空 m2 缓存」按 workflow_dispatch 默认 skipped) |
| form-center-front | `cebc32f` | `fd28372..cebc32f main -> main` | [run 1457](http://192.168.10.160:3000/form-center/form-center-front/actions/runs/1457) | **completed / success**(6 步全绿:装 git-curl-zip → clone → node:20 `npm ci` + `npm run build` → dist 打 zip → 上传 Nexus `front-hosted` → 通知 projman 建档) |
首推纪律:两仓均在 push 前跑过 `git merge origin/main --allow-unrelated-histories`,
因采用 clone 而非本地 init,注入提交已在历史中,merge 返回 `Already up to date`(问题单 P13);
未使用 `git reset`,暂存按显式路径逐个 `git add`。
> 本节的回填本身是一次 docs-only 提交,不改任何构建输入;其后同流水线再跑一次,结论与上表一致。