Remove obsolete export APIs and persist recruitment work history

This commit is contained in:
wkc
2026-04-22 13:38:43 +08:00
parent 94507e3747
commit 0c5fa6b2c8
47 changed files with 823 additions and 408 deletions

View File

@@ -80,18 +80,6 @@ public class CcdiAccountInfoController extends BaseController {
return success(accountInfoService.selectAccountInfoById(id));
}
/**
* 导出账户库列表
*/
@Operation(summary = "导出账户库列表")
@PreAuthorize("@ss.hasPermi('ccdi:accountInfo:export')")
@Log(title = "账户库管理", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, CcdiAccountInfoQueryDTO queryDTO) {
List<CcdiAccountInfoExcel> list = accountInfoService.selectAccountInfoListForExport(queryDTO);
EasyExcelUtil.exportExcel(response, list, CcdiAccountInfoExcel.class, "账户库管理");
}
/**
* 新增账户
*/

View File

@@ -70,18 +70,6 @@ public class CcdiBaseStaffController extends BaseController {
return success(list);
}
/**
* 导出员工列表
*/
@Operation(summary = "导出员工列表")
@PreAuthorize("@ss.hasPermi('ccdi:baseStaff:export')")
@Log(title = "员工信息", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, CcdiBaseStaffQueryDTO queryDTO) {
List<CcdiBaseStaffExcel> list = baseStaffService.selectBaseStaffListForExport(queryDTO);
EasyExcelUtil.exportExcel(response, list, CcdiBaseStaffExcel.class, "员工信息");
}
/**
* 获取员工详细信息
*/

View File

@@ -63,18 +63,6 @@ public class CcdiCustEnterpriseRelationController extends BaseController {
return getDataTable(result.getRecords(), result.getTotal());
}
/**
* 导出信贷客户实体关联列表
*/
@Operation(summary = "导出信贷客户实体关联列表")
@PreAuthorize("@ss.hasPermi('ccdi:custEnterpriseRelation:export')")
@Log(title = "信贷客户实体关联信息", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, CcdiCustEnterpriseRelationQueryDTO queryDTO) {
List<CcdiCustEnterpriseRelationExcel> list = relationService.selectRelationListForExport(queryDTO);
EasyExcelUtil.exportExcel(response, list, CcdiCustEnterpriseRelationExcel.class, "信贷客户实体关联信息");
}
/**
* 获取信贷客户实体关联详细信息
*/

View File

@@ -103,17 +103,6 @@ public class CcdiCustFmyRelationController extends BaseController {
return toAjax(relationService.deleteRelationByIds(ids));
}
/**
* 导出信贷客户家庭关系
*/
@Operation(summary = "导出信贷客户家庭关系")
@PreAuthorize("@ss.hasPermi('ccdi:custFmyRelation:export')")
@Log(title = "信贷客户家庭关系", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, CcdiCustFmyRelationQueryDTO query) {
relationService.exportRelations(query, response);
}
/**
* 下载带字典下拉框的导入模板
* 使用@DictDropdown注解自动添加下拉框

View File

@@ -63,18 +63,6 @@ public class CcdiPurchaseTransactionController extends BaseController {
return getDataTable(result.getRecords(), result.getTotal());
}
/**
* 导出采购交易列表
*/
@Operation(summary = "导出采购交易列表")
@PreAuthorize("@ss.hasPermi('ccdi:purchaseTransaction:export')")
@Log(title = "采购交易信息", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, CcdiPurchaseTransactionQueryDTO queryDTO) {
List<CcdiPurchaseTransactionExcel> list = transactionService.selectTransactionListForExport(queryDTO);
EasyExcelUtil.exportExcel(response, list, CcdiPurchaseTransactionExcel.class, "采购交易信息");
}
/**
* 获取采购交易详细信息
*/

View File

@@ -63,18 +63,6 @@ public class CcdiStaffEnterpriseRelationController extends BaseController {
return getDataTable(result.getRecords(), result.getTotal());
}
/**
* 导出员工实体关系列表
*/
@Operation(summary = "导出员工实体关系列表")
@PreAuthorize("@ss.hasPermi('ccdi:staffEnterpriseRelation:export')")
@Log(title = "员工实体关系信息", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, CcdiStaffEnterpriseRelationQueryDTO queryDTO) {
List<CcdiStaffEnterpriseRelationExcel> list = relationService.selectRelationListForExport(queryDTO);
EasyExcelUtil.exportExcel(response, list, CcdiStaffEnterpriseRelationExcel.class, "员工实体关系信息");
}
/**
* 获取员工实体关系详细信息
*/

View File

@@ -63,18 +63,6 @@ public class CcdiStaffFmyRelationController extends BaseController {
return getDataTable(result.getRecords(), result.getTotal());
}
/**
* 导出员工亲属关系列表
*/
@Operation(summary = "导出员工亲属关系列表")
@PreAuthorize("@ss.hasPermi('ccdi:staffFmyRelation:export')")
@Log(title = "员工亲属关系", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, CcdiStaffFmyRelationQueryDTO queryDTO) {
List<CcdiStaffFmyRelationExcel> list = relationService.selectRelationListForExport(queryDTO);
EasyExcelUtil.exportExcel(response, list, CcdiStaffFmyRelationExcel.class, "员工亲属关系信息");
}
/**
* 获取员工亲属关系详细信息
*/

View File

@@ -64,18 +64,6 @@ public class CcdiStaffRecruitmentController extends BaseController {
return getDataTable(result.getRecords(), result.getTotal());
}
/**
* 导出招聘信息列表
*/
@Operation(summary = "导出招聘信息列表")
@PreAuthorize("@ss.hasPermi('ccdi:staffRecruitment:export')")
@Log(title = "员工招聘信息", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, CcdiStaffRecruitmentQueryDTO queryDTO) {
List<CcdiStaffRecruitmentExcel> list = recruitmentService.selectRecruitmentListForExport(queryDTO);
EasyExcelUtil.exportExcel(response, list, CcdiStaffRecruitmentExcel.class, "员工招聘信息");
}
/**
* 获取招聘信息详细信息
*/

View File

@@ -63,18 +63,6 @@ public class CcdiStaffTransferController extends BaseController {
return getDataTable(result.getRecords(), result.getTotal());
}
/**
* 导出员工调动记录列表
*/
@Operation(summary = "导出员工调动记录列表")
@PreAuthorize("@ss.hasPermi('ccdi:staffTransfer:export')")
@Log(title = "员工调动记录", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, CcdiStaffTransferQueryDTO queryDTO) {
List<CcdiStaffTransferExcel> list = transferService.selectTransferListForExport(queryDTO);
EasyExcelUtil.exportExcel(response, list, CcdiStaffTransferExcel.class, "员工调动记录信息");
}
/**
* 获取员工调动记录详细信息
*/

View File

@@ -7,10 +7,12 @@ import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import jakarta.validation.Valid;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
/**
* 员工招聘信息编辑DTO
@@ -91,4 +93,8 @@ public class CcdiStaffRecruitmentEditDTO implements Serializable {
/** 面试官2工号 */
@Size(max = 10, message = "面试官2工号长度不能超过10个字符")
private String interviewerId2;
/** 历史工作经历列表 */
@Valid
private List<CcdiStaffRecruitmentWorkEditDTO> workExperienceList;
}

View File

@@ -0,0 +1,56 @@
package com.ruoyi.info.collection.domain.dto;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 招聘记录历史工作经历编辑DTO
*
* @author ruoyi
* @date 2026-04-22
*/
@Data
public class CcdiStaffRecruitmentWorkEditDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 排序号 */
private Integer sortOrder;
/** 工作单位 */
@Size(max = 200, message = "工作单位长度不能超过200个字符")
private String companyName;
/** 所属部门 */
@Size(max = 100, message = "所属部门长度不能超过100个字符")
private String departmentName;
/** 岗位名称 */
@Size(max = 100, message = "岗位名称长度不能超过100个字符")
private String positionName;
/** 入职年月 */
@Pattern(regexp = "^$|^((19|20)\\d{2})-(0[1-9]|1[0-2])$", message = "入职年月格式不正确,应为YYYY-MM")
private String jobStartMonth;
/** 离职年月 */
@Pattern(regexp = "^$|^((19|20)\\d{2})-(0[1-9]|1[0-2])$", message = "离职年月格式不正确,应为YYYY-MM")
private String jobEndMonth;
/** 离职原因 */
@Size(max = 500, message = "离职原因长度不能超过500个字符")
private String departureReason;
/** 主要工作内容 */
@Size(max = 1000, message = "主要工作内容长度不能超过1000个字符")
private String workContent;
/** 备注 */
@Size(max = 500, message = "备注长度不能超过500个字符")
private String remark;
}

