From 41b8575b8d878d872639e7be4917241ddc4899ac Mon Sep 17 00:00:00 2001 From: puhui999 Date: Thu, 22 Feb 2024 11:07:34 +0800 Subject: [PATCH] =?UTF-8?q?CRM=EF=BC=9A=E5=AE=8C=E5=96=84=E5=AE=A2?= =?UTF-8?q?=E6=88=B7=E5=AF=BC=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../framework/ip/core/utils/AreaUtils.java | 57 ++++++++++++++----- .../yudao-spring-boot-starter-excel/pom.xml | 5 ++ .../excel/core/convert/AreaConvert.java | 46 +++++++++++++++ .../core/handler/SelectSheetWriteHandler.java | 16 +++--- .../admin/customer/CrmCustomerController.java | 7 ++- .../vo/customer/CrmCustomerImportExcelVO.java | 5 +- 6 files changed, 108 insertions(+), 28 deletions(-) create mode 100644 yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/convert/AreaConvert.java diff --git a/yudao-framework/yudao-spring-boot-starter-biz-ip/src/main/java/cn/iocoder/yudao/framework/ip/core/utils/AreaUtils.java b/yudao-framework/yudao-spring-boot-starter-biz-ip/src/main/java/cn/iocoder/yudao/framework/ip/core/utils/AreaUtils.java index 1a773cda5..adcfc345b 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-ip/src/main/java/cn/iocoder/yudao/framework/ip/core/utils/AreaUtils.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-ip/src/main/java/cn/iocoder/yudao/framework/ip/core/utils/AreaUtils.java @@ -4,7 +4,7 @@ import cn.hutool.core.io.resource.ResourceUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.text.csv.CsvRow; import cn.hutool.core.text.csv.CsvUtil; -import cn.hutool.core.util.StrUtil; +import cn.hutool.core.util.ObjUtil; import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.framework.ip.core.Area; import cn.iocoder.yudao.framework.ip.core.enums.AreaTypeEnum; @@ -18,6 +18,7 @@ import java.util.Map; import java.util.function.Function; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.findFirst; /** * 区域工具类 @@ -75,6 +76,26 @@ public class AreaUtils { return areas.get(id); } + /** + * 获得指定区域对应的编号 + * + * @param path 区域编号 + * @return 编号 + */ + public static Area getArea(String path) { + String[] paths = path.split("/"); + Area area = null; + for (int i = 0; i < paths.length; i++) { + final int finalI = i; + if (area == null) { + area = findFirst(convertList(areas.values(), a -> a), item -> ObjUtil.equal(paths[finalI], item.getName())); + continue; + } + area = findFirst(area.getChildren(), item -> ObjUtil.equal(paths[finalI], item.getName())); + } + return area; + } + /** * 获取所有节点的全路径名称如:河南省/石家庄市/新华区 * @@ -82,23 +103,29 @@ public class AreaUtils { * @return 所有节点的全路径名称 */ public static List getAllAreaNodePaths(List areas) { - return convertList(areas, AreaUtils::buildTreePath); + List paths = new ArrayList<>(); + areas.forEach(area -> traverse(area, "", paths)); + return paths; } - // TODO @puhui999: 展开树再构建全路径 - private static String buildTreePath(Area node) { - if (node.getParent() == null || Area.ID_CHINA.equals(node.getParent().getId())) { // 忽略中国 - // 已经是根节点,直接返回节点名称 - return node.getName(); - } else { - // 递归拼接上级节点的名称 - Area parent = getArea(node.getParent().getId()); - if (parent != null) { - String parentPath = buildTreePath(parent); - return parentPath + "/" + node.getName(); - } + /** + * 构建一棵树的所有节点的全路径名称,并将其存储为 "祖先/父级/子级" 的形式 + * + * @param node 父节点 + * @param path 全路径名称 + * @param paths 全路径名称列表 + */ + private static void traverse(Area node, String path, List paths) { + if (node == null) { + return; + } + // 构建当前节点的路径 + String currentPath = path.isEmpty() ? node.getName() : path + "/" + node.getName(); + paths.add(currentPath); + // 递归遍历子节点 + for (Area child : node.getChildren()) { + traverse(child, currentPath, paths); } - return StrUtil.EMPTY; } /** diff --git a/yudao-framework/yudao-spring-boot-starter-excel/pom.xml b/yudao-framework/yudao-spring-boot-starter-excel/pom.xml index 5280f72f7..b5d5c24a2 100644 --- a/yudao-framework/yudao-spring-boot-starter-excel/pom.xml +++ b/yudao-framework/yudao-spring-boot-starter-excel/pom.xml @@ -46,6 +46,11 @@ com.alibaba easyexcel + + cn.iocoder.boot + yudao-spring-boot-starter-biz-ip + provided + diff --git a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/convert/AreaConvert.java b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/convert/AreaConvert.java new file mode 100644 index 000000000..f218c0b14 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/convert/AreaConvert.java @@ -0,0 +1,46 @@ +package cn.iocoder.yudao.framework.excel.core.convert; + +import cn.hutool.core.convert.Convert; +import cn.iocoder.yudao.framework.ip.core.Area; +import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.data.ReadCellData; +import com.alibaba.excel.metadata.property.ExcelContentProperty; +import lombok.extern.slf4j.Slf4j; + +/** + * Excel 数据地区转换器 + * + * @author HUIHUI + */ +@Slf4j +public class AreaConvert implements Converter { + + @Override + public Class supportJavaTypeKey() { + throw new UnsupportedOperationException("暂不支持,也不需要"); + } + + @Override + public CellDataTypeEnum supportExcelTypeKey() { + throw new UnsupportedOperationException("暂不支持,也不需要"); + } + + @Override + public Object convertToJavaData(ReadCellData readCellData, ExcelContentProperty contentProperty, + GlobalConfiguration globalConfiguration) { + // 解析地区编号 + String label = readCellData.getStringValue(); + Area area = AreaUtils.getArea(label); + if (area == null) { + log.error("[convertToJavaData][label({}) 解析不掉]", label); + return null; + } + // 将 value 转换成对应的属性 + Class fieldClazz = contentProperty.getField().getType(); + return Convert.convert(fieldClazz, area.getId()); + } + +} diff --git a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/SelectSheetWriteHandler.java b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/SelectSheetWriteHandler.java index 571f4c983..661db5369 100644 --- a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/SelectSheetWriteHandler.java +++ b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/SelectSheetWriteHandler.java @@ -9,6 +9,7 @@ import org.apache.poi.hssf.usermodel.HSSFDataValidation; import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellRangeAddressList; +import java.util.Comparator; import java.util.List; /** @@ -18,12 +19,13 @@ import java.util.List; */ public class SelectSheetWriteHandler implements SheetWriteHandler { - private List>> selectMap; + private final List>> selectMap; - private final char[] alphabet = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', + private static final char[] ALPHABET = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'}; public SelectSheetWriteHandler(List>> selectMap) { + selectMap.sort(Comparator.comparing(item -> item.getValue().size())); // 升序不然创建下拉会报错 this.selectMap = selectMap; } @@ -86,17 +88,17 @@ public class SelectSheetWriteHandler implements SheetWriteHandler { */ private String getExcelColumn(int num) { String column = ""; - int len = alphabet.length - 1; + int len = ALPHABET.length - 1; int first = num / len; int second = num % len; if (num <= len) { - column = alphabet[num] + ""; + column = ALPHABET[num] + ""; } else { - column = alphabet[first - 1] + ""; + column = ALPHABET[first - 1] + ""; if (second == 0) { - column = column + alphabet[len] + ""; + column = column + ALPHABET[len] + ""; } else { - column = column + alphabet[second - 1] + ""; + column = column + ALPHABET[second - 1] + ""; } } return column; diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java index beb477988..df6e0e625 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java @@ -37,7 +37,10 @@ import org.springframework.web.bind.annotation.*; import java.io.IOException; import java.time.LocalDateTime; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; import java.util.stream.Stream; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -332,8 +335,6 @@ public class CrmCustomerController { // 获取客户来源 List customerSources = dictDataApi.getDictDataLabelList(CRM_CUSTOMER_SOURCE); selectMap.add(new KeyValue<>(10, customerSources)); - // 升序不然创建下拉会报错 - selectMap.sort(Comparator.comparing(item -> item.getValue().size())); return selectMap; } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerImportExcelVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerImportExcelVO.java index 4b21fff1c..2c39472fd 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerImportExcelVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerImportExcelVO.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.crm.controller.admin.customer.vo.customer; import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; +import cn.iocoder.yudao.framework.excel.core.convert.AreaConvert; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import com.alibaba.excel.annotation.ExcelProperty; import lombok.AllArgsConstructor; @@ -39,14 +40,12 @@ public class CrmCustomerImportExcelVO { @ExcelProperty("邮箱") private String email; - // TODO @puhui999:需要选择省市区,需要研究下,怎么搞合理点; - @ExcelProperty("地区编号") + @ExcelProperty(value = "地区", converter = AreaConvert.class) private Integer areaId; @ExcelProperty("详细地址") private String detailAddress; - // TODO @puhui999:industryId、level、source 字段,可以研究下怎么搞下拉框 @ExcelProperty(value = "所属行业", converter = DictConvert.class) @DictFormat(CRM_CUSTOMER_INDUSTRY) private Integer industryId;