20260615-开发记录_见习岗位与见习人员管理模块.md 43 KB

见习岗位管理与见习人员管理模块开发记录

开发日期

2026-06-03

模块概述

本次开发实现了"见习岗位管理"和"见习人员管理"两个模块的完整后端+前端代码,参考 FocusPersonnel 模块的代码模式。


一、见习岗位管理(InternshipPost)

1.1 后端代码

文件 路径 说明
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自动构建查询条件

关键设计:

  • /list 接口使用 QueryGenerator 自动构建查询条件(不需要自定义queryPageList)
  • 权限前缀:internship_post
  • 实体类使用 @TableId(type = IdType.ASSIGN_ID)

1.2 前端代码

文件 路径 说明
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/ 弹窗组件

关键设计:

  • 查询区域:单位名称(输入框)、工作地点(输入框)、见习岗位(输入框)、发布状态(a-select: 0未发布/1已发布)、报名状态(a-select: 01报名中/02人员已满)
  • 表单分两个卡片:卡片1-见习单位信息、卡片2-见习岗位信息
  • 身份要求使用 a-checkbox-group(高校毕业生/失业青年/脱贫家庭青年),存储为逗号分隔字符串
  • 单位性质使用 a-select 硬编码选项(国有企业/民营企业/外资企业/事业单位/社会团体)
  • 报名方式使用 a-select 硬编码选项(网上报名/现场报名)
  • 报名截止日期使用 a-date-picker 日期选择器

1.3 Flyway菜单SQL

文件 路径
V20260603_5__menu_insert_InternshipPost.sql flyway/sql/mysql/

菜单结构:

  • 一级菜单"见习管理":id=178060100000030
  • 二级菜单"见习岗位管理":id=178060100000031
  • 按钮权限:add(1780601000000311), edit(1780601000000312), delete(1780601000000313), deleteBatch(1780601000000314), exportXls(1780601000000315), importExcel(1780601000000316)
  • 角色授权:ID从1780601000000317开始

二、见习人员管理(InternshipPersonnel)

2.1 后端代码

文件 路径 说明
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模式

关键设计:

  • /list 接口使用 queryPageList(参考FocusPersonnelController),从视图v_internship_personnel_list查询
  • 查询参数:fullName(模糊)、internshipStatus(精确)、auditStatus(精确)、postName(模糊)、companyName(模糊)
  • 权限前缀:internship_personnel
  • 排序:ORDER BY id DESC

2.2 前端代码

文件 路径 说明
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/ 弹窗组件

关键设计:

  • 查询区域:姓名(输入框)、见习状态(a-select: 见习中/已期满/已退出)、审核状态(a-select: 待审核/已通过/未通过)、见习单位(输入框)、见习岗位(输入框)
  • 表单字段:关联个人信息(personalId输入框)、关联见习岗位(internshipPostId输入框)、见习状态(下拉框)、见习开始日期(日期选择器)、见习结束日期(日期选择器)、审核状态(下拉框)、审核意见(文本域)

2.3 Flyway菜单SQL

文件 路径
V20260603_6__menu_insert_InternshipPersonnel.sql flyway/sql/mysql/

菜单结构:

  • 二级菜单"见习人员管理":id=178060100000032,parent_id=178060100000030(见习管理)
  • 按钮权限:add(1780601000000321), edit(1780601000000322), delete(1780601000000323), deleteBatch(1780601000000324), exportXls(1780601000000325), importExcel(1780601000000326)
  • 角色授权:ID从1780601000000327开始

三、注意事项

  1. 所有Java注释使用中文
  2. Flyway SQL不使用反引号(达梦数据库兼容)
  3. 见习岗位模块的/list接口使用标准QueryGenerator模式(不需要视图)
  4. 见习人员模块的/list接口使用queryPageList模式(从视图v_internship_personnel_list查询)
  5. 实体类使用 @TableId(type = IdType.ASSIGN_ID)
  6. Controller 继承 JeecgController
  7. 前端表单下拉框使用 a-select 硬编码选项
  8. Flyway SQL中INSERT语句每行一个,不使用多行VALUES
  9. 见习岗位表单的身份要求使用 a-checkbox-group,存储为逗号分隔字符串

四、见习人员详情与服务跟进组件开发(2026-06-04)

