hsy
9 天以前 e11706ad56843610601c14aa15868c4c3b908548
feat: 新增部门和岗位模块的Excel导入及导出模板功能

- **岗位模块 (Post)**:
1. 新增 `PostImportExcelVO` 和 `PostImportRespVO`。
2. 在 `PostController` 中新增 `/import`(数据导入)和 `/get-import-template`(获取模板)接口。
3. 在 `PostServiceImpl` 完善导入保存和更新逻辑,支持重复数据的覆盖更新。
4. 增加 `POST_IMPORT_LIST_IS_EMPTY` 错误码。

- **部门模块 (Dept)**:
1. 新增 `DeptImportExcelVO` 和 `DeptImportRespVO`(不包含非必填的负责人字段)。
2. 在 `DeptController` 中新增 `/import` 和 `/get-import-template` 接口。
3. 在 `DeptServiceImpl` 中实现树形结构数据的导入逻辑:通过“上级部门全路径”深度排序,确保在插入子部门前优先处理父部门;实时构建全路径映射解决上下级关联关系。
4. 增加 `DEPT_IMPORT_LIST_IS_EMPTY` 错误码。
```
已修改8个文件
已添加4个文件
348 ■■■■■ 文件已修改
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/statistics/SrmStatisticsServiceImpl.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/DeptController.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/PostController.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptImportExcelVO.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptImportRespVO.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostImportExcelVO.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostImportRespVO.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImpl.java 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dept/PostService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dept/PostServiceImpl.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/statistics/SrmStatisticsServiceImpl.java
@@ -44,12 +44,15 @@
                        .apply("YEAR(create_time) = {0}", year));
        long totalTenderCount = projects.size();
        //招标总金额(预算金额)
        BigDecimal totalTenderAmount = projects.stream()
                .map(p -> p.getBudgetAmount() != null ? p.getBudgetAmount() : BigDecimal.ZERO)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        //定标总金额(中标金额)
        BigDecimal totalAwardAmount = awards.stream()
                .map(a -> a.getAwardAmount() != null ? a.getAwardAmount() : BigDecimal.ZERO)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        //节约金额(预算金额-中标金额)
        BigDecimal savedAmount = totalTenderAmount.subtract(totalAwardAmount);
        long supplierCount = bids.stream()
                .map(SrmTenderBidDO::getSupplierId)
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/DeptController.java
@@ -7,17 +7,25 @@
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptRespVO;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptSaveReqVO;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptSimpleRespVO;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptImportExcelVO;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptImportRespVO;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
import cn.iocoder.yudao.module.system.service.dept.DeptService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -90,4 +98,27 @@
        return success(BeanUtils.toBean(dept, DeptRespVO.class));
    }
    @GetMapping("/get-import-template")
    @Operation(summary = "获得导入部门模板")
    public void importTemplate(HttpServletResponse response) throws IOException {
        List<DeptImportExcelVO> list = Arrays.asList(
                DeptImportExcelVO.builder().name("研发部").parentPath("总公司").sort(1).status(CommonStatusEnum.ENABLE.getStatus()).build(),
                DeptImportExcelVO.builder().name("财务部").parentPath("总公司").sort(2).status(CommonStatusEnum.ENABLE.getStatus()).build()
        );
        ExcelUtils.write(response, "部门导入模板.xls", "部门列表", DeptImportExcelVO.class, list);
    }
    @PostMapping("/import")
    @Operation(summary = "导入部门")
    @Parameters({
            @Parameter(name = "file", description = "Excel æ–‡ä»¶", required = true),
            @Parameter(name = "updateSupport", description = "是否支持更新,默认为 false", example = "true")
    })
    @PreAuthorize("@ss.hasPermission('system:dept:import')")
    public CommonResult<DeptImportRespVO> importExcel(@RequestParam("file") MultipartFile file,
                                                      @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception {
        List<DeptImportExcelVO> list = ExcelUtils.read(file, DeptImportExcelVO.class);
        return success(deptService.importDeptList(list, updateSupport));
    }
}
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/PostController.java
@@ -11,6 +11,8 @@
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostRespVO;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostSaveReqVO;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostSimpleRespVO;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostImportExcelVO;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostImportRespVO;
import cn.iocoder.yudao.module.system.dal.dataobject.dept.PostDO;
import cn.iocoder.yudao.module.system.service.dept.PostService;
import io.swagger.v3.oas.annotations.Operation;
@@ -22,8 +24,11 @@
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import io.swagger.v3.oas.annotations.Parameters;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@@ -100,7 +105,7 @@
    }
    @GetMapping("/export-excel")
    @Operation(summary = "岗位管理")
    @Operation(summary = "导出岗位 Excel")
    @PreAuthorize("@ss.hasPermission('system:post:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void export(HttpServletResponse response, @Validated PostPageReqVO reqVO) throws IOException {
@@ -111,4 +116,31 @@
                BeanUtils.toBean(list, PostRespVO.class));
    }
    @GetMapping("/get-import-template")
    @Operation(summary = "获得导入岗位模板")
    public void importTemplate(HttpServletResponse response) throws IOException {
        // æ‰‹åŠ¨åˆ›å»ºå¯¼å‡º demo
        List<PostImportExcelVO> list = Arrays.asList(
                PostImportExcelVO.builder().name("全栈开发").code("fullstack").sort(1)
                        .status(CommonStatusEnum.ENABLE.getStatus()).remark("全栈开发工程师").build(),
                PostImportExcelVO.builder().name("前端开发").code("frontend").sort(2)
                        .status(CommonStatusEnum.ENABLE.getStatus()).remark("前端开发工程师").build()
        );
        // è¾“出
        ExcelUtils.write(response, "岗位导入模板.xls", "岗位列表", PostImportExcelVO.class, list);
    }
    @PostMapping("/import")
    @Operation(summary = "导入岗位")
    @Parameters({
            @Parameter(name = "file", description = "Excel æ–‡ä»¶", required = true),
            @Parameter(name = "updateSupport", description = "是否支持更新,默认为 false", example = "true")
    })
    @PreAuthorize("@ss.hasPermission('system:post:import')")
    public CommonResult<PostImportRespVO> importExcel(@RequestParam("file") MultipartFile file,
                                                      @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception {
        List<PostImportExcelVO> list = ExcelUtils.read(file, PostImportExcelVO.class);
        return success(postService.importPostList(list, updateSupport));
    }
}
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptImportExcelVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,37 @@
package cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept;
import cn.idev.excel.annotation.ExcelProperty;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class DeptImportExcelVO {
    @ExcelProperty("部门名称")
    private String name;
    @ExcelProperty("上级部门全路径")
    private String parentPath;
    @ExcelProperty("显示顺序")
    private Integer sort;
    @ExcelProperty("联系电话")
    private String phone;
    @ExcelProperty("邮箱")
    private String email;
    @ExcelProperty(value = "状态", converter = DictConvert.class)
    @DictFormat(DictTypeConstants.COMMON_STATUS)
    private Integer status;
}
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptImportRespVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
package cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Data;
import java.util.List;
import java.util.Map;
@Schema(description = "管理后台 - éƒ¨é—¨å¯¼å…¥ Response VO")
@Data
@Builder
public class DeptImportRespVO {
    @Schema(description = "创建成功的部门数组", requiredMode = Schema.RequiredMode.REQUIRED)
    private List<String> createDeptNames;
    @Schema(description = "更新成功的部门数组", requiredMode = Schema.RequiredMode.REQUIRED)
    private List<String> updateDeptNames;
    @Schema(description = "导入失败的部门集合 key ä¸ºéƒ¨é—¨åï¼Œvalue ä¸ºå¤±è´¥åŽŸå› ", requiredMode = Schema.RequiredMode.REQUIRED)
    private Map<String, String> failureDeptNames;
}
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostImportExcelVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,34 @@
package cn.iocoder.yudao.module.system.controller.admin.dept.vo.post;
import cn.idev.excel.annotation.ExcelProperty;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class PostImportExcelVO {
    @ExcelProperty("岗位名称")
    private String name;
    @ExcelProperty("岗位编码")
    private String code;
    @ExcelProperty("岗位排序")
    private Integer sort;
    @ExcelProperty(value = "状态", converter = DictConvert.class)
    @DictFormat(DictTypeConstants.COMMON_STATUS)
    private Integer status;
    @ExcelProperty("备注")
    private String remark;
}
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostImportRespVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
package cn.iocoder.yudao.module.system.controller.admin.dept.vo.post;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Data;
import java.util.List;
import java.util.Map;
@Schema(description = "管理后台 - å²—位导入 Response VO")
@Data
@Builder
public class PostImportRespVO {
    @Schema(description = "创建成功的岗位数组", requiredMode = Schema.RequiredMode.REQUIRED)
    private List<String> createPostNames;
    @Schema(description = "更新成功的岗位数组", requiredMode = Schema.RequiredMode.REQUIRED)
    private List<String> updatePostNames;
    @Schema(description = "导入失败的岗位集合 key ä¸ºå²—位名称,value ä¸ºå¤±è´¥åŽŸå› ", requiredMode = Schema.RequiredMode.REQUIRED)
    private Map<String, String> failurePostNames;
}
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java
@@ -55,12 +55,14 @@
    ErrorCode DEPT_PARENT_ERROR = new ErrorCode(1_002_004_004, "不能设置自己为父部门");
    ErrorCode DEPT_NOT_ENABLE = new ErrorCode(1_002_004_006, "部门({})不处于开启状态,不允许选择");
    ErrorCode DEPT_PARENT_IS_CHILD = new ErrorCode(1_002_004_007, "不能设置自己的子部门为父部门");
    ErrorCode DEPT_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_002_004_008, "导入部门数据不能为空!");
    // ========== å²—位模块 1-002-005-000 ==========
    ErrorCode POST_NOT_FOUND = new ErrorCode(1_002_005_000, "当前岗位不存在");
    ErrorCode POST_NOT_ENABLE = new ErrorCode(1_002_005_001, "岗位({}) ä¸å¤„于开启状态,不允许选择");
    ErrorCode POST_NAME_DUPLICATE = new ErrorCode(1_002_005_002, "已经存在该名字的岗位");
    ErrorCode POST_CODE_DUPLICATE = new ErrorCode(1_002_005_003, "已经存在该标识的岗位");
    ErrorCode POST_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_002_005_004, "导入岗位数据不能为空!");
    // ========== å­—典类型 1-002-006-000 ==========
    ErrorCode DICT_TYPE_NOT_EXISTS = new ErrorCode(1_002_006_001, "当前字典类型不存在");
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptService.java
@@ -3,6 +3,8 @@
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptListReqVO;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptSaveReqVO;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptImportExcelVO;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptImportRespVO;
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
import java.util.*;
@@ -121,4 +123,13 @@
     */
    void validateDeptList(Collection<Long> ids);
    /**
     * å¯¼å…¥éƒ¨é—¨åˆ—表
     *
     * @param importDepts     å¯¼å…¥éƒ¨é—¨åˆ—表
     * @param isUpdateSupport æ˜¯å¦æ”¯æŒæ›´æ–°
     * @return å¯¼å…¥ç»“æžœ
     */
    DeptImportRespVO importDeptList(List<DeptImportExcelVO> importDepts, boolean isUpdateSupport);
}
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImpl.java
@@ -2,11 +2,15 @@
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptListReqVO;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptSaveReqVO;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptImportExcelVO;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptImportRespVO;
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
import cn.iocoder.yudao.module.system.dal.mysql.dept.DeptMapper;
import cn.iocoder.yudao.module.system.dal.redis.RedisKeyConstants;
@@ -235,4 +239,83 @@
        });
    }
    @Override
    public DeptImportRespVO importDeptList(List<DeptImportExcelVO> importDepts, boolean isUpdateSupport) {
        if (CollUtil.isEmpty(importDepts)) {
            throw exception(DEPT_IMPORT_LIST_IS_EMPTY);
        }
        DeptImportRespVO respVO = DeptImportRespVO.builder().createDeptNames(new ArrayList<>())
                .updateDeptNames(new ArrayList<>()).failureDeptNames(new LinkedHashMap<>()).build();
        // 1. åˆå§‹åŒ–现有的全路径与部门ID映射
        List<DeptDO> allDepts = getDeptList(new DeptListReqVO());
        Map<Long, DeptDO> idDeptMap = cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap(allDepts, DeptDO::getId);
        Map<String, Long> fullPathDeptIdMap = new HashMap<>();
        for (DeptDO dept : allDepts) {
            fullPathDeptIdMap.put(getFullPath(dept, idDeptMap), dept.getId());
        }
        // 2. å°†å¯¼å…¥çš„部门按照父部门路径深度排序,确保先处理父部门
        importDepts.sort(Comparator.comparingInt(dept -> StrUtil.isEmpty(dept.getParentPath()) ? 0 : dept.getParentPath().split("/").length));
        // 3. éåކ坼入
        for (DeptImportExcelVO importDept : importDepts) {
            // 3.1 èŽ·å–çˆ¶éƒ¨é—¨ ID
            Long parentId = DeptDO.PARENT_ID_ROOT;
            if (StrUtil.isNotEmpty(importDept.getParentPath())) {
                parentId = fullPathDeptIdMap.get(importDept.getParentPath());
                if (parentId == null) {
                    respVO.getFailureDeptNames().put(importDept.getName(), "上级部门不存在: " + importDept.getParentPath());
                    continue;
                }
            }
            // 3.2 æ ¡éªŒéƒ¨é—¨åç§°æ˜¯å¦å”¯ä¸€
            try {
                validateDeptNameUnique(null, parentId, importDept.getName());
            } catch (ServiceException ex) {
                if (!isUpdateSupport) {
                    respVO.getFailureDeptNames().put(importDept.getName(), ex.getMessage());
                    continue;
                }
                // æ”¯æŒæ›´æ–°ï¼Œæ‰§è¡Œæ›´æ–°
                DeptDO existDept = deptMapper.selectByParentIdAndName(parentId, importDept.getName());
                DeptDO updateDept = BeanUtils.toBean(importDept, DeptDO.class);
                updateDept.setId(existDept.getId());
                updateDept.setParentId(parentId);
                deptMapper.updateById(updateDept);
                respVO.getUpdateDeptNames().add(importDept.getName());
                String myFullPath = StrUtil.isEmpty(importDept.getParentPath()) ? importDept.getName() : importDept.getParentPath() + "/" + importDept.getName();
                fullPathDeptIdMap.put(myFullPath, existDept.getId());
                continue;
            }
            // 3.3 æ–°å¢žéƒ¨é—¨
            DeptDO newDept = BeanUtils.toBean(importDept, DeptDO.class);
            newDept.setParentId(parentId);
            deptMapper.insert(newDept);
            respVO.getCreateDeptNames().add(importDept.getName());
            // æ›´æ–°ç¼“存,供后续子部门使用
            String myFullPath = StrUtil.isEmpty(importDept.getParentPath()) ? importDept.getName() : importDept.getParentPath() + "/" + importDept.getName();
            fullPathDeptIdMap.put(myFullPath, newDept.getId());
        }
        return respVO;
    }
    private String getFullPath(DeptDO dept, Map<Long, DeptDO> idDeptMap) {
        StringBuilder path = new StringBuilder(dept.getName());
        Long parentId = dept.getParentId();
        while (parentId != null && !DeptDO.PARENT_ID_ROOT.equals(parentId)) {
            DeptDO parent = idDeptMap.get(parentId);
            if (parent == null) {
                break;
            }
            path.insert(0, parent.getName() + "/");
            parentId = parent.getParentId();
        }
        return path.toString();
    }
}
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dept/PostService.java
@@ -3,6 +3,8 @@
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostSaveReqVO;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostImportExcelVO;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostImportRespVO;
import cn.iocoder.yudao.module.system.dal.dataobject.dept.PostDO;
import org.jspecify.annotations.Nullable;
@@ -88,4 +90,13 @@
     */
    void validatePostList(Collection<Long> ids);
    /**
     * å¯¼å…¥å²—位列表
     *
     * @param importPosts     å¯¼å…¥å²—位列表
     * @param isUpdateSupport æ˜¯å¦æ”¯æŒæ›´æ–°
     * @return å¯¼å…¥ç»“æžœ
     */
    PostImportRespVO importPostList(List<PostImportExcelVO> importPosts, boolean isUpdateSupport);
}
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dept/PostServiceImpl.java
@@ -16,6 +16,12 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostImportExcelVO;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostImportRespVO;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
@@ -155,4 +161,52 @@
            }
        });
    }
    @Override
    public PostImportRespVO importPostList(List<PostImportExcelVO> importPosts, boolean isUpdateSupport) {
        if (CollUtil.isEmpty(importPosts)) {
            throw exception(POST_IMPORT_LIST_IS_EMPTY);
        }
        PostImportRespVO respVO = PostImportRespVO.builder().createPostNames(new ArrayList<>())
                .updatePostNames(new ArrayList<>()).failurePostNames(new LinkedHashMap<>()).build();
        importPosts.forEach(importPost -> {
            // æ ¡éªŒï¼Œåˆ¤æ–­æ˜¯å¦æœ‰ä¸ç¬¦åˆçš„原因
            try {
                validatePostForCreateOrUpdate(null, importPost.getName(), importPost.getCode());
            } catch (ServiceException ex) {
                // å¦‚果是重复异常,而且支持更新
                if (isUpdateSupport && (POST_NAME_DUPLICATE.getCode().equals(ex.getCode()) || POST_CODE_DUPLICATE.getCode().equals(ex.getCode()))) {
                    // ignore
                } else {
                    respVO.getFailurePostNames().put(importPost.getName(), ex.getMessage());
                    return;
                }
            }
            // åˆ¤æ–­å¦‚果存在,在进行更新
            PostDO existPost = postMapper.selectByName(importPost.getName());
            if (existPost == null) {
                existPost = postMapper.selectByCode(importPost.getCode());
            }
            if (existPost == null) {
                PostDO post = BeanUtils.toBean(importPost, PostDO.class);
                postMapper.insert(post);
                respVO.getCreatePostNames().add(importPost.getName());
                return;
            }
            // å¦‚果存在,判断是否允许更新
            if (!isUpdateSupport) {
                respVO.getFailurePostNames().put(importPost.getName(), "岗位名或编码已经存在");
                return;
            }
            // æ›´æ–°å²—位
            PostDO updatePost = BeanUtils.toBean(importPost, PostDO.class);
            updatePost.setId(existPost.getId());
            postMapper.updateById(updatePost);
            respVO.getUpdatePostNames().add(importPost.getName());
        });
        return respVO;
    }
}