From b88a1b13d57c299ff12101cabc48b04064bfcb8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E5=85=81=E6=9E=9E?= <3422692813@qq.com> Date: Thu, 13 Feb 2025 16:17:15 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=A3=80=E6=B5=8B=E5=91=98?= =?UTF-8?q?=E5=B7=A5=E5=AF=BC=E5=85=A5=E7=9B=B8=E5=85=B3=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/InspectionStaffController.java | 85 ++++++---- .../service/InspectionStaffService.java | 10 ++ .../impl/InspectionStaffServiceImpl.java | 147 ++++++++++++++++++ .../module/inspection/vo/ImportStaffVo.java | 24 +++ .../inspection/vo/StaffImportExcelVO.java | 50 ++++-- .../framework/excel/core/util/ExcelUtils.java | 50 +++++- 6 files changed, 321 insertions(+), 45 deletions(-) create mode 100644 dl-module-inspection/src/main/java/cn/iocoder/yudao/module/inspection/vo/ImportStaffVo.java diff --git a/dl-module-inspection/src/main/java/cn/iocoder/yudao/module/inspection/controller/InspectionStaffController.java b/dl-module-inspection/src/main/java/cn/iocoder/yudao/module/inspection/controller/InspectionStaffController.java index 977661f4..5fad688e 100644 --- a/dl-module-inspection/src/main/java/cn/iocoder/yudao/module/inspection/controller/InspectionStaffController.java +++ b/dl-module-inspection/src/main/java/cn/iocoder/yudao/module/inspection/controller/InspectionStaffController.java @@ -16,18 +16,21 @@ import cn.iocoder.yudao.module.inspection.query.InspectionStaffQuery; import cn.iocoder.yudao.module.inspection.service.InspectionStaffService; import cn.iocoder.yudao.module.inspection.vo.InspectionStaffExportVo; import cn.iocoder.yudao.module.inspection.vo.InspectionStaffSaveVo; +import cn.iocoder.yudao.module.inspection.vo.StaffImportExcelVO; import cn.iocoder.yudao.module.system.api.dict.DictDataApi; import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO; +import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO; +import cn.iocoder.yudao.module.system.service.permission.RoleService; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; import static cn.iocoder.yudao.framework.excel.core.util.ExcelUtils.exportBlankTemplate; @@ -44,7 +47,9 @@ public class InspectionStaffController extends BaseController { @Autowired private InspectionStaffService inspectionStaffService; @Autowired - DictDataApi dictDataApi; + DictDataApi dictDataApi; + @Resource + private RoleService roleService; /** * 获取检测员工列表 @@ -107,47 +112,55 @@ public class InspectionStaffController extends BaseController { */ @GetMapping("/get-import-template") public void importTemplate(HttpServletResponse response) throws IOException { - // 手动创建导出 demo - // 输出 -// ExcelUtils.write(response, "用户导入模板.xls", "用户列表", StaffImportExcelVO.class, null); - - // 使用 HashMap 来替代 Map.of,兼容 JDK 1.8 Map headerMap = new HashMap<>(); headerMap.put(0, "部门名称"); headerMap.put(1, "员工姓名"); - headerMap.put(2, "身份证号码"); - headerMap.put(3, "居住地址"); - headerMap.put(4, "学历"); - headerMap.put(5, "毕业院校"); - headerMap.put(6, "电话号码"); - headerMap.put(7, "短号"); - headerMap.put(8, "入职时间"); - headerMap.put(9, "试用期"); - headerMap.put(10, "社保购买日期"); - headerMap.put(11, "紧急联系人"); - headerMap.put(12, "紧急联系人电话"); - headerMap.put(13, "驾驶证类型"); - headerMap.put(14, "备注"); + headerMap.put(2, "岗位"); + headerMap.put(3, "身份证号码"); + headerMap.put(4, "居住地址"); + headerMap.put(5, "学历"); + headerMap.put(6, "毕业院校"); + headerMap.put(7, "电话号码"); + headerMap.put(8, "短号"); + headerMap.put(9, "入职时间"); + headerMap.put(10, "试用期"); + headerMap.put(11, "社保购买日期"); + headerMap.put(12, "紧急联系人"); + headerMap.put(13, "紧急联系人电话"); + headerMap.put(14, "驾驶证类型"); + headerMap.put(15, "备注"); // 下拉框列及选项:列索引 -> 下拉框选项 Map dropdownColumns = new HashMap<>(); - List allId = DriverLicenseType.getAllId(); - String[] array = ArrayUtil.toArray(allId, String.class); - dropdownColumns.put(13, array); // 驾照类型 //查询学历 List education = dictDataApi.getDictDataList("company_staff_edu"); String[] array1 = education.stream() .map(DictDataRespDTO::getLabel) .toArray(String[]::new); + dropdownColumns.put(5, array1); + //查询岗位 + RoleDO roleDO = new RoleDO(); + roleDO.setServicePackageId("jiance"); + List roleDOS = roleService.pageByQuery(roleDO); - dropdownColumns.put(4, array1); - int[] dateColumns = {8, 9,10}; + String[] roles = roleDOS.stream() + .map(RoleDO::getName) + .toArray(String[]::new); + + dropdownColumns.put(2, roles); + + int[] dateColumns = {9, 10, 11}; + + List> exampleDataList = Arrays.asList( + Arrays.asList("测试部门", "测试员工","岗位时下拉框选择","xxxxxxxxxxxxxxxxx","居住地","学历是下拉框","xxx学校","手机号","短号","2023/5/2(日期格式)","2023/5/2(日期格式)","2023/5/2(日期格式","紧急联系人","xxxxxxxx","A1,C1(有多个驾驶证类型使用逗号分割)","备注") + ); + + List textColumns = Collections.singletonList(3); // 导出空白模板到Excel - exportBlankTemplate(response, "staff_template.xlsx", "员工信息", headerMap, dropdownColumns, dateColumns,true); - + exportBlankTemplate(response, "staff_template.xlsx", "员工信息", headerMap, dropdownColumns, dateColumns, true, exampleDataList,textColumns); } @GetMapping("/export") @@ -160,6 +173,20 @@ public class InspectionStaffController extends BaseController { list); } + /** + * 导入 + */ + @PostMapping("/import") + public CommonResult importUser(@RequestParam("file") MultipartFile file) { + try { + List list = ExcelUtils.read(file, StaffImportExcelVO.class); + Map map = inspectionStaffService.importStaff(list); + return success(map); + } catch (Exception e) { + throw new RuntimeException(e.getMessage()); + } + } + /** * 校验信息 * diff --git a/dl-module-inspection/src/main/java/cn/iocoder/yudao/module/inspection/service/InspectionStaffService.java b/dl-module-inspection/src/main/java/cn/iocoder/yudao/module/inspection/service/InspectionStaffService.java index 55b8283c..7c82ccd4 100644 --- a/dl-module-inspection/src/main/java/cn/iocoder/yudao/module/inspection/service/InspectionStaffService.java +++ b/dl-module-inspection/src/main/java/cn/iocoder/yudao/module/inspection/service/InspectionStaffService.java @@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import java.util.List; +import java.util.Map; /** * 检测员工子表(InspectionStaff)表服务接口 @@ -26,6 +27,7 @@ public interface InspectionStaffService extends IService { * @return */ IPage getList(Page page, InspectionStaffQuery query); + /** * 获取所有检测员工 * @@ -57,5 +59,13 @@ public interface InspectionStaffService extends IService { * @return */ Long saveInspectionStaff(InspectionStaffSaveVo inspectionStaffVo); + + /** + * 导入检测员工 + * + * @param list 检测员工 + * @return + */ + Map importStaff(List list); } diff --git a/dl-module-inspection/src/main/java/cn/iocoder/yudao/module/inspection/service/impl/InspectionStaffServiceImpl.java b/dl-module-inspection/src/main/java/cn/iocoder/yudao/module/inspection/service/impl/InspectionStaffServiceImpl.java index 54e62f0b..3bfbd6f1 100644 --- a/dl-module-inspection/src/main/java/cn/iocoder/yudao/module/inspection/service/impl/InspectionStaffServiceImpl.java +++ b/dl-module-inspection/src/main/java/cn/iocoder/yudao/module/inspection/service/impl/InspectionStaffServiceImpl.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.inspection.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.IdcardUtil; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.module.constant.InspectionConstants; import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO; @@ -12,12 +13,15 @@ import cn.iocoder.yudao.module.inspection.mapper.InspectionStaffMapper; import cn.iocoder.yudao.module.inspection.query.InspectionStaffQuery; import cn.iocoder.yudao.module.inspection.service.IInspectionFileService; import cn.iocoder.yudao.module.inspection.service.InspectionStaffService; +import cn.iocoder.yudao.module.inspection.vo.ImportStaffVo; import cn.iocoder.yudao.module.inspection.vo.InspectionStaffExportVo; import cn.iocoder.yudao.module.inspection.vo.InspectionStaffSaveVo; +import cn.iocoder.yudao.module.inspection.vo.StaffImportExcelVO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.UserDTO; import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserSaveReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO; +import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; import cn.iocoder.yudao.module.system.service.permission.PermissionService; import cn.iocoder.yudao.module.system.service.permission.RoleService; import cn.iocoder.yudao.module.system.service.user.AdminUserService; @@ -33,6 +37,8 @@ import org.springframework.transaction.annotation.Transactional; import java.util.*; import java.util.stream.Collectors; +import static cn.iocoder.yudao.framework.common.config.CommonStr.USER_TYPE_STAFF; + /** * 检测员工子表(InspectionStaff)表服务实现类 @@ -180,6 +186,147 @@ public class InspectionStaffServiceImpl extends ServiceImpl importStaff(List list) { + if (ObjectUtil.isEmpty(list)) { + throw new RuntimeException("导入数据为空"); + } + Map resultMap = new HashMap<>(); + + //校验信息 + ImportStaffVo importStaffVo = validImportStaff(list); + + //保存用户信息 + int saveNum = saveImportStaff(importStaffVo.getSuccessList()); + resultMap.put("saveNum", saveNum); + resultMap.put("failList", importStaffVo.getFailList()); + resultMap.put("successList", importStaffVo.getSuccessList()); + return resultMap; + } + + /** + * 保存检测员工 + * + * @param successList + * @return + */ + private int saveImportStaff(List successList) { + //将员工插入主表 + List userDTOList = new ArrayList<>(); + for (StaffImportExcelVO staffImportExcelVO : successList) { + AdminUserDO userDTO = new AdminUserDO(); + userDTO.setUsername(staffImportExcelVO.getUsername()); + userDTO.setNickname(staffImportExcelVO.getUsername()); + userDTO.setMobile(staffImportExcelVO.getMobile()); + userDTO.setPassword("123456"); + userDTO.setUserType(USER_TYPE_STAFF); + + userDTOList.add(userDTO); + + } + userService.saveBatch(userDTOList); + + Map users = userDTOList.stream().collect(Collectors.toMap(AdminUserDO::getMobile, AdminUserDO::getId)); + + //插入检测员工子表 + List inspectionStaffList = new ArrayList<>(); + for (StaffImportExcelVO staffImportExcelVO : successList) { + Long userId = users.get(staffImportExcelVO.getMobile()); + InspectionStaff inspectionStaff = BeanUtil.copyProperties(staffImportExcelVO, InspectionStaff.class); + inspectionStaff.setUserId(userId); + inspectionStaffList.add(inspectionStaff); + + permissionService.assignUserRole(userId, Collections.singleton(staffImportExcelVO.getRoleId())); + } + this.saveBatch(inspectionStaffList); + return 0; + } + + /** + * 验证导入员工数据 + * + * @param list + * @return + */ + private ImportStaffVo validImportStaff(List list) { + List successList = new ArrayList<>(); + List failList = new ArrayList<>(); + + //查询检测角色 + RoleDO roleDO = new RoleDO(); + roleDO.setServicePackageId("jiance"); + List roleDOS = roleService.pageByQuery(roleDO); + Map roleMap = roleDOS.stream().collect(Collectors.toMap(RoleDO::getName, RoleDO::getId)); + + //根据手机号查询员工 + List list1 = userService.list(Wrappers.lambdaQuery().in(AdminUserDO::getMobile, list.stream().map(StaffImportExcelVO::getMobile).collect(Collectors.toList()))); + Map mobileMap = list1.stream().collect(Collectors.toMap(AdminUserDO::getMobile, AdminUserDO::getId)); + + //判断第一条数据是否是测试数据 + if (ObjectUtil.isNotEmpty(list)) { + if ("测试员工".equals(list.get(0).getUsername())) { + list.remove(0); + } + } + for (StaffImportExcelVO staffImportExcelVO : list) { + if (ObjectUtil.isNull(staffImportExcelVO)) { + continue; + } + //判断员工姓名是否为空 + if (ObjectUtil.isEmpty(staffImportExcelVO.getUsername())) { + staffImportExcelVO.setReason("员工姓名不能为空"); + failList.add(staffImportExcelVO); + continue; + } + // 判断手机号是否为空 + if (ObjectUtil.isEmpty(staffImportExcelVO.getMobile())) { + staffImportExcelVO.setReason("员工" + staffImportExcelVO.getUsername() + "手机号不能为空"); + failList.add(staffImportExcelVO); + continue; + } + //判断手机号是否存在 + if (ObjectUtil.isNotEmpty(mobileMap.get(staffImportExcelVO.getMobile()))) { + staffImportExcelVO.setReason("员工" + staffImportExcelVO.getUsername() + "的手机号已存在"); + failList.add(staffImportExcelVO); + continue; + } + //如果身份证存在验证身份证是否正确 + if (ObjectUtil.isNotEmpty(staffImportExcelVO.getIdCard())) { + if (!IdcardUtil.isValidCard(staffImportExcelVO.getIdCard())) { + staffImportExcelVO.setReason("员工" + staffImportExcelVO.getUsername() + "身份证格式不正确"); + failList.add(staffImportExcelVO); + continue; + } + } + //判断员工角色是否为空 + if (ObjectUtil.isEmpty(staffImportExcelVO.getRoleName())) { + staffImportExcelVO.setReason("员工" + staffImportExcelVO.getUsername() + "员工角色不能为空"); + failList.add(staffImportExcelVO); + continue; + } + //查询员工角色对应id + Long roleId = roleMap.get(staffImportExcelVO.getRoleName()); + staffImportExcelVO.setRoleId(roleId); + //如果驾驶证类型不为空,将字符串里的所有英文转成大写 + if (ObjectUtil.isNotEmpty(staffImportExcelVO.getDriverLicenseType())) { + staffImportExcelVO.setDriverLicenseType(staffImportExcelVO.getDriverLicenseType().toUpperCase()); + //将中文逗号替换为英文 + staffImportExcelVO.setDriverLicenseType(staffImportExcelVO.getDriverLicenseType().replaceAll(",", ",")); + } + successList.add(staffImportExcelVO); + } + ImportStaffVo importStaffVo = new ImportStaffVo(); + importStaffVo.setSuccessList(successList); + importStaffVo.setFailList(failList); + return importStaffVo; + } + /** * 添加员工附件 * diff --git a/dl-module-inspection/src/main/java/cn/iocoder/yudao/module/inspection/vo/ImportStaffVo.java b/dl-module-inspection/src/main/java/cn/iocoder/yudao/module/inspection/vo/ImportStaffVo.java new file mode 100644 index 00000000..83721011 --- /dev/null +++ b/dl-module-inspection/src/main/java/cn/iocoder/yudao/module/inspection/vo/ImportStaffVo.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.inspection.vo; + +import lombok.Data; + +import java.util.List; + +/** + * @Description: 导入实习生返回对象 + * @Author: 86187 + * @Date: 2025/02/13 11:46 + * @Version: 1.0 + */ +@Data +public class ImportStaffVo { + /** + * 导入成功的集合 + */ + private List successList; + + /** + * 导入失败的集合 + */ + private List failList; +} diff --git a/dl-module-inspection/src/main/java/cn/iocoder/yudao/module/inspection/vo/StaffImportExcelVO.java b/dl-module-inspection/src/main/java/cn/iocoder/yudao/module/inspection/vo/StaffImportExcelVO.java index b5186439..e44235e6 100644 --- a/dl-module-inspection/src/main/java/cn/iocoder/yudao/module/inspection/vo/StaffImportExcelVO.java +++ b/dl-module-inspection/src/main/java/cn/iocoder/yudao/module/inspection/vo/StaffImportExcelVO.java @@ -1,8 +1,13 @@ package cn.iocoder.yudao.module.inspection.vo; +import com.alibaba.excel.annotation.ExcelIgnore; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.converters.localdate.LocalDateStringConverter; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; /** * @Description: 检测员工Excel @@ -11,50 +16,65 @@ import lombok.Data; * @Version: 1.0 */ @Data +@Accessors(chain = false) // 禁用链式调用 +@AllArgsConstructor +@NoArgsConstructor public class StaffImportExcelVO { - @ExcelProperty("部门名称") + @ExcelProperty(value = "部门名称", index = 0) private String deptName; - @ExcelProperty("员工姓名") + @ExcelProperty(value = "员工姓名", index = 1) private String username; - @ExcelProperty("身份证号码") + @ExcelProperty(value ="岗位", index = 2) + private String roleName; + + @ExcelProperty(value ="身份证号码", index = 3) private String idCard; - @ExcelProperty("居住地址") + @ExcelProperty(value ="居住地址", index = 4) private String address; - @ExcelProperty("学历") + @ExcelProperty(value ="学历", index = 5) private String educational; - @ExcelProperty("毕业院校") + @ExcelProperty(value ="毕业院校", index = 6) private String school; - @ExcelProperty("电话号码") + @ExcelProperty(value ="电话号码", index = 7) private String mobile; - @ExcelProperty("短号") + @ExcelProperty(value ="短号", index = 8) private String shortNumber; - @ExcelProperty(value = "入职时间") + @ExcelProperty(value = "入职时间", index = 9) private String joinDate; - @ExcelProperty("试用期") + @ExcelProperty(value ="试用期", index = 10) private String probationPeriod; - @ExcelProperty(value = "社保购买日期") + @ExcelProperty(value = "社保购买日期", index = 11) private String socialSecurityBuyDate; - @ExcelProperty("紧急联系人") + @ExcelProperty(value ="紧急联系人", index = 12) private String emergencyContactName; - @ExcelProperty("紧急联系人电话") + @ExcelProperty(value ="紧急联系人电话", index = 13) private String emergencyContactPhone; - @ExcelProperty("驾驶证类型") + @ExcelProperty(value ="驾驶证类型", index = 14) private String driverLicenseType; - @ExcelProperty("备注") + @ExcelProperty(value ="备注", index = 15) private String remark; + + @ExcelIgnore + private String reason; + + /** + * 角色id + */ + @ExcelIgnore + private Long roleId; } diff --git a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java index e99b2f06..80e7b426 100644 --- a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java +++ b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java @@ -104,7 +104,10 @@ public class ExcelUtils { Map headerMap, Map dropdownColumns, int[] dateTimeColumns, - boolean isMultiSelect) throws IOException { + boolean isMultiSelect, + List> exampleDataList, + List textColumns) throws IOException { + Workbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet(sheetName); @@ -114,6 +117,31 @@ public class ExcelUtils { headerRow.createCell(entry.getKey()).setCellValue(entry.getValue()); } + // 创建一个 CellStyle 对象,用于设置文本格式 + CellStyle textCellStyle = workbook.createCellStyle(); + DataFormat dataFormat = workbook.createDataFormat(); + textCellStyle.setDataFormat(dataFormat.getFormat("@")); // "@" 表示文本格式 + + // 为每个需要文本格式的列设置整个列的文本格式 + for (Integer columnIndex : textColumns) { + setColumnTextFormat(sheet, columnIndex, textCellStyle); + } + + // 添加多行自定义示例数据 + for (int i = 0; i < exampleDataList.size(); i++) { + List exampleData = exampleDataList.get(i); + Row exampleRow = sheet.createRow(i + 1); // 示例数据从第二行开始 + for (int j = 0; j < exampleData.size(); j++) { + Cell cell = exampleRow.createCell(j); + cell.setCellValue(exampleData.get(j)); + + // 如果当前列索引在 textColumns 列表中,则设置为文本格式 + if (textColumns.contains(j)) { + cell.setCellStyle(textCellStyle); + } + } + } + // 添加下拉框到指定列 if (dropdownColumns != null) { for (Map.Entry entry : dropdownColumns.entrySet()) { @@ -141,6 +169,8 @@ public class ExcelUtils { } } + + /** * 为指定列添加日期时间格式验证 * @@ -182,4 +212,22 @@ public class ExcelUtils { sheet.addValidationData(validation); } + /** + * 为指定列设置整个列的文本格式 + */ + private static void setColumnTextFormat(Sheet sheet, int columnIndex, CellStyle textCellStyle) { + int rowCount = 1000; // 获取当前表格中的总行数 + for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) { + Row row = sheet.getRow(rowIndex); + if (row == null) { + row = sheet.createRow(rowIndex); // 如果该行不存在,则创建它 + } + Cell cell = row.getCell(columnIndex); + if (cell == null) { + cell = row.createCell(columnIndex); // 如果该单元格不存在,则创建它 + } + cell.setCellStyle(textCellStyle); // 设置为文本格式 + } + } + }