Skip to content

hc-hire-center 项目结构与新手上手指南

适用项目:/Users/admin/code/hc-project/api-java/hc-hire-center
分析日期:2026-07-16
项目规模:649 个有效项目文件,其中 573 个代码文件、57 个配置文件、18 个 SQL 文件、1 个说明文档
说明:当前目录不是 Git 仓库,因此本文无法关联具体提交号;内容以分析当日的本地源码为准。

1. 先用一句话理解项目

hc-hire-center 是欢创招聘中心后端服务,围绕以下三条业务主线展开:

  1. candidate:候选人简历、人才库、导入、检索、权限、版本与附件。
  2. position:职位、职位参与人、供应商、登记、申请审批与职位下推荐。
  3. reco:候选人推荐后的跟进流程,包括沟通、面试、Offer、入职和过保。

它不是一个可以脱离公司基础设施独立运行的演示项目。项目依赖欢创内部 hc-* starter、Maven 私服、配置中心、租户和用户上下文,以及 PostgreSQL、Redis、Elasticsearch、XXL-Job、OSS 和多个内部微服务。

2. 技术栈速览

类别项目中的实际技术
语言与构建Java 8、Maven 多模块
Web 框架Spring Boot、Spring MVC、Spring Cloud 服务发现、内部 hc-starter-web
持久化PostgreSQL、MyBatis-Plus、内部 IHcService / IHcServiceImpl
对象转换MapStruct、Lombok
搜索Spring Data Elasticsearch、内部 hc-starter-es
缓存与锁Redis、内部 hc-starter-cacheRedisLockUtil
调度XXL-Job、Spring Scheduling
文件租户动态 OSS
远程调用内部 Feign、租户中心、项目中心、流程中心等 API Client
接口文档Swagger 2 注解
其他PDFBox、简历解析第三方 API、邮件和浏览器插件导入

3. Maven 模块

text
hc-hire-center/
├── pom.xml
├── hc-hire-center-api/
│   └── pom.xml
└── hc-hire-center-service/
    ├── pom.xml
    └── src/main/
        ├── java/com/hc/hire/
        └── resources/

3.1 根模块 hc-hire-center

pom.xml 的 packaging 是 pom,负责聚合两个子模块,并统一指定 Java 8。它继承内部父 POM:

text
com.hcframework.boot:hc-boot-starter:1.0.0-SNAPSHOT

这个父 POM 在公司 Maven 私服中。没有私服凭证时,Maven 在读取项目模型的第一步就会失败。

3.2 hc-hire-center-api

按命名习惯,这个模块应承载可供其他服务依赖的 Feign Client、Form、DTO、VO 或接口契约。但在当前源码快照中,它只有 pom.xml,没有 Java 源码。

新人需要注意:不要因为模块名中有 api,就去这里寻找当前系统的 Controller 或请求对象。现有业务代码全部在 hc-hire-center-service 中。

3.3 hc-hire-center-service

这是实际可运行模块,包含:

  • Spring Boot 启动类;
  • Web Controller;
  • 业务 Service;
  • Entity、Mapper 和 SQL;
  • Elasticsearch Document 与 Repository;
  • XXL-Job 任务;
  • OSS、Feign 和第三方 API 适配;
  • HTTP 手工调试请求。

4. 运行时架构

mermaid
flowchart LR
    Client[前端或外部调用方] --> Gateway[网关与认证]
    Gateway --> Controller[Controller]
    Controller --> Service[业务 Service]
    Service --> Permission[数据权限服务]
    Service --> Mapper[MyBatis Mapper]
    Mapper --> PG[(PostgreSQL)]
    Service --> ES[(Elasticsearch)]
    Service --> Redis[(Redis)]
    Service --> OSS[(租户 OSS)]
    Service --> Remote[内部 Feign/API Client]
    Remote --> Tenant[租户中心]
    Remote --> PMS[项目中心]
    Remote --> Process[流程中心]
    Job[XXL-Job] --> Service

大多数同步 HTTP 请求遵循下面的调用方向:

text
Controller -> Service 接口 -> ServiceImpl -> Mapper -> PostgreSQL
                        |          |
                        |          +-> Elasticsearch / Redis / OSS
                        +------------> 内部服务网关或第三方 API

