12 KiB
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-dependenciesBOM /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(本应用授权模块树, 经 SDKYschBaseOpenApi.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 | 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 | 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 提交,不改任何构建输入;其后同流水线再跑一次,结论与上表一致。