2026-06-03
本次开发实现了"见习岗位管理"和"见习人员管理"两个模块的完整后端+前端代码,参考 FocusPersonnel 模块的代码模式。
| 文件 | 路径 | 说明 |
|---|---|---|
| InternshipPost.java | org.jeecg.modules.zjrs.internshippost.entity | 实体类,@TableName("internship_post"),包含22个字段 |
| InternshipPostMapper.java | org.jeecg.modules.zjrs.internshippost.mapper | Mapper接口,继承BaseMapper |
| InternshipPostMapper.xml | org.jeecg.modules.zjrs.internshippost.mapper.xml | Mapper XML,基础配置(此表不需要JOIN) |
| IInternshipPostService.java | org.jeecg.modules.zjrs.internshippost.service | Service接口,继承IService |
| InternshipPostServiceImpl.java | org.jeecg.modules.zjrs.internshippost.service.impl | Service实现类 |
| InternshipPostController.java | org.jeecg.modules.zjrs.internshippost.controller | Controller,使用QueryGenerator自动构建查询条件 |
关键设计:
| 文件 | 路径 | 说明 |
|---|---|---|
| InternshipPost.api.ts | views/internshippost/ | API定义,基础路径 /internshipPost |
| InternshipPost.data.ts | views/internshippost/ | 列定义和高级查询配置 |
| InternshipPostList.vue | views/internshippost/ | 列表页面 |
| InternshipPostForm.vue | views/internshippost/components/ | 表单组件,分两个卡片区域 |
| InternshipPostModal.vue | views/internshippost/components/ | 弹窗组件 |
关键设计:
| 文件 | 路径 |
|---|---|
| V20260603_5__menu_insert_InternshipPost.sql | flyway/sql/mysql/ |
菜单结构:
| 文件 | 路径 | 说明 |
|---|---|---|
| InternshipPersonnel.java | org.jeecg.modules.zjrs.internshippersonnel.entity | 实体类,@TableName("internship_personnel"),只包含表自身字段 |
| InternshipPersonnelPageVo.java | org.jeecg.modules.zjrs.internshippersonnel.entity | 列表VO,映射视图v_internship_personnel_list字段 |
| InternshipPersonnelMapper.java | org.jeecg.modules.zjrs.internshippersonnel.mapper | Mapper接口,添加queryPageList方法 |
| InternshipPersonnelMapper.xml | org.jeecg.modules.zjrs.internshippersonnel.mapper.xml | queryPageList从视图查询,支持5个查询参数 |
| IInternshipPersonnelService.java | org.jeecg.modules.zjrs.internshippersonnel.service | Service接口,添加queryPageList方法 |
| InternshipPersonnelServiceImpl.java | org.jeecg.modules.zjrs.internshippersonnel.service.impl | Service实现类 |
| InternshipPersonnelController.java | org.jeecg.modules.zjrs.internshippersonnel.controller | Controller,/list使用queryPageList模式 |
关键设计:
| 文件 | 路径 | 说明 |
|---|---|---|
| InternshipPersonnel.api.ts | views/internshippersonnel/ | API定义,基础路径 /internshipPersonnel |
| InternshipPersonnel.data.ts | views/internshippersonnel/ | 列定义和高级查询配置 |
| InternshipPersonnelList.vue | views/internshippersonnel/ | 列表页面 |
| InternshipPersonnelForm.vue | views/internshippersonnel/components/ | 表单组件 |
| InternshipPersonnelModal.vue | views/internshippersonnel/components/ | 弹窗组件 |
关键设计:
| 文件 | 路径 |
|---|---|
| V20260603_6__menu_insert_InternshipPersonnel.sql | flyway/sql/mysql/ |
菜单结构:
| 文件 | 路径 | 说明 |
|---|---|---|
| InternshipPersonnel.api.ts | views/internshippersonnel/ | 新增queryDetailById、listCustomTags、listCustomTagsPage、addCustomTagItem、deleteCustomTagItem、updateCustomTagItem、batchUpdateCustomTag、listServiceFollow、addServiceFollow、editServiceFollow、deleteServiceFollow等API函数 |
| 文件 | 路径 | 说明 |
|---|---|---|
| InternshipPersonnelDetail.vue | views/internshippersonnel/components/ | 见习人员详情组件,参照FocusPersonnelDetail改造 |
| InternshipPersonnelServiceFollowList.vue | views/internshippersonnel/components/ | 见习人员服务跟进列表组件,参照FocusPersonnelServiceFollowList改造 |
/internshipPersonnel/queryDetailById 而非 /focusPersonnel/queryDetailByIdinternship_custom_tag 而非 focus_custom_taginternship-personnel-detail 而非 focus-personnel-detail/internshipPersonnelServiceFollow/* 而非 /focusPersonnelServiceFollow/*internshipPersonnelId 而非 focusPersonnelId../InternshipPersonnel.api 导入internship_personnel:serviceFollow参照重点关注人员模块(FocusPersonnel),对见习人员管理后端进行完整改造:
| 文件 | 路径 | 说明 |
|---|---|---|
| InternshipPersonnelDetailVo.java | internshippersonnel/entity | 详情VO,含个人信息全部字段+见习岗位信息 |
| InternshipPersonnelServiceFollow.java | internshippersonnel/entity | 服务跟进记录实体类,@TableName("internship_personnel_service_follow") |
| InternshipPersonnelServiceFollowMapper.java | internshippersonnel/mapper | 服务跟进Mapper接口 |
| IInternshipPersonnelServiceFollowService.java | internshippersonnel/service | 服务跟进Service接口 |
| InternshipPersonnelServiceFollowServiceImpl.java | internshippersonnel/service/impl | 服务跟进Service实现类 |
| InternshipPersonnelServiceFollowController.java | internshippersonnel/controller | 服务跟进Controller,权限:internship_personnel:serviceFollow |
| 文件 | 修改内容 |
|---|---|
| InternshipPersonnel.java | 新增 customTag 字段(自定义标签,@Dict(dicCode="internship_custom_tag")) |
| InternshipPersonnelPageVo.java | 新增 customTag 字段 |
| InternshipPersonnelMapper.java | 新增 queryDetailById 方法 |
| InternshipPersonnelMapper.xml | 新增 queryDetailById SQL(关联personal_info+internship_post三表查询) |
| IInternshipPersonnelService.java | 新增 queryDetailById、listCustomTags、queryCustomTagPage、addCustomTagItem、deleteCustomTagItem、updateCustomTagItem、batchUpdateCustomTag 方法 |
| InternshipPersonnelServiceImpl.java | 实现上述所有新增方法,自定义标签字典编码:internship_custom_tag |
| InternshipPersonnelController.java | 新增 queryDetailById、listCustomTags、listCustomTagsPage、addCustomTagItem、deleteCustomTagItem、batchUpdateCustomTag、updateCustomTagItem 接口 |
| 文件 | 修改内容 |
|---|---|
| InternshipPersonnel.api.ts | 新增11个API函数(详情查询+自定义标签管理+服务跟进CRUD) |
| InternshipPersonnel.data.ts | 新增序号列和自定义标签列 |
| InternshipPersonnelList.vue | 新增查看/服务跟进按钮、批量标签弹窗、字典翻译、服务跟进弹窗 |
| InternshipPersonnelModal.vue | 区分详情/编辑模式,详情模式显示InternshipPersonnelDetail |
| 文件 | 路径 | 说明 |
|---|---|---|
| 见习人员字典.sql | .docs/sql/ | 初始化 internship_minor_tag(见习人员小类标签)和 internship_custom_tag(自定义标签)字典 |
| 见习人员服务跟进表.sql | .docs/sql/ | 创建 INTERNSHIP_PERSONNEL_SERVICE_FOLLOW 表 |
| 见习人员表新增自定义标签字段.sql | .docs/sql/ | ALTER TABLE internship_personnel ADD custom_tag |
| 见习人员视图.sql | .docs/sql/ | 更新视图,新增 custom_tag 字段 |
| V20260604_2__menu_insert_InternshipPersonnelServiceFollow.sql | flyway/sql/mysql/ | 服务跟进按钮权限+角色授权 |
| V20260604_3__init_internship_personnel_dict.sql | flyway/sql/mysql/ | 见习人员字典数据初始化 |
.docs/sql/见习人员服务跟进表.sql.docs/sql/见习人员表新增自定义标签字段.sql.docs/sql/见习人员视图.sql(DROP后CREATE)V20260604_2(菜单权限)和 V20260604_3(字典数据)完全参照重点关注人员模块(FocusPersonnel)实现见习人员管理,两个模块功能一致,只有业务字段差异。
| 文件 | 修改内容 |
|---|---|
| InternshipPersonnel.java | 新增 majorTag(@Dict dicCode="internship_major_tag")、minorTag(@Dict dicCode="internship_minor_tag")、customTag 字段 |
| InternshipPersonnelPageVo.java | 新增 majorTag、minorTag、age、householdLocation、currentResidence、jobSeekerCategory、jobSearchStatus、customTag 字段 |
| InternshipPersonnelDetailVo.java | 新增 majorTag、minorTag 字段 + 个人信息全部字段 + 见习岗位信息 |
| InternshipPersonnelMapper.java | 新增 queryDetailById、countPersonnelByCustomTag、updatePersonnelCustomTagName 方法 |
| InternshipPersonnelMapper.xml | queryPageList 新增10个查询条件;新增 queryDetailById(三表JOIN)、countPersonnelByCustomTag、updatePersonnelCustomTagName SQL |
| InternshipPersonnelServiceImpl.java | deleteCustomTagItem 添加标签绑定检查;updateCustomTagItem 添加标签名同步逻辑;字典编码常量 CUSTOM_TAG_DICT_CODE |
| InternshipPersonnelController.java | list接口新增10个查询参数;新增 queryDetailById、自定义标签管理接口 |
| 文件 | 修改内容 |
|---|---|
| InternshipPersonnelList.vue | 完全重写,参照FocusPersonnelList:去掉新增/编辑/删除按钮,操作栏改为3个直接按钮(查看、岗位推送、服务跟进),添加导出按钮,使用useDict加载3个字典,bodyCell插槽字典翻译,批量标签弹窗,服务跟进弹窗 |
| InternshipPersonnel.api.ts | 新增11个API函数 |
| InternshipPersonnel.data.ts | 新增列:序号、年龄、户口所在地、现居住地、求职人员类别、求职状态、人员大类标签、人员小类标签、自定义标签 |
| InternshipPersonnelModal.vue | 区分详情/编辑模式,详情显示InternshipPersonnelDetail,编辑显示InternshipPersonnelForm |
| InternshipPersonnelForm.vue | 新增 majorTag/minorTag(JDictSelectTag)、customTag 字段 |
| 文件 | 说明 |
|---|---|
| InternshipPersonnelDetail.vue | 见习人员详情组件 |
| InternshipPersonnelServiceFollowList.vue | 服务跟进列表组件 |
| InternshipPersonnelServiceFollow.java | 服务跟进实体类 |
| InternshipPersonnelServiceFollowController.java | 服务跟进Controller |
| 文件 | 说明 |
|---|---|
| V20260604_2__menu_insert_InternshipPersonnelServiceFollow.sql | 服务跟进按钮权限+角色授权 |
| V20260604_3__init_internship_personnel_dict.sql | 初始化3个字典到sys_dict/sys_dict_item |
| V20260604_7__migrate_internship_tags_to_dictionary_item.sql | 字典数据迁移到DICTIONARY_ITEM表(useDict从该表加载) |
[22018] Fail to cast string (-6111)TIMESTAMPDIFF(YEAR, birth_date, CURDATE()) 是MySQL函数,达梦不支持FLOOR(MONTHS_BETWEEN(CURRENT_DATE, birth_date) / 12)COMMENT 关键字,达梦不支持CREATE TABLE + COMMENT ON COLUMN 单独语句CURDATE() 是MySQL函数CURRENT_DATE由于Flyway可能已记录失败状态,以下SQL需要手动在数据库中执行:
.docs/sql/见习人员管理_全部重建.sql(DROP并重建所有表+视图+测试数据)完全参照重点关注人员模块,修复见习人员管理的6个问题:
| 序号 | 问题描述 | 修复方案 | 涉及文件 |
|---|---|---|---|
| 1 | 见习人员的标签应该和重点关注人员一样数据库用数字保存 | V20260604_7脚本改为直接INSERT数字Value的字典项;全部重建脚本测试数据改为数字 | V20260604_7__migrate_internship_tags_to_dictionary_item.sql、见习人员管理_全部重建.sql |
| 2 | 添加8条自定义标签数据到数据库给见习人员使用 | V20260604_7脚本中添加8条internship_custom_tag字典项(零就业家庭/低保家庭/残疾人员/长期失业/特困人员/刑满释放/社会救助/优抚对象) | V20260604_7__migrate_internship_tags_to_dictionary_item.sql |
| 3 | 见习人员管理缺少导出功能 | 前端导出按钮和exportConfig已存在,后端exportXls接口已存在,权限已配置(internship_personnel:exportXls),确认代码层面完整 | InternshipPersonnelList.vue、InternshipPersonnelController.java |
| 4 | 见习人员管理服务跟进缺失新增服务跟进数据按钮 | 修复权限判断:getPermList → getPermCodeList(参照重点关注人员) | InternshipPersonnelServiceFollowList.vue |
| 5 | 搜索条件无效果 | 1. beforeFetch改为同步函数并显式return params;2. 性别搜索值从"男性"/"女性"改为"1"/"2"(与数据库存储一致);3. 简化后端性别SQL条件 | InternshipPersonnelList.vue、InternshipPersonnelMapper.xml |
| 6 | 列表性别显示有问题,有的显示数字 | 添加genderMap映射 + bodyCell插槽翻译性别字段 | InternshipPersonnelList.vue |
InternshipPersonnelList.vue
beforeFetch 从 async 改为同步函数,显式 return params(避免useListPage包装逻辑中返回值被忽略的问题)<a-select-option value="1">男性</a-select-option> / <a-select-option value="2">女性</a-select-option>(与数据库数字存储格式一致)genderMap 映射和 bodyCell 插槽性别翻译(兼容数字和文本两种格式)FocusPersonnelList.vue(同步修复)
genderMap 映射和 bodyCell 插槽性别翻译beforeFetch 从 async 改为同步函数InternshipPersonnelServiceFollowList.vue
permissionStore.getPermList 改为 permissionStore.getPermCodeList(参照重点关注人员)InternshipPersonnelMapper.xml
CASE WHEN 兼容逻辑简化为 AND gender = #{params.gender}(前端已传数字值)InternshipPersonnelServiceImpl.java
deleteCustomTagItem 方法:改用 item.getValue() 数字值去 countPersonnelByCustomTag 检查绑定(因为custom_tag列存储数字值)updateCustomTagItem 方法:移除 updatePersonnelCustomTagName 调用(标签重命名只改Name,数字Value不变,无需同步更新custom_tag列)FocusPersonnelServiceImpl.java(同步修复)
deleteCustomTagItem 方法:同上,改用数字值检查绑定updateCustomTagItem 方法:同上,移除 updatePersonnelCustomTagName 调用V20260604_7__cleanup_old_sys_dict_tags.sql 重命名为 V20260604_10__cleanup_old_sys_dict_tags.sql(避免与迁移脚本版本号冲突)见习人员与重点关注人员的标签存储格式统一为数字值:
major_tag 列存储数字(如 '1'),前端通过 useDict('internship_major_tag') 翻译显示minor_tag 列存储数字(如 '1', '2'),前端通过 useDict('internship_minor_tag') 翻译显示custom_tag 列存储逗号分隔的数字(如 '1,3,5'),前端通过 useDict('internship_custom_tag') 翻译显示DICTIONARY_ITEM 表中,Value 字段为 Integer 类型(1, 2, 3...),Name 字段为显示文本| 序号 | 问题描述 | 修复方案 | 涉及文件 |
|---|---|---|---|
| 1 | 导出按钮和服务跟进新增按钮不显示 | 权限ID冲突:V20260604_2脚本中服务跟进权限ID 1780601000000327 与V20260603_6脚本中角色授权ID冲突,导致服务跟进权限未插入成功。修改权限ID为 1780601000000340,并补充导出权限角色授权 |
V20260604_2__menu_insert_InternshipPersonnelServiceFollow.sql |
| 2 | 列表求职状态显示数字 | 数据库 job_search_status 字段存储数字(1-6),需通过 useDict('JobSeekerStatus') 翻译显示。搜索下拉也改为字典选项 |
InternshipPersonnelList.vue、FocusPersonnelList.vue |
| 3 | 自定义标签已设置但页面不显示 | 原因同问题2,标签值是数字,需通过 getDictText 翻译。已确认翻译逻辑正确,需确保字典数据已插入数据库 |
确认DICTIONARY_ITEM表数据 |
| 4 | 自定义标签样式与人员大类/小类不一致 | 统一使用 <a-tag> 组件:大类蓝色(blue)、小类绿色(green)、自定义橙色(orange) |
InternshipPersonnelList.vue、FocusPersonnelList.vue |
V20260604_2__menu_insert_InternshipPersonnelServiceFollow.sql
1780601000000327 改为 1780601000000340(避免与V20260603_6中角色授权ID冲突)1780601000000334 改为 1780601000000341internship_personnel:exportXls 的角色授权(使用NOT EXISTS防重复)SELECT ... FROM DUAL WHERE NOT EXISTS 格式(幂等执行)InternshipPersonnelList.vue
useDict 增加 'JobSeekerStatus' 字典编码jobSearchStatusOptions 计算属性(从字典加载求职状态选项)jobSearchStatus 翻译(getDictText('JobSeekerStatus', text))majorTag 用 <a-tag color="blue">,minorTag 用 <a-tag color="green">,customTag 用 <a-tag color="orange">-FocusPersonnelList.vue(同步修复)
.docs/sql/修复见习人员权限数据.sql(修复导出按钮和服务跟进新增按钮不显示的问题)DICTIONARY_ITEM 表中 JobSeekerStatus 字典数据已存在(参考 .docs/sql/数据字典数据插入.sql)internship_major_tag、internship_minor_tag、internship_custom_tag 字典数据已存在(参考 V20260604_7 脚本)| 序号 | 问题描述 | 修复方案 | 涉及文件 |
|---|---|---|---|
| 1 | 标签样式不应该用tag组件,应该和列表普通文本一样 | 列表bodyCell中标签改为纯文本显示(与重点关注人员一致),详情页保留tag样式 | InternshipPersonnelList.vue、FocusPersonnelList.vue |
| 2 | 导出和新增按钮不显示 | 根本原因是数据库权限数据冲突,创建独立修复SQL脚本 | .docs/sql/修复见习人员权限数据.sql |
| 3 | 详情页自定义标签不显示 | 详情页header区域自定义标签缺少字典翻译(直接显示数字) | InternshipPersonnelDetail.vue、FocusPersonnelDetail.vue |
经过深入对比重点关注人员的实现,找到了导出按钮和服务跟进新增按钮不显示的根本原因:
后端 SysPermissionController 构建 codeList 时,过滤条件为 status = "1":
List<String> codeList = metaList.stream()
.filter((permission) -> CommonConstant.MENU_TYPE_2.equals(permission.getMenuType())
&& CommonConstant.STATUS_1.equals(permission.getStatus()))
.collect(...);
但 V20260603_6 插入的见习人员权限 status = NULL,V20260604_9 只修复了重点关注人员的status,遗漏了见习人员。
status = NULL → "1".equals(null) → false → 权限码被排除 → 前端 v-auth 指令从DOM移除按钮| 文件 | 修改内容 |
|---|---|
| V20260605_1__fix_internship_personnel_permission_status.sql | 新建flyway脚本,修复见习人员所有按钮权限的status=NULL问题 |
| .docs/sql/修复见习人员权限数据.sql | 重写为综合修复SQL,包含4个部分:权限status修复、ID冲突修复、字典数据保障、旧数据清理 |
| 部分 | 修复内容 | 解决的问题 |
|---|---|---|
| 第一部分 | UPDATE sys_permission SET status=1 WHERE perms LIKE 'internship_personnel:%' | 导出按钮和服务跟进新增按钮不显示(根本原因) |
| 第二部分 | 清理ID冲突 + 插入服务跟进权限(status=1) + 角色授权 | 服务跟进权限ID冲突导致数据不完整 |
| 第三部分 | 确保DICTIONARY/DICTIONARY_ITEM字典数据存在 | 自定义标签不显示(V20260604_7可能未成功执行) |
| 第四部分 | 清理sys_dict/sys_dict_item中的旧数据 | 避免旧字典数据干扰 |
| 第五部分 | 验证修复结果 | 确认所有修复生效 |
.docs/sql/修复见习人员权限数据.sql根本原因:jobSeekerCategory 字段在数据库中存储数字1-10,对应 JobSeekerCategory 字典(DICTIONARY_ITEM表),但前端列表和详情页都没有做字典翻译。重点关注人员也有同样的问题。个人信息模块(PersonalInfoList.vue)已正确实现。
修复方案:在useDict中加载JobSeekerCategory字典,bodyCell和详情页中添加翻译。
| 文件 | 修改内容 |
|---|---|
| InternshipPersonnelList.vue | useDict增加JobSeekerCategory,bodyCell增加jobSeekerCategory翻译 |
| FocusPersonnelList.vue | useDict增加JobSeekerCategory,bodyCell增加jobSeekerCategory翻译 |
| InternshipPersonnelDetail.vue | useDict增加JobSeekerCategory,求职人员类别字段添加getDictText翻译 |
| FocusPersonnelDetail.vue | useDict增加JobSeekerCategory,求职人员类别字段添加getDictText翻译 |
根本原因:DICTIONARY/DICTIONARY_ITEM表中可能缺少字典数据。V20260604_7脚本可能因之前的CAST错误未成功执行,且数据字典数据插入.sql使用了双引号(达梦不兼容)。
修复方案:在综合修复SQL中增加JobSeekerCategory和JobSeekerStatus字典数据保障。
| 文件 | 修改内容 |
|---|---|
| .docs/sql/修复见习人员权限数据.sql | 增加3.5节JobSeekerCategory字典数据、3.6节JobSeekerStatus字典数据 |
根本原因:后端详情查询遗漏了 custom_tag 字段。
InternshipPersonnelDetailVo 缺少 customTag 字段InternshipPersonnelMapper.xml 的 queryDetailById SQL 遗漏了 ip.custom_tag AS customTagFocusPersonnelDetailVo 和 FocusPersonnelMapper.xml 都有 customTag 字段,见习人员遗漏了修复方案:参照重点关注人员,补全缺失的字段和SQL。
| 文件 | 修改内容 |
|---|---|
| InternshipPersonnelDetailVo.java | 添加 customTag 字段(在 minorTag 之后) |
| InternshipPersonnelMapper.xml | queryDetailById SQL 添加 ip.custom_tag AS customTag |
ant-design:audit-outlined,见习人员=ant-design:user-outlinedv-auth 指令(见习岗位=internship_post:exportXls、见习人员=internship_personnel:exportXls)v-auth="welfare_post:exportXls"v-auth="job_recommend:exportXls"信息智能匹配推送 → 见习岗位管理、公益性岗位管理 — 导出按钮不显示
后端 SysPermissionController 构建权限码列表(codeList)时过滤条件为 status = '1',但 Flyway 脚本 V20260603_5 和 V20260603_7 插入按钮权限时 status 字段值为 NULL,导致后端不返回这些权限码。前端 v-auth 指令检查不到权限则从 DOM 中移除按钮。
.docs/sql/修复见习岗位和公益性岗位导出按钮权限.sql信息智能匹配推送下 5 个子菜单(重点关注人员、见习岗位、见习人员、公益性岗位、岗位推荐)存在以下问题:
<a-select-option>,非从字典表动态加载<template #bodyCell> 字典翻译插槽,列表显示原始值src/hooks/dictionary/useDict.ts:
Code 匹配回退,同时尝试 value 和 code 两种方式匹配字典项item.code(VARCHAR)作为选项值,解决 Value(INT) 与 DB 文本字段不匹配问题。Code 为空时回退到 String(item.value)| 模块 | 文件 | 改动 |
|---|---|---|
| 重点关注人员 | FocusPersonnelList.vue |
户口/居住地→XZQH树形, 性别/学历→字典下拉, 新增education翻译, 自定义标签→personal_tag库 |
| 见习岗位 | InternshipPostList.vue |
全部搜索下拉→字典, 工作地点→XZQH树形, 新增完整bodyCell翻译, 新增identity_requirement翻译 |
| 见习人员 | InternshipPersonnelList.vue |
户口/居住地→XZQH树形, 性别/学历→字典下拉, 补充6项bodyCell翻译, 自定义标签→personal_tag库 |
| 公益性岗位 | WelfarePostList.vue |
全部搜索下拉→字典, 新增完整bodyCell翻译 |
| 岗位推荐 | JobRecommendList.vue |
推荐类型/状态→字典下拉, 新增bodyCell翻译(4项) |
| 文件 | 改动 |
|---|---|
InternshipPost.data.ts |
移除 publishStatus/applyStatus/identityRequirement 硬编码 customRender |
WelfarePost.data.ts |
移除 postType/publishStatus/postStatus 硬编码 customRender |
JobRecommend.data.ts |
移除 recommendType/recommendStatus 硬编码 customRender |
| 文件 | 改动 |
|---|---|
FocusPersonnelDetail.vue |
户口所在地/现居住地新增XZQH翻译+6位回退, 自定义标签→personal_tag库 |
InternshipPersonnelDetail.vue |
同上 |
| 字段 | 显示规则 | 9位编码容错 |
|---|---|---|
| 户口所在地 | 去除"广东省湛江市"前缀 → "xx区" | 前6位回退查区县 |
| 现居住地/工作地点 | 完整路径 "xx省xx市xx区" | 前6位回退查区县 |
.docs/sql/信息智能推送模块-补充字典数据.sql — 向 DM8 DICTIONARY/DICTIONARY_ITEM 表插入 11 个字典:
| 字典 | 条目 | 值类型 |
|---|---|---|
publish_status |
0=未发布, 1=已发布 | Value(INT) |
apply_status |
01=报名中, 02=人员已满 | Code(VARCHAR) |
company_nature |
国有企业/民营企业/外资企业/事业单位/社会团体 | Code(VARCHAR) |
welfare_post_type |
社区服务/城市管理/公共管理/后勤服务 | Code(VARCHAR) |
welfare_post_status |
招聘中/已满/已关闭 | Code(VARCHAR) |
recommend_type |
1=岗位推荐到人, 2=人推荐到岗位 | Code(VARCHAR) |
recommend_status |
0=待查看, 1=已查看, 2=已接受, 3=已拒绝 | Code(VARCHAR) |
internship_status |
见习中/已期满/已退出 | Code(VARCHAR) |
audit_status |
待审核/已通过/未通过 | Code(VARCHAR) |
identity_requirement |
高校毕业生/失业青年/脱贫家庭青年 | Code(VARCHAR) |
apply_method |
网上报名/现场报名 | Code(VARCHAR) |
getDictText 通过 String(Value)===String(data) 匹配getDictText 通过 Code 匹配文本| 表 | 字段 | 旧值 → 新值 |
|---|---|---|
internship_post |
company_nature |
私营企业→民营企业, 有限责任公司→民营企业, 民办非企业→社会团体 |
internship_personnel ID 334 |
internship_status |
待审核→见习中 |
根因:focus_major_tag 等字典的 Code 字段存储了文本值(如'就业困难人员'),但 DB 数据存储的是数值('1','2'),getDictText 无法匹配。
修复:清除 6 个 tag 字典的 Code 字段(设回 ''),统一使用 Value(INT) 匹配:
自定义标签选项和显示改用 personal_tag 表(求职信息库→个人标签库):
| 模块 | personal_tag 父级 ID | API |
|---|---|---|
| 重点关注人员 | 2064950954964254722 |
/tag/personalTag/listForSelect?parentId=xxx&tagLevel=2 |
| 见习人员 | 2064950598742016001 |
同上 |
bodyCell 使用三级回退兼容新旧数据:
customTagMap[val] — personal_tag UUID 查找getDictText(..., val) — DICTIONARY_ITEM 数值查找(旧数据)val — 原始值兜底useDict → /system/dictionary/getDictBatch → 自定义 DictionaryController → DICTIONARY/DICTIONARY_ITEM 表V20260605_3) → sys_dict/sys_dict_item 表 → 未被 useDict 使用DICTIONARY/DICTIONARY_ITEM 表中才能被前端加载所有 5 个模块的详情组件全部改用 getDictText 翻译:
FocusPersonnelDetail.vue / InternshipPersonnelDetail.vue:
| 字段 | 字典 | 数据→显示 |
|------|------|-----------|
| 性别 | Gender | 1→男 |
| 学历 | Education | 3→大学本科 |
| 民族 | Nation | 1→汉族 |
| 国籍 | Nationality | 1→中国 |
| 婚姻状况 | MaritalStatus | 1→未婚 |
| 政治面貌 | PoliticalStatus | 3→共青团员 |
| 户口性质 | HouseholdType | 1→非农业户口(城镇) |
| 工作经验 | WorkExperience | 4→3-5年 |
| 证件类型 | IDType | 1→居民身份证(户口簿) |
| 求职状态 | JobSeekerStatus | 2→离职-随时到岗 |
| 是否留学人才 | Whether | 1→是 |
| 是否接受推荐职位 | Whether | 0→否 |
| 见习状态 | internship_status | 见习中 |
| 审核状态 | audit_status | 已通过 |
InternshipPostForm.vue: 单位性质/报名方式→字典options,工作地点详情→XZQH翻译
WelfarePostForm.vue: 岗位类型/报名方式→字典options,工作地点详情→XZQH翻译
JobRecommendForm.vue: 推荐类型/状态→字典options;关联个人信息→显示姓名(非ID),关联岗位→显示岗位名(单位名)
| 字典 | 条目数 | 用途 |
|---|---|---|
Nation |
56 | 民族 |
Whether |
0=否,1=是 | 通用是否 |
| 字段类型 | 显示格式 | 示例 | 实现方式 |
|---|---|---|---|
| 户口所在地 | XX区 |
赤坎区 | 优先取6位区级编码,.replace('广东省湛江市','') |
| 所属区县 | XX区 |
赤坎区 | xzqhMap[code] |
| 现居住地 | XX省XX市XX区XX街道 |
广东省湛江市赤坎区中华街道 | buildXzqhPath(code, map) |
| 工作地点 | XX省XX市XX区XX街道 |
同上 | buildXzqhPath(code, map) |
XZQH 编码逐级解析为完整层级路径:
function buildXzqhPath(code: string, map: Record<string, string>): string {
if (!code) return '';
const s = String(code);
const parts: string[] = [];
if (s.length >= 9) { const street = map[s.substring(0, 9)]; if (street) parts.unshift(street); }
if (s.length >= 6) { const district = map[s.substring(0, 6)]; if (district) parts.unshift(district); }
if (s.length >= 4) { const city = map[s.substring(0, 4)]; if (city) parts.unshift(city); }
if (s.length >= 2) { const prov = map[s.substring(0, 2)]; if (prov) parts.unshift(prov); }
return parts.join('') || map[s] || code;
}
关键发现:XZQH 字典中省级 Code 为 '44'(非 '440000'),市级 Code 为 '4408'(非 '440800')。直接用 substring(0,2) 和 substring(0,4) 匹配,无需补零。
涉及文件(9个):
FocusPersonnelList.vue / InternshipPersonnelList.vue / InternshipPostList.vue / WelfarePostList.vue / JobRecommendList.vue — bodyCell 翻译FocusPersonnelDetail.vue / InternshipPersonnelDetail.vue — 详情翻译InternshipPostForm.vue / WelfarePostForm.vue — 表单详情模式参照 PersonalInfoList.vue 实现,使用 treeNode.dataRef.children 和 treeNode.value:
const residenceTreeData = ref<any[]>([]);
async function loadResidenceTreeRoot() {
const res = await defHttp.get({
url: '/system/dictionary/getDictTreeChildren',
params: { dictionaryCode: 'XZQH', parentCode: '' },
}, { isTransformResponse: false });
if (res.success && res.result) {
return res.result.map((item) => ({ key: item.key, title: item.title, value: item.key, isLeaf: item.leaf }));
}
return [];
}
async function loadResidenceTreeChildren(treeNode) {
if (treeNode.dataRef.children) return;
const res = await defHttp.get({
url: '/system/dictionary/getDictTreeChildren',
params: { dictionaryCode: 'XZQH', parentCode: treeNode.value },
}, { isTransformResponse: false });
if (res.success && res.result) {
treeNode.dataRef.children = res.result.map((item) => ({ key: item.key, title: item.title, value: item.key, isLeaf: item.leaf }));
residenceTreeData.value = [...residenceTreeData.value];
}
}
户口所在地保持湛江市区县(loadZhanjiangDistricts 程序化定位)。
初始误清空了 Code,后恢复为文本值(因 DB 存储的是 '见习中' 等文本,非数值):
internship_status: Code='见习中'/'已期满'/'已退出'audit_status: Code='待审核'/'已通过'/'未通过'导出Excel时性别、学历等字典字段显示为原始编码,日期格式异常。
| 文件 | 修改 |
|---|---|
IInternshipPersonnelService.java |
新增 translateDictFieldsForPageVo() 方法 |
InternshipPersonnelServiceImpl.java |
注入 IDictionaryItemService,批量查询字典 → switch-case替换字段值为标签 |
InternshipPersonnelController.java |
重写 exportXls:查询 InternshipPersonnelPageVo 数据 → 过滤选中 → 字典翻译 → 导出为 .xlsx |
列表操作栏"岗位推送"按钮为占位状态,点击提示"岗位推送功能待开发"。
复用 JobRecommend 模块的 /jobRecommend/add 接口,前端新增通用 JobPushModal 弹窗供用户选择岗位后推送。
| 文件 | 修改 |
|---|---|
jobrecommend/dto/AvailablePostVo.java |
新增 — 可选岗位VO |
jobrecommend/mapper/xml/JobRecommendMapper.xml |
新增 — UNION 查询三张岗位表,支持 keyword 模糊搜索 |
jobrecommend/mapper/JobRecommendMapper.java |
新增 — queryAvailablePosts() 方法 |
jobrecommend/service/IJobRecommendService.java |
新增 — queryAvailablePosts() 接口 |
jobrecommend/service/impl/JobRecommendServiceImpl.java |
新增 — queryAvailablePosts() 实现 |
jobrecommend/controller/JobRecommendController.java |
新增 — GET /jobRecommend/availablePosts 端点 |
| 文件 | 修改 |
|---|---|
jobrecommend/JobRecommend.api.ts |
新增 — listAvailablePosts() + pushJob() API |
jobrecommend/components/JobPushModal.vue |
新增 — 通用岗位推送弹窗(岗位类型筛选、名称搜索、单选表格、推荐意见),FocusPersonnel 和 InternshipPersonnel 共用 |
internshippersonnel/InternshipPersonnelList.vue |
修改 — 替换 handleJobPush 占位函数,接入 JobPushModal 弹窗 |
点击"岗位推送" → 弹窗自动加载可选岗位列表 → 可筛选岗位类型(见习/公益/普通)+ 模糊搜索 → 单选岗位 → 填写推荐意见(选填)→ 确定 → 调用 /jobRecommend/add 创建推荐记录(recommendType=1, recommendStatus=0),后端自动填充推荐人/机构/时间