Controller 不直接写数据库。跨系统调用通常再包一层项目内 Gateway Service,以免核心业务代码直接依赖外部系统的 Form 和 VO。

5. 业务包怎么读

hc-hire-center-service/src/main/java/com/hc/hire 下有 5 个一级区域:

规模主要职责
candidate251 个 Java 文件候选人主数据、简历、人才库、导入、ES 检索、权限和版本
position203 个 Java 文件职位主数据、项目关联、参与人、供应商、登记、审批和职位推荐
reco90 个 Java 文件推荐记录、跟进状态机、面试、Offer、入职、保证期和业绩拆分
common11 个 Java 文件公共常量、第三方策略框架、通用 OSS 文件服务
config3 个 Java 文件业务编码、Elasticsearch 扩展和 RestTemplate 配置

5.1 candidate:候选人领域

主要能力包括:

  • 手工录入和编辑候选人;
  • 批量、Excel、扫码、邮箱、浏览器插件和外部接口导入;
  • 候选人工作、项目、教育、语言、技能等简历板块;
  • 候选人查重、完整度、保护期、版本快照和回滚;
  • 人才库、我的候选人、收藏、预览、备注、标签和黑名单;
  • 供应商维度的数据权限;
  • PostgreSQL 到 Elasticsearch 的同步、失败记录和补偿任务;
  • 简历附件上传 OSS、预览和下载;
  • 候选人加入职位并生成推荐记录。

阅读起点:

text
candidate/controller/web/client/CandidateManualController.java
candidate/service/CandidateManualService.java
candidate/service/impl/CandidateManualServiceImpl.java
candidate/service/impl/CandidateLifecycleServiceImpl.java
candidate/entity/HireCandidate.java

5.2 position:职位领域

主要能力包括:

  • 职位新增、编辑、详情、暂停、结束、显示和置顶;
  • 职位与外部项目、客户、产品、项目人员的关联;
  • 招聘负责人、交付负责人、顾问等职位参与人;
  • 职位供应商、供应商管理人转移和保证期配置;
  • 申请加入职位及流程中心审批;
  • 面试登记配置、扫码令牌和登记结果;
  • 职位附件、备注和职位下的候选人推荐;
  • 简历下载、导出、面试结果导入等异步任务。

阅读起点:

text
position/controller/web/client/PositionController.java
position/service/PositionService.java
position/service/impl/PositionServiceImpl.java
position/service/PositionDataPermissionService.java
position/service/impl/PositionDataPermissionServiceImpl.java
position/entity/HirePosition.java

5.3 reco:推荐跟进领域

reco 不是“推荐算法”模块,而是候选人被推荐到某个职位之后的业务过程。核心记录是 HireReco,跟进阶段大致为:

text
初步沟通
  -> 推荐
  -> 预约面试
  -> 到场
  -> 面试通过
  -> 接 Offer
  -> 入职
  -> 过保

每一步都存在否决、放弃、不到场、不通过、不过保或回退等分支。合法流转由 RecoFollowStateServiceImpl 校验,不应在 Controller 或其他 Service 中自行拼接状态编码。

阅读起点:

text
reco/controller/web/client/RecoController.java
reco/service/RecoService.java
reco/service/impl/RecoServiceImpl.java
reco/service/RecoFollowStateService.java
reco/service/impl/RecoFollowStateServiceImpl.java
reco/enums/HireFollowStageEnum.java
reco/enums/HireFollowActionEnum.java

6. 每个业务包内部的技术分层

目录放什么新手常见误区
controllerHTTP 路由、参数接收、校验、统一结果封装不要在这里写事务和复杂业务
form新增、编辑、查询等入参它不是数据库 Entity
dto服务间或内部步骤的数据载体DTO 不一定直接返回给前端
vo返回前端的展示对象不要直接把 Entity 当完整响应
service业务接口、领域能力定义接口用于表达能力,不只是为形式而存在
service/impl事务、编排、权限、状态变化和外部调用复杂度主要集中在这里
entityMyBatis-Plus 数据库实体字段和表结构必须保持一致
mapper数据访问接口简单 CRUD 通常继承基础 Mapper,不需要 XML SQL
converterMapStruct 的 Form/DTO/Entity/VO 转换新字段增加后要检查映射是否被忽略
documentElasticsearch 索引文档与数据库 Entity 不是同一个一致性边界
repositoryElasticsearch Repository不是 PostgreSQL Mapper
enums稳定业务编码与状态不要在调用处散落魔法数字
constants业务常量、状态流转表、路径等修改会影响多个流程,应搜索全部引用
taskXXL-Job 任务多实例执行时需要分布式锁或幂等
processor导入框架处理器由内部导入 SDK 的工厂发现和调用