4.1 修改文件

文件 路径 说明
InternshipPersonnel.api.ts views/internshippersonnel/ 新增queryDetailById、listCustomTags、listCustomTagsPage、addCustomTagItem、deleteCustomTagItem、updateCustomTagItem、batchUpdateCustomTag、listServiceFollow、addServiceFollow、editServiceFollow、deleteServiceFollow等API函数

4.2 新增文件

文件 路径 说明
InternshipPersonnelDetail.vue views/internshippersonnel/components/ 见习人员详情组件,参照FocusPersonnelDetail改造
InternshipPersonnelServiceFollowList.vue views/internshippersonnel/components/ 见习人员服务跟进列表组件,参照FocusPersonnelServiceFollowList改造

4.3 InternshipPersonnelDetail.vue 与 FocusPersonnelDetail.vue 的差异

  • API路径:使用 /internshipPersonnel/queryDetailById 而非 /focusPersonnel/queryDetailById
  • 标签字段:没有 majorTag/minorTag(人员大类/小类标签),但有 customTag 自定义标签
  • 自定义标签字典:使用 internship_custom_tag 而非 focus_custom_tag
  • 见习特有字段:internshipStatus(见习状态)、startDate(见习开始日期)、endDate(见习结束日期)、auditStatus(审核状态)、auditOpinion(审核意见)、postName(见习岗位)、companyName(见习单位)
  • 布局调整
    • 顶部概要:姓名、性别、年龄、学历、电话、求职状态、见习状态、见习岗位、见习单位
    • 见习信息区域:独立分组展示见习状态、见习岗位、见习单位、见习开始/结束日期、审核状态、审核意见
    • 个人信息区域:证件类型、证件号码、出生日期、民族、国籍、婚姻状况、政治面貌、学历、毕业日期、毕业院校、专业、工作经验、技能等级、户口性质、户口所在地、现居住地、现居住地址、求职人员类别、联系方式、是否留学人才、求职状态、是否接受推荐
    • 自定义标签区域:与FocusPersonnelDetail相同的编辑功能,使用internship_custom_tag字典
  • CSS类名:使用 internship-personnel-detail 而非 focus-personnel-detail

