Commit cd87f2e4aa24a91e10e90894a65a930ab2e94a3e
1 parent
e7bd2a56
✨ CRM:code review 客户导出的实现
Showing
6 changed files
with
64 additions
and
84 deletions
yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/enums/ExcelColumn.java
| ... | ... | @@ -3,6 +3,7 @@ package cn.iocoder.yudao.framework.excel.core.enums; |
| 3 | 3 | import lombok.AllArgsConstructor; |
| 4 | 4 | import lombok.Getter; |
| 5 | 5 | |
| 6 | +// TODO @puhui999:列表有办法通过 field name 么?主要考虑一个点,可能导入模版的顺序可能会变 | |
| 6 | 7 | /** |
| 7 | 8 | * Excel 列名枚举 |
| 8 | 9 | * 默认枚举 26 列列名如果有需求更多的列名请自行补充 |
| ... | ... | @@ -12,6 +13,7 @@ import lombok.Getter; |
| 12 | 13 | @Getter |
| 13 | 14 | @AllArgsConstructor |
| 14 | 15 | public enum ExcelColumn { |
| 16 | + | |
| 15 | 17 | A(0), B(1), C(2), D(3), E(4), F(5), G(6), H(7), I(8), |
| 16 | 18 | J(9), K(10), L(11), M(12), N(13), O(14), P(15), Q(16), |
| 17 | 19 | R(17), S(18), T(19), U(20), V(21), W(22), X(23), Y(24), | ... | ... |
yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/SelectSheetWriteHandler.java
| ... | ... | @@ -23,9 +23,20 @@ import java.util.stream.Collectors; |
| 23 | 23 | */ |
| 24 | 24 | public class SelectSheetWriteHandler implements SheetWriteHandler { |
| 25 | 25 | |
| 26 | + /** | |
| 27 | + * 数据起始行从 0 开始 | |
| 28 | + * | |
| 29 | + * 约定:本项目第一行有标题所以从 1 开始如果您的 Excel 有多行标题请自行更改 | |
| 30 | + */ | |
| 31 | + public static final int FIRST_ROW = 1; | |
| 32 | + /** | |
| 33 | + * 下拉列需要创建下拉框的行数,默认两千行如需更多请自行调整 | |
| 34 | + */ | |
| 35 | + public static final int LAST_ROW = 2000; | |
| 36 | + | |
| 26 | 37 | private static final String DICT_SHEET_NAME = "字典sheet"; |
| 27 | - public static final int FIRST_ROW = 1; // 数据起始行从 0 开始,本项目第一行有标题所以从 1 开始如果您的 Excel 有多行标题请自行更改 | |
| 28 | - public static final int LAST_ROW = 2000; // 下拉列需要创建下拉框的行数,默认两千行如需更多请自行调整 | |
| 38 | + | |
| 39 | + // TODO @puhui999:Map<ExcelColumn, List<String>> 可以么?之前用 keyvalue 的原因,返回给前端,无法用 linkedhashmap,默认 key 会乱序 | |
| 29 | 40 | private final List<KeyValue<ExcelColumn, List<String>>> selectMap; |
| 30 | 41 | |
| 31 | 42 | public SelectSheetWriteHandler(List<KeyValue<ExcelColumn, List<String>>> selectMap) { |
| ... | ... | @@ -48,32 +59,32 @@ public class SelectSheetWriteHandler implements SheetWriteHandler { |
| 48 | 59 | return; |
| 49 | 60 | } |
| 50 | 61 | |
| 51 | - // 1.1 获取相应操作对象 | |
| 62 | + // 1. 获取相应操作对象 | |
| 52 | 63 | DataValidationHelper helper = writeSheetHolder.getSheet().getDataValidationHelper(); // 需要设置下拉框的 sheet 页的数据验证助手 |
| 53 | 64 | Workbook workbook = writeWorkbookHolder.getWorkbook(); // 获得工作簿 |
| 54 | 65 | |
| 55 | - // 1.2 创建数据字典的 sheet 页 | |
| 66 | + // 2. 创建数据字典的 sheet 页 | |
| 56 | 67 | Sheet dictSheet = workbook.createSheet(DICT_SHEET_NAME); |
| 57 | 68 | for (KeyValue<ExcelColumn, List<String>> keyValue : selectMap) { |
| 58 | - int rowLen = keyValue.getValue().size(); | |
| 59 | - // 设置字典 sheet 页的值 每一列一个字典项 | |
| 60 | - for (int i = 0; i < rowLen; i++) { | |
| 69 | + int rowLength = keyValue.getValue().size(); | |
| 70 | + // 2.1 设置字典 sheet 页的值 每一列一个字典项 | |
| 71 | + for (int i = 0; i < rowLength; i++) { | |
| 61 | 72 | Row row = dictSheet.getRow(i); |
| 62 | 73 | if (row == null) { |
| 63 | 74 | row = dictSheet.createRow(i); |
| 64 | 75 | } |
| 65 | 76 | row.createCell(keyValue.getKey().getColNum()).setCellValue(keyValue.getValue().get(i)); |
| 66 | 77 | } |
| 67 | - // 1.3 设置单元格下拉选择 | |
| 68 | - setColSelect(writeSheetHolder, workbook, helper, keyValue); | |
| 78 | + // 2.2 设置单元格下拉选择 | |
| 79 | + setColumnSelect(writeSheetHolder, workbook, helper, keyValue); | |
| 69 | 80 | } |
| 70 | 81 | } |
| 71 | 82 | |
| 72 | 83 | /** |
| 73 | 84 | * 设置单元格下拉选择 |
| 74 | 85 | */ |
| 75 | - private static void setColSelect(WriteSheetHolder writeSheetHolder, Workbook workbook, DataValidationHelper helper, | |
| 76 | - KeyValue<ExcelColumn, List<String>> keyValue) { | |
| 86 | + private static void setColumnSelect(WriteSheetHolder writeSheetHolder, Workbook workbook, DataValidationHelper helper, | |
| 87 | + KeyValue<ExcelColumn, List<String>> keyValue) { | |
| 77 | 88 | // 1.1 创建可被其他单元格引用的名称 |
| 78 | 89 | Name name = workbook.createName(); |
| 79 | 90 | String excelColumn = keyValue.getKey().name(); |
| ... | ... | @@ -81,6 +92,7 @@ public class SelectSheetWriteHandler implements SheetWriteHandler { |
| 81 | 92 | String refers = DICT_SHEET_NAME + "!$" + excelColumn + "$1:$" + excelColumn + "$" + keyValue.getValue().size(); |
| 82 | 93 | name.setNameName("dict" + keyValue.getKey()); // 设置名称的名字 |
| 83 | 94 | name.setRefersToFormula(refers); // 设置公式 |
| 95 | + | |
| 84 | 96 | // 2.1 设置约束 |
| 85 | 97 | DataValidationConstraint constraint = helper.createFormulaListConstraint("dict" + keyValue.getKey()); // 设置引用约束 |
| 86 | 98 | // 设置下拉单元格的首行、末行、首列、末列 | ... | ... |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.java
| ... | ... | @@ -3,11 +3,11 @@ package cn.iocoder.yudao.module.crm.controller.admin.permission; |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 5 | 5 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 6 | +import cn.iocoder.yudao.framework.common.util.collection.MapUtils; | |
| 6 | 7 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 7 | 8 | import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionCreateReqVO; |
| 8 | 9 | import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionRespVO; |
| 9 | 10 | import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionUpdateReqVO; |
| 10 | -import cn.iocoder.yudao.module.crm.convert.permission.CrmPermissionConvert; | |
| 11 | 11 | import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO; |
| 12 | 12 | import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; |
| 13 | 13 | import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission; |
| ... | ... | @@ -19,6 +19,7 @@ import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; |
| 19 | 19 | import cn.iocoder.yudao.module.system.api.dept.dto.PostRespDTO; |
| 20 | 20 | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| 21 | 21 | import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; |
| 22 | +import com.google.common.collect.Multimaps; | |
| 22 | 23 | import io.swagger.v3.oas.annotations.Operation; |
| 23 | 24 | import io.swagger.v3.oas.annotations.Parameter; |
| 24 | 25 | import io.swagger.v3.oas.annotations.Parameters; |
| ... | ... | @@ -29,11 +30,16 @@ import org.springframework.security.access.prepost.PreAuthorize; |
| 29 | 30 | import org.springframework.validation.annotation.Validated; |
| 30 | 31 | import org.springframework.web.bind.annotation.*; |
| 31 | 32 | |
| 32 | -import java.util.*; | |
| 33 | +import java.util.Collection; | |
| 34 | +import java.util.Collections; | |
| 35 | +import java.util.List; | |
| 36 | +import java.util.Map; | |
| 33 | 37 | import java.util.stream.Stream; |
| 34 | 38 | |
| 35 | 39 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 36 | 40 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| 41 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap; | |
| 42 | +import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; | |
| 37 | 43 | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; |
| 38 | 44 | |
| 39 | 45 | @Tag(name = "管理后台 - CRM 数据权限") |
| ... | ... | @@ -98,18 +104,32 @@ public class CrmPermissionController { |
| 98 | 104 | @PreAuthorize("@ss.hasPermission('crm:permission:query')") |
| 99 | 105 | public CommonResult<List<CrmPermissionRespVO>> getPermissionList(@RequestParam("bizType") Integer bizType, |
| 100 | 106 | @RequestParam("bizId") Long bizId) { |
| 101 | - List<CrmPermissionDO> permission = permissionService.getPermissionListByBiz(bizType, bizId); | |
| 102 | - if (CollUtil.isEmpty(permission)) { | |
| 107 | + List<CrmPermissionDO> permissions = permissionService.getPermissionListByBiz(bizType, bizId); | |
| 108 | + if (CollUtil.isEmpty(permissions)) { | |
| 103 | 109 | return success(Collections.emptyList()); |
| 104 | 110 | } |
| 105 | 111 | |
| 112 | + // 查询相关数据 | |
| 113 | + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap( | |
| 114 | + convertSet(permissions, CrmPermissionDO::getUserId)); | |
| 115 | + Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId)); | |
| 116 | + Map<Long, PostRespDTO> postMap = postApi.getPostMap( | |
| 117 | + convertSetByFlatMap(userMap.values(), AdminUserRespDTO::getPostIds, | |
| 118 | + item -> item != null ? item.stream() : Stream.empty())); | |
| 106 | 119 | // 拼接数据 |
| 107 | - List<AdminUserRespDTO> userList = adminUserApi.getUserList(convertSet(permission, CrmPermissionDO::getUserId)); | |
| 108 | - Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userList, AdminUserRespDTO::getDeptId)); | |
| 109 | - Set<Long> postIds = CollectionUtils.convertSetByFlatMap(userList, AdminUserRespDTO::getPostIds, | |
| 110 | - item -> item != null ? item.stream() : Stream.empty()); | |
| 111 | - Map<Long, PostRespDTO> postMap = postApi.getPostMap(postIds); | |
| 112 | - return success(CrmPermissionConvert.INSTANCE.convert(permission, userList, deptMap, postMap)); | |
| 120 | + return success(CollectionUtils.convertList(BeanUtils.toBean(permissions, CrmPermissionRespVO.class), item -> { | |
| 121 | + findAndThen(userMap, item.getUserId(), user -> { | |
| 122 | + item.setNickname(user.getNickname()); | |
| 123 | + findAndThen(deptMap, user.getDeptId(), deptRespDTO -> item.setDeptName(deptRespDTO.getName())); | |
| 124 | + if (CollUtil.isEmpty(user.getPostIds())) { | |
| 125 | + item.setPostNames(Collections.emptySet()); | |
| 126 | + return; | |
| 127 | + } | |
| 128 | + List<PostRespDTO> postList = MapUtils.getList(Multimaps.forMap(postMap), user.getPostIds()); | |
| 129 | + item.setPostNames(CollectionUtils.convertSet(postList, PostRespDTO::getName)); | |
| 130 | + }); | |
| 131 | + return item; | |
| 132 | + })); | |
| 113 | 133 | } |
| 114 | 134 | |
| 115 | 135 | } | ... | ... |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/permission/CrmPermissionConvert.java deleted
| 1 | -package cn.iocoder.yudao.module.crm.convert.permission; | |
| 2 | - | |
| 3 | -import cn.hutool.core.collection.CollUtil; | |
| 4 | -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 5 | -import cn.iocoder.yudao.framework.common.util.collection.MapUtils; | |
| 6 | -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | |
| 7 | -import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionRespVO; | |
| 8 | -import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionUpdateReqVO; | |
| 9 | -import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO; | |
| 10 | -import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; | |
| 11 | -import cn.iocoder.yudao.module.system.api.dept.dto.PostRespDTO; | |
| 12 | -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | |
| 13 | -import com.google.common.collect.Multimaps; | |
| 14 | -import org.mapstruct.Mapper; | |
| 15 | -import org.mapstruct.factory.Mappers; | |
| 16 | - | |
| 17 | -import java.util.Collections; | |
| 18 | -import java.util.List; | |
| 19 | -import java.util.Map; | |
| 20 | - | |
| 21 | -import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; | |
| 22 | - | |
| 23 | -// TODO @芋艿:要干掉 | |
| 24 | -/** | |
| 25 | - * Crm 数据权限 Convert | |
| 26 | - * | |
| 27 | - * @author HUIHUI | |
| 28 | - */ | |
| 29 | -@Mapper | |
| 30 | -public interface CrmPermissionConvert { | |
| 31 | - | |
| 32 | - CrmPermissionConvert INSTANCE = Mappers.getMapper(CrmPermissionConvert.class); | |
| 33 | - | |
| 34 | - default List<CrmPermissionRespVO> convert(List<CrmPermissionDO> permissions, List<AdminUserRespDTO> userList, | |
| 35 | - Map<Long, DeptRespDTO> deptMap, Map<Long, PostRespDTO> postMap) { | |
| 36 | - Map<Long, AdminUserRespDTO> userMap = CollectionUtils.convertMap(userList, AdminUserRespDTO::getId); | |
| 37 | - return CollectionUtils.convertList(BeanUtils.toBean(permissions, CrmPermissionRespVO.class), item -> { | |
| 38 | - findAndThen(userMap, item.getUserId(), user -> { | |
| 39 | - item.setNickname(user.getNickname()); | |
| 40 | - findAndThen(deptMap, user.getDeptId(), deptRespDTO -> item.setDeptName(deptRespDTO.getName())); | |
| 41 | - if (CollUtil.isEmpty(user.getPostIds())) { | |
| 42 | - item.setPostNames(Collections.emptySet()); | |
| 43 | - return; | |
| 44 | - } | |
| 45 | - List<PostRespDTO> postList = MapUtils.getList(Multimaps.forMap(postMap), user.getPostIds()); | |
| 46 | - item.setPostNames(CollectionUtils.convertSet(postList, PostRespDTO::getName)); | |
| 47 | - }); | |
| 48 | - return item; | |
| 49 | - }); | |
| 50 | - } | |
| 51 | - | |
| 52 | - default List<CrmPermissionDO> convertList(CrmPermissionUpdateReqVO updateReqVO) { | |
| 53 | - return CollectionUtils.convertList(updateReqVO.getIds(), | |
| 54 | - id -> new CrmPermissionDO().setId(id).setLevel(updateReqVO.getLevel())); | |
| 55 | - } | |
| 56 | - | |
| 57 | -} |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java
| ... | ... | @@ -258,11 +258,13 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { |
| 258 | 258 | @Override |
| 259 | 259 | public CrmCustomerImportRespVO importCustomerList(List<CrmCustomerImportExcelVO> importCustomers, |
| 260 | 260 | CrmCustomerImportReqVO importReqVO) { |
| 261 | + // 校验非空 | |
| 262 | + importCustomers = filterList(importCustomers, item -> Objects.nonNull(item.getName())); | |
| 261 | 263 | if (CollUtil.isEmpty(importCustomers)) { |
| 262 | 264 | throw exception(CUSTOMER_IMPORT_LIST_IS_EMPTY); |
| 263 | 265 | } |
| 264 | - // 因为有下拉所以需要过滤掉空行 | |
| 265 | - importCustomers = filterList(importCustomers, item -> Objects.nonNull(item.getName())); | |
| 266 | + | |
| 267 | + // 逐条处理 | |
| 266 | 268 | CrmCustomerImportRespVO respVO = CrmCustomerImportRespVO.builder().createCustomerNames(new ArrayList<>()) |
| 267 | 269 | .updateCustomerNames(new ArrayList<>()).failureCustomerNames(new LinkedHashMap<>()).build(); |
| 268 | 270 | importCustomers.forEach(importCustomer -> { | ... | ... |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java
| ... | ... | @@ -2,16 +2,16 @@ package cn.iocoder.yudao.module.crm.service.permission; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | 4 | import cn.hutool.core.util.ObjUtil; |
| 5 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 5 | 6 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 6 | 7 | import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionUpdateReqVO; |
| 7 | -import cn.iocoder.yudao.module.crm.convert.permission.CrmPermissionConvert; | |
| 8 | 8 | import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO; |
| 9 | 9 | import cn.iocoder.yudao.module.crm.dal.mysql.permission.CrmPermissionMapper; |
| 10 | 10 | import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; |
| 11 | 11 | import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; |
| 12 | -import cn.iocoder.yudao.module.crm.util.CrmPermissionUtils; | |
| 13 | 12 | import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; |
| 14 | 13 | import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; |
| 14 | +import cn.iocoder.yudao.module.crm.util.CrmPermissionUtils; | |
| 15 | 15 | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| 16 | 16 | import jakarta.annotation.Resource; |
| 17 | 17 | import org.springframework.stereotype.Service; |
| ... | ... | @@ -74,8 +74,9 @@ public class CrmPermissionServiceImpl implements CrmPermissionService { |
| 74 | 74 | // 1. 校验存在 |
| 75 | 75 | validatePermissionExists(updateReqVO.getIds()); |
| 76 | 76 | // 2. 更新 |
| 77 | - List<CrmPermissionDO> updateDO = CrmPermissionConvert.INSTANCE.convertList(updateReqVO); | |
| 78 | - permissionMapper.updateBatch(updateDO); | |
| 77 | + List<CrmPermissionDO> updateList = CollectionUtils.convertList(updateReqVO.getIds(), | |
| 78 | + id -> new CrmPermissionDO().setId(id).setLevel(updateReqVO.getLevel())); | |
| 79 | + permissionMapper.updateBatch(updateList); | |
| 79 | 80 | } |
| 80 | 81 | |
| 81 | 82 | private void validatePermissionExists(Collection<Long> ids) { | ... | ... |