View File

@@ -7,11 +7,13 @@ import com.ruoyi.info.collection.domain.CcdiStaffRecruitmentWork;
import com.ruoyi.info.collection.domain.dto.CcdiStaffRecruitmentAddDTO;
import com.ruoyi.info.collection.domain.dto.CcdiStaffRecruitmentEditDTO;
import com.ruoyi.info.collection.domain.dto.CcdiStaffRecruitmentQueryDTO;
import com.ruoyi.info.collection.domain.dto.CcdiStaffRecruitmentWorkEditDTO;
import com.ruoyi.info.collection.domain.excel.CcdiStaffRecruitmentExcel;
import com.ruoyi.info.collection.domain.excel.CcdiStaffRecruitmentWorkExcel;
import com.ruoyi.info.collection.domain.vo.CcdiStaffRecruitmentVO;
import com.ruoyi.info.collection.domain.vo.CcdiStaffRecruitmentWorkVO;
import com.ruoyi.info.collection.enums.AdmitStatus;
import com.ruoyi.info.collection.enums.RecruitType;
import com.ruoyi.info.collection.mapper.CcdiStaffRecruitmentWorkMapper;
import com.ruoyi.info.collection.mapper.CcdiStaffRecruitmentMapper;
import com.ruoyi.info.collection.service.ICcdiStaffRecruitmentImportService;
@@ -28,6 +30,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@@ -151,6 +154,7 @@ public class CcdiStaffRecruitmentServiceImpl implements ICcdiStaffRecruitmentSer
CcdiStaffRecruitment recruitment = new CcdiStaffRecruitment();
BeanUtils.copyProperties(editDTO, recruitment);
int result = recruitmentMapper.updateById(recruitment);
replaceWorkExperienceList(editDTO);
return result;
}
@@ -262,4 +266,43 @@ public class CcdiStaffRecruitmentServiceImpl implements ICcdiStaffRecruitmentSer
return vo;
}).toList();
}
private void replaceWorkExperienceList(CcdiStaffRecruitmentEditDTO editDTO) {
LambdaQueryWrapper<CcdiStaffRecruitmentWork> deleteWrapper = new LambdaQueryWrapper<>();
deleteWrapper.eq(CcdiStaffRecruitmentWork::getRecruitId, editDTO.getRecruitId());
if (!Objects.equals(RecruitType.SOCIAL.getCode(), editDTO.getRecruitType())) {
recruitmentWorkMapper.delete(deleteWrapper);
return;
}
if (editDTO.getWorkExperienceList() == null) {
return;
}
recruitmentWorkMapper.delete(deleteWrapper);
List<CcdiStaffRecruitmentWork> workList = buildWorkExperienceEntities(editDTO);
workList.forEach(recruitmentWorkMapper::insert);
}
private List<CcdiStaffRecruitmentWork> buildWorkExperienceEntities(CcdiStaffRecruitmentEditDTO editDTO) {
List<CcdiStaffRecruitmentWorkEditDTO> workExperienceList = editDTO.getWorkExperienceList();
if (workExperienceList == null || workExperienceList.isEmpty()) {
return new ArrayList<>();
}
List<CcdiStaffRecruitmentWork> entityList = new ArrayList<>();
for (int i = 0; i < workExperienceList.size(); i++) {
CcdiStaffRecruitmentWorkEditDTO item = workExperienceList.get(i);
if (item == null || StringUtils.isBlank(item.getCompanyName()) || StringUtils.isBlank(item.getJobStartMonth())) {
continue;
}
CcdiStaffRecruitmentWork work = new CcdiStaffRecruitmentWork();
BeanUtils.copyProperties(item, work);
work.setRecruitId(editDTO.getRecruitId());
work.setSortOrder(i + 1);
entityList.add(work);
}
return entityList;
}
}

View File