4.4 InternshipPersonnelServiceFollowList.vue 与 FocusPersonnelServiceFollowList.vue 的差异

  • API路径:使用 /internshipPersonnelServiceFollow/* 而非 /focusPersonnelServiceFollow/*
  • 关联字段:使用 internshipPersonnelId 而非 focusPersonnelId
  • API导入:从 ../InternshipPersonnel.api 导入
  • 权限:使用 internship_personnel:serviceFollow

4.5 后端改造(2026-06-04)

参照重点关注人员模块(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

4.6 SQL脚本

文件 路径 说明
见习人员字典.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/ 见习人员字典数据初始化

4.7 部署步骤

  1. 执行建表SQL:.docs/sql/见习人员服务跟进表.sql
  2. 执行字段新增SQL:.docs/sql/见习人员表新增自定义标签字段.sql
  3. 重建视图:.docs/sql/见习人员视图.sql(DROP后CREATE)
  4. Flyway会自动执行:V20260604_2(菜单权限)和 V20260604_3(字典数据)
  5. 重新编译部署后端服务
  6. 重新构建部署前端服务

五、见习人员管理完全参照重点关注人员改造(2026-06-04 续)

5.1 改造目标

完全参照重点关注人员模块(FocusPersonnel)实现见习人员管理,两个模块功能一致,只有业务字段差异。

5.2 修改文件清单

后端修改

文件 修改内容
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

5.3 Flyway迁移脚本

文件 说明
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从该表加载)

5.4 达梦数据库兼容问题修复记录

问题1:V20260604_7 CAST错误

  • 错误[22018] Fail to cast string (-6111)
  • 原因:internship_major_tag/internship_minor_tag 的 sys_dict_item.item_value 存的是中文文本(如"见习人员"、"离校2年内未就业高校毕业生"),无法 CAST 为 INT
  • 修复:所有三个字典迁移都使用 ROWNUM 生成 Value 值,不再 CAST item_value
  • 注意:Flyway已记录V20260604_7为失败状态,修复后需手动执行该SQL

问题2:见习人员管理_全部重建.sql 达梦不兼容

  • 错误1TIMESTAMPDIFF(YEAR, birth_date, CURDATE()) 是MySQL函数,达梦不支持
  • 修复1:改为 FLOOR(MONTHS_BETWEEN(CURRENT_DATE, birth_date) / 12)
  • 错误2:CREATE TABLE 中内联 COMMENT 关键字,达梦不支持
  • 修复2:拆分为 CREATE TABLE + COMMENT ON COLUMN 单独语句
  • 错误3CURDATE() 是MySQL函数
  • 修复3:改为 CURRENT_DATE

5.5 手动执行脚本

由于Flyway可能已记录失败状态,以下SQL需要手动在数据库中执行:

  1. 见习人员管理_全部重建.sql.docs/sql/见习人员管理_全部重建.sql(DROP并重建所有表+视图+测试数据)
  2. V20260604_7迁移脚本:手动执行修复后的SQL,将字典数据插入DICTIONARY_ITEM表
  3. V20260604_10清理旧字典:清理sys_dict/sys_dict_item中的旧标签数据

六、见习人员管理Bug修复(2026-06-05)

6.1 修复清单

完全参照重点关注人员模块,修复见习人员管理的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

6.2 修改文件详细说明

前端修改

InternshipPersonnelList.vue

  • beforeFetchasync 改为同步函数,显式 return params(避免useListPage包装逻辑中返回值被忽略的问题)
  • 性别搜索 <a-select-option value="1">男性</a-select-option> / <a-select-option value="2">女性</a-select-option>(与数据库数字存储格式一致)
  • 新增 genderMap 映射和 bodyCell 插槽性别翻译(兼容数字和文本两种格式)

FocusPersonnelList.vue(同步修复)

  • 性别搜索值从"男性"/"女性"改为"1"/"2"
  • 新增 genderMap 映射和 bodyCell 插槽性别翻译
  • beforeFetchasync 改为同步函数

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 调用

Flyway脚本修改

  • V20260604_7__cleanup_old_sys_dict_tags.sql 重命名为 V20260604_10__cleanup_old_sys_dict_tags.sql(避免与迁移脚本版本号冲突)

6.3 标签存储格式说明

见习人员与重点关注人员的标签存储格式统一为数字值

  • 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 字段为显示文本

七、见习人员管理Bug修复第二轮(2026-06-05)

7.1 修复清单

序号 问题描述 修复方案 涉及文件
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

7.2 修改文件详细说明

权限修复

V20260604_2__menu_insert_InternshipPersonnelServiceFollow.sql

  • 服务跟进权限ID从 1780601000000327 改为 1780601000000340(避免与V20260603_6中角色授权ID冲突)
  • 角色授权ID从 1780601000000334 改为 1780601000000341
  • 补充导出权限 internship_personnel:exportXls 的角色授权(使用NOT EXISTS防重复)
  • 所有INSERT改为 SELECT ... FROM DUAL WHERE NOT EXISTS 格式(幂等执行)

前端修改

InternshipPersonnelList.vue

  • useDict 增加 'JobSeekerStatus' 字典编码
  • 新增 jobSearchStatusOptions 计算属性(从字典加载求职状态选项)
  • 搜索区域"就业状态"改为"求职状态",下拉选项从硬编码改为字典选项
  • bodyCell插槽新增 jobSearchStatus 翻译(getDictText('JobSeekerStatus', text)
  • 标签样式统一:majorTag<a-tag color="blue">minorTag<a-tag color="green">customTag<a-tag color="orange">
  • 空值标签显示 -

FocusPersonnelList.vue(同步修复)

  • 同上所有修改,保持与见习人员模块一致

7.3 需要手动执行的数据库操作

  1. 修复权限数据:执行 .docs/sql/修复见习人员权限数据.sql(修复导出按钮和服务跟进新增按钮不显示的问题)
  2. 确认字典数据:确保 DICTIONARY_ITEM 表中 JobSeekerStatus 字典数据已存在(参考 .docs/sql/数据字典数据插入.sql
  3. 确认标签字典数据:确保 internship_major_taginternship_minor_taginternship_custom_tag 字典数据已存在(参考 V20260604_7 脚本)
  4. 执行后需重新登录:权限数据修改后需要重新登录系统,让后端重新加载权限码列表

7.4 第三轮修复(2026-06-05 续)

序号 问题描述 修复方案 涉及文件
1 标签样式不应该用tag组件,应该和列表普通文本一样 列表bodyCell中标签改为纯文本显示(与重点关注人员一致),详情页保留tag样式 InternshipPersonnelList.vue、FocusPersonnelList.vue
2 导出和新增按钮不显示 根本原因是数据库权限数据冲突,创建独立修复SQL脚本 .docs/sql/修复见习人员权限数据.sql
3 详情页自定义标签不显示 详情页header区域自定义标签缺少字典翻译(直接显示数字) InternshipPersonnelDetail.vue、FocusPersonnelDetail.vue

7.5 第四轮修复 - 根本原因分析(2026-06-05)

核心发现

经过深入对比重点关注人员的实现,找到了导出按钮和服务跟进新增按钮不显示的根本原因

后端 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 = NULLV20260604_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冲突修复、字典数据保障、旧数据清理

综合修复SQL说明(.docs/sql/修复见习人员权限数据.sql)

部分 修复内容 解决的问题
第一部分 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中的旧数据 避免旧字典数据干扰
第五部分 验证修复结果 确认所有修复生效

执行步骤

  1. 在达梦数据库中执行 .docs/sql/修复见习人员权限数据.sql
  2. 重新登录系统(权限数据修改后需要重新登录才能生效)
  3. 验证导出按钮、服务跟进新增按钮、自定义标签显示是否正常

7.6 第五轮修复 - 求职人员类别显示数字 + 自定义标签不显示(2026-06-05)

问题1:求职人员类别列表显示数字

根本原因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翻译

问题2:自定义标签不显示

根本原因:DICTIONARY/DICTIONARY_ITEM表中可能缺少字典数据。V20260604_7脚本可能因之前的CAST错误未成功执行,且数据字典数据插入.sql使用了双引号(达梦不兼容)。

修复方案:在综合修复SQL中增加JobSeekerCategory和JobSeekerStatus字典数据保障。

文件 修改内容
.docs/sql/修复见习人员权限数据.sql 增加3.5节JobSeekerCategory字典数据、3.6节JobSeekerStatus字典数据

7.7 第六轮修复 - 详情页自定义标签有数据但不显示(2026-06-05)

根本原因:后端详情查询遗漏了 custom_tag 字段。

  • InternshipPersonnelDetailVo 缺少 customTag 字段
  • InternshipPersonnelMapper.xmlqueryDetailById SQL 遗漏了 ip.custom_tag AS customTag
  • 重点关注人员的 FocusPersonnelDetailVoFocusPersonnelMapper.xml 都有 customTag 字段,见习人员遗漏了

修复方案:参照重点关注人员,补全缺失的字段和SQL。

文件 修改内容
InternshipPersonnelDetailVo.java 添加 customTag 字段(在 minorTag 之后)
InternshipPersonnelMapper.xml queryDetailById SQL 添加 ip.custom_tag AS customTag

2026-06-10 修复与优化记录

菜单恢复

  • DM8 数据库中见习岗位管理(178060100000031)和见习人员管理(178060100000032)菜单项被删除,已重建
  • 图标恢复:见习岗位=ant-design:audit-outlined,见习人员=ant-design:user-outlined
  • 已加入 admin 角色授权

前端修复

  • 导出按钮补 v-auth 指令(见习岗位=internship_post:exportXls、见习人员=internship_personnel:exportXls

其他模块同批修复

  • 公益性岗位管理:导出按钮补 v-auth="welfare_post:exportXls"
  • 岗位推荐:导出按钮补 v-auth="job_recommend:exportXls"
  • 重点关注人员:户口所在地/现居住地加XZQH字典翻译,性别改用字典

八、2026-06-11 修复 — 见习岗位/公益性岗位导出按钮不显示

问题现象

信息智能匹配推送 → 见习岗位管理、公益性岗位管理 — 导出按钮不显示

根本原因

后端 SysPermissionController 构建权限码列表(codeList)时过滤条件为 status = '1',但 Flyway 脚本 V20260603_5V20260603_7 插入按钮权限时 status 字段值为 NULL,导致后端不返回这些权限码。前端 v-auth 指令检查不到权限则从 DOM 中移除按钮。

修复方案

  1. 执行 .docs/sql/修复见习岗位和公益性岗位导出按钮权限.sql
  2. 重新登录系统(权限数据修改后需重新登录让后端重新加载权限码列表)

九、2026-06-11 信息智能推送模块 — 搜索条件与列表翻译全面修复

问题现象

信息智能匹配推送下 5 个子菜单(重点关注人员、见习岗位、见习人员、公益性岗位、岗位推荐)存在以下问题:

  1. 搜索下拉框使用硬编码 <a-select-option>,非从字典表动态加载
  2. 区县字段使用文本输入框,应改为 XZQH 树形下拉
  3. 见习岗位/公益性岗位/岗位推荐缺少 <template #bodyCell> 字典翻译插槽,列表显示原始值
  4. 列表翻译显示数字而非中文

前端修复 — useDict.ts 核心优化

src/hooks/dictionary/useDict.ts:

  • getDictText: 新增 Code 匹配回退,同时尝试 valuecode 两种方式匹配字典项
  • 缓存映射: 优先使用 item.code(VARCHAR)作为选项值,解决 Value(INT) 与 DB 文本字段不匹配问题。Code 为空时回退到 String(item.value)

前端修复 — 5 个列表页面

模块 文件 改动
重点关注人员 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项)

前端修复 — 3 个 data.ts

文件 改动
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)

字典值类型规则

  • 数值型字段(DB存'0'/'1'等):Code='',Value存INT,getDictText 通过 String(Value)===String(data) 匹配
  • 文本型字段(DB存'国有企业'等):Code存文本值,Value存序号(INT),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) 匹配:

  • focus_major_tag(2条), focus_minor_tag(16条), focus_custom_tag(3条)
  • internship_major_tag(1条), internship_minor_tag(2条), internship_custom_tag(8条)

自定义标签迁移到个人标签库

自定义标签选项和显示改用 personal_tag 表(求职信息库→个人标签库):

模块 personal_tag 父级 ID API
重点关注人员 2064950954964254722 /tag/personalTag/listForSelect?parentId=xxx&tagLevel=2
见习人员 2064950598742016001 同上

bodyCell 使用三级回退兼容新旧数据:

  1. customTagMap[val] — personal_tag UUID 查找
  2. getDictText(..., val) — DICTIONARY_ITEM 数值查找(旧数据)
  3. val — 原始值兜底

字典表数据源说明

  • 前端 useDict/system/dictionary/getDictBatch → 自定义 DictionaryControllerDICTIONARY/DICTIONARY_ITEM
  • Flyway 脚本 (V20260605_3) → sys_dict/sys_dict_item 表 → 未被 useDict 使用
  • 所有字典数据必须在 DICTIONARY/DICTIONARY_ITEM 表中才能被前端加载

十、2026-06-11 详情页与地址显示全面修复

查看详情页字典翻译修复

所有 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)

buildXzqhPath 实现

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.childrentreeNode.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 程序化定位)。

internship_status / audit_status Code 回退修正

初始误清空了 Code,后恢复为文本值(因 DB 存储的是 '见习中' 等文本,非数值):

  • internship_status: Code='见习中'/'已期满'/'已退出'
  • audit_status: Code='待审核'/'已通过'/'未通过'

2026-06-12 导出字典翻译修复

问题

导出Excel时性别、学历等字典字段显示为原始编码,日期格式异常。

修复文件

文件 修改
IInternshipPersonnelService.java 新增 translateDictFieldsForPageVo() 方法
InternshipPersonnelServiceImpl.java 注入 IDictionaryItemService,批量查询字典 → switch-case替换字段值为标签
InternshipPersonnelController.java 重写 exportXls:查询 InternshipPersonnelPageVo 数据 → 过滤选中 → 字典翻译 → 导出为 .xlsx

2026-06-12 岗位推送功能实现

问题

列表操作栏"岗位推送"按钮为占位状态,点击提示"岗位推送功能待开发"。

实现方案

复用 JobRecommend 模块的 /jobRecommend/add 接口,前端新增通用 JobPushModal 弹窗供用户选择岗位后推送。

后端修改(JobRecommend 模块)

文件 修改
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),后端自动填充推荐人/机构/时间