前言
科研3.0系统前后端代码在一个工程里,代码仓库地址:https://gitlab.cmkn.cn/isrsp/researchplatform
新人开发入门:东篱智慧科研系统
适用对象:首次参与本项目的 Java / Vue 开发人员。命令是操作指南,不表示已在新机器完成启动验证。账号、租户配置及外部服务需要团队提供。
建议阅读顺序:本文 → AI 辅助开发实战教程 → 与任务相关的源码及专题文档。
1. 先理解这个系统
这是科研业务管理平台,覆盖人员、项目申报与立项、成果、经费、学科建设、科研诚信及审批流等业务。后端是一个 Spring Boot 应用装配多个 Gradle 模块,前端是 Vue 应用;这些模块不是分别启动的微服务。
项目的重要特点是“业务代码 + 配置共同决定行为”:
- 表单:动态组件与表单配置共同决定字段、校验、联动和展示。
- 列表:查询定义决定查询条件、返回列、SQL 和部分操作入口。
- 流程:Camunda 流程定义、业务处理器和业务单据状态共同参与审批。
- 租户:同一份代码在不同租户下可能加载不同的菜单、权限、表单和流程。
因此,“页面少一个字段”不一定需要新增 Vue 页面,“按钮看不到”不一定是前端 bug,“改了 BPMN”也不代表运行中的流程实例已经切换版本。
2. 第一周路线与交付物
| 阶段 | 要完成的事 | 完成标准 |
|---|---|---|
| 第一天 | 获取环境资料,导入工程,运行前端及后端或连接指定开发后端 | 能登录指定租户,说明请求实际发往哪里;记录未就绪的依赖 |
| 第二天 | 跟踪“关于”接口,再跟踪一个真实业务列表 | 能指出页面、模型、API、UseCase、数据来源及权限位置 |
| 第三天 | 阅读动态表单、查询定义和流程配置 | 能判断一个需求应该改代码、迁移还是租户配置包 |
| 第四天 | 在个人分支完成一个小需求并补充必要验证 | 提供最小差异、测试命令及实际结果 |
| 第五天 | 完成代码评审及测试环境验收 | 解释兼容性、权限、租户边界与未验证项目 |
入职时向导师获取:仓库及分支规范、JDK/Node 安装基线、依赖镜像访问方式、脱敏开发数据库、测试租户及各角色账号、租户配置包位置与版本、附件/文档转换等服务配置、提交和发布流程。仓库没有提供可直接依赖的统一 Docker Compose 新人环境;不要假定空数据库启动后就能完成所有业务操作。
3. 工程地图
| 路径 | 内容 / 从哪里看起 |
|---|---|
src/main/java/cn/net/keyan/research/Application.java |
应用入口,开启调度、异步及流程应用 |
src/main/resources/application*.properties |
公共和环境配置,使用前核实连接目标 |
modules/ |
业务模块,按领域及职责拆分 |
frameworks/ |
Payload、Id、上下文、权限、持久化及测试等基础能力 |
frontends/research.webui/ |
Vue 前端,从 src/main.ts、src/router/index.ts 阅读 |
src/main/resources/db/migration/ |
Flyway SQL 迁移;Java 迁移另在 src/main/java/db/migration/ |
src/main/resources/workflow/ |
BPMN 资源;运行时定义还需结合数据库和部署逻辑确认 |
gradle/libs.versions.toml |
后端依赖版本 |
gradle/config/scripts/、coverage.gradle |
构建、Checkstyle、测试和覆盖率约束 |
scripts/ |
检查、构建、发布及专项维护脚本,先读脚本再运行 |
docs/、documents/、CLAUDE.md |
专题文档与编码约定;示例和源码不一致时以当前实现为准 |
常用业务模块:
| 前缀 | 主要职责 |
|---|---|
iam / personnel |
账号、租户、权限 / 人员 |
basics |
基础设置、字典等公共业务 |
declaring / pm |
申报 / 项目管理 |
fm |
经费管理,包含拨款、预算、报销;不要将缩写理解为文件管理 |
om / academic |
科研成果 / 学术相关业务 |
orchestrating |
表单部署、业务流程编排与 Camunda 适配 |
querying |
配置化查询 |
dc / sri |
学科建设 / 科研诚信 |
importing / exporting |
导入 / 导出 |
notifying / openapi / dlsm |
通知 / 开放接口 / 商城对接 |
并非每个领域都有完全相同的四层目录,具体依赖看该模块 build.gradle。Gradle 项目名来自 settings.gradle:业务模块如 :pm.domain,基础模块如 :frameworks.test.postgres,前端为 :frontends.research.webui。
4. 环境准备与启动
4.1 版本和工具
| 工具 | 仓库依据 / 建议 |
|---|---|
| Java | JDK 17,见 gradle.properties;IDE 的 Gradle JVM 也设为 17 |
| Gradle | 使用仓库 ./gradlew,Wrapper 固定 7.6.1 |
| 后端 | Spring Boot 3.3.0、Camunda 7.21.0、Flyway 9.22.3,见版本目录;README 中旧版参考链接不是当前版本声明 |
| Node | 当前前端没有声明 engines 或统一 Node 版本;使用团队验证的版本,不根据 @types/node 推断运行版本 |
| Yarn | 前端 packageManager 指向 Yarn 1.22.22;优先保持现有 Yarn 工作流,不混用包管理器更新锁文件 |
| 数据库 | PostgreSQL;集成测试容器固定 postgres:15,实际开发库版本向团队确认 |
| Docker | 运行 Testcontainers 集成测试需要可用 Docker daemon 和镜像下载能力 |
在仓库根目录检查:
git status --short
java -version
./gradlew --version
node --version
yarn --version
docker info
首次 Wrapper、Gradle 依赖、前端依赖和容器镜像下载都需要网络。导入 IDE 时选择仓库根目录,等待 Gradle 同步;不要把单个业务模块当成独立工程。
4.2 后端:先准备连接,再启动
application.properties 和各 profile 文件包含数据库及外部服务配置。local 这个名字不保证所有依赖都在本机。请让导师提供独立开发环境配置,存于仓库外,不复制真实密码、私钥到文档或 AI 对话。
外置文件至少核实以下配置,按实际业务补齐附件、文档转换、SSO 等项:
# 示例占位,不能原样连接;使用团队提供的独立开发库
spring.datasource.url=jdbc:postgresql://<开发数据库主机>:5432/<数据库名>
spring.datasource.username=<开发数据库用户名>
spring.datasource.password=<开发数据库密码>
server.port=8081
外置配置会与仓库配置合并,不会自动清空其他已配置的外部服务。应用启用了调度和异步,启动前请确认使用的是隔离开发资源。Flyway 迁移也可能随启动执行,因此先确认目标库和初始化方案,不用共享生产库做入门练习。
在根目录运行,替换外置配置的绝对路径:
./gradlew bootRun --args='--spring.profiles.active=local --spring.config.additional-location=file:/绝对路径/researchplatform-dev.properties'
IDE 也可运行 cn.net.keyan.research.Application,传入相同的程序参数,工作目录设为仓库根目录。IDE 启动与 Gradle 资源生成行为可能不同;产品版本信息由根 build.gradle 的 generateVersionProperties 生成,不手动提交生成文件。
启动检查:日志出现应用启动完成、监听预期端口、数据库迁移无异常。默认关闭了 Actuator 端点,不要把 /actuator/health 返回 404 当作应用启动失败。账号、租户、授权、表单和流程初始化由导师提供;本文不约定默认管理员密码。
4.3 前端:明确选择联调目标
在前端目录安装依赖:
cd frontends/research.webui
yarn install --frozen-lockfile
若提示锁文件与依赖不一致,先核对所在分支和团队基线,不直接删锁文件或批量升级。
当前 vite.config.ts 的 /api 代理指向 QA,且没有启用路径重写。选择一种模式:
| 模式 | 配置方式 |
|---|---|
| 前端连接团队开发/QA 后端 | 核实 server.proxy['/api'].target 与测试租户;使用远端网关约定的路径 |
| 前后端均在本机 | target 改成 http://localhost:8081;按下方配置移除 /api 前缀 |
本机后端 Controller 路径通常不含 /api,例如 /about。直接代理到本机应用时使用:
'/api': {
target: 'http://localhost:8081',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
},
另一个重要检查点:Vite 注册了 mockServer(),它从 mock/ 读取配置并拦截匹配请求。做真实联调时,在个人工作区临时移除 plugins 中的 mockServer() 调用,并重启 Vite;不要只看到返回 200 就以为访问了后端。临时代理/Mock 调整不混入业务提交,恢复时保留自己和其他人的既有改动。
yarn dev
访问终端打印的地址。配置启用了自动打开浏览器,端口以实际输出为准。登录后通过浏览器 Network 和后端日志确认:请求到达预期服务,登录使用的是指定租户,数据来自真实接口。
5. 如何读懂一条业务链路
5.1 从“关于”功能开始
按以下顺序阅读,路径均相对仓库根目录:
frontends/research.webui/src/components/header/MainHeader.vue:展示字段。- 同目录
MainHeaderModel.ts、AboutInfo.ts:交互、加载与响应解析。 frontends/research.webui/src/boot/axios.ts:/api前缀、Bearer token、错误处理;成功响应直接返回response.data。modules/basics.gateways/src/main/java/cn/net/keyan/research/basics/gateways/ohs/AboutController.java:GET /about。modules/basics.application/src/main/java/cn/net/keyan/research/basics/application/GetAboutInfoUseCase.java:权限声明、当前租户、版本及授权信息组装。- 同目录
AboutInfo.java,以及modules/basics.application/src/test/java/cn/net/keyan/research/basics/application/下同名测试:输出和边界行为。
这个例子也说明:不要机械照抄历史文档中的签名,当前前端 AboutInfo.load() 是实例方法,当前后端 AboutInfo 位于 application 模块。
图表示常见调用协作,不表示 domain 可以反向导入 gateways。业务规则应放到合适的业务对象中,Controller 保持轻薄,application 协调用例,gateways 实现存储及外部系统适配。
5.2 再读动态表单、查询和流程
| 场景 | 起点 | 必须继续追踪 |
|---|---|---|
| 动态表单 | src/pages/customer-form/(前端) |
src/components/input/BaseInputModel.ts、src/components/dynamic-components.ts、表单部署配置及后端保存结构 |
| 配置列表 | modules/querying.gateways/.../ohs/QueriesController.java |
POST /queries/{id}/executions → ExecuteQueryUseCase → 查询工厂/执行器 → 目标租户查询定义 |
| 审批流程 | modules/orchestrating.* |
表单、流程定义、任务处理器、业务单据及历史记录;涉及操作时检查 WorkflowBusinessDataGuard |
| 数据字段 | 对应领域对象与 gateways 持久化实现 | 数据库列还是 JSON 内容、迁移、列表查询、导入导出及历史空值 |
这里的 ... 表示 Java 包路径,可按类名搜索,不是可复制的文件路径。优先用下面命令定位:
rg -n 'GetAboutInfoUseCase|class AboutInfo' modules frontends/research.webui/src
rg -n '目标字段名或接口片段' modules frontends/research.webui/src src/main/resources/db/migration
rg --files modules | rg 'QueryProcessSchedule|WorkflowBusinessDataGuard|QueriesController'
代码中找不到某租户的字段或查询时,先查配置归属。部分配置由独立租户配置包维护,应让导师确认仓库和发布方式;不要凭当前代码推定线上数据库内容。
6. 日常开发必须保留的约定
- 后端复用
Id、Payload、ObjectSink/ValueSinkFactory、@UseCase等框架能力;先找邻近实现和测试。 - 前端通过
boot/axios的api调接口,按实际返回结构解析。它已经解包成功响应,避免再习惯性读取一层.data。 - 默认从
GlobalUserContext获取当前用户和租户;跨租户和匿名入口按现有业务约定与授权检查处理,不能简单信任客户端 tenantId。 - 保持字段 key、绑定、默认值、顺序和历史空值兼容。金额规则与业务单据状态变化需追踪完整调用链。
- 前端按钮可见性不等于后端操作权限;两侧都要核对。
- SQL 迁移按
VYYYYMMDDHHMM__description.sql命名,版本精确到分钟并检查是否冲突。不修改已执行迁移来“修复”旧库,新增迁移并说明目标租户、影响范围与回退方案。 - 科研模块列表人员姓名从
personnel_persons获取;使用process-schedule-selector时同步核对QueryProcessSchedule#tableName()映射。 - 新增列表查询定义优先拆分到
query_definition_conditions、query_definition_fields、query_definition_parameters;字典选项优先复用dict+meta.type。完整要求见 科研模块开发约束。 - 流程变更要分别验证新实例和历史实例,不能只修改流程图;重启、撤回、资金退还等操作需要检查已有业务处理器。
7. 开发验证与提交
先运行受影响范围的检查,再在推送前完成仓库质量门禁。以下命令在根目录执行:
# 实际存在的测试类示例,任务名包含模块
./gradlew :basics.application:test --tests 'cn.net.keyan.research.basics.application.AboutInfoTest'
# 模块检查示例
./gradlew :basics.application:checkstyleMain :basics.application:checkstyleTest
# 仓库质量门禁(含 clean,耗时可能较长)
./scripts/check-all
# 资源充足时可改用 ./scripts/check-all-parallel
前端命令在 frontends/research.webui 执行:
# 单次运行;yarn test 默认进入监听模式
yarn test --run src/components/header/MenuTree.test.ts
yarn lint
yarn build
yarn coverage
后端 JaCoCo 根门禁对纳入统计的包要求指令、行、类、分支覆盖率均为 100%,排除项见 coverage.gradle。一个测试类通过不等于全模块或根门禁通过;不以增加排除项代替必要测试。只读取旧报告或用 -x test 复用旧执行数据,也不能证明本次修改通过了完整门禁。
报告常见位置:<模块>/build/reports/tests/test/、build/reports/allTests/、build/reports/jacoco/jacocoRootReport/。前端构建输出在 frontends/research.webui/dist/;后端打包可用 ./gradlew bootJar,产物位于 build/libs/。
scripts/build-all 不只是编译:还会清理用户主目录下匹配的旧 JAR/ZIP 并复制产物。新人本地验证优先使用上述检查和打包命令。package-all、push-all、deploy-* 属于交付流程,执行前按团队发布安排确认目标;CI 实际任务以 .gitlab-ci.yml 为准。
提交前:
git diff --check、git diff --stat,确认没有临时代理、账号配置、无关格式化或锁文件变更。- 只暂存本次任务文件,保留工作区已有改动。
- 使用仓库约定提交信息,例如
[docs]: 补充新人开发教程。 - 在评审说明里写清需求、改动、实际检查结果、是否需要迁移/配置部署及未验证项。
8. 常见问题排查表
| 现象 | 优先核对 |
|---|---|
| Gradle 同步/下载失败 | JDK 17、Wrapper 下载、依赖镜像网络、代理;不要先改依赖版本 |
| 前端有数据但本地后端没日志 | Mock 是否命中、代理是否仍指向 QA |
| 本机接口 404 | 浏览器 /api/about 是否被重写成后端 /about,后端端口是否一致 |
| 登录成功但没菜单/按钮 | 当前租户、账号角色、菜单和权限配置;不要直接放开鉴权 |
| 表单不随源码修改变化 | 实际表单部署、配置版本、组件注册和缓存;确认改的是当前租户使用的配置 |
| 流程图改了但实例没变化 | 实例使用的流程定义版本、部署记录、重启策略及历史数据 |
| Testcontainers 失败 | docker info、postgres:15 拉取、Docker 连接和容器日志 |
| 页面能打开但附件/报表失败 | SFTP、转换服务、实际请求状态及服务日志;页面启动不等于所有依赖就绪 |
| Flyway 校验或执行失败 | 首个异常、迁移版本/校验和、目标库基线;不直接执行 repair 或清空历史表 |
| 构建/测试全量失败 | 记录具体模块和首个失败;区分本次引入、既有失败、环境未就绪 |
验收记录要分开写:源码检查、单元测试、构建、浏览器操作、数据库迁移、外部服务联调。完成前几项不代表后几项也已验证。
9. 后续资料
- AI 辅助开发实战教程:按任务分阶段使用 AI,包含可复制提示词和练习。
- CLAUDE.md:架构、编码和导出功能约定;注意其中部分示例与当前代码存在差异。
- 科研模块开发约束:表单、查询、人员联表等要求。
- 数据库表中文映射:辅助定位业务表,实际结构仍需核对迁移和目标库。
- 查询汇总列表说明、组件文档:按具体需求阅读。
- AI 流程自动配置说明:系统业务功能说明,与开发人员使用 AI 编程的教程不同。
最后编辑:向海林 更新时间:2026-10-22 08:56