7. 项目特有的框架约定

项目大量能力来自私有 hc-* starter。只熟悉标准 Spring Boot 时,下面这些类型最容易让人困惑。

7.1 Controller 约定

java
@WebClientRestController("/candidate/manual")
public class CandidateManualController
        extends BaseController<HireCandidate, CandidateManualService> {
}
  • @WebClientRestController 是内部路由注解,承担标准 @RestController 加客户端路由语义。
  • BaseController<E, S> 提供统一 Service 注入等基础能力。
  • 返回值统一使用 Result<T>
  • 列表分页常使用 @QueryPageQueryModelQueryResultModel<T>
  • 外部开放接口可以直接使用标准 @RestController,例如 CandidateExternalPushController

注解中声明的是服务内路由。线上完整 URL 还可能包含网关前缀,必须以网关配置或实际 Swagger 为准。

7.2 Service 与 Mapper 约定

常见继承关系是:

java
public interface XxxService extends IHcService<XxxEntity> {
}

public class XxxServiceImpl
        extends IHcServiceImpl<XxxMapper, XxxEntity>
        implements XxxService {
}

它们在 MyBatis-Plus 的基础上提供公司统一能力。因此:

  • 常规 saveupdateByIdgetByIdlist 不需要重复写 Mapper 方法;
  • 复杂联表查询会使用 MPJLambdaWrapperHcMPJLambdaWrapper
  • 少量定制 SQL 放在 resources/mapper/*.xml
  • 当前多数 Mapper XML 只是空骨架,SQL 主要来自基础 Mapper 和 Wrapper。

7.3 用户和租户上下文

业务代码通过以下上下文获取当前身份:

text
UserContext.getOpenId()
UserContext.getUser()
TenantContextHolder.getTenantId()

这意味着直接调用 Service、用普通 MockMvc 发请求或绕过公司网关时,如果没有构造用户和租户上下文,常见结果是“当前用户未登录”或“租户信息不能为空”。不要为了本地跑通而删除这些校验。

8. 三条最值得跟读的调用链

8.1 手工录入候选人

入口:POST /candidate/manual/save

text
CandidateManualController.saveCandidate
  -> CandidateManualService.saveCandidate
  -> CandidateManualServiceImpl.saveCandidate
       1. CandidateDuplicateService:手机号/邮箱查重
       2. CandidateLifecycleService.initializeForCreate:租户、创建人、保护期、默认值、候选人编号
       3. 保存 HireCandidate 主表
       4. 保存残障、意向、工作、项目、教育、语言、技能等子表
       5. CandidateLifecycleService.afterCreated
            -> 刷新简历完整度
            -> 创建版本快照
            -> 同步 Elasticsearch
       6. 特殊候选人按规则自动推荐

这个流程能一次看懂项目中的 Form、Converter、Entity、事务、子表 Service、生命周期和 ES 同步。

8.2 候选人 PostgreSQL 与 Elasticsearch 一致性

text
业务事务修改 PostgreSQL
  -> CandidateLifecycleService.afterChanged
  -> CandidateSyncService.incrementalSync / syncAfterCommit
  -> CandidateDocumentConverter
  -> CandidateSearchRepository
  -> Elasticsearch

同步失败时不会回滚已经提交的 PostgreSQL 主事务,而是记录到 hire_candidate_es_sync_failEsSyncCompensateTask 通过 XXL-Job 定期补偿,并使用 Redis 分布式锁避免多个实例重复执行。

理解这个边界很重要:

  • PostgreSQL 是候选人主数据源;
  • Elasticsearch 是查询索引,不应被当作唯一数据源;
  • 新增候选人字段后,要同步检查 Entity、Document、Converter、查询条件和全量同步;
  • 修改事务代码时,要注意同步是在提交前还是提交后触发。

8.3 推荐跟进状态机

text
RecoController.submitFollow
  -> CandidateFollowService.submitFollow
  -> RecoFollowStateService.validateStageTransfer
  -> RecoFollowStateService.resolveAction
  -> RecoFollowBusinessService.saveBusinessData
  -> 保存 HireFollowRecord
  -> 更新 HireReco 当前阶段和状态

核心规则分散在:

  • HireFollowStageEnum:有哪些阶段,哪些是结束阶段,哪些允许再次推荐;
  • HireFollowActionEnum:有哪些动作;
  • CandidateFollowConstant:前进和回退阶段映射;
  • RecoFollowStateServiceImpl:合法性校验和动作解析;
  • RecoFollowBusinessServiceImpl:不同动作产生的面试、Offer、入职、保证期等业务明细。

修改流程时不能只改一个枚举。至少要同时核对状态映射、业务明细、列表展示、ES 文档和历史数据兼容性。

9. 职位模块的外部系统边界

职位并不拥有所有相关主数据。项目、客户、产品、部门成员、供应商和审批流来自其他中心。项目通过 Gateway Service 把外部类型隔离在边界处:

项目内边界外部依赖
PositionProjectGatewayService项目中心、部门成员 API
PositionApplyApprovalGatewayService流程中心流程模型、实例和审批详情 API
ExternalSupplierGatewayService租户中心供应商与成员 API
PositionProjectManageService项目中心招聘入口项目管理 Feign Client

新增跨服务逻辑时,优先扩展 Gateway 接口和默认实现,不要让核心 PositionServiceImpl 到处直接引用外部系统 Form/VO。这样更容易测试,也能避免外部契约变化污染整个领域。

10. 数据层与表结构

主数据库是 PostgreSQL,数据库名配置为 hc_hire_center。Entity 使用 @TableName 显式映射,核心表可按领域理解:

候选人

text
hire_candidate
hire_candidate_work
hire_candidate_project
hire_candidate_education
hire_candidate_language
hire_candidate_skill
hire_candidate_intention
hire_candidate_file
hire_candidate_version
hire_candidate_collection
hire_candidate_remark
hire_candidate_blacklist
hire_candidate_es_sync_fail

职位

text
hire_position
hire_position_person
hire_position_supplier
hire_position_supplier_warranty
hire_position_apply
hire_position_file
hire_position_remark
hire_position_register
hire_position_register_submit
hire_position_scan_token
hire_position_reco_task
hire_position_reco_result

推荐跟进

text
hire_reco
hire_follow_record
hire_interview_arrangement
hire_offer
hire_onboarding
hire_guarantee_period
hire_supplier_guarantee_period
hire_performance_splitting
hire_reco_comm

src/main/resources/sql 中只有 2026 年 5 月的一组增量脚本,不包含完整基线建库脚本。新人本地建库前必须向团队确认:

  1. 基线数据库从哪里初始化;
  2. 这些 SQL 是否由 Flyway、发布平台还是人工按顺序执行;
  3. 当前环境已经执行到哪个版本;
  4. 租户字段、逻辑删除字段和审计字段的统一约定。

不要看到 CREATE TABLE IF NOT EXISTS 就默认这些文件足以创建完整数据库。

11. 配置文件怎么理解

11.1 application.yml

主要包含:

  • 服务端口 7007
  • Maven 过滤后的应用名;
  • 动态租户数据源;
  • PostgreSQL 连接占位符;
  • Elasticsearch;
  • Swagger;
  • XXL-Job;
  • SaaS 多租户;
  • 简历解析和浏览器插件配置。

11.2 nacos-application.yml

内容与运行时业务配置高度重合,表明项目配置可能通过 Nacos 或公司配置体系下发。启动前要向团队确认实际加载顺序和环境 Data ID,不能只修改本地 YAML 后就认为配置一定生效。

11.3 当前配置的安全与正确性注意事项

当前源码配置中存在明文敏感信息或带默认值的凭证。本文不会记录这些值。正确做法是:

  • 把密钥放到环境变量、Nacos Secret 或发布系统密文变量;
  • 不在文档、日志和截图中传播真实值;
  • 如果这些值已经进入版本历史,应按安全流程轮换,而不是只删除当前文件内容;
  • 本地调试使用独立的开发环境凭证。

另外,当前 application.yml 中出现重复的顶级 spring 节点。不同 YAML 解析策略可能覆盖前一个节点或直接报重复 key,修改配置前应先确认最终生效结果并合并节点。

Swagger 配置的扫描包是 com.hc.hire.controller,但实际 Controller 位于 com.hc.hire.candidate.controllercom.hc.hire.position.controllercom.hc.hire.reco.controller。如果 Swagger 页面为空,首先检查这个 base-package 是否覆盖实际包路径。

12. 本地环境准备

12.1 必需软件

软件或服务建议/项目要求
JDKJava 8;当前项目编译目标为 1.8
Maven3.8+;本次验证使用 3.9.9
IDEIntelliJ IDEA,并启用 Lombok annotation processing
Maven 私服需要访问公司阿里云 Maven 仓库并配置凭证
PostgreSQL需要可用的 hc_hire_center 基线库
Redis动态租户、缓存和分布式锁依赖
Elasticsearch候选人和推荐搜索依赖
Nacos/注册中心服务发现和环境配置依赖
XXL-Job补偿任务等调度依赖
OSS简历和职位附件依赖

12.2 先解决 Maven 私服

根 POM 的仓库 ID 是 hcjt。请从团队获取正确的 Maven settings.xml,并确保 <server><id> 与 POM 一致:

xml
<settings>
    <servers>
        <server>
            <id>hcjt</id>
            <username>由团队提供</username>
            <password>由团队提供或使用加密配置</password>
        </server>
    </servers>
</settings>

不要把个人账号和密码写进项目 POM。

检查环境:

bash
java -version
mvn -version
mvn -DskipTests package

本次实际构建在解析 hc-boot-starter:1.0.0-SNAPSHOT 时收到私服 401,因此没有完成编译。这不是 Java 源码编译错误,而是当前机器缺少有效的私服授权。

12.3 准备环境配置

至少确认以下配置由本地环境、Nacos 或发布平台提供:

text
spring.application.name
spring.database.host
spring.database.port
spring.database.username
spring.database.password
spring.redis.host
spring.redis.port
spring.elasticsearch.rest.*
XXL-Job 执行器配置
OSS 租户配置
内部 SDK/Feign 地址和认证配置

还要确认依赖的租户中心、项目中心和流程中心在当前环境可访问。

12.4 启动方式

私服、数据库和中间件准备完成后,可从根目录尝试:

bash
mvn -pl hc-hire-center-service -am spring-boot:run

也可以在 IDEA 中运行:

text
com.hc.hire.HireApplication

启动类启用了:

text
@SpringBootApplication
@EnableScheduling
@EnableHcFeign
@EnableAsync
@EnableDiscoveryClient
@ComponentScan("com.hc")

默认服务端口是 7007。看到“招聘中心启动成功”只说明 Spring 容器完成启动,不代表数据库、ES、Redis、Feign 和 XXL-Job 的全部业务链路都已经验证。

13. 如何调接口

src/main/resources/http 下有一组 IntelliJ HTTP Client 文件,覆盖:

  • 候选人邮箱;
  • 外部推送;
  • 候选人附件;
  • 候选人跟进与操作;
  • 浏览器插件;
  • 人才库和我的候选人;
  • 报告;
  • 简历导入;
  • 第三方 API 策略框架。

这些是手工调试样例,不是自动化测试。使用前要:

  1. 替换环境地址;
  2. 使用开发环境的认证信息;
  3. 补齐网关要求的租户和用户上下文;
  4. 避免把真实手机号、简历和 Token 提交到仓库;
  5. 核对 URL 是否还需要网关前缀。

当前项目没有 src/test 下的自动化测试。修改核心状态流转、权限或同步逻辑时,不能只依赖这些 .http 文件,至少应补充 Service 单元测试或集成测试。

14. 新增一个功能时的标准落点

假设要给候选人增加一个可编辑字段,建议按下面顺序检查:

  1. 数据库:新增有序、幂等的 SQL 迁移,确认类型、默认值、索引和注释。
  2. Entity:更新对应 Hire* 实体。
  3. Form:在新增/编辑请求对象中增加字段和校验注解。
  4. VO/DTO:确认列表、详情、导出或跨服务对象是否需要该字段。
  5. Converter:检查 MapStruct 映射,尤其项目普遍配置了 unmappedTargetPolicy = IGNORE,漏映射不会总是编译失败。
  6. Service:把业务规则、权限和事务写在 ServiceImpl,不放进 Controller。
  7. Mapper/查询:确认 Wrapper、联表查询和 XML 是否需要选择该字段。
  8. Elasticsearch:如果字段参与搜索,更新 Document、Converter、索引 mapping、查询和全量同步。
  9. 版本快照:候选人编辑是否要生成版本记录、支持比较和回滚。
  10. 数据权限:是否受创建人、保护人、供应商或职位角色约束。
  11. 接口样例和测试:更新 .http,并为核心规则补自动化测试。
  12. 发布清单:写明 SQL、配置、索引重建、任务和回滚步骤。

15. 复杂度热点

下面这些文件行数大、依赖多或处于关键一致性边界,新人第一次改动前应先画出调用链:

文件约行数为什么复杂
position/service/impl/PositionServiceImpl.java891职位主流程、多个子表、权限和外部项目数据编排
candidate/service/impl/CandidateManualServiceImpl.java841候选人主表和大量简历子表的创建、编辑与替换
candidate/service/impl/ResumeImportServiceImpl.java732多种导入来源、解析、查重、附件和失败处理
position/service/impl/PositionRecoServiceImpl.java728职位下候选人加入、推荐、批量动作和任务
position/service/impl/PositionPersonServiceImpl.java701多角色参与人、权限和转移规则
candidate/service/impl/CandidateRecommendServiceImpl.java603推荐资格、重复推荐、职位和候选人联动
position/service/impl/PositionApplyServiceImpl.java567本地申请状态与外部流程中心状态一致性
candidate/service/CandidateSyncService.java501PostgreSQL、ES、失败补偿和事务提交边界
reco/service/impl/RecoFollowBusinessServiceImpl.java412一个状态动作可能写入多类业务明细
position/service/impl/PositionDataPermissionServiceImpl.java392管理员、职位角色、项目角色和供应商角色组合权限

修改这些文件时优先使用以下办法降低风险:

  • 从 Controller 或任务入口反向确定真实调用者;
  • 搜索接口和实现的全部引用;
  • 列出事务内外的数据库、ES、OSS 和远程调用;
  • 明确失败后的补偿或回滚策略;
  • 对状态和权限建立表驱动测试;
  • 避免在已有大类中继续堆叠无关职责。

16. 常见问题排查

16.1 Maven 一开始就报 Non-resolvable parent POM401

原因通常不是代码,而是没有正确配置 hcjt 私服凭证、账号无权限或公司网络不可达。先解决 settings.xml 和仓库访问,再看编译错误。

16.2 spring.application.name 显示成 @artifactId@

这是 Maven resource filtering 占位符。确认从 Maven 构建后的资源启动,或确认 IDE 已执行 Maven 资源过滤。不要把错误的应用名注册到服务发现。

16.3 启动时报数据库或 Redis 占位符无法解析

本地 YAML 依赖环境配置。确认 Nacos 加载、环境变量和启动 profile,而不是在源码中硬编码生产连接信息。

16.4 接口总是提示未登录、无租户或无权限

请求没有经过正确网关,或没有建立 UserContextTenantContextHolder。也可能是当前用户不在数据权限服务计算出的可见范围内。

16.5 Swagger 页面没有接口

先检查 Swagger base-package 是否覆盖实际的三个业务 Controller 包,再检查内部 @WebClientRestController 是否被 Swagger 配置识别。

16.6 数据库有数据,但列表搜索不到

候选人和推荐列表可能走 Elasticsearch。检查:

  1. PostgreSQL 事务是否成功;
  2. 增量同步是否触发;
  3. hire_candidate_es_sync_fail 是否有失败记录;
  4. XXL-Job 补偿任务是否启用;
  5. ES 索引和 mapping 是否与 Document 一致;
  6. 当前租户和数据权限过滤条件。

16.7 修改状态后出现“不允许流转”

不要直接改数据库状态。检查当前阶段、目标阶段、前进/回退/停留方向,以及 CandidateFollowConstantRecoFollowStateServiceImpl 的映射。

17. 推荐的新手阅读路线

第 1 阶段:先看项目怎么启动

text
pom.xml
hc-hire-center-service/pom.xml
HireApplication.java
application.yml
nacos-application.yml

目标:知道项目依赖什么、配置从哪里来、为什么不能脱离公司环境直接运行。

第 2 阶段:跟一条最典型的 CRUD 加业务规则链路

text
CandidateManualController
CandidateManualService
CandidateManualServiceImpl
HireCandidateConverter
HireCandidate
HireCandidateMapper

目标:分清 Form、Entity、VO、Converter、Service 和 Mapper。

第 3 阶段:理解横切规则

text
CandidateLifecycleServiceImpl
CandidateDataPermissionServiceImpl
PositionDataPermissionServiceImpl
CommonFileStorageServiceImpl

目标:理解租户、用户、数据权限、版本、完整度和 OSS。

第 4 阶段:理解搜索一致性

text
CandidateDocument
CandidateDocumentConverter
CandidateSearchService
CandidateSyncService
CandidateEsSyncFailServiceImpl
EsSyncCompensateTask

目标:知道 PostgreSQL 和 Elasticsearch 各自负责什么,以及失败如何补偿。

第 5 阶段:理解核心业务状态机

text
HireFollowStageEnum
HireFollowActionEnum
CandidateFollowConstant
RecoFollowStateServiceImpl
RecoFollowBusinessServiceImpl

目标:能够判断一次跟进动作是否合法、会更新哪些数据。

第 6 阶段:理解跨服务边界

text
PositionProjectGatewayService
DefaultPositionProjectGatewayServiceImpl
PositionApplyApprovalGatewayService
DefaultPositionApplyApprovalGatewayServiceImpl
ExternalSupplierGatewayService

目标:知道招聘中心拥有的数据和外部中心拥有的数据分别是什么。

18. 接手第一个需求前的检查清单

  • [ ] Maven 私服依赖能够完整解析。
  • [ ] 明确当前环境的 Nacos、数据库、Redis、ES、XXL-Job 和 OSS 配置来源。
  • [ ] 获得完整基线数据库及 SQL 执行规则。
  • [ ] 知道请求如何经过网关并建立用户、租户上下文。
  • [ ] 能从一个 Controller 跟到 ServiceImpl、Mapper 和 Entity。
  • [ ] 能说明目标接口是否查询 ES。
  • [ ] 能说明目标操作是否需要数据权限校验。
  • [ ] 能说明目标操作是否涉及远程服务、OSS 或异步任务。
  • [ ] 核对状态枚举和流转表,避免散落魔法数字。
  • [ ] 为修改准备自动化测试或至少可重复的验证步骤。
  • [ ] 发布说明包含 SQL、配置、索引、任务和回滚方案。

19. 当前项目值得优先补齐的工程基础

从新手可上手性和变更安全性看,以下事项优先级较高:

  1. 在仓库根目录补正式 README.md,说明私服、配置中心、依赖服务和启动方式。
  2. hc-hire-center-api 明确定位:补充公共契约,或在暂不使用时说明原因。
  3. 增加 src/test 自动化测试,优先覆盖推荐状态机、候选人查重、数据权限和 ES 补偿。
  4. 建立完整、可追踪的数据库迁移机制,而不是只保留零散 SQL。
  5. 清理源码中的明文敏感配置并完成密钥轮换。
  6. 合并 application.yml 中重复的 spring 节点,并校验 Swagger 扫描包。
  7. 为超过 500 行的核心 Service 逐步提取领域服务和外部适配器。
  8. 补充本地开发环境或容器化依赖说明,降低对口头交接的依赖。

完成前 5 个阅读阶段后,再接一个影响范围小、无需状态流转和跨服务一致性的查询类需求,会比直接修改 PositionServiceImpl 或推荐状态机稳妥得多。

Lucking