@@ -0,0 +1,47 @@
# 信息维护移除导出与菜单排序后端实施计划
**Goal:** 移除信息维护相关模块的后端导出接口与导出权限,并通过增量 SQL 统一“信息维护”目录下的菜单顺序。
**Architecture:** 后端仅收口 `ccdi-info-collection` 控制器层的 `/export` 接口,不调整列表、详情、导入与删除链路;菜单治理通过 `sql/migration` 新增一份可重复执行脚本完成,脚本同时删除导出权限按钮并更新 `order_num`
**Tech Stack:** Java 21, Spring Boot 3, MyBatis Plus, MySQL, Markdown
---
## 文件结构与职责
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/`
移除信息维护模块各控制器的 `/export` 接口。
- `sql/migration/2026-04-22-remove-info-maintenance-export-and-sort-menus.sql`
删除导出权限菜单并统一“信息维护”子菜单排序。
- `sql/*.sql`
修正仓库内已有菜单脚本,避免新库初始化时继续带出导出权限或错误顺序。
## 实施步骤
- [x] 盘点信息维护模块现存 `/export` 接口与导出权限点
- [x] 移除员工、关系、招聘、调动、采购、账户等模块的控制器导出接口
- [x] 新增菜单增量脚本,删除导出权限并统一菜单排序
- [x] 同步修正仓库内已有菜单 SQL避免新环境重新带回导出权限
- [x] 运行检索校验,确认控制器层不再暴露信息维护导出接口
## 验证
```bash
rg -n "@PostMapping\\(\"/export\"\\)|hasPermi\\('ccdi:.*:export'\\)" \
ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiAccountInfoController.java \
ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiBaseStaffController.java \
ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiCustEnterpriseRelationController.java \
ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiCustFmyRelationController.java \
ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiPurchaseTransactionController.java \
ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiStaffEnterpriseRelationController.java \
ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiStaffFmyRelationController.java \
ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiStaffRecruitmentController.java \
ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiStaffTransferController.java
```
## 完成标准
- 信息维护相关控制器不再提供 `/export` 接口
- “信息维护”菜单下相关导出权限按钮已可通过增量 SQL 清理
- 菜单排序调整为统一且可重复执行的固定顺序

View File

@@ -0,0 +1,36 @@
# 招聘信息历史工作经历手动编辑后端实施计划
## 文档信息
- 保存路径:`docs/plans/backend/2026-04-22-staff-recruitment-work-experience-manual-edit-plan.md`
- 适用范围:招聘信息管理编辑接口
- 需求目标:在招聘信息编辑页支持手动维护历史工作经历,并保证保存后落到 `ccdi_staff_recruitment_work` 子表
## 实施范围
1. 扩展招聘信息编辑 DTO允许接收历史工作经历列表。
2. 增加历史工作经历子项 DTO并对字符长度、年月格式进行基础校验。
3. 调整招聘信息编辑服务:
- 主表 `ccdi_staff_recruitment` 继续按原逻辑更新;
- 当招聘类型为 `SOCIAL` 且前端传入工作经历列表时,按招聘记录编号先删后插覆盖子表;
- 当招聘类型改为 `CAMPUS` 时,删除该记录已存在的历史工作经历。
## 实施步骤
1. 新增历史工作经历编辑 DTO约束 `companyName``departmentName``positionName`、年月等字段长度与格式。
2.`CcdiStaffRecruitmentEditDTO` 中增加 `workExperienceList` 字段,并启用嵌套校验。
3.`CcdiStaffRecruitmentServiceImpl.updateRecruitment` 中增加子表覆盖保存逻辑。
4. 保持详情查询逻辑不变,继续通过已有 `selectWorkExperienceList` 返回子表明细。
## 影响评估
- 仅影响招聘信息编辑接口,不影响招聘信息导入、详情查询、列表分页逻辑。
- 不新增数据库结构变更,不新增菜单或权限。
- 旧前端若未传 `workExperienceList`,社招编辑仍保留已有工作经历数据,不会被误删。
## 验证要点
1. 编辑社招记录时可提交多条历史工作经历并成功保存。
2. 编辑社招记录时删除全部历史工作经历后提交,子表数据应被清空。
3. 将社招记录改为校招后提交,历史工作经历应自动删除。
4. 非法年月格式或超长字段应被后端校验拒绝。

View File

@@ -0,0 +1,36 @@
# 员工信息维护资产表单单横向滚动实施计划
> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 修复员工信息维护页“新增员工”弹窗中资产信息表单出现两条横向滚动条的问题,仅保留一条可用横向滚动条。
**Architecture:** 本次仅调整 `ccdiBaseStaff` 页面资产编辑表格的容器样式,不改动资产字段、提交参数、接口结构和详情展示逻辑。实现路径为移除外层包裹容器的横向滚动能力,并取消表格根节点的强制最小宽度,让横向滚动统一由 `el-table` 内部负责。
**Tech Stack:** Vue 2, Element UI, JavaScript, Markdown
---
## 文件结构与职责
- `ruoyi-ui/src/views/ccdiBaseStaff/index.vue`
调整资产编辑表格容器样式,消除双横向滚动条。
## 实施步骤
- [x] 定位资产编辑表格双横向滚动条的成因
- [x] 删除外层滚动容器的横向滚动能力
- [x] 取消表格根节点的强制最小宽度,保留 `el-table` 内部横向滚动
- [x] 运行前端构建校验模板与样式改动未引入语法问题
- [x] 使用浏览器实际打开员工信息维护弹窗,确认资产表单只剩一条横向滚动条
## 验证
```bash
source ~/.nvm/nvm.sh && nvm use 14.21.3 >/dev/null && cd ruoyi-ui && npm run build:prod
```
## 完成标准
- 员工信息维护页资产信息编辑表格仅保留一条横向滚动条
- 资产字段录入、删除和提交交互保持不变
- 页面未新增额外横向滚动副作用

View File

@@ -0,0 +1,36 @@
# 信息维护移除导出与菜单排序前端实施计划
**Goal:** 移除信息维护相关页面中的导出按钮和前端下载逻辑,确保页面仅保留查询、新增、编辑、删除、导入等当前需要的能力。
**Architecture:** 前端只在现有信息维护页面内做删除型改动,直接移除按钮 DOM 与 `handleExport` 方法,不改动查询表单、表格展示、导入弹窗和失败记录查看能力;同时清理对应 API 文件中的导出封装,避免保留无效前端调用入口。
**Tech Stack:** Vue 2, Element UI, JavaScript, Markdown
---
## 文件结构与职责
- `ruoyi-ui/src/views/ccdi*/index.vue`
移除账户库、员工关系、客户关系、招聘、调动、采购等页面的导出按钮和下载方法。
- `ruoyi-ui/src/api/ccdi*.js`
删除不再使用的导出 API 封装。
## 实施步骤
- [x] 盘点信息维护中仍显示导出按钮的前端页面
- [x] 移除 8 个页面的导出按钮与 `handleExport` 方法
- [x] 清理对应 API 文件中的导出封装
- [x] 运行前端构建校验模板和脚本改动未引入语法问题
- [x] 使用 Playwright 在真实浏览器中确认侧边栏顺序与页面按钮状态
## 验证
```bash
source ~/.nvm/nvm.sh && nvm use 14.21.3 >/dev/null && cd ruoyi-ui && npm run build:prod
```
## 完成标准
- 信息维护相关页面不再展示“导出”按钮
- 页面中不再保留导出下载方法
- 前端导入、失败记录、详情和编辑交互保持正常

View File

@@ -0,0 +1,36 @@
# 员工亲属资产表单单横向滚动实施计划
> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 修复员工亲属关系维护页中亲属资产信息表单出现两条横向滚动条的问题,仅保留一条可用横向滚动条。
**Architecture:** 本次仅调整 `ccdiStaffFmyRelation` 页面亲属资产编辑表格的容器样式,不改动亲属资产字段、提交参数、接口结构和详情展示逻辑。实现路径与员工信息维护页保持一致:移除外层包裹容器的横向滚动能力,并取消表格根节点的强制最小宽度,让横向滚动统一由 `el-table` 内部负责。
**Tech Stack:** Vue 2, Element UI, JavaScript, Markdown
---
## 文件结构与职责
- `ruoyi-ui/src/views/ccdiStaffFmyRelation/index.vue`
调整亲属资产编辑表格容器样式,消除双横向滚动条。
## 实施步骤
- [x] 定位亲属资产编辑表格双横向滚动条的成因
- [x] 删除外层滚动容器的横向滚动能力
- [x] 取消表格根节点的强制最小宽度,保留 `el-table` 内部横向滚动
- [x] 运行前端构建校验模板与样式改动未引入语法问题
- [x] 使用浏览器实际打开员工亲属关系维护弹窗,确认亲属资产表单只剩一条横向滚动条
## 验证
```bash
source ~/.nvm/nvm.sh && nvm use 14.21.3 >/dev/null && cd ruoyi-ui && npm run build:prod
```
## 完成标准
- 员工亲属关系维护页亲属资产信息编辑表格仅保留一条横向滚动条
- 亲属资产字段录入、删除和提交交互保持不变
- 页面未新增额外横向滚动副作用

View File

@@ -0,0 +1,35 @@
# 招聘信息历史工作经历手动编辑前端实施计划
## 文档信息
- 保存路径:`docs/plans/frontend/2026-04-22-staff-recruitment-work-experience-manual-edit-plan.md`
- 适用范围:`ruoyi-ui/src/views/ccdiStaffRecruitment/index.vue`
- 需求目标:在招聘信息管理编辑页支持手动新增、删除并提交历史工作经历
## 实施范围
1. 在招聘信息编辑弹窗中,为社招记录增加“候选人历史工作经历”编辑区域。
2. 提供手动新增、删除经历行的交互能力。
3. 提交编辑时将历史工作经历列表一并传给后端。
4. 在前端提交前补充基础校验,避免空工作单位、空入职年月或错误年月范围直接提交。
## 实施步骤
1. 在编辑弹窗中新增工作经历表格,仅在“编辑 + 社招”场景展示。
2. 为每条经历提供工作单位、所属部门、岗位名称、入职年月、离职年月、离职原因、主要工作内容、备注输入项。
3. 将入职时间、离职时间改为月份选择器,避免手输年月格式。
4. 增加 `handleAddWorkExperience``handleRemoveWorkExperience``syncWorkExperienceSortOrder` 等方法维护列表顺序。
5. 在提交前执行工作经历校验,并按顺序规范化后再调用编辑接口。
## 交互约束
- 本次仅支持编辑页手动维护,不扩展新增页展示范围。
- 招聘类型为校招时不展示工作经历编辑区域。
- 保存时以当前表格内容覆盖后端已有历史工作经历。
## 验证要点
1. 打开社招编辑弹窗时可看到历史工作经历编辑区。
2. 可新增、删除多条经历,序号自动重排。
3. 入职年月、离职年月格式错误或离职早于入职时,页面阻止提交并提示。
4. 保存成功后再次打开详情/编辑页,工作经历展示与提交内容一致。

View File

@@ -0,0 +1,28 @@
# 员工信息维护资产表单单横向滚动实施记录
## 文档信息
- 保存路径:`docs/reports/implementation/2026-04-22-base-staff-asset-single-horizontal-scroll-implementation.md`
- 实施日期2026-04-22
- 关联范围:员工信息维护前端页面
## 本次修改内容
1. 定位到员工信息维护页资产编辑表格存在双横向滚动条,原因是外层 `assets-table-wrapper``el-table` 内层同时承担横向滚动。
2. 移除外层容器的 `overflow-x: auto`,避免包裹层再次生成横向滚动条。
3. 将资产编辑表格根节点从强制 `min-width` 调整为 `width: 100%`,保持表格横向滚动由 `el-table` 自身管理。
4. 新增本次前端实施计划与实施记录,沉淀问题定位、改动范围与验证要求。
## 影响范围
- 前端:`ruoyi-ui/src/views/ccdiBaseStaff/index.vue` 资产信息编辑弹窗样式。
- 文档:新增前端实施计划与实施记录。
## 验证情况
1. 前端构建校验:
- 执行命令:`source ~/.nvm/nvm.sh && nvm use 14.21.3 && cd ruoyi-ui && npm run build:prod`
- 结果:构建成功;存在项目原有的 bundle size warnings本次改动未引入构建失败。
2. Playwright 浏览器实测:
- 执行方式:通过 `nvm use 25.9.0` 启动 `playwright-cli`,在浏览器中 mock 登录态与员工信息维护页最小依赖接口后打开 `/maintain/baseStaff`,进入“新增员工”弹窗并新增一条资产记录。
- 结果:资产表单外层包装器 `clientWidth=984``scrollWidth=984``overflowX=visible``el-table` 内部滚动区 `clientWidth=982``scrollWidth=1560``overflowX=auto`。说明外层不再生成横向滚动条,仅保留表格内部一条横向滚动条。

View File

@@ -0,0 +1,75 @@
# 信息维护移除导出与菜单排序实施记录
## 文档信息
- 保存路径:`docs/reports/implementation/2026-04-22-info-maintenance-remove-export-and-menu-sort-implementation.md`
- 实施日期2026-04-22
- 关联计划:
- `docs/plans/backend/2026-04-22-info-maintenance-remove-export-and-menu-sort-backend-implementation.md`
- `docs/plans/frontend/2026-04-22-info-maintenance-remove-export-and-menu-sort-frontend-implementation.md`
## 本次修改内容
1. 移除信息维护下 8 个前端页面中的“导出”按钮和对应 `handleExport` 下载逻辑,覆盖账户库、员工/客户关系、采购交易、招聘、调动等当前仍暴露导出的页面。
2. 删除信息维护相关控制器中的 `/export` 接口,包括员工信息维护中仅后端残留的导出接口,避免前后端出现一端已删、一端仍可访问的链路分叉。
3. 清理对应前端 API 文件中的导出封装,避免保留无实际使用价值的调用入口。
4. 新增 `sql/migration/2026-04-22-remove-info-maintenance-export-and-sort-menus.sql`,用于删除信息维护导出权限按钮并统一“信息维护”子菜单顺序。
5. 同步修正仓库内已有菜单 SQL确保新库初始化时不再带出导出按钮且菜单默认顺序与本次规则一致。
## 菜单排序口径
“信息维护”目录下菜单统一按以下顺序排列:
1. 员工信息维护
2. 招聘信息维护
3. 员工调动记录
4. 员工亲属关系维护
5. 员工实体关系维护
6. 征信维护
7. 实体库管理
8. 中介库管理
9. 账户库管理
10. 信贷客户家庭关系
11. 信贷客户实体关联
12. 采购交易管理
## 影响范围
- 前端:
- `ruoyi-ui/src/views/ccdiAccountInfo/index.vue`
- `ruoyi-ui/src/views/ccdiCustEnterpriseRelation/index.vue`
- `ruoyi-ui/src/views/ccdiCustFmyRelation/index.vue`
- `ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue`
- `ruoyi-ui/src/views/ccdiStaffEnterpriseRelation/index.vue`
- `ruoyi-ui/src/views/ccdiStaffFmyRelation/index.vue`
- `ruoyi-ui/src/views/ccdiStaffRecruitment/index.vue`
- `ruoyi-ui/src/views/ccdiStaffTransfer/index.vue`
- 后端:
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/` 下 9 个信息维护控制器
- SQL
- `sql/migration/2026-04-22-remove-info-maintenance-export-and-sort-menus.sql`
- `sql/ccdi_credit_info_menu.sql`
- `sql/ccdi_cust_fmy_relation_menu.sql`
- `sql/ccdi_purchase_transaction_menu.sql`
- `sql/ccdi_staff_fmy_relation_menu.sql`
- `sql/dpc_intermediary_blacklist.sql`
- `sql/menu-intermediary.sql`
- `sql/migration/2026-04-13-add-ccdi-account-info-menu.sql`
- `sql/migration/2026-04-17-add-enterprise-base-info-menu.sql`
## 验证情况
1. 文本回归校验:
- 使用 `rg` 检查信息维护相关页面后,已不再发现“导出”按钮文本、`handleExport` 方法以及对应的导出下载路径。
- 使用 `rg` 检查后端控制器后,已不再发现信息维护相关 `/export` 接口和 `ccdi:*:export` 权限声明。
2. 后端编译校验:
- 执行命令:`mvn -pl ccdi-info-collection -am compile -DskipTests`
- 结果:编译成功;存在模块 `ccdi-info-collection` 的历史重复依赖告警,但本次改动未引入新的编译错误。
3. 前端构建校验:
- 执行命令:`source ~/.nvm/nvm.sh && nvm use 14.21.3 >/dev/null && cd ruoyi-ui && npm run build:prod`
- 结果:构建成功;仅存在项目原有的 bundle size warnings本次改动未引入新的构建错误。
4. Playwright 浏览器实测:
- 执行方式:通过 `nvm` 切换 Node 版本后启动前端页面,使用 Playwright 打开真实浏览器验证信息维护菜单顺序及页面按钮状态。
- 结果:在 mock 登录态与最小接口夹具下打开 `http://127.0.0.1:8080/maintain/baseStaff`,读取到“信息维护”子菜单顺序为“员工信息维护 -> 招聘信息维护 -> 员工调动记录 -> 员工亲属关系维护 -> 员工实体关系维护 -> 征信维护 -> 实体库管理 -> 中介库管理 -> 账户库管理 -> 信贷客户家庭关系 -> 信贷客户实体关联 -> 采购交易管理”,与本次排序一致。
- 结果:继续在 `accountInfo``custEnterpriseRelation``custFmyRelation``purchaseTransaction``staffEnterpriseRelation``staffFmyRelation``staffRecruitment``staffTransfer` 8 个页面读取按钮文本,均未出现“导出”按钮。
- 结果:已生成浏览器截图 `.playwright-cli/page-2026-04-22T03-10-32-002Z.png` 作为页面验证留痕,并在验证后关闭 Playwright 浏览器与前端 dev server。

View File

@@ -0,0 +1,28 @@
# 员工亲属资产表单单横向滚动实施记录
## 文档信息
- 保存路径:`docs/reports/implementation/2026-04-22-staff-family-asset-single-horizontal-scroll-implementation.md`
- 实施日期2026-04-22
- 关联范围:员工亲属关系维护前端页面
## 本次修改内容
1. 定位到员工亲属关系维护页亲属资产编辑表格存在双横向滚动条,原因是外层 `assets-table-wrapper``el-table` 内层同时承担横向滚动。
2. 移除外层容器的 `overflow-x: auto`,避免包裹层再次生成横向滚动条。
3. 将亲属资产编辑表格根节点从强制 `min-width` 调整为 `width: 100%`,保持表格横向滚动由 `el-table` 自身管理。
4. 新增本次前端实施计划与实施记录,沉淀问题定位、改动范围与验证要求。
## 影响范围
- 前端:`ruoyi-ui/src/views/ccdiStaffFmyRelation/index.vue` 亲属资产信息编辑弹窗样式。
- 文档:新增前端实施计划与实施记录。
## 验证情况
1. 前端构建校验:
- 执行命令:`source ~/.nvm/nvm.sh && nvm use 14.21.3 && cd ruoyi-ui && npm run build:prod`
- 结果:构建成功;存在项目原有的 bundle size warnings本次改动未引入构建失败。
2. Playwright 浏览器实测:
- 执行方式:通过 `nvm use 25.9.0` 启动 `playwright-cli`,在浏览器中 mock 登录态与员工亲属关系维护页最小依赖接口后打开 `/maintain/staffFmyRelation`,进入“添加员工亲属关系”弹窗并新增一条亲属资产记录。
- 结果:亲属资产表单外层包装器 `clientWidth=984``scrollWidth=984``overflowX=visible``el-table` 内部滚动区 `clientWidth=982``scrollWidth=1530``overflowX=auto`。说明外层不再生成横向滚动条,仅保留表格内部一条横向滚动条。

View File

