# 岗位信息模块开发记录 **日期:** 2026-06-04 ## 模块概述 岗位信息模块(post)是招聘管理系统中的核心模块,负责管理招聘岗位的基本信息。该模块采用 JeecgBoot 的前后端分离架构,前端基于 Vue3 + Ant Design Vue,后端基于 Spring Boot + MyBatis-Plus。 ### 业务关系 - **PostInfo(岗位信息)**:唯一的主表,通过 `enterprise_id` 字段关联 EnterpriseInfo(企业基本信息)表。列表查询时通过 LEFT JOIN 获取关联企业的单位名称(companyName),表单中通过 JSearchSelect 组件从企业信息表中搜索选择关联企业。 --- ## 模块文件结构 ### 前端(jeecgboot-vue3/src/views/recruitment/post/) | 文件 | 用途 | |-------------------------------------|--------------------------------| | `PostInfoList.vue` | 岗位信息列表页面,提供查询、新增、编辑、详情、删除、批量删除、导入导出等功能 | | `PostInfo.api.ts` | 岗位信息 API 封装 | | `PostInfo.data.ts` | 列表页表格列配置(14列)与高级查询字段定义(22个查询字段) | | `components/PostInfoForm.vue` | 岗位信息新增/编辑/详情表单组件,关联企业通过搜索选择下拉框录入 | | `components/PostInfoModal.vue` | 岗位信息弹窗组件,包裹 PostInfoForm,全屏模式 | ### 后端(jeecg-boot/jeecg-boot-module/jeecg-module-zjrs/.../org/jeecg/modules/zjrs/post/) | 层次 | 文件 | |--------------|---------------------------------------------| | Controller | `PostInfoController.java` | | Entity | `PostInfo.java` | | VO | `vo/PostInfoVo.java` | | Service | `IPostInfoService.java` | | Service Impl | `PostInfoServiceImpl.java` | | Mapper | `PostInfoMapper.java` | | Mapper XML | `mapper/xml/PostInfoMapper.xml` | --- ## 开发记录 ### 功能清单 | 功能 | 说明 | |---------------|----------------------------------------------------------------| | 分页列表查询 | 支持按岗位名称、单位名称、工作地点、学历要求等条件查询,14 列展示 | | 新增 | 全屏表单,支持 23 个岗位字段录入,关联企业通过搜索选择下拉框从企业信息表中选择 | | 编辑 | 复用新增表单,预填充已有数据 | | 详情 | 表单禁用模式查看岗位全部信息 | | 删除 / 批量删除 | 支持单条删除和批量删除,删除前弹窗确认 | | 导入 / 导出 Excel | 基于 Jeecg 标准 Excel 导入导出功能,导出使用 PostInfoVo 包含关联企业名称 | | 高级查询 | 22 个查询字段,支持灵活的筛选条件 | | 字段必填校验 | 前端(Ant Design Vue Form 校验)+ 后端(Service 层 `validatePostInfo`)双重校验 | | 薪酬范围校验 | 前后端均校验最高薪酬必须大于最低薪酬 | | 联系电话格式校验 | 前后端均校验联系电话格式(`^1[3-9]\d{9}$`) | ### 必填字段(前后端一致) 共 16 个必填字段:关联企业、职业、岗位名称、工作性质、薪酬待遇、招聘人数(必须大于0)、岗位有效期、职位标签、岗位描述、学历要求、工作经验、职业技能等级、联系人、联系电话(需匹配手机号格式)、工作地点、详细地址、数据来源。 --- ### 功能开发 | 日期 | 内容 | 涉及文件 | 说明 | |------------|--------------|---------------|------------------------| | 2026-06-04 | 岗位信息模块初始构建 | 前端 5 个文件 + 后端 7 个文件 | 完成岗位信息管理的基础 CRUD 功能,含 Excel 导入导出、企业信息关联 LEFT JOIN 查询与企业搜索选择下拉框 | ### PostInfo 实体字段一览 | 分类 | 字段 | 说明 | |--------|----------------------|---------------| | 基本关联 | enterpriseId | 关联企业基本信息ID | | 岗位信息 | occupation | 职业 | | | postName | 岗位名称 | | | workNature | 工作性质 | | | postTag | 职位标签 | | | postDesc | 岗位描述 | | 薪酬信息 | salaryType | 薪酬待遇 | | | salaryMin | 最低薪酬 | | | salaryMax | 最高薪酬 | | | recruitCount | 招聘人数 | | 时效 | postValidDate | 岗位有效期 | | 福利 | otherBenefits | 其他福利 | | 要求条件 | educationRequire | 学历要求 | | | workExperienceRequire| 工作经验 | | | skillLevelRequire | 职业技能等级 | | | foreignLanguage | 外语语种 | | | languageLevel | 外语水平要求 | | 联系方式 | contactPerson | 联系人 | | | contactPhone | 联系电话 | | 工作地点 | workLocation | 工作地点 | | | detailedAddress | 详细地址 | | 配置 | dataSource | 数据来源 | | 系统字段 | id / createBy / createTime / updateBy / updateTime / sysOrgCode | 系统内置字段 | ### PostInfoVo 扩展字段 | 字段 | 说明 | 来源 | |-------------|------------------|---------------------| | companyName | 单位名称 | LEFT JOIN enterprise_info 表获取 | --- ### 2026-06-04:岗位信息模块初始构建 **需求描述:** 构建岗位信息管理模块,实现岗位信息的基础 CRUD、Excel 导入导出功能。岗位需关联企业基本信息表,列表和导出中需要显示企业名称。 **表格列(14列):** | 列 | 对应字段 | 说明 | |---------------|-------------------|------------------------| | 序号 | index | 自定义列,customRender 显示行索引 | | 单位名称 | companyName | 自 enterprise_info 表 LEFT JOIN 获取 | | 职业 | occupation | — | | 岗位名称 | postName | — | | 工作性质 | workNature | — | | 薪酬待遇 | salaryType | — | | 最低薪酬 | salaryMin | — | | 最高薪酬 | salaryMax | — | | 招聘人数 | recruitCount | — | | 岗位有效期 | postValidDate | — | | 学历要求 | educationRequire | — | | 联系人 | contactPerson | — | | 联系电话 | contactPhone | — | | 工作地点 | workLocation | — | **搜索区域(4个查询条件):** 岗位名称、单位名称、工作地点、学历要求 **涉及文件:** | 文件 | 操作 | 原因 | |--------------------------------------------------|----|---------------------------------------| | `jeecgboot-vue3/src/views/recruitment/post/PostInfoList.vue` | 新增 | 岗位信息列表页,含查询区域、表格、操作栏、导入导出按钮 | | `jeecgboot-vue3/src/views/recruitment/post/PostInfo.api.ts` | 新增 | 封装岗位信息 CRUD、导入导出 API 接口 | | `jeecgboot-vue3/src/views/recruitment/post/PostInfo.data.ts` | 新增 | 定义 14 列表格列配置与 22 个高级查询字段 | | `jeecgboot-vue3/src/views/recruitment/post/components/PostInfoForm.vue` | 新增 | 岗位信息表单,含 JSearchSelect 关联企业搜索选择、前后端双校验 | | `jeecgboot-vue3/src/views/recruitment/post/components/PostInfoModal.vue` | 新增 | 全屏弹窗包裹 PostInfoForm,提供新增/编辑/详情入口 | | `jeecg-boot/.../post/controller/PostInfoController.java` | 新增 | 岗位信息 REST 控制器,分页列表使用 `queryPageListWithEnterprise` 返回 PostInfoVo 含企业名称;导出使用 `queryListWithEnterprise` 支持选中导出和全量导出 | | `jeecg-boot/.../post/entity/PostInfo.java` | 新增 | 岗位信息实体,映射 `post_info` 表,含 23 个业务字段 + 系统字段 | | `jeecg-boot/.../post/vo/PostInfoVo.java` | 新增 | 岗位信息 VO,包含 PostInfo 所有字段 + companyName 扩展字段(关联企业名称),用于列表展示和 Excel 导出 | | `jeecg-boot/.../post/service/IPostInfoService.java` | 新增 | 岗位信息服务接口,定义 `queryPageListWithEnterprise` 和 `queryListWithEnterprise` 两个自定义查询方法 | | `jeecg-boot/.../post/service/impl/PostInfoServiceImpl.java` | 新增 | 服务实现,重写 `save`/`updateById` 增加 `validatePostInfo` 校验(16个必填项 + 薪酬范围 + 手机号格式) | | `jeecg-boot/.../post/mapper/PostInfoMapper.java` | 新增 | Mapper 接口,定义 `queryPageListWithEnterprise`(分页)和 `queryListWithEnterprise`(全量)两个自定义 SQL 方法 | | `jeecg-boot/.../post/mapper/xml/PostInfoMapper.xml` | 新增 | MyBatis XML 映射,LEFT JOIN enterprise_info 表获取 companyName 字段 | --- ### 2026-06-04:岗位列表查询字段与展示字段调整 **需求描述:** 调整岗位信息列表页的查询条件字段和表格展示字段,使其与实际业务需求更加匹配。 **查询字段调整(6个):** | 新查询字段 | 对应字段 | 说明 | |-----------|-------------------|----------------------------| | 企业名称 | companyName | 原"单位名称"改名为"企业名称" | | 职业工种 | occupation | 原"职业"改名为"职业工种" | | 岗位名称 | postName | 保留 | | 学历要求 | educationRequire | 保留 | | 联系人 | contactPerson | 新增查询字段 | | 数据来源 | dataSource | 新增查询字段 | **删除的查询字段:** 工作地点 **表格列调整(14列):** | 新列 | 对应字段 | 说明 | |------------------|---------------------|------------------------| | 序号 | index | 保留 | | 企业名称 | companyName | 原"单位名称"改名为"企业名称" | | 职业工种 | occupation | 原"职业"改名为"职业工种" | | 岗位名称 | postName | 保留 | | 薪酬待遇(最低) | salaryMin | 原"最低薪酬"改名,合并薪酬展示 | | 薪酬待遇(最高) | salaryMax | 原"最高薪酬"改名,合并薪酬展示 | | 招聘人数 | recruitCount | 保留 | | 岗位有效期 | postValidDate | 保留 | | 职位标签 | postTag | 新增显示字段 | | 学历要求 | educationRequire | 保留 | | 工作经验 | workExperienceRequire | 新增显示字段 | | 联系人 | contactPerson | 保留 | | 联系电话 | contactPhone | 保留 | | 数据来源 | dataSource | 新增显示字段 | **删除的列:** 工作性质、薪酬待遇、工作地点 **涉及文件:** | 文件 | 操作 | 原因 | |--------------------------------------------------|----|---------------------------------------| | `jeecgboot-vue3/src/views/recruitment/post/PostInfoList.vue` | 修改 | 查询表单 4 个字段改为 6 个(企业名称、职业工种、岗位名称、学历要求、联系人、数据来源) | | `jeecgboot-vue3/src/views/recruitment/post/PostInfo.data.ts` | 修改 | 更新 columns 定义,调整为 14 列新字段配置(移除工作性质、薪酬待遇、工作地点,新增职位标签、工作经验、数据来源,改名企业名称、职业工种、薪酬待遇列标题) | | `jeecg-boot/.../post/controller/PostInfoController.java` | 修改 | 分页列表查询接口新增 companyName 查询参数处理并委托 Service 实现;导出接口同步增加 companyName 查询条件支持 | | `jeecg-boot/.../post/service/IPostInfoService.java` | 修改 | 方法签名增加 `HttpServletRequest req` 参数 | | `jeecg-boot/.../post/service/impl/PostInfoServiceImpl.java` | 修改 | 将 companyName 模糊查询和导出 selections 选中筛选逻辑从 Controller 移到 Service 层的 `applyCustomConditions` 私有方法 | --- ### 2026-06-04:Controller 业务逻辑下沉到 Service 层 **需求描述:** 将 PostInfoController 中本应属于 Service 层的业务逻辑代码(企业名称手动查询条件拼接、导出选中记录筛选)迁移到 Service 层,保持 Controller 层职责清晰。 **涉及文件:** | 文件 | 操作 | 原因 | |--------------------------------------------------|----|---------------------------------------| | `jeecg-boot/.../post/controller/PostInfoController.java` | 修改 | 移除 `queryPageList` 中的 `companyName` 手动拼接代码;移除 `exportXls` 中的 `selections` 解析和 `companyName` 拼接代码,改为委托 Service 方法处理;移除不再使用的 `java.util.List` 导入 | | `jeecg-boot/.../post/service/IPostInfoService.java` | 修改 | `queryPageListWithEnterprise` 和 `queryListWithEnterprise` 方法签名增加 `HttpServletRequest req` 参数 | | `jeecg-boot/.../post/service/impl/PostInfoServiceImpl.java` | 修改 | 新增 `applyCustomConditions` 私有方法封装企业名称模糊查询逻辑;`queryListWithEnterprise` 中新增导出 selections 选中记录筛选处理;新增 `QueryWrapper`、`HttpServletRequest`、`oConvertUtils`、`Arrays` 导入 | --- ### 2026-06-04:数据字典字段适配(查询表单 + 数据表格 + 编辑表单 + 导出翻译) **需求描述:** 将岗位信息模块中匹配数据字典的字段从普通文本输入改为下拉选择,列表页显示中文标签,导出时自动翻译字典值为中文。 **涉及字典及字段映射:** | 字段名 | 字典编码 | 说明 | |--------------------------|-----------------|--------| | `workNature` | WorkNature | 工作性质 | | `salaryType` | SalaryType | 薪酬待遇 | | `postTag` | PostTag | 职位标签 | | `educationRequire` | Education | 学历要求 | | `workExperienceRequire` | WorkExperience | 工作经验 | | `skillLevelRequire` | SkillLevel | 职业技能等级 | | `languageLevel` | LanguageLevel | 外语水平要求 | | `dataSource` | DataSource | 数据来源 | **涉及文件:** | 文件 | 操作 | 原因 | |--------------------------------------------------|----|---------------------------------------| | `jeecgboot-vue3/src/views/recruitment/post/PostInfoList.vue` | 修改 | 导入 `useDict` 并添加 `getDictText`/`getDictOptions`;查询表单中学历要求、数据来源从 `` 改为 `` 字典下拉;`bodyCell` 插槽添加 4 个字典字段(职位标签、学历要求、工作经验、数据来源)的翻译渲染 | | `jeecgboot-vue3/src/views/recruitment/post/components/PostInfoForm.vue` | 修改 | 导入 `useDict`,预加载 8 个字典;工作性质、薪酬待遇、职位标签、学历要求、工作经验、职业技能等级、外语水平要求、数据来源 从 `` 改为 `` 下拉选择;校验提示从"请输入"改为"请选择" | | `jeecg-boot/.../post/controller/PostInfoController.java` | 修改 | 添加 `EXPORT_DICT_FIELD_MAP` 静态常量映射 8 个字段到字典编码;导出流程增加 `translateDictFields` 调用 | | `jeecg-boot/.../post/service/IPostInfoService.java` | 修改 | 添加 `translateDictFields` 方法声明 | | `jeecg-boot/.../post/service/impl/PostInfoServiceImpl.java` | 修改 | 注入 `IDictionaryItemService`;实现 `translateDictFields` 方法,采用后端内存映射方案批量查询字典并替换字段值;移除未使用的 `Collectors` 导入 | ### 2026-06-05:详情查看改用独立的 a-descriptions 详情弹窗 **问题描述:** 原详情查看功能复用 `PostInfoModal` + `PostInfoForm`,打开的是禁用状态的编辑表单,布局与编辑界面相同但字段不可编辑,体验与其他模块详情修改前一致。 **解决方案:** 新建独立的 `PostInfoDetailModal` 组件,使用 `a-descriptions` 描述列表以只读方式展示数据。 **实现要点:** - 使用 `a-descriptions :column="3" bordered` 展示全部 22 个字段,与编辑表单布局一致 - 字典字段通过 `getDictText` 转换:WorkNature(工作性质)、SalaryType(薪酬待遇)、PostTag(职位标签)、Education(学历要求)、WorkExperience(工作经验)、SkillLevel(职业技能等级)、LanguageLevel(外语水平要求)、DataSource(数据来源) - 单位名称优先显示 `companyName`(列表查询返回的扩展字段),降级显示 `enterpriseId` - 岗位描述占全宽(span=3),其他福利占 2 列(span=2) - 弹窗默认为全屏模式(`:fullscreen="true"`),底部仅保留「关闭」按钮 - 内容区域添加 `padding: 14px 20px` 内边距 **涉及文件:** - `jeecgboot-vue3/src/views/recruitment/post/components/PostInfoDetailModal.vue` — 新增岗位信息详情弹窗组件 - `jeecgboot-vue3/src/views/recruitment/post/PostInfoList.vue` — 导入新组件,修改 `handleDetail` 方法调用新弹窗