From 92572cd398d65aaa7f32f8be295bd5dc23b6ce3d Mon Sep 17 00:00:00 2001 From: qinyulong Date: Fri, 9 Jan 2026 17:00:49 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=BC=E5=85=A5=E4=BA=BA=E5=91=98=E5=B2=97?= =?UTF-8?q?=E4=BD=8D+=E6=8A=80=E8=83=BD=E3=80=81=E5=A9=9A=E5=A7=BB?= =?UTF-8?q?=E6=9E=9A=E4=B8=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pojo/entity/PostHandleEntity.java | 2 +- .../jobTransfer/pojo/enums/MarriageEnum.java | 57 ++++++++ .../jobTransfer/pojo/enums/SkillEnum.java | 58 ++++++++ .../pojo/excel/PostHandleImport.java | 130 ++++++++++++++++++ .../controller/PostHandleController.java | 45 +++++- .../service/IPostHandleService.java | 8 ++ .../service/impl/PostHandleServiceImpl.java | 113 ++++++++++++--- .../岗位处理导入模板下载.xls | Bin 0 -> 21504 bytes 8 files changed, 389 insertions(+), 24 deletions(-) create mode 100644 blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/jobTransfer/pojo/enums/MarriageEnum.java create mode 100644 blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/jobTransfer/pojo/enums/SkillEnum.java create mode 100644 blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/jobTransfer/pojo/excel/PostHandleImport.java create mode 100644 blade-service/blade-desk/src/main/resources/Excel/jobTransfer/岗位处理导入模板下载.xls diff --git a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/jobTransfer/pojo/entity/PostHandleEntity.java b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/jobTransfer/pojo/entity/PostHandleEntity.java index 707e37d2..31355182 100644 --- a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/jobTransfer/pojo/entity/PostHandleEntity.java +++ b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/jobTransfer/pojo/entity/PostHandleEntity.java @@ -104,7 +104,7 @@ public class PostHandleEntity extends BaseEntity { /** * 用工类型 */ - @Schema(description = "用工类型") + @Schema(description = "用工类型(1实习工,2正式工)") private Short staffType; /** * 参加工作时间 diff --git a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/jobTransfer/pojo/enums/MarriageEnum.java b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/jobTransfer/pojo/enums/MarriageEnum.java new file mode 100644 index 00000000..0a5eba2b --- /dev/null +++ b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/jobTransfer/pojo/enums/MarriageEnum.java @@ -0,0 +1,57 @@ +package org.springblade.desk.jobTransfer.pojo.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springblade.core.tool.utils.ObjectUtil; +import org.springblade.core.tool.utils.StringPool; + +import java.util.Arrays; + +/** + * 婚姻枚举 + * + * @author qyl + * @date 2026-01-09 + */ +@Getter +@AllArgsConstructor +public enum MarriageEnum { + EMPTY(StringPool.EMPTY, ""), + + /** + * 状态枚举 + */ + MARRIED("已婚", "1"), + SPINSTERHOOD("未婚", "0"), + ; + final String name; + final String code; + + /** + * 匹配枚举值 + * + * @param name 名称 + * @return + */ + public static MarriageEnum of(String name) { + return Arrays.stream(MarriageEnum.values()) + .filter(enumItem -> enumItem.getName().equalsIgnoreCase(name != null ? name : "")) + .findFirst() + // 在没有找到匹配项时返回默认值 + .orElse(MarriageEnum.EMPTY); + } + + /** + * 根据值获取名称 + * + * @param code + * @return + */ + public static String getName(String code) { + MarriageEnum item = Arrays.stream(MarriageEnum.values()) + .filter(enumItem -> enumItem.getCode().equalsIgnoreCase(code)) + .findFirst() + .orElse(null); + return ObjectUtil.isEmpty(item) ? StringPool.EMPTY : item.getName(); + } +} diff --git a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/jobTransfer/pojo/enums/SkillEnum.java b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/jobTransfer/pojo/enums/SkillEnum.java new file mode 100644 index 00000000..53f4f507 --- /dev/null +++ b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/jobTransfer/pojo/enums/SkillEnum.java @@ -0,0 +1,58 @@ +package org.springblade.desk.jobTransfer.pojo.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springblade.core.tool.utils.ObjectUtil; +import org.springblade.core.tool.utils.StringPool; + +import java.util.Arrays; + +/** + * 技能等级枚举 + * + * @author qyl + * @date 2026-01-09 + */ +@Getter +@AllArgsConstructor +public enum SkillEnum { + EMPTY(StringPool.EMPTY, -1), + + /** + * 状态枚举 + */ + MIDDLE_RANK("中级", 1), + SENIOR("高级", 2), + ARTIFICER("技师", 3), + ; + final String name; + final Integer code; + + /** + * 匹配枚举值 + * + * @param name 名称 + * @return + */ + public static SkillEnum of(String name) { + return Arrays.stream(SkillEnum.values()) + .filter(enumItem -> enumItem.getName().equalsIgnoreCase(name != null ? name : "")) + .findFirst() + // 在没有找到匹配项时返回默认值 + .orElse(SkillEnum.EMPTY); + } + + /** + * 根据值获取名称 + * + * @param code + * @return + */ + public static String getName(int code) { + SkillEnum item = Arrays.stream(SkillEnum.values()) + .filter(enumItem -> enumItem.getCode() == code) + .findFirst() + .orElse(null); + return ObjectUtil.isEmpty(item) ? StringPool.EMPTY : item.getName(); + } +} diff --git a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/jobTransfer/pojo/excel/PostHandleImport.java b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/jobTransfer/pojo/excel/PostHandleImport.java new file mode 100644 index 00000000..f8234e17 --- /dev/null +++ b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/jobTransfer/pojo/excel/PostHandleImport.java @@ -0,0 +1,130 @@ +package org.springblade.desk.jobTransfer.pojo.excel; + +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.format.DateTimeFormat; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springblade.core.mp.base.BaseEntity; + +import java.io.Serial; +import java.util.Date; + +/** + * 岗位处理导入 + * + * @author qyl + * @since 2026-01-09 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class PostHandleImport extends BaseEntity { + + /** + * 用户code + */ + @ExcelProperty(index = 0) + private String code; + /** + * 名称 + */ + @ExcelProperty(index = 1) + private String name; + /** + * 民族 + */ + @ExcelProperty(index = 2) + private String nation; + /** + * 年龄 + */ + @ExcelProperty(index = 3) + private Short age; + /** + * 身份证号码 + */ + @ExcelProperty(index = 4) + private String idCard; + /** + * 籍贯 + */ + @ExcelProperty(index = 5) + private String nativePlace; + + /** + * 所属岗位 + */ + @ExcelProperty(index = 6) + private String station; + /** + * 出生日期 + */ + @ExcelProperty(index = 7) + @DateTimeFormat("yyyy/MM/dd") + private Date dataBirth; + /** + * 政治面貌 + */ + @ExcelProperty(index = 8) + private String face; + /** + * 婚姻状态(0未婚,1已婚) + */ + @ExcelProperty(index = 9) + private String marriageName; + /** + * 毕业院校 + */ + @ExcelProperty(index = 10) + private String school; + /** + * 所学专业 + */ + @ExcelProperty(index = 11) + private String major; + /** + * 最高学历 + */ + @ExcelProperty(index = 12) + private String education; + /** + * 毕业时间 + */ + @ExcelProperty(index = 13) + @DateTimeFormat("yyyy/MM/dd") + private Date endDate; + /** + * 用工类型 + */ + @ExcelProperty(index = 14) + private String staffTypeName; + /** + * 参加工作时间 + */ + @ExcelProperty(index = 15) + @DateTimeFormat("yyyy/MM/dd") + private Date joinJobDate; + /** + * 技能等级 + */ + @ExcelProperty(index = 16) + private String skillName; + /** + * 任现职时间 + */ + @ExcelProperty(index = 17) + @DateTimeFormat("yyyy/MM/dd") + private Date inJobDate; + /** + * 合同到期 + */ + @ExcelProperty(index = 18) + @DateTimeFormat("yyyy/MM/dd") + private Date conExpDate; + /** + * 家庭住址 + */ + @ExcelProperty(index = 19) + private String address; +} diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/jobTransfer/controller/PostHandleController.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/jobTransfer/controller/PostHandleController.java index 470a2afb..a6810c52 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/jobTransfer/controller/PostHandleController.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/jobTransfer/controller/PostHandleController.java @@ -1,7 +1,5 @@ package org.springblade.desk.jobTransfer.controller; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.enums.ParameterIn; import io.swagger.v3.oas.annotations.media.Schema; @@ -18,8 +16,13 @@ import org.springblade.core.mp.support.Condition; import org.springblade.core.mp.support.Query; import org.springblade.core.tool.api.R; import org.springblade.core.tool.utils.Func; +import org.springblade.desk.basic.util.ExcelExtUtil; import org.springblade.desk.jobTransfer.pojo.excel.PostHandleExcel; +import org.springblade.desk.jobTransfer.pojo.excel.PostHandleImport; import org.springblade.desk.jobTransfer.pojo.request.PostHandleQuery; +import org.springframework.beans.BeanUtils; +import org.springframework.core.io.Resource; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; @@ -30,12 +33,13 @@ import org.springblade.desk.jobTransfer.service.IPostHandleService; import org.springblade.core.boot.ctrl.BladeController; import org.springblade.core.tool.utils.DateUtil; import org.springblade.core.excel.util.ExcelUtil; -import org.springblade.core.tool.constant.BladeConstant; import java.util.Map; import java.util.List; +import java.util.stream.Collectors; import jakarta.servlet.http.HttpServletResponse; +import org.springframework.web.multipart.MultipartFile; /** * 岗位处理 控制器 @@ -147,7 +151,7 @@ public class PostHandleController extends BladeController { * @return */ @PostMapping("/JobTransferPlan") - @ApiOperationSupport(order = 8) + @ApiOperationSupport(order = 9) @Operation(summary = "批量转岗计划", description = "传入ids") public R JobTransferPlan(@Parameter(description = "主键集合", required = true) @RequestParam String ids, @Parameter(description = "培训师id", required = true) @RequestParam Long teacherId, @@ -166,7 +170,7 @@ public class PostHandleController extends BladeController { * @return */ @PostMapping("/layoffPlan") - @ApiOperationSupport(order = 8) + @ApiOperationSupport(order = 10) @Operation(summary = "批量下岗计划", description = "传入ids") public R layoffPlan(@Parameter(description = "主键集合", required = true) @RequestParam String ids, @Parameter(description = "培训师id", required = true) @RequestParam Long teacherId, @@ -180,7 +184,7 @@ public class PostHandleController extends BladeController { */ @IsAdmin @GetMapping("/export-postHandle") - @ApiOperationSupport(order = 9) + @ApiOperationSupport(order = 11) @Operation(summary = "导出数据", description = "传入postHandle") public void exportPostHandle(@Parameter(hidden = true) @RequestParam Map postHandle, BladeUser bladeUser, HttpServletResponse response) { QueryWrapper queryWrapper = Condition.getQueryWrapper(postHandle, PostHandleEntity.class); @@ -192,4 +196,33 @@ public class PostHandleController extends BladeController { ExcelUtil.export(response, "岗位处理数据" + DateUtil.time(), "岗位处理数据表", list, PostHandleExcel.class); } + /** + * 下载Excel模板 + */ + @GetMapping("/downloadExcelTemplate") + @ApiOperationSupport(order = 12) + @Operation(summary = "下载Excel模板", description = "") + public ResponseEntity downloadExcelTemplate() { + return ExcelExtUtil.downloadXlsTemplate( + "Excel/jobTransfer/岗位处理导入模板下载.xls", + "岗位处理导入模板下载.xls"); + } + + /** + * 导入Excel + */ + @PostMapping("/importExcel") + @ApiOperationSupport(order = 13) + @Operation(summary = "导入Excel", description = "MultipartFile") + public R importExcel(@RequestParam("file") MultipartFile file) { + R checkR = ExcelExtUtil.importExcelCheck(file); + if (checkR != null) { + return checkR; + } + List importList = ExcelUtil.read( + file, 0, 1, PostHandleImport.class + ); + return postHandleService.saveExcelData(importList); + } + } diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/jobTransfer/service/IPostHandleService.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/jobTransfer/service/IPostHandleService.java index 10945d1e..05d9052b 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/jobTransfer/service/IPostHandleService.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/jobTransfer/service/IPostHandleService.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper; import org.springblade.core.tool.api.R; import org.springblade.desk.jobTransfer.pojo.entity.PostHandleEntity; import org.springblade.desk.jobTransfer.pojo.excel.PostHandleExcel; +import org.springblade.desk.jobTransfer.pojo.excel.PostHandleImport; import org.springblade.desk.jobTransfer.pojo.request.PostHandleQuery; import org.springblade.desk.jobTransfer.pojo.vo.PostHandleVO; import com.baomidou.mybatisplus.core.metadata.IPage; @@ -74,4 +75,11 @@ public interface IPostHandleService extends BaseService { */ R layoffPlan(List ids, Long teacherId, String teacherName, Long trainingPlanId); + /** + * 导入Excel + * + * @param postHandleEntityList + * @return + */ + R saveExcelData(List postHandleEntityList); } diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/jobTransfer/service/impl/PostHandleServiceImpl.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/jobTransfer/service/impl/PostHandleServiceImpl.java index e6ec1149..70815818 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/jobTransfer/service/impl/PostHandleServiceImpl.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/jobTransfer/service/impl/PostHandleServiceImpl.java @@ -1,18 +1,23 @@ package org.springblade.desk.jobTransfer.service.impl; import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import jakarta.annotation.Resource; import org.springblade.core.tool.api.R; import org.springblade.desk.jobTransfer.pojo.entity.CultivateDetailEntity; import org.springblade.desk.jobTransfer.pojo.entity.PostHandleEntity; -import org.springblade.desk.jobTransfer.pojo.enums.PostHandleStatusEnum; -import org.springblade.desk.jobTransfer.pojo.enums.StaffTypeEnum; -import org.springblade.desk.jobTransfer.pojo.enums.TrainingStatusEnum; +import org.springblade.desk.jobTransfer.pojo.enums.*; import org.springblade.desk.jobTransfer.pojo.excel.PostHandleExcel; +import org.springblade.desk.jobTransfer.pojo.excel.PostHandleImport; import org.springblade.desk.jobTransfer.pojo.request.PostHandleQuery; import org.springblade.desk.jobTransfer.pojo.vo.PostHandleVO; import org.springblade.desk.jobTransfer.mapper.PostHandleMapper; import org.springblade.desk.jobTransfer.service.ICultivateDetailService; import org.springblade.desk.jobTransfer.service.IPostHandleService; +import org.springblade.system.cache.SysCache; +import org.springblade.system.cache.UserCache; +import org.springblade.system.pojo.entity.User; +import org.springblade.system.pojo.entity.UserInfo; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.core.conditions.Wrapper; @@ -20,9 +25,8 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import org.springblade.core.mp.base.BaseServiceImpl; import org.springframework.transaction.annotation.Transactional; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; +import java.util.*; +import java.util.stream.Collectors; /** * 岗位处理 服务实现类 @@ -33,7 +37,7 @@ import java.util.List; @Service public class PostHandleServiceImpl extends BaseServiceImpl implements IPostHandleService { - @Autowired + @Resource private ICultivateDetailService iCultivateDetailService; @Override @@ -102,7 +106,7 @@ public class PostHandleServiceImpl extends BaseServiceImpl postHandleImports) { + //检查导入的集合postHandleImports,不允许用户code重复 + Set importedCodes = new HashSet<>(); + Set duplicateCodes = postHandleImports.stream() + .map(PostHandleImport::getCode) // 假设PostHandleImport有getCode方法 + .filter(code -> !importedCodes.add(code)) // 如果add失败,说明已存在,即重复 + .collect(Collectors.toSet()); + + if (!duplicateCodes.isEmpty()) { + // 存在重复的用户code,返回错误信息。假设R是统一的返回结果类 + return R.fail("导入数据中存在重复的工号:" + duplicateCodes); + } + List list = postHandleImports.stream().map(this::convertSingle).collect(Collectors.toList()); + //获取全部用户id,对比PostHandleEntity已有数据,不允许重复添加 + List ids = list.stream().map(PostHandleEntity::getUserId) + .collect(Collectors.toList()); + Long existCount = this.lambdaQuery() + .in(PostHandleEntity::getUserId, ids) + .eq(PostHandleEntity::getIsDeleted, 0) + .count(); + if (existCount > 0) { + return R.fail("用户已存在岗位处理记录,不允许重复添加"); + } + boolean saved = this.saveBatch(list); + if (!saved) { + return R.fail("操作失败"); + } + try { + createPlan(list); // 确保此方法中的异常能传播出来 + } catch (Exception e) { + // 由于配置了 rollbackFor = Exception.class,异常抛出后事务将回滚 + throw new RuntimeException("创建培训计划失败,数据已回滚", e); + } + return R.status(saved); + } + + /** + * 转换单个对象 + */ + private PostHandleEntity convertSingle(PostHandleImport excel) { + PostHandleEntity entity = new PostHandleEntity(); + // 核心:属性拷贝,两个类的字段名和类型必须一致 + BeanUtils.copyProperties(excel, entity); + // 对于字段名不完全一致或有特殊处理的字段,可以在此手动设置 + //用工类型 + entity.setStaffType(StaffTypeEnum.of(excel.getStaffTypeName()).getCode().shortValue()); + //用户及部门 + UserInfo userByCode = UserCache.getUserByCode(excel.getCode()); + if (userByCode == null || userByCode.getUser() == null) { + //报错并提示 + throw new IllegalArgumentException("工号 '" + excel.getCode() + "' 在系统中不存在,请检查数据准确性"); + } + entity.setUserId(userByCode.getUser().getId()); + entity.setName(userByCode.getUser().getRealName()); + entity.setDeptId(Long.valueOf(userByCode.getUser().getDeptId())); + //技能等级 + entity.setSkill(SkillEnum.of(excel.getSkillName()).getCode().shortValue()); + //婚姻状态 + entity.setMarriage(MarriageEnum.of(excel.getMarriageName()).getCode().toString()); + // 如果是正式工状态为正常 + if (entity.getStaffType() == StaffTypeEnum.FORMAL.getCode().shortValue()) { + entity.setPhStatus(PostHandleStatusEnum.NORMALITY.getCode().shortValue()); + } else { + entity.setPhStatus(PostHandleStatusEnum.IN_PRACTICE.getCode().shortValue()); + } + return entity; + } /** * 实习工自动创建一条培训计划 * - * @param postHandleEntity + * @param postHandleEntitys */ - public void createPlan(PostHandleEntity postHandleEntity) { - if (postHandleEntity.getStaffType() == StaffTypeEnum.of("实习工").getCode().shortValue()) { - CultivateDetailEntity cultivateDetailEntity = new CultivateDetailEntity(); - cultivateDetailEntity.setPhId(postHandleEntity.getId()); - cultivateDetailEntity.setType((short) 1); - cultivateDetailEntity.setCaStatus(TrainingStatusEnum.of("未配置").getCode().shortValue()); - iCultivateDetailService.save(cultivateDetailEntity); - } + public void createPlan(List postHandleEntitys) { + //新增实习工时,为其创建一条培训计划 + List cultivateDetailEntities = postHandleEntitys.stream() + .filter(entity -> entity.getStaffType() == StaffTypeEnum.FIELD_WORK.getCode().shortValue()) + .map(fieldWork -> { + CultivateDetailEntity detailEntity = new CultivateDetailEntity(); + detailEntity.setPhId(fieldWork.getId()); + detailEntity.setType((short) 1); + detailEntity.setCaStatus(TrainingStatusEnum.NOT_CONFIGURED.getCode().shortValue()); + return detailEntity; + }) + .collect(Collectors.toList()); + + iCultivateDetailService.saveBatch(cultivateDetailEntities); } } diff --git a/blade-service/blade-desk/src/main/resources/Excel/jobTransfer/岗位处理导入模板下载.xls b/blade-service/blade-desk/src/main/resources/Excel/jobTransfer/岗位处理导入模板下载.xls new file mode 100644 index 0000000000000000000000000000000000000000..125619c021d7c87804525efe3383472e435586a9 GIT binary patch literal 21504 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 literal 0 HcmV?d00001