@@ -0,0 +1,48 @@
# 招聘信息编辑页手动维护历史工作经历实施记录
## 文档信息
- 保存路径:`docs/reports/implementation/2026-04-22-staff-recruitment-work-experience-manual-edit-implementation.md`
- 实施日期2026-04-22
- 关联范围:招聘信息管理前后端
## 本次修改内容
### 后端
1. 新增 `CcdiStaffRecruitmentWorkEditDTO`,接收编辑页提交的历史工作经历子项。
2.`CcdiStaffRecruitmentEditDTO` 中补充 `workExperienceList` 字段,并启用嵌套校验。
3.`CcdiStaffRecruitmentServiceImpl.updateRecruitment` 中增加历史工作经历覆盖保存逻辑:
- 社招且前端传入工作经历列表时,按当前表单内容覆盖 `ccdi_staff_recruitment_work`
- 切换为校招时,自动清空该招聘记录的历史工作经历。
### 前端
1. 在招聘信息编辑弹窗中新增“候选人历史工作经历”编辑表格。
2. 支持手动新增、删除历史工作经历,并在前端自动重排序号。
3. 将入职时间、离职时间改为月份选择器,避免手输格式错误。
4. 提交编辑前增加年月格式、开始结束时间顺序、必填项校验。
5. 编辑提交时将规范化后的历史工作经历列表一并提交给后端;新增请求继续沿用原字段集,不携带额外子表字段。
## 影响范围
- 后端:招聘信息编辑接口、历史工作经历子表保存逻辑。
- 前端:招聘信息管理编辑弹窗。
- 文档:新增前后端实施计划与本实施记录。
## 验证情况
1. Maven 编译校验通过:
- 执行命令:`mvn -pl ccdi-info-collection -am compile -DskipTests`
- 结果:编译成功。
2. 前端构建校验通过:
- 执行命令:`cd ruoyi-ui && source ~/.nvm/nvm.sh && nvm use 14.21.3 && npm run build:prod`
- 结果:构建成功,仅存在原有体积告警,无新增构建错误。
3. 浏览器实测通过:
- 先通过真实登录页进入实际业务路由 `/maintain/staffRecruitment`
- 在真实“招聘信息管理”页面编辑社招记录 `RC2025001805`,手动新增一条历史工作经历并保存;
- 保存后列表中的“历史工作经历”由 `0段` 变为 `1段`
- 打开真实详情弹窗后,新增的工作经历可正常展示。
- 在另一条 `0段` 记录的编辑弹窗中确认“入职时间 / 离职时间”已切换为月份选择器,点击后会弹出月份面板。
4. 测试进程清理:
- 已关闭本次测试过程中打开的 Playwright 浏览器、前端 dev server 和后端进程。

View File

