Browse Source

CRM:完善客户导入

puhui999 1 year ago
parent
commit
41b8575b8d

+ 42 - 15
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<String> getAllAreaNodePaths(List<Area> areas) {
-        return convertList(areas, AreaUtils::buildTreePath);
+        List<String> 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<String> 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;
     }
 
     /**

+ 5 - 0
yudao-framework/yudao-spring-boot-starter-excel/pom.xml

@@ -46,6 +46,11 @@
             <groupId>com.alibaba</groupId>
             <artifactId>easyexcel</artifactId>
         </dependency>
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
+            <scope>provided</scope> <!-- 设置为 provided,只有 ExcelUtils 使用 -->
+        </dependency>
     </dependencies>
 
 </project>

+ 46 - 0
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<Object> {
+
+    @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());
+    }
+
+}

+ 9 - 7
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<KeyValue<Integer, List<String>>> selectMap;
+    private final List<KeyValue<Integer, List<String>>> 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<KeyValue<Integer, List<String>>> 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;

+ 4 - 3
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<String> customerSources = dictDataApi.getDictDataLabelList(CRM_CUSTOMER_SOURCE);
         selectMap.add(new KeyValue<>(10, customerSources));
-        // 升序不然创建下拉会报错
-        selectMap.sort(Comparator.comparing(item -> item.getValue().size()));
         return selectMap;
     }
 

+ 2 - 3
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;