@@ -43,15 +43,6 @@ export function delRelation(ids) {
})
}
// 导出信贷客户实体关联
export function exportRelation(query) {
return request({
url: '/ccdi/custEnterpriseRelation/export',
method: 'post',
params: query
})
}
// 下载导入模板
export function importTemplate() {
return request({

View File

@@ -43,15 +43,6 @@ export function delRelation(ids) {
})
}
// 导出信贷客户家庭关系
export function exportRelation(query) {
return request({
url: '/ccdi/custFmyRelation/export',
method: 'post',
params: query
})
}
// 下载导入模板
export function importTemplate() {
return request({

View File

@@ -43,15 +43,6 @@ export function delTransaction(purchaseIds) {
})
}
// 导出采购交易
export function exportTransaction(query) {
return request({
url: '/ccdi/purchaseTransaction/export',
method: 'post',
params: query
})
}
// 下载导入模板
export function importTemplate() {
return request({

View File

@@ -43,15 +43,6 @@ export function delRelation(ids) {
})
}
// 导出员工实体关系
export function exportRelation(query) {
return request({
url: '/ccdi/staffEnterpriseRelation/export',
method: 'post',
params: query
})
}
// 下载导入模板
export function importTemplate() {
return request({

View File

@@ -43,15 +43,6 @@ export function delRelation(ids) {
})
}
// 导出员工亲属关系
export function exportRelation(query) {
return request({
url: '/ccdi/staffFmyRelation/export',
method: 'post',
params: query
})
}
// 下载导入模板
export function importTemplate() {
return request({

View File

@@ -78,12 +78,3 @@ export function getImportFailures(taskId, pageNum, pageSize) {
params: { pageNum, pageSize }
})
}
// 导出招聘信息
export function exportStaffRecruitment(query) {
return request({
url: '/ccdi/staffRecruitment/export',
method: 'post',
params: query
})
}

View File

@@ -43,15 +43,6 @@ export function delTransfer(ids) {
})
}
// 导出员工调动记录
export function exportTransfer(query) {
return request({
url: '/ccdi/staffTransfer/export',
method: 'post',
params: query
})
}
// 下载导入模板
export function importTemplate() {
return request({

View File

@@ -89,16 +89,6 @@
v-hasPermi="['ccdi:accountInfo:import']"
>导入</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['ccdi:accountInfo:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList" />
</el-row>
@@ -646,11 +636,6 @@ export default {
handleImport() {
this.upload.open = true
},
handleExport() {
this.download('ccdi/accountInfo/export', {
...this.queryParams
}, `账户库管理_${new Date().getTime()}.xlsx`)
},
importTemplate() {
this.download('ccdi/accountInfo/importTemplate', {}, `账户库导入模板_${new Date().getTime()}.xlsx`)
},

View File

@@ -1675,11 +1675,10 @@ export default {
.employee-edit-dialog .assets-table-wrapper {
width: 100%;
overflow-x: auto;
}
.employee-edit-dialog .assets-table {
min-width: 1460px;
width: 100%;
}
.employee-edit-dialog .assets-table .el-input,

View File

@@ -61,16 +61,6 @@
v-hasPermi="['ccdi:custEnterpriseRelation:import']"
>导入</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['ccdi:custEnterpriseRelation:export']"
>导出</el-button>
</el-col>
<el-col :span="1.5" v-if="showFailureButton">
<el-tooltip
:content="getLastImportTooltip()"
@@ -554,12 +544,6 @@ export default {
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
this.download('ccdi/custEnterpriseRelation/export', {
...this.queryParams
}, `信贷客户实体关联_${new Date().getTime()}.xlsx`);
},
/** 导入按钮操作 */
handleImport() {
this.upload.title = "信贷客户实体关联数据导入";

View File

@@ -62,16 +62,6 @@
v-hasPermi="['ccdi:custFmyRelation:import']"
>导入</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['ccdi:custFmyRelation:export']"
>导出</el-button>
</el-col>
<el-col :span="1.5" v-if="showFailureButton">
<el-tooltip
:content="getLastImportTooltip()"
@@ -869,12 +859,6 @@ export default {
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
this.download('ccdi/custFmyRelation/export', {
...this.queryParams
}, `信贷客户家庭关系_${new Date().getTime()}.xlsx`);
},
/** 导入按钮操作 */
handleImport() {
this.upload.title = "信贷客户家庭关系数据导入";

View File

@@ -66,16 +66,6 @@
v-hasPermi="['ccdi:purchaseTransaction:import']"
>导入</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['ccdi:purchaseTransaction:export']"
>导出</el-button>
</el-col>
<el-col :span="1.5" v-if="showFailureButton">
<el-tooltip
:content="getLastImportTooltip()"
@@ -929,12 +919,6 @@ export default {
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
this.download('ccdi/purchaseTransaction/export', {
...this.queryParams
}, `采购交易_${new Date().getTime()}.xlsx`);
},
/** 导入按钮操作 */
handleImport() {
this.upload.title = "采购交易数据导入";

View File

@@ -61,16 +61,6 @@
v-hasPermi="['ccdi:staffEnterpriseRelation:import']"
>导入</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['ccdi:staffEnterpriseRelation:export']"
>导出</el-button>
</el-col>
<el-col :span="1.5" v-if="showFailureButton">
<el-tooltip
:content="getLastImportTooltip()"
@@ -630,12 +620,6 @@ export default {
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
this.download('ccdi/staffEnterpriseRelation/export', {
...this.queryParams
}, `员工实体关系_${new Date().getTime()}.xlsx`);
},
/** 导入按钮操作 */
handleImport() {
this.upload.title = "员工实体关系数据导入";

View File

@@ -72,16 +72,6 @@
v-hasPermi="['ccdi:staffFmyRelation:import']"
>导入亲属资产信息</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['ccdi:staffFmyRelation:export']"
>导出</el-button>
</el-col>
<el-col :span="1.5" v-if="showFailureButton">
<el-tooltip
:content="getLastImportTooltip()"
@@ -1215,12 +1205,6 @@ export default {
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
this.download('ccdi/staffFmyRelation/export', {
...this.queryParams
}, `员工亲属关系_${new Date().getTime()}.xlsx`);
},
/** 导入按钮操作 */
handleImport() {
this.upload.title = "员工亲属关系数据导入";
@@ -1690,11 +1674,10 @@ export default {
.assets-table-wrapper {
width: 100%;
overflow-x: auto;
}
.assets-table {
min-width: 1440px;
width: 100%;
}
.assets-table .el-input,

View File

@@ -118,25 +118,6 @@
v-hasPermi="['ccdi:staffRecruitment:import']"
>导入工作经历</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-if="isPreviewMode()"
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
>导出</el-button>
<el-button
v-else
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['ccdi:staffRecruitment:export']"
>导出</el-button>
</el-col>
<el-col :span="1.5" v-if="showFailureButton">
<el-tooltip
:content="getLastImportTooltip()"
@@ -339,6 +320,101 @@
</el-col>
</el-row>
<template v-if="!isAdd && isSocialRecruitment(form)">
<el-divider content-position="left">候选人历史工作经历</el-divider>
<div class="work-experience-toolbar">
<span class="work-experience-tip">支持在编辑页手动补录候选人的历史工作经历保存后会覆盖当前记录下已有的工作经历</span>
<el-button type="primary" plain size="mini" icon="el-icon-plus" @click="handleAddWorkExperience">新增经历</el-button>
</div>
<el-table
:data="form.workExperienceList"
border
class="work-experience-edit-table"
empty-text="暂无历史工作经历请点击新增经历手动补录"
>
<el-table-column label="序号" align="center" width="80">
<template slot-scope="scope">
{{ scope.$index + 1 }}
</template>
</el-table-column>
<el-table-column label="工作单位" min-width="180">
<template slot-scope="scope">
<el-input v-model.trim="scope.row.companyName" placeholder="请输入工作单位" maxlength="200" />
</template>
</el-table-column>
<el-table-column label="所属部门" min-width="140">
<template slot-scope="scope">
<el-input v-model.trim="scope.row.departmentName" placeholder="请输入所属部门" maxlength="100" />
</template>
</el-table-column>
<el-table-column label="岗位名称" min-width="140">
<template slot-scope="scope">
<el-input v-model.trim="scope.row.positionName" placeholder="请输入岗位名称" maxlength="100" />
</template>
</el-table-column>
<el-table-column label="入职时间" width="180">
<template slot-scope="scope">
<el-date-picker
v-model="scope.row.jobStartMonth"
type="month"
value-format="yyyy-MM"
format="yyyy-MM"
placeholder="请选择入职时间"
clearable
style="width: 100%;"
/>
</template>
</el-table-column>
<el-table-column label="离职时间" width="180">
<template slot-scope="scope">
<el-date-picker
v-model="scope.row.jobEndMonth"
type="month"
value-format="yyyy-MM"
format="yyyy-MM"
placeholder="请选择离职时间"
clearable
style="width: 100%;"
/>
</template>
</el-table-column>
<el-table-column label="离职原因" min-width="180">
<template slot-scope="scope">
<el-input v-model.trim="scope.row.departureReason" placeholder="请输入离职原因" maxlength="500" />
</template>
</el-table-column>
<el-table-column label="主要工作内容" min-width="220">
<template slot-scope="scope">
<el-input
v-model.trim="scope.row.workContent"
type="textarea"
:rows="2"
placeholder="请输入主要工作内容"
maxlength="1000"
show-word-limit
/>
</template>
</el-table-column>
<el-table-column label="备注" min-width="180">
<template slot-scope="scope">
<el-input
v-model.trim="scope.row.remark"
type="textarea"
:rows="2"
placeholder="请输入备注"
maxlength="500"
show-word-limit
/>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="90" fixed="right">
<template slot-scope="scope">
<el-button type="text" icon="el-icon-delete" @click="handleRemoveWorkExperience(scope.$index)">删除</el-button>
</template>
</el-table-column>
</el-table>
</template>
<el-divider content-position="left">面试官信息</el-divider>
<el-row :gutter="16">
<el-col :span="12">
@@ -558,6 +634,8 @@ import ImportResultDialog from "@/components/ImportResultDialog.vue";
const idCardPattern = /^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/;
// 毕业年月校验正则 (YYYYMM)
const gradPattern = /^((19|20)\d{2})(0[1-9]|1[0-2])$/;
// 工作经历年月校验正则 (YYYY-MM)
const workMonthPattern = /^((19|20)\d{2})-(0[1-9]|1[0-2])$/;
const previewRecruitmentList = [
{
recruitId: "RC2025001205",
@@ -990,8 +1068,88 @@ export default {
const first = Number(a.sortOrder || 0);
const second = Number(b.sortOrder || 0);
return first - second;
}).map((item, index) => {
const normalizedItem = this.createEmptyWorkExperience(index + 1);
return {
...normalizedItem,
...item,
sortOrder: index + 1
};
});
},
/** 新建空工作经历 */
createEmptyWorkExperience(sortOrder) {
return {
sortOrder,
companyName: "",
departmentName: "",
positionName: "",
jobStartMonth: "",
jobEndMonth: "",
departureReason: "",
workContent: "",
remark: ""
};
},
/** 新增工作经历 */
handleAddWorkExperience() {
const currentList = Array.isArray(this.form.workExperienceList) ? this.form.workExperienceList.slice() : [];
currentList.push(this.createEmptyWorkExperience(currentList.length + 1));
this.form.workExperienceList = currentList;
this.syncWorkExperienceSortOrder();
},
/** 删除工作经历 */
handleRemoveWorkExperience(index) {
if (!Array.isArray(this.form.workExperienceList)) {
return;
}
this.form.workExperienceList.splice(index, 1);
this.syncWorkExperienceSortOrder();
},
/** 同步工作经历排序号 */
syncWorkExperienceSortOrder() {
if (!Array.isArray(this.form.workExperienceList)) {
this.form.workExperienceList = [];
return;
}
this.form.workExperienceList = this.form.workExperienceList.map((item, index) => ({
...this.createEmptyWorkExperience(index + 1),
...item,
sortOrder: index + 1
}));
},
/** 校验工作经历 */
validateWorkExperienceList() {
if (this.isAdd || !this.isSocialRecruitment(this.form)) {
return true;
}
const workExperienceList = this.normalizeWorkExperienceList(this.form.workExperienceList);
for (let index = 0; index < workExperienceList.length; index++) {
const item = workExperienceList[index];
const rowLabel = `${index + 1}条历史工作经历`;
if (!item.companyName) {
this.$modal.msgError(`${rowLabel}的工作单位不能为空`);
return false;
}
if (!item.jobStartMonth) {
this.$modal.msgError(`${rowLabel}的入职年月不能为空`);
return false;
}
if (!workMonthPattern.test(item.jobStartMonth)) {
this.$modal.msgError(`${rowLabel}的入职年月格式不正确应为YYYY-MM`);
return false;
}
if (item.jobEndMonth && !workMonthPattern.test(item.jobEndMonth)) {
this.$modal.msgError(`${rowLabel}的离职年月格式不正确应为YYYY-MM`);
return false;
}
if (item.jobEndMonth && item.jobEndMonth < item.jobStartMonth) {
this.$modal.msgError(`${rowLabel}的离职年月不能早于入职年月`);
return false;
}
}
return true;
},
/** 是否为预览模式 */
isPreviewMode() {
return this.$route && this.$route.query && this.$route.query.preview === "1";
@@ -1030,19 +1188,30 @@ export default {
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (!this.validateWorkExperienceList()) {
return;
}
const formData = {
...this.form,
workExperienceList: this.isSocialRecruitment(this.form)
? this.normalizeWorkExperienceList(this.form.workExperienceList)
: []
};
if (this.isPreviewMode()) {
this.$modal.msgSuccess(this.isAdd ? "预览模式:新增成功" : "预览模式:修改成功");
this.open = false;
return;
}
if (this.isAdd) {
addStaffRecruitment(this.form).then(response => {
const addData = { ...formData };
delete addData.workExperienceList;
addStaffRecruitment(addData).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
} else {
updateStaffRecruitment(this.form).then(response => {
updateStaffRecruitment(formData).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
@@ -1065,12 +1234,6 @@ export default {
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
this.download('ccdi/staffRecruitment/export', {
...this.queryParams
}, `招聘信息_${new Date().getTime()}.xlsx`);
},
/** 导入按钮操作 */
handleImport() {
this.openImportDialog("recruitment");
@@ -1406,4 +1569,22 @@ export default {
.work-experience-empty {
padding: 24px 0 8px;
}
.work-experience-toolbar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
margin-bottom: 12px;
}
.work-experience-tip {
color: #909399;
font-size: 12px;
line-height: 1.5;
}
.work-experience-edit-table ::v-deep .el-textarea__inner {
min-height: 54px !important;
}
</style>

View File

@@ -97,16 +97,6 @@
v-hasPermi="['ccdi:staffTransfer:import']"
>导入</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['ccdi:staffTransfer:export']"
>导出</el-button>
</el-col>
<el-col :span="1.5" v-if="showFailureButton">
<el-tooltip
:content="getLastImportTooltip()"
@@ -737,18 +727,6 @@ export default {
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
const params = { ...this.queryParams };
// 处理日期范围
if (params.transferDateRange && params.transferDateRange.length === 2) {
params.beginTransferDate = params.transferDateRange[0];
params.endTransferDate = params.transferDateRange[1];
}
delete params.transferDateRange;
this.download('ccdi/staffTransfer/export', params, `员工调动记录_${new Date().getTime()}.xlsx`);
},
/** 导入按钮操作 */
handleImport() {
this.upload.title = "员工调动记录数据导入";

View File

@@ -7,7 +7,7 @@
SET @parent_menu_id = (SELECT menu_id FROM sys_menu WHERE menu_name = '信息维护' AND parent_id = 0 LIMIT 1);
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
VALUES ('征信维护', @parent_menu_id, 4, 'creditInfo', 'ccdiCreditInfo/index', 1, 0, 'C', '0', '0', 'ccdi:creditInfo:list', 'document', 'admin', NOW(), '', NULL, '员工征信维护菜单');
VALUES ('征信维护', @parent_menu_id, 6, 'creditInfo', 'ccdiCreditInfo/index', 1, 0, 'C', '0', '0', 'ccdi:creditInfo:list', 'document', 'admin', NOW(), '', NULL, '员工征信维护菜单');
SET @menu_id = LAST_INSERT_ID();

View File

@@ -8,7 +8,7 @@ INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame
VALUES (
'信贷客户家庭关系',
@parent_id,
5,
10,
'custFmyRelation',
1,
0,
@@ -33,5 +33,4 @@ VALUES
('信贷客户家庭关系新增', @cust_menu_id, 2, '#', '', 1, 0, 'F', '0', '0', 'ccdi:custFmyRelation:add', '#', 'admin', NOW(), ''),
('信贷客户家庭关系修改', @cust_menu_id, 3, '#', '', 1, 0, 'F', '0', '0', 'ccdi:custFmyRelation:edit', '#', 'admin', NOW(), ''),
('信贷客户家庭关系删除', @cust_menu_id, 4, '#', '', 1, 0, 'F', '0', '0', 'ccdi:custFmyRelation:remove', '#', 'admin', NOW(), ''),
('信贷客户家庭关系导', @cust_menu_id, 5, '#', '', 1, 0, 'F', '0', '0', 'ccdi:custFmyRelation:export', '#', 'admin', NOW(), ''),
('信贷客户家庭关系导入', @cust_menu_id, 6, '#', '', 1, 0, 'F', '0', '0', 'ccdi:custFmyRelation:import', '#', 'admin', NOW(), '');
('信贷客户家庭关系导', @cust_menu_id, 5, '#', '', 1, 0, 'F', '0', '0', 'ccdi:custFmyRelation:import', '#', 'admin', NOW(), '');

View File

@@ -10,7 +10,7 @@ SET @parent_menu_id = (SELECT menu_id FROM sys_menu WHERE menu_name='信息维
-- 添加采购交易管理菜单
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
VALUES
('采购交易管理', @parent_menu_id, 2, 'purchaseTransaction', 'ccdiPurchaseTransaction/index', 1, 0, 'C', '0', '0', 'ccdi:purchaseTransaction:list', 'shopping', 'admin', NOW(), '', NULL, '采购交易信息管理菜单');
('采购交易管理', @parent_menu_id, 12, 'purchaseTransaction', 'ccdiPurchaseTransaction/index', 1, 0, 'C', '0', '0', 'ccdi:purchaseTransaction:list', 'shopping', 'admin', NOW(), '', NULL, '采购交易信息管理菜单');
-- 获取刚插入的菜单ID
SET @menu_id = LAST_INSERT_ID();
@@ -21,8 +21,7 @@ INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame
('采购交易新增', @menu_id, 2, '', '', 1, 0, 'F', '0', '0', 'ccdi:purchaseTransaction:add', '#', 'admin', NOW(), ''),
('采购交易修改', @menu_id, 3, '', '', 1, 0, 'F', '0', '0', 'ccdi:purchaseTransaction:edit', '#', 'admin', NOW(), ''),
('采购交易删除', @menu_id, 4, '', '', 1, 0, 'F', '0', '0', 'ccdi:purchaseTransaction:remove', '#', 'admin', NOW(), ''),
('采购交易导', @menu_id, 5, '', '', 1, 0, 'F', '0', '0', 'ccdi:purchaseTransaction:export', '#', 'admin', NOW(), ''),
('采购交易导入', @menu_id, 6, '', '', 1, 0, 'F', '0', '0', 'ccdi:purchaseTransaction:import', '#', 'admin', NOW(), '');
('采购交易导', @menu_id, 5, '', '', 1, 0, 'F', '0', '0', 'ccdi:purchaseTransaction:import', '#', 'admin', NOW(), '');
-- 查询结果验证
SELECT

View File

@@ -10,7 +10,7 @@ SET @parent_menu_id = (SELECT menu_id FROM sys_menu WHERE menu_name='信息维
-- 添加员工亲属关系维护菜单
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
VALUES
('员工亲属关系维护', @parent_menu_id, 3, 'staffFmyRelation', 'ccdiStaffFmyRelation/index', 1, 0, 'C', '0', '0', 'ccdi:staffFmyRelation:list', 'peoples', 'admin', NOW(), '', NULL, '员工亲属关系信息管理菜单');
('员工亲属关系维护', @parent_menu_id, 4, 'staffFmyRelation', 'ccdiStaffFmyRelation/index', 1, 0, 'C', '0', '0', 'ccdi:staffFmyRelation:list', 'peoples', 'admin', NOW(), '', NULL, '员工亲属关系信息管理菜单');
-- 获取刚插入的菜单ID
SET @menu_id = LAST_INSERT_ID();
@@ -21,8 +21,7 @@ INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame
('亲属关系新增', @menu_id, 2, '', '', 1, 0, 'F', '0', '0', 'ccdi:staffFmyRelation:add', '#', 'admin', NOW(), ''),
('亲属关系修改', @menu_id, 3, '', '', 1, 0, 'F', '0', '0', 'ccdi:staffFmyRelation:edit', '#', 'admin', NOW(), ''),
('亲属关系删除', @menu_id, 4, '', '', 1, 0, 'F', '0', '0', 'ccdi:staffFmyRelation:remove', '#', 'admin', NOW(), ''),
('亲属关系导', @menu_id, 5, '', '', 1, 0, 'F', '0', '0', 'ccdi:staffFmyRelation:export', '#', 'admin', NOW(), ''),
('亲属关系导入', @menu_id, 6, '', '', 1, 0, 'F', '0', '0', 'ccdi:staffFmyRelation:import', '#', 'admin', NOW(), '');
('亲属关系导', @menu_id, 5, '', '', 1, 0, 'F', '0', '0', 'ccdi:staffFmyRelation:import', '#', 'admin', NOW(), '');
-- 查询结果验证
SELECT

View File

@@ -32,15 +32,14 @@ CREATE TABLE `ccdi_intermediary_blacklist` (
INSERT INTO `sys_menu` VALUES (2000, '信息维护', '0', '4', 'dpc', NULL, '', '', 1, 0, 'M', '0', '0', '', 'example', 'admin', sysdate(), '', NULL, '信息维护目录');
-- 二级菜单:中介库管理
INSERT INTO `sys_menu` VALUES (2001, '中介库管理', 2000, '1', 'intermediary', 'dpcIntermediary/index', '', '', 1, 0, 'C', '0', '0', 'dpc:intermediary:list', 'user', 'admin', sysdate(), '', NULL, '中介库管理菜单');
INSERT INTO `sys_menu` VALUES (2001, '中介库管理', 2000, '8', 'intermediary', 'dpcIntermediary/index', '', '', 1, 0, 'C', '0', '0', 'dpc:intermediary:list', 'user', 'admin', sysdate(), '', NULL, '中介库管理菜单');
-- 中介库管理按钮权限
INSERT INTO `sys_menu` VALUES (2002, '中介查询', 2001, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'dpc:intermediary:query', '#', 'admin', sysdate(), '', NULL, '');
INSERT INTO `sys_menu` VALUES (2003, '中介新增', 2001, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'dpc:intermediary:add', '#', 'admin', sysdate(), '', NULL, '');
INSERT INTO `sys_menu` VALUES (2004, '中介修改', 2001, '3', '', '', '', '', 1, 0, 'F', '0', '0', 'dpc:intermediary:edit', '#', 'admin', sysdate(), '', NULL, '');
INSERT INTO `sys_menu` VALUES (2005, '中介删除', 2001, '4', '', '', '', '', 1, 0, 'F', '0', '0', 'dpc:intermediary:remove', '#', 'admin', sysdate(), '', NULL, '');
INSERT INTO `sys_menu` VALUES (2006, '中介导', 2001, '5', '', '', '', '', 1, 0, 'F', '0', '0', 'dpc:intermediary:export', '#', 'admin', sysdate(), '', NULL, '');
INSERT INTO `sys_menu` VALUES (2007, '中介导入', 2001, '6', '', '', '', '', 1, 0, 'F', '0', '0', 'dpc:intermediary:import', '#', 'admin', sysdate(), '', NULL, '');
INSERT INTO `sys_menu` VALUES (2007, '中介导', 2001, '5', '', '', '', '', 1, 0, 'F', '0', '0', 'dpc:intermediary:import', '#', 'admin', sysdate(), '', NULL, '');
-- ----------------------------
-- 3. 字典数据 SQL

View File

@@ -12,7 +12,7 @@ INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, query, p
VALUES (
'中介黑名单',
2000,
5,
8,
'intermediary',
NULL,
NULL,
@@ -161,33 +161,12 @@ VALUES (
''
);
-- 导出权限
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, query, perms, icon, menu_type, status, visible, create_by, create_time, update_by, update_time, remark)
VALUES (
'中介导出',
@intermediary_menu_id,
6,
'',
NULL,
NULL,
'ccdi:intermediary:export',
'#',
'F',
'0',
'0',
'admin',
NOW(),
'',
NULL,
''
);
-- 导入权限
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, query, perms, icon, menu_type, status, visible, create_by, create_time, update_by, update_time, remark)
VALUES (
'中介导入',
@intermediary_menu_id,
7,
6,
'',
NULL,
NULL,
@@ -216,7 +195,6 @@ VALUES (
-- - ccdi:intermediary:add (新增)
-- - ccdi:intermediary:edit (修改)
-- - ccdi:intermediary:remove (删除)
-- - ccdi:intermediary:export (导出)
-- - ccdi:intermediary:import (导入)
--
-- 3. 使用说明:

View File

@@ -31,7 +31,7 @@ INSERT INTO sys_menu (
SELECT
'账户库管理',
@parent_menu_id,
11,
9,
'accountInfo',
'ccdiAccountInfo/index',
1,
@@ -198,33 +198,6 @@ WHERE @menu_id IS NOT NULL
AND perms = 'ccdi:accountInfo:import'
);
INSERT INTO sys_menu (
menu_name,
parent_id,
order_num,
path,
component,
is_frame,
is_cache,
menu_type,
visible,
status,
perms,
icon,
create_by,
create_time,
remark
)
SELECT '账户导出', @menu_id, 6, '', '', 1, 0, 'F', '0', '0', 'ccdi:accountInfo:export', '#', 'admin', NOW(), ''
FROM dual
WHERE @menu_id IS NOT NULL
AND NOT EXISTS (
SELECT 1
FROM sys_menu
WHERE parent_id = @menu_id
AND perms = 'ccdi:accountInfo:export'
);
INSERT INTO sys_role_menu (role_id, menu_id)
SELECT 1, @menu_id
FROM dual
@@ -284,30 +257,6 @@ WHERE @menu_id IS NOT NULL
)
);
INSERT INTO sys_role_menu (role_id, menu_id)
SELECT 1,
(
SELECT menu_id
FROM sys_menu
WHERE parent_id = @menu_id
AND perms = 'ccdi:accountInfo:export'
LIMIT 1
)
FROM dual
WHERE @menu_id IS NOT NULL
AND NOT EXISTS (
SELECT 1
FROM sys_role_menu
WHERE role_id = 1
AND menu_id = (
SELECT menu_id
FROM sys_menu
WHERE parent_id = @menu_id
AND perms = 'ccdi:accountInfo:export'
LIMIT 1
)
);
INSERT INTO sys_role_menu (role_id, menu_id)
SELECT 1,
(

View File

@@ -31,7 +31,7 @@ INSERT INTO sys_menu (
SELECT
'实体库管理',
@parent_menu_id,
12,
7,
'enterpriseBaseInfo',
'ccdiEnterpriseBaseInfo/index',
1,

View File

@@ -0,0 +1,90 @@
-- 信息维护菜单移除导出权限并统一菜单顺序
-- 可重复执行
DELETE rm
FROM sys_role_menu rm
JOIN sys_menu m ON m.menu_id = rm.menu_id
WHERE m.perms IN (
'ccdi:baseStaff:export',
'ccdi:staffFmyRelation:export',
'ccdi:staffEnterpriseRelation:export',
'ccdi:staffRecruitment:export',
'ccdi:staffTransfer:export',
'ccdi:custFmyRelation:export',
'ccdi:custEnterpriseRelation:export',
'ccdi:purchaseTransaction:export',
'ccdi:accountInfo:export',
'ccdi:intermediary:export',
'dpc:intermediary:export'
);
DELETE FROM sys_menu
WHERE perms IN (
'ccdi:baseStaff:export',
'ccdi:staffFmyRelation:export',
'ccdi:staffEnterpriseRelation:export',
'ccdi:staffRecruitment:export',
'ccdi:staffTransfer:export',
'ccdi:custFmyRelation:export',
'ccdi:custEnterpriseRelation:export',
'ccdi:purchaseTransaction:export',
'ccdi:accountInfo:export',
'ccdi:intermediary:export',
'dpc:intermediary:export'
);
SET @parent_menu_id = (
SELECT menu_id
FROM sys_menu
WHERE menu_name = '信息维护'
AND parent_id = 0
LIMIT 1
);
UPDATE sys_menu
SET order_num = CASE
WHEN path = 'baseStaff'
OR perms = 'ccdi:baseStaff:list'
OR menu_name = '员工信息维护' THEN 1
WHEN path = 'staffRecruitment'
OR perms = 'ccdi:staffRecruitment:list'
OR menu_name = '招聘信息维护'
OR menu_name = '员工招聘信息' THEN 2
WHEN path = 'staffTransfer'
OR perms = 'ccdi:staffTransfer:list'
OR menu_name = '员工调动记录'
OR menu_name = '员工调动信息' THEN 3
WHEN path = 'staffFmyRelation'
OR perms = 'ccdi:staffFmyRelation:list'
OR menu_name = '员工亲属关系维护' THEN 4
WHEN path = 'staffEnterpriseRelation'
OR perms = 'ccdi:staffEnterpriseRelation:list'
OR menu_name = '员工实体关系维护'
OR menu_name = '员工实体关系' THEN 5
WHEN path = 'creditInfo'
OR perms = 'ccdi:creditInfo:list'
OR menu_name = '征信维护' THEN 6
WHEN path = 'enterpriseBaseInfo'
OR perms = 'ccdi:enterpriseBaseInfo:list'
OR menu_name = '实体库管理' THEN 7
WHEN path = 'intermediary'
OR perms IN ('ccdi:intermediary:list', 'dpc:intermediary:list')
OR menu_name = '中介库管理'
OR menu_name = '中介黑名单'
OR menu_name = '中介管理' THEN 8
WHEN path = 'accountInfo'
OR perms = 'ccdi:accountInfo:list'
OR menu_name = '账户库管理' THEN 9
WHEN path = 'custFmyRelation'
OR perms = 'ccdi:custFmyRelation:list'
OR menu_name = '信贷客户家庭关系' THEN 10
WHEN path = 'custEnterpriseRelation'
OR perms = 'ccdi:custEnterpriseRelation:list'
OR menu_name = '信贷客户实体关联' THEN 11
WHEN path = 'purchaseTransaction'
OR perms = 'ccdi:purchaseTransaction:list'
OR menu_name = '采购交易管理' THEN 12
ELSE order_num
END
WHERE @parent_menu_id IS NOT NULL
AND parent_id = @parent_menu_id;