Commit e53a0ca8845229fb298c4d77da0f09315a6a5a4f

Authored by YunaiV
1 parent a64da48a

✨ CRM:code review 客户导入

Showing 33 changed files with 273 additions and 213 deletions
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtils.java
@@ -257,11 +257,11 @@ public class CollectionUtils { @@ -257,11 +257,11 @@ public class CollectionUtils {
257 return !CollectionUtil.isEmpty(from) ? from.get(0) : null; 257 return !CollectionUtil.isEmpty(from) ? from.get(0) : null;
258 } 258 }
259 259
260 - public static <T> T findFirst(List<T> from, Predicate<T> predicate) { 260 + public static <T> T findFirst(Collection<T> from, Predicate<T> predicate) {
261 return findFirst(from, predicate, Function.identity()); 261 return findFirst(from, predicate, Function.identity());
262 } 262 }
263 263
264 - public static <T, U> U findFirst(List<T> from, Predicate<T> predicate, Function<T, U> func) { 264 + public static <T, U> U findFirst(Collection<T> from, Predicate<T> predicate, Function<T, U> func) {
265 if (CollUtil.isEmpty(from)) { 265 if (CollUtil.isEmpty(from)) {
266 return null; 266 return null;
267 } 267 }
yudao-framework/yudao-spring-boot-starter-biz-ip/src/main/java/cn/iocoder/yudao/framework/ip/core/utils/AreaUtils.java
@@ -4,7 +4,6 @@ import cn.hutool.core.io.resource.ResourceUtil; @@ -4,7 +4,6 @@ import cn.hutool.core.io.resource.ResourceUtil;
4 import cn.hutool.core.lang.Assert; 4 import cn.hutool.core.lang.Assert;
5 import cn.hutool.core.text.csv.CsvRow; 5 import cn.hutool.core.text.csv.CsvRow;
6 import cn.hutool.core.text.csv.CsvUtil; 6 import cn.hutool.core.text.csv.CsvUtil;
7 -import cn.hutool.core.util.ObjUtil;  
8 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; 7 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
9 import cn.iocoder.yudao.framework.ip.core.Area; 8 import cn.iocoder.yudao.framework.ip.core.Area;
10 import cn.iocoder.yudao.framework.ip.core.enums.AreaTypeEnum; 9 import cn.iocoder.yudao.framework.ip.core.enums.AreaTypeEnum;
@@ -72,26 +71,25 @@ public class AreaUtils { @@ -72,26 +71,25 @@ public class AreaUtils {
72 * @param id 区域编号 71 * @param id 区域编号
73 * @return 区域 72 * @return 区域
74 */ 73 */
75 - public static Area getArea(Integer id) { 74 + public static Area parseArea(Integer id) {
76 return areas.get(id); 75 return areas.get(id);
77 } 76 }
78 77
79 /** 78 /**
80 * 获得指定区域对应的编号 79 * 获得指定区域对应的编号
81 * 80 *
82 - * @param path 区域编号  
83 - * @return 编号 81 + * @param pathStr 区域路径,例如说:河南省/石家庄市/新华区
  82 + * @return 区域
84 */ 83 */
85 - public static Area getArea(String path) {  
86 - String[] paths = path.split("/"); 84 + public static Area parseArea(String pathStr) {
  85 + String[] paths = pathStr.split("/");
87 Area area = null; 86 Area area = null;
88 - for (int i = 0; i < paths.length; i++) {  
89 - final int finalI = i; 87 + for (String path : paths) {
90 if (area == null) { 88 if (area == null) {
91 - area = findFirst(convertList(areas.values(), a -> a), item -> ObjUtil.equal(paths[finalI], item.getName()));  
92 - continue; 89 + area = findFirst(areas.values(), item -> item.getName().equals(path));
  90 + } else {
  91 + area = findFirst(area.getChildren(), item -> item.getName().equals(path));
93 } 92 }
94 - area = findFirst(area.getChildren(), item -> ObjUtil.equal(paths[finalI], item.getName()));  
95 } 93 }
96 return area; 94 return area;
97 } 95 }
@@ -102,9 +100,9 @@ public class AreaUtils { @@ -102,9 +100,9 @@ public class AreaUtils {
102 * @param areas 地区树 100 * @param areas 地区树
103 * @return 所有节点的全路径名称 101 * @return 所有节点的全路径名称
104 */ 102 */
105 - public static List<String> getAllAreaNodePaths(List<Area> areas) { 103 + public static List<String> getAreaNodePathList(List<Area> areas) {
106 List<String> paths = new ArrayList<>(); 104 List<String> paths = new ArrayList<>();
107 - areas.forEach(area -> traverse(area, "", paths)); 105 + areas.forEach(area -> getAreaNodePathList(area, "", paths));
108 return paths; 106 return paths;
109 } 107 }
110 108
@@ -113,9 +111,9 @@ public class AreaUtils { @@ -113,9 +111,9 @@ public class AreaUtils {
113 * 111 *
114 * @param node 父节点 112 * @param node 父节点
115 * @param path 全路径名称 113 * @param path 全路径名称
116 - * @param paths 全路径名称列表 114 + * @param paths 全路径名称列表,省份/城市/地区
117 */ 115 */
118 - private static void traverse(Area node, String path, List<String> paths) { 116 + private static void getAreaNodePathList(Area node, String path, List<String> paths) {
119 if (node == null) { 117 if (node == null) {
120 return; 118 return;
121 } 119 }
@@ -124,7 +122,7 @@ public class AreaUtils { @@ -124,7 +122,7 @@ public class AreaUtils {
124 paths.add(currentPath); 122 paths.add(currentPath);
125 // 递归遍历子节点 123 // 递归遍历子节点
126 for (Area child : node.getChildren()) { 124 for (Area child : node.getChildren()) {
127 - traverse(child, currentPath, paths); 125 + getAreaNodePathList(child, currentPath, paths);
128 } 126 }
129 } 127 }
130 128
@@ -195,7 +193,7 @@ public class AreaUtils { @@ -195,7 +193,7 @@ public class AreaUtils {
195 */ 193 */
196 public static Integer getParentIdByType(Integer id, @NonNull AreaTypeEnum type) { 194 public static Integer getParentIdByType(Integer id, @NonNull AreaTypeEnum type) {
197 for (int i = 0; i < Byte.MAX_VALUE; i++) { 195 for (int i = 0; i < Byte.MAX_VALUE; i++) {
198 - Area area = AreaUtils.getArea(id); 196 + Area area = AreaUtils.parseArea(id);
199 if (area == null) { 197 if (area == null) {
200 return null; 198 return null;
201 } 199 }
yudao-framework/yudao-spring-boot-starter-biz-ip/src/main/java/cn/iocoder/yudao/framework/ip/core/utils/IPUtils.java
@@ -72,7 +72,7 @@ public class IPUtils { @@ -72,7 +72,7 @@ public class IPUtils {
72 * @return 地区 72 * @return 地区
73 */ 73 */
74 public static Area getArea(String ip) { 74 public static Area getArea(String ip) {
75 - return AreaUtils.getArea(getAreaId(ip)); 75 + return AreaUtils.parseArea(getAreaId(ip));
76 } 76 }
77 77
78 /** 78 /**
@@ -82,6 +82,6 @@ public class IPUtils { @@ -82,6 +82,6 @@ public class IPUtils {
82 * @return 地区 82 * @return 地区
83 */ 83 */
84 public static Area getArea(long ip) { 84 public static Area getArea(long ip) {
85 - return AreaUtils.getArea(getAreaId(ip)); 85 + return AreaUtils.parseArea(getAreaId(ip));
86 } 86 }
87 } 87 }
yudao-framework/yudao-spring-boot-starter-biz-ip/src/test/java/cn/iocoder/yudao/framework/ip/core/utils/AreaUtilsTest.java
@@ -17,7 +17,7 @@ public class AreaUtilsTest { @@ -17,7 +17,7 @@ public class AreaUtilsTest {
17 @Test 17 @Test
18 public void testGetArea() { 18 public void testGetArea() {
19 // 调用:北京 19 // 调用:北京
20 - Area area = AreaUtils.getArea(110100); 20 + Area area = AreaUtils.parseArea(110100);
21 // 断言 21 // 断言
22 assertEquals(area.getId(), 110100); 22 assertEquals(area.getId(), 110100);
23 assertEquals(area.getName(), "北京市"); 23 assertEquals(area.getName(), "北京市");
yudao-framework/yudao-spring-boot-starter-excel/pom.xml
@@ -49,7 +49,7 @@ @@ -49,7 +49,7 @@
49 <dependency> 49 <dependency>
50 <groupId>cn.iocoder.boot</groupId> 50 <groupId>cn.iocoder.boot</groupId>
51 <artifactId>yudao-spring-boot-starter-biz-ip</artifactId> 51 <artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
52 - <scope>provided</scope> <!-- 设置为 provided,只有 ExcelUtils 使用 --> 52 + <optional>true</optional> <!-- 设置为 optional,只有在 AreaConvert 的时候使用 -->
53 </dependency> 53 </dependency>
54 </dependencies> 54 </dependencies>
55 55
yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/convert/AreaConvert.java
@@ -33,7 +33,7 @@ public class AreaConvert implements Converter&lt;Object&gt; { @@ -33,7 +33,7 @@ public class AreaConvert implements Converter&lt;Object&gt; {
33 GlobalConfiguration globalConfiguration) { 33 GlobalConfiguration globalConfiguration) {
34 // 解析地区编号 34 // 解析地区编号
35 String label = readCellData.getStringValue(); 35 String label = readCellData.getStringValue();
36 - Area area = AreaUtils.getArea(label); 36 + Area area = AreaUtils.parseArea(label);
37 if (area == null) { 37 if (area == null) {
38 log.error("[convertToJavaData][label({}) 解析不掉]", label); 38 log.error("[convertToJavaData][label({}) 解析不掉]", label);
39 return null; 39 return null;
yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/SelectSheetWriteHandler.java
@@ -19,33 +19,40 @@ import java.util.List; @@ -19,33 +19,40 @@ import java.util.List;
19 */ 19 */
20 public class SelectSheetWriteHandler implements SheetWriteHandler { 20 public class SelectSheetWriteHandler implements SheetWriteHandler {
21 21
  22 + private static final String DICT_SHEET_NAME = "字典sheet";
  23 +
  24 + // TODO @puhui999:key 不使用 int 值么?感觉不是很优雅哈。
22 private final List<KeyValue<Integer, List<String>>> selectMap; 25 private final List<KeyValue<Integer, List<String>>> selectMap;
23 26
24 private static final char[] ALPHABET = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 27 private static final char[] ALPHABET = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
25 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'}; 28 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
26 29
27 public SelectSheetWriteHandler(List<KeyValue<Integer, List<String>>> selectMap) { 30 public SelectSheetWriteHandler(List<KeyValue<Integer, List<String>>> selectMap) {
  31 + if (CollUtil.isEmpty(selectMap)) {
  32 + this.selectMap = null;
  33 + return;
  34 + }
28 selectMap.sort(Comparator.comparing(item -> item.getValue().size())); // 升序不然创建下拉会报错 35 selectMap.sort(Comparator.comparing(item -> item.getValue().size())); // 升序不然创建下拉会报错
29 this.selectMap = selectMap; 36 this.selectMap = selectMap;
30 } 37 }
31 38
32 @Override 39 @Override
33 public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) { 40 public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
34 - if (selectMap == null || CollUtil.isEmpty(selectMap)) { 41 + if (CollUtil.isEmpty(selectMap)) {
35 return; 42 return;
36 } 43 }
37 - // 需要设置下拉框的sheet页  
38 - Sheet curSheet = writeSheetHolder.getSheet();  
39 - DataValidationHelper helper = curSheet.getDataValidationHelper();  
40 - String dictSheetName = "字典sheet"; 44 + // 需要设置下拉框的 sheet 页
  45 + Sheet currentSheet = writeSheetHolder.getSheet();
  46 + DataValidationHelper helper = currentSheet.getDataValidationHelper();
41 Workbook workbook = writeWorkbookHolder.getWorkbook(); 47 Workbook workbook = writeWorkbookHolder.getWorkbook();
42 - // 数据字典的sheet页  
43 - Sheet dictSheet = workbook.createSheet(dictSheetName); 48 +
  49 + // 数据字典的 sheet 页
  50 + Sheet dictSheet = workbook.createSheet(DICT_SHEET_NAME);
44 for (KeyValue<Integer, List<String>> keyValue : selectMap) { 51 for (KeyValue<Integer, List<String>> keyValue : selectMap) {
45 // 设置下拉单元格的首行、末行、首列、末列 52 // 设置下拉单元格的首行、末行、首列、末列
46 CellRangeAddressList rangeAddressList = new CellRangeAddressList(1, 65533, keyValue.getKey(), keyValue.getKey()); 53 CellRangeAddressList rangeAddressList = new CellRangeAddressList(1, 65533, keyValue.getKey(), keyValue.getKey());
47 int rowLen = keyValue.getValue().size(); 54 int rowLen = keyValue.getValue().size();
48 - // 设置字典sheet页的值 每一列一个字典项 55 + // 设置字典 sheet 页的值 每一列一个字典项
49 for (int i = 0; i < rowLen; i++) { 56 for (int i = 0; i < rowLen; i++) {
50 Row row = dictSheet.getRow(i); 57 Row row = dictSheet.getRow(i);
51 if (row == null) { 58 if (row == null) {
@@ -53,18 +60,18 @@ public class SelectSheetWriteHandler implements SheetWriteHandler { @@ -53,18 +60,18 @@ public class SelectSheetWriteHandler implements SheetWriteHandler {
53 } 60 }
54 row.createCell(keyValue.getKey()).setCellValue(keyValue.getValue().get(i)); 61 row.createCell(keyValue.getKey()).setCellValue(keyValue.getValue().get(i));
55 } 62 }
56 - String excelColumn = getExcelColumn(keyValue.getKey());  
57 - // 下拉框数据来源 eg:字典sheet!$B1:$B2  
58 - String refers = dictSheetName + "!$" + excelColumn + "$1:$" + excelColumn + "$" + rowLen;  
59 - // 创建可被其他单元格引用的名称 63 +
  64 + // TODO @puhui999:下面 1. 2.1 2.2 2.3 我是按照已经理解的,调整了下格式;这样可读性更好;在 52 到 62 行,你可以看看,是不是也弄下序号;
  65 + // 1. 创建可被其他单元格引用的名称
60 Name name = workbook.createName(); 66 Name name = workbook.createName();
61 - // 设置名称的名字  
62 - name.setNameName("dict" + keyValue.getKey());  
63 - // 设置公式  
64 - name.setRefersToFormula(refers);  
65 - // 设置引用约束  
66 - DataValidationConstraint constraint = helper.createFormulaListConstraint("dict" + keyValue.getKey());  
67 - // 设置约束 67 + // TODO @puhui999:下面的 excelColumn 和 refers 两行,是不是可以封装成一个方法,替代 getExcelColumn;
  68 + String excelColumn = getExcelColumn(keyValue.getKey());
  69 + String refers = DICT_SHEET_NAME + "!$" + excelColumn + "$1:$" + excelColumn + "$" + rowLen; // 下拉框数据来源 eg:字典sheet!$B1:$B2
  70 + name.setNameName("dict" + keyValue.getKey()); // 设置名称的名字
  71 + name.setRefersToFormula(refers); // 设置公式
  72 +
  73 + // 2.1 设置约束
  74 + DataValidationConstraint constraint = helper.createFormulaListConstraint("dict" + keyValue.getKey()); // 设置引用约束
68 DataValidation validation = helper.createValidation(constraint, rangeAddressList); 75 DataValidation validation = helper.createValidation(constraint, rangeAddressList);
69 if (validation instanceof HSSFDataValidation) { 76 if (validation instanceof HSSFDataValidation) {
70 validation.setSuppressDropDownArrow(false); 77 validation.setSuppressDropDownArrow(false);
@@ -72,10 +79,10 @@ public class SelectSheetWriteHandler implements SheetWriteHandler { @@ -72,10 +79,10 @@ public class SelectSheetWriteHandler implements SheetWriteHandler {
72 validation.setSuppressDropDownArrow(true); 79 validation.setSuppressDropDownArrow(true);
73 validation.setShowErrorBox(true); 80 validation.setShowErrorBox(true);
74 } 81 }
75 - // 阻止输入非下拉框的值 82 + // 2.2 阻止输入非下拉框的值
76 validation.setErrorStyle(DataValidation.ErrorStyle.STOP); 83 validation.setErrorStyle(DataValidation.ErrorStyle.STOP);
77 validation.createErrorBox("提示", "此值不存在于下拉选择中!"); 84 validation.createErrorBox("提示", "此值不存在于下拉选择中!");
78 - // 添加下拉框约束 85 + // 2.3 添加下拉框约束
79 writeSheetHolder.getSheet().addValidationData(validation); 86 writeSheetHolder.getSheet().addValidationData(validation);
80 } 87 }
81 } 88 }
@@ -86,8 +93,9 @@ public class SelectSheetWriteHandler implements SheetWriteHandler { @@ -86,8 +93,9 @@ public class SelectSheetWriteHandler implements SheetWriteHandler {
86 * @param num 数字 93 * @param num 数字
87 * @return 字母 94 * @return 字母
88 */ 95 */
  96 + // TODO @puhui999:这个是必须字母列哇?还是数字其实也可以哈?主要想看看,怎么能把这个逻辑,进一步简化
89 private String getExcelColumn(int num) { 97 private String getExcelColumn(int num) {
90 - String column = ""; 98 + String column;
91 int len = ALPHABET.length - 1; 99 int len = ALPHABET.length - 1;
92 int first = num / len; 100 int first = num / len;
93 int second = num % len; 101 int second = num % len;
@@ -96,9 +104,9 @@ public class SelectSheetWriteHandler implements SheetWriteHandler { @@ -96,9 +104,9 @@ public class SelectSheetWriteHandler implements SheetWriteHandler {
96 } else { 104 } else {
97 column = ALPHABET[first - 1] + ""; 105 column = ALPHABET[first - 1] + "";
98 if (second == 0) { 106 if (second == 0) {
99 - column = column + ALPHABET[len] + ""; 107 + column = column + ALPHABET[len];
100 } else { 108 } else {
101 - column = column + ALPHABET[second - 1] + ""; 109 + column = column + ALPHABET[second - 1];
102 } 110 }
103 } 111 }
104 return column; 112 return column;
yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java
@@ -33,15 +33,7 @@ public class ExcelUtils { @@ -33,15 +33,7 @@ public class ExcelUtils {
33 */ 33 */
34 public static <T> void write(HttpServletResponse response, String filename, String sheetName, 34 public static <T> void write(HttpServletResponse response, String filename, String sheetName,
35 Class<T> head, List<T> data) throws IOException { 35 Class<T> head, List<T> data) throws IOException {
36 - // 输出 Excel  
37 - EasyExcel.write(response.getOutputStream(), head)  
38 - .autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理  
39 - .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 基于 column 长度,自动适配。最大 255 宽度  
40 - .registerConverter(new LongStringConverter()) // 避免 Long 类型丢失精度  
41 - .sheet(sheetName).doWrite(data);  
42 - // 设置 header 和 contentType。写在最后的原因是,避免报错时,响应 contentType 已经被修改了  
43 - response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, StandardCharsets.UTF_8.name()));  
44 - response.setContentType("application/vnd.ms-excel;charset=UTF-8"); 36 + write(response, filename, sheetName, head, data, null);
45 } 37 }
46 38
47 /** 39 /**
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java
@@ -14,6 +14,7 @@ public interface ErrorCodeConstants { @@ -14,6 +14,7 @@ public interface ErrorCodeConstants {
14 ErrorCode CONTRACT_UPDATE_FAIL_NOT_DRAFT = new ErrorCode(1_020_000_001, "合同更新失败,原因:合同不是草稿状态"); 14 ErrorCode CONTRACT_UPDATE_FAIL_NOT_DRAFT = new ErrorCode(1_020_000_001, "合同更新失败,原因:合同不是草稿状态");
15 ErrorCode CONTRACT_SUBMIT_FAIL_NOT_DRAFT = new ErrorCode(1_020_000_002, "合同提交审核失败,原因:合同没处在未提交状态"); 15 ErrorCode CONTRACT_SUBMIT_FAIL_NOT_DRAFT = new ErrorCode(1_020_000_002, "合同提交审核失败,原因:合同没处在未提交状态");
16 ErrorCode CONTRACT_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS = new ErrorCode(1_020_000_003, "更新合同审核状态失败,原因:合同不是审核中状态"); 16 ErrorCode CONTRACT_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS = new ErrorCode(1_020_000_003, "更新合同审核状态失败,原因:合同不是审核中状态");
  17 + ErrorCode CONTRACT_NO_EXISTS = new ErrorCode(1_020_000_004, "生成合同序列号重复,请重试");
17 18
18 // ========== 线索管理 1-020-001-000 ========== 19 // ========== 线索管理 1-020-001-000 ==========
19 ErrorCode CLUE_NOT_EXISTS = new ErrorCode(1_020_001_000, "线索不存在"); 20 ErrorCode CLUE_NOT_EXISTS = new ErrorCode(1_020_001_000, "线索不存在");
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/receivable/CrmReturnTypeEnum.java renamed to yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/receivable/CrmReceivableReturnTypeEnum.java
@@ -13,26 +13,18 @@ import java.util.Arrays; @@ -13,26 +13,18 @@ import java.util.Arrays;
13 */ 13 */
14 @Getter 14 @Getter
15 @AllArgsConstructor 15 @AllArgsConstructor
16 -public enum CrmReturnTypeEnum implements IntArrayValuable { 16 +public enum CrmReceivableReturnTypeEnum implements IntArrayValuable {
17 17
18 - // 支票  
19 CHECK(1, "支票"), 18 CHECK(1, "支票"),
20 - // 现金  
21 CASH(2, "现金"), 19 CASH(2, "现金"),
22 - // 邮政汇款  
23 POSTAL_REMITTANCE(3, "邮政汇款"), 20 POSTAL_REMITTANCE(3, "邮政汇款"),
24 - // 电汇  
25 TELEGRAPHIC_TRANSFER(4, "电汇"), 21 TELEGRAPHIC_TRANSFER(4, "电汇"),
26 - // 网上转账  
27 ONLINE_TRANSFER(5, "网上转账"), 22 ONLINE_TRANSFER(5, "网上转账"),
28 - // 支付宝  
29 ALIPAY(6, "支付宝"), 23 ALIPAY(6, "支付宝"),
30 - // 微信支付  
31 WECHAT_PAY(7, "微信支付"), 24 WECHAT_PAY(7, "微信支付"),
32 - // 其他  
33 OTHER(8, "其它"); 25 OTHER(8, "其它");
34 26
35 - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CrmReturnTypeEnum::getType).toArray(); 27 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CrmReceivableReturnTypeEnum::getType).toArray();
36 28
37 /** 29 /**
38 * 类型 30 * 类型
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java
@@ -268,6 +268,24 @@ public class CrmCustomerController { @@ -268,6 +268,24 @@ public class CrmCustomerController {
268 ExcelUtils.write(response, "客户导入模板.xls", "客户列表", CrmCustomerImportExcelVO.class, list, builderSelectMap()); 268 ExcelUtils.write(response, "客户导入模板.xls", "客户列表", CrmCustomerImportExcelVO.class, list, builderSelectMap());
269 } 269 }
270 270
  271 + private List<KeyValue<Integer, List<String>>> builderSelectMap() {
  272 + List<KeyValue<Integer, List<String>>> selectMap = new ArrayList<>();
  273 + // 获取地区下拉数据
  274 + // TODO @puhui999:嘿嘿,这里改成省份、城市、区域,三个选项,难度大么?
  275 + Area area = AreaUtils.parseArea(Area.ID_CHINA);
  276 + selectMap.add(new KeyValue<>(6, AreaUtils.getAreaNodePathList(area.getChildren())));
  277 + // 获取客户所属行业
  278 + List<String> customerIndustries = dictDataApi.getDictDataLabelList(CRM_CUSTOMER_INDUSTRY);
  279 + selectMap.add(new KeyValue<>(8, customerIndustries));
  280 + // 获取客户等级
  281 + List<String> customerLevels = dictDataApi.getDictDataLabelList(CRM_CUSTOMER_LEVEL);
  282 + selectMap.add(new KeyValue<>(9, customerLevels));
  283 + // 获取客户来源
  284 + List<String> customerSources = dictDataApi.getDictDataLabelList(CRM_CUSTOMER_SOURCE);
  285 + selectMap.add(new KeyValue<>(10, customerSources));
  286 + return selectMap;
  287 + }
  288 +
271 @PostMapping("/import") 289 @PostMapping("/import")
272 @Operation(summary = "导入客户") 290 @Operation(summary = "导入客户")
273 @PreAuthorize("@ss.hasPermission('system:customer:import')") 291 @PreAuthorize("@ss.hasPermission('system:customer:import')")
@@ -321,21 +339,4 @@ public class CrmCustomerController { @@ -321,21 +339,4 @@ public class CrmCustomerController {
321 return success(true); 339 return success(true);
322 } 340 }
323 341
324 - private List<KeyValue<Integer, List<String>>> builderSelectMap() {  
325 - List<KeyValue<Integer, List<String>>> selectMap = new ArrayList<>();  
326 - // 获取地区下拉数据  
327 - Area area = AreaUtils.getArea(Area.ID_CHINA);  
328 - selectMap.add(new KeyValue<>(6, AreaUtils.getAllAreaNodePaths(area.getChildren())));  
329 - // 获取客户所属行业  
330 - List<String> customerIndustries = dictDataApi.getDictDataLabelList(CRM_CUSTOMER_INDUSTRY);  
331 - selectMap.add(new KeyValue<>(8, customerIndustries));  
332 - // 获取客户等级  
333 - List<String> customerLevels = dictDataApi.getDictDataLabelList(CRM_CUSTOMER_LEVEL);  
334 - selectMap.add(new KeyValue<>(9, customerLevels));  
335 - // 获取客户来源  
336 - List<String> customerSources = dictDataApi.getDictDataLabelList(CRM_CUSTOMER_SOURCE);  
337 - selectMap.add(new KeyValue<>(10, customerSources));  
338 - return selectMap;  
339 - }  
340 -  
341 } 342 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java
@@ -107,7 +107,6 @@ public class CrmReceivableController { @@ -107,7 +107,6 @@ public class CrmReceivableController {
107 return success(buildReceivableDetailPage(pageResult)); 107 return success(buildReceivableDetailPage(pageResult));
108 } 108 }
109 109
110 - // TODO 芋艿:后面在优化导出  
111 @GetMapping("/export-excel") 110 @GetMapping("/export-excel")
112 @Operation(summary = "导出回款 Excel") 111 @Operation(summary = "导出回款 Excel")
113 @PreAuthorize("@ss.hasPermission('crm:receivable:export')") 112 @PreAuthorize("@ss.hasPermission('crm:receivable:export')")
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java
@@ -28,7 +28,6 @@ import io.swagger.v3.oas.annotations.tags.Tag; @@ -28,7 +28,6 @@ import io.swagger.v3.oas.annotations.tags.Tag;
28 import jakarta.annotation.Resource; 28 import jakarta.annotation.Resource;
29 import jakarta.servlet.http.HttpServletResponse; 29 import jakarta.servlet.http.HttpServletResponse;
30 import jakarta.validation.Valid; 30 import jakarta.validation.Valid;
31 -import org.springframework.context.annotation.Lazy;  
32 import org.springframework.security.access.prepost.PreAuthorize; 31 import org.springframework.security.access.prepost.PreAuthorize;
33 import org.springframework.validation.annotation.Validated; 32 import org.springframework.validation.annotation.Validated;
34 import org.springframework.web.bind.annotation.*; 33 import org.springframework.web.bind.annotation.*;
@@ -56,7 +55,6 @@ public class CrmReceivablePlanController { @@ -56,7 +55,6 @@ public class CrmReceivablePlanController {
56 @Resource 55 @Resource
57 private CrmReceivableService receivableService; 56 private CrmReceivableService receivableService;
58 @Resource 57 @Resource
59 - @Lazy  
60 private CrmContractService contractService; 58 private CrmContractService contractService;
61 @Resource 59 @Resource
62 private CrmCustomerService customerService; 60 private CrmCustomerService customerService;
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanRespVO.java
@@ -6,6 +6,7 @@ import lombok.Data; @@ -6,6 +6,7 @@ import lombok.Data;
6 import java.math.BigDecimal; 6 import java.math.BigDecimal;
7 import java.time.LocalDateTime; 7 import java.time.LocalDateTime;
8 8
  9 +// TODO @puhui999:缺导出
9 @Schema(description = "管理后台 - CRM 回款计划 Response VO") 10 @Schema(description = "管理后台 - CRM 回款计划 Response VO")
10 @Data 11 @Data
11 public class CrmReceivablePlanRespVO { 12 public class CrmReceivablePlanRespVO {
@@ -13,35 +14,44 @@ public class CrmReceivablePlanRespVO { @@ -13,35 +14,44 @@ public class CrmReceivablePlanRespVO {
13 @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") 14 @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
14 private Long id; 15 private Long id;
15 16
16 - @Schema(description = "回款编号", example = "19852")  
17 - private Long receivableId;  
18 -  
19 @Schema(description = "期数", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") 17 @Schema(description = "期数", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
20 private Integer period; 18 private Integer period;
21 19
22 - @Schema(description = "计划回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "9000")  
23 - private BigDecimal price;  
24 -  
25 - @Schema(description = "计划回款日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02")  
26 - private LocalDateTime returnTime;  
27 -  
28 - @Schema(description = "提前几天提醒", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")  
29 - private Integer remindDays;  
30 -  
31 - @Schema(description = "提醒日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02")  
32 - private LocalDateTime remindTime;  
33 -  
34 @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") 20 @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
35 private Long customerId; 21 private Long customerId;
  22 + @Schema(description = "客户名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "test")
  23 + private String customerName;
36 24
37 @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") 25 @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
38 private Long contractId; 26 private Long contractId;
  27 + @Schema(description = "合同编号", example = "Q110")
  28 + private String contractNo;
39 29
40 @Schema(description = "负责人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") 30 @Schema(description = "负责人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
41 private Long ownerUserId; 31 private Long ownerUserId;
  32 + @Schema(description = "负责人", example = "test")
  33 + private String ownerUserName;
  34 +
  35 + @Schema(description = "计划回款日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02")
  36 + private LocalDateTime returnTime;
  37 +
  38 + @Schema(description = "回款方式", example = "1")
  39 + private Integer returnType; // 来自 Receivable 的 returnType 字段
42 40
43 - @Schema(description = "显示顺序")  
44 - private Integer sort; 41 + @Schema(description = "计划回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "9000")
  42 + private BigDecimal price;
  43 +
  44 + @Schema(description = "回款编号", example = "19852")
  45 + private Long receivableId;
  46 +
  47 + @Schema(description = "完成状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
  48 + private Boolean finishStatus;
  49 +
  50 + @Schema(description = "提前几天提醒", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  51 + private Integer remindDays;
  52 +
  53 + @Schema(description = "提醒日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02")
  54 + private LocalDateTime remindTime;
45 55
46 @Schema(description = "备注", example = "备注") 56 @Schema(description = "备注", example = "备注")
47 private String remark; 57 private String remark;
@@ -49,25 +59,10 @@ public class CrmReceivablePlanRespVO { @@ -49,25 +59,10 @@ public class CrmReceivablePlanRespVO {
49 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 59 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
50 private LocalDateTime createTime; 60 private LocalDateTime createTime;
51 61
52 - @Schema(description = "客户名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "test")  
53 - private String customerName;  
54 -  
55 - @Schema(description = "合同编号", example = "Q110")  
56 - private String contractNo;  
57 -  
58 - @Schema(description = "负责人", example = "test")  
59 - private String ownerUserName;  
60 -  
61 @Schema(description = "创建人", example = "25682") 62 @Schema(description = "创建人", example = "25682")
62 private String creator; 63 private String creator;
63 64
64 @Schema(description = "创建人名字", example = "test") 65 @Schema(description = "创建人名字", example = "test")
65 private String creatorName; 66 private String creatorName;
66 67
67 - @Schema(description = "完成状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")  
68 - private Boolean finishStatus;  
69 -  
70 - @Schema(description = "回款方式", example = "1")  
71 - private Integer returnType; // 来自 Receivable 的 returnType 字段  
72 -  
73 } 68 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanSaveReqVO.java
@@ -14,26 +14,6 @@ public class CrmReceivablePlanSaveReqVO { @@ -14,26 +14,6 @@ public class CrmReceivablePlanSaveReqVO {
14 @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") 14 @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
15 private Long id; 15 private Long id;
16 16
17 - @Schema(description = "期数", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")  
18 - @NotNull(message = "期数不能为空")  
19 - private Integer period;  
20 -  
21 - @Schema(description = "计划回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "9000")  
22 - @NotNull(message = "计划回款金额不能为空")  
23 - private BigDecimal price;  
24 -  
25 - @Schema(description = "计划回款日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02")  
26 - @NotNull(message = "计划回款日期不能为空")  
27 - private LocalDateTime returnTime;  
28 -  
29 - @Schema(description = "提前几天提醒", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")  
30 - @NotNull(message = "提前几天提醒不能为空")  
31 - private Integer remindDays;  
32 -  
33 - @Schema(description = "提醒日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02")  
34 - @NotNull(message = "提醒日期不能为空")  
35 - private LocalDateTime remindTime;  
36 -  
37 @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") 17 @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
38 @NotNull(message = "客户编号不能为空") 18 @NotNull(message = "客户编号不能为空")
39 private Long customerId; 19 private Long customerId;
@@ -46,8 +26,19 @@ public class CrmReceivablePlanSaveReqVO { @@ -46,8 +26,19 @@ public class CrmReceivablePlanSaveReqVO {
46 @NotNull(message = "负责人编号不能为空") 26 @NotNull(message = "负责人编号不能为空")
47 private Long ownerUserId; 27 private Long ownerUserId;
48 28
49 - @Schema(description = "显示顺序")  
50 - private Integer sort; 29 + @Schema(description = "计划回款日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02")
  30 + @NotNull(message = "计划回款日期不能为空")
  31 + private LocalDateTime returnTime;
  32 +
  33 + @Schema(description = "回款方式", example = "1")
  34 + private Integer returnType;
  35 +
  36 + @Schema(description = "计划回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "9000")
  37 + @NotNull(message = "计划回款金额不能为空")
  38 + private BigDecimal price;
  39 +
  40 + @Schema(description = "提前几天提醒", example = "1")
  41 + private Integer remindDays;
51 42
52 @Schema(description = "备注", example = "备注") 43 @Schema(description = "备注", example = "备注")
53 private String remark; 44 private String remark;
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/receivable/CrmReceivableSaveReqVO.java
1 package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable; 1 package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable;
2 2
3 import cn.iocoder.yudao.framework.common.validation.InEnum; 3 import cn.iocoder.yudao.framework.common.validation.InEnum;
4 -import cn.iocoder.yudao.module.crm.enums.receivable.CrmReturnTypeEnum; 4 +import cn.iocoder.yudao.module.crm.enums.receivable.CrmReceivableReturnTypeEnum;
5 import io.swagger.v3.oas.annotations.media.Schema; 5 import io.swagger.v3.oas.annotations.media.Schema;
6 import jakarta.validation.constraints.NotNull; 6 import jakarta.validation.constraints.NotNull;
7 import lombok.Data; 7 import lombok.Data;
@@ -23,7 +23,7 @@ public class CrmReceivableSaveReqVO { @@ -23,7 +23,7 @@ public class CrmReceivableSaveReqVO {
23 private Long planId; // 不是通过回款计划创建的回款没有回款计划编号 23 private Long planId; // 不是通过回款计划创建的回款没有回款计划编号
24 24
25 @Schema(description = "回款方式", example = "2") 25 @Schema(description = "回款方式", example = "2")
26 - @InEnum(CrmReturnTypeEnum.class) 26 + @InEnum(CrmReceivableReturnTypeEnum.class)
27 private Integer returnType; 27 private Integer returnType;
28 28
29 @Schema(description = "回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "9000") 29 @Schema(description = "回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "9000")
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/receivable/CrmReceivableDO.java
@@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; @@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; 4 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
5 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 5 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
6 import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum; 6 import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum;
7 -import cn.iocoder.yudao.module.crm.enums.receivable.CrmReturnTypeEnum; 7 +import cn.iocoder.yudao.module.crm.enums.receivable.CrmReceivableReturnTypeEnum;
8 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 8 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
9 import com.baomidou.mybatisplus.annotation.KeySequence; 9 import com.baomidou.mybatisplus.annotation.KeySequence;
10 import com.baomidou.mybatisplus.annotation.TableId; 10 import com.baomidou.mybatisplus.annotation.TableId;
@@ -60,7 +60,7 @@ public class CrmReceivableDO extends BaseDO { @@ -60,7 +60,7 @@ public class CrmReceivableDO extends BaseDO {
60 */ 60 */
61 private LocalDateTime returnTime; 61 private LocalDateTime returnTime;
62 /** 62 /**
63 - * 回款方式,关联枚举{@link CrmReturnTypeEnum} 63 + * 回款方式,关联枚举{@link CrmReceivableReturnTypeEnum}
64 */ 64 */
65 private Integer returnType; 65 private Integer returnType;
66 /** 66 /**
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/receivable/CrmReceivablePlanDO.java
@@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.crm.dal.dataobject.receivable; @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.crm.dal.dataobject.receivable;
3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; 4 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
5 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 5 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
6 -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 6 +import cn.iocoder.yudao.module.crm.enums.receivable.CrmReceivableReturnTypeEnum;
7 import com.baomidou.mybatisplus.annotation.KeySequence; 7 import com.baomidou.mybatisplus.annotation.KeySequence;
8 import com.baomidou.mybatisplus.annotation.TableId; 8 import com.baomidou.mybatisplus.annotation.TableId;
9 import com.baomidou.mybatisplus.annotation.TableName; 9 import com.baomidou.mybatisplus.annotation.TableName;
@@ -13,7 +13,7 @@ import java.math.BigDecimal; @@ -13,7 +13,7 @@ import java.math.BigDecimal;
13 import java.time.LocalDateTime; 13 import java.time.LocalDateTime;
14 14
15 /** 15 /**
16 - * 回款计划 DO 16 + * CRM 回款计划 DO
17 * 17 *
18 * @author 芋道源码 18 * @author 芋道源码
19 */ 19 */
@@ -37,49 +37,60 @@ public class CrmReceivablePlanDO extends BaseDO { @@ -37,49 +37,60 @@ public class CrmReceivablePlanDO extends BaseDO {
37 */ 37 */
38 private Integer period; 38 private Integer period;
39 /** 39 /**
40 - * 回款编号,关联 {@link CrmReceivableDO#getId()} 40 + * 客户编号
  41 + *
  42 + * 关联 {@link CrmCustomerDO#getId()}
41 */ 43 */
42 - private Long receivableId; 44 + private Long customerId;
43 /** 45 /**
44 - * 计划回款金额,单位:元 46 + * 合同编号
  47 + *
  48 + * 关联 {@link CrmContractDO#getId()}
45 */ 49 */
46 - private BigDecimal price; 50 + private Long contractId;
  51 +
  52 + /**
  53 + * 负责人编号
  54 + *
  55 + * 关联 AdminUserDO 的 id 字段
  56 + */
  57 + private Long ownerUserId;
  58 +
47 /** 59 /**
48 * 计划回款日期 60 * 计划回款日期
49 */ 61 */
50 private LocalDateTime returnTime; 62 private LocalDateTime returnTime;
51 /** 63 /**
52 - * 提前几天提醒 64 + * 回款类型
  65 + *
  66 + * 枚举 {@link CrmReceivableReturnTypeEnum}
53 */ 67 */
54 - private Integer remindDays; 68 + private Integer returnType;
55 /** 69 /**
56 - * 提醒日期 70 + * 计划回款金额,单位:元
57 */ 71 */
58 - private LocalDateTime remindTime; 72 + private BigDecimal price;
  73 +
59 /** 74 /**
60 - * 客户编号,关联 {@link CrmCustomerDO#getId()} 75 + * 回款编号,关联 {@link CrmReceivableDO#getId()}
61 */ 76 */
62 - private Long customerId; 77 + private Long receivableId;
63 /** 78 /**
64 - * 合同编号,关联 {@link CrmContractDO#getId()} 79 + * 完成状态
65 */ 80 */
66 - private Long contractId; 81 + private Boolean finishStatus;
  82 +
67 /** 83 /**
68 - * 负责人编号,关联 {@link AdminUserRespDTO#getId()} 84 + * 提前几天提醒
69 */ 85 */
70 - private Long ownerUserId; 86 + private Integer remindDays;
71 /** 87 /**
72 - * 显示顺序 88 + * 提醒日期
73 */ 89 */
74 - private Integer sort; 90 + private LocalDateTime remindTime;
75 /** 91 /**
76 * 备注 92 * 备注
77 */ 93 */
78 private String remark; 94 private String remark;
79 95
80 - /**  
81 - * 完成状态  
82 - */  
83 - private Boolean finishStatus;  
84 -  
85 } 96 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java
@@ -11,7 +11,6 @@ import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum; @@ -11,7 +11,6 @@ import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum;
11 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; 11 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
12 import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum; 12 import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum;
13 import cn.iocoder.yudao.module.crm.util.CrmQueryWrapperUtils; 13 import cn.iocoder.yudao.module.crm.util.CrmQueryWrapperUtils;
14 -import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;  
15 import org.apache.ibatis.annotations.Mapper; 14 import org.apache.ibatis.annotations.Mapper;
16 15
17 import java.time.LocalDateTime; 16 import java.time.LocalDateTime;
@@ -26,10 +25,8 @@ import java.util.List; @@ -26,10 +25,8 @@ import java.util.List;
26 @Mapper 25 @Mapper
27 public interface CrmContractMapper extends BaseMapperX<CrmContractDO> { 26 public interface CrmContractMapper extends BaseMapperX<CrmContractDO> {
28 27
29 - default int updateOwnerUserIdById(Long id, Long ownerUserId) {  
30 - return update(new LambdaUpdateWrapper<CrmContractDO>()  
31 - .eq(CrmContractDO::getId, id)  
32 - .set(CrmContractDO::getOwnerUserId, ownerUserId)); 28 + default CrmContractDO selectByNo(String no) {
  29 + return selectOne(CrmContractDO::getNo, no);
33 } 30 }
34 31
35 default PageResult<CrmContractDO> selectPageByCustomerId(CrmContractPageReqVO pageReqVO) { 32 default PageResult<CrmContractDO> selectPageByCustomerId(CrmContractPageReqVO pageReqVO) {
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/redis/RedisKeyConstants.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.dal.redis;
  2 +
  3 +/**
  4 + * CRM Redis Key 枚举类
  5 + *
  6 + * @author 芋道源码
  7 + */
  8 +public interface RedisKeyConstants {
  9 +
  10 + /**
  11 + * 序号的缓存
  12 + *
  13 + * KEY 格式:trade_no:{prefix}
  14 + * VALUE 数据格式:编号自增
  15 + */
  16 + String NO = "crm:seq_no:";
  17 +
  18 +}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/redis/no/CrmNoRedisDAO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.dal.redis.no;
  2 +
  3 +import cn.hutool.core.date.DatePattern;
  4 +import cn.hutool.core.date.DateUtil;
  5 +import cn.iocoder.yudao.module.crm.dal.redis.RedisKeyConstants;
  6 +import jakarta.annotation.Resource;
  7 +import org.springframework.data.redis.core.StringRedisTemplate;
  8 +import org.springframework.stereotype.Repository;
  9 +
  10 +import java.time.Duration;
  11 +import java.time.LocalDateTime;
  12 +
  13 +
  14 +/**
  15 + * Crm 订单序号的 Redis DAO
  16 + *
  17 + * @author HUIHUI
  18 + */
  19 +@Repository
  20 +public class CrmNoRedisDAO {
  21 +
  22 + /**
  23 + * 合同 {@link cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO}
  24 + */
  25 + public static final String CONTRACT_NO_PREFIX = "HT";
  26 +
  27 + /**
  28 + * 还款 {@link cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivablePlanDO}
  29 + */
  30 + public static final String RECEIVABLE_PREFIX = "HK";
  31 +
  32 + @Resource
  33 + private StringRedisTemplate stringRedisTemplate;
  34 +
  35 + /**
  36 + * 生成序号,使用当前日期,格式为 {PREFIX} + yyyyMMdd + 6 位自增
  37 + * 例如说:QTRK 202109 000001 (没有中间空格)
  38 + *
  39 + * @param prefix 前缀
  40 + * @return 序号
  41 + */
  42 + public String generate(String prefix) {
  43 + // 递增序号
  44 + String noPrefix = prefix + DateUtil.format(LocalDateTime.now(), DatePattern.PURE_DATE_PATTERN);
  45 + String key = RedisKeyConstants.NO + noPrefix;
  46 + Long no = stringRedisTemplate.opsForValue().increment(key);
  47 + // 设置过期时间
  48 + stringRedisTemplate.expire(key, Duration.ofDays(1L));
  49 + return noPrefix + String.format("%06d", no);
  50 + }
  51 +
  52 +}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java
@@ -17,6 +17,7 @@ import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; @@ -17,6 +17,7 @@ import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
17 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractProductDO; 17 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractProductDO;
18 import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper; 18 import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper;
19 import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractProductMapper; 19 import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractProductMapper;
  20 +import cn.iocoder.yudao.module.crm.dal.redis.no.CrmNoRedisDAO;
20 import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum; 21 import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum;
21 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; 22 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
22 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; 23 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
@@ -70,6 +71,9 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -70,6 +71,9 @@ public class CrmContractServiceImpl implements CrmContractService {
70 private CrmContractProductMapper contractProductMapper; 71 private CrmContractProductMapper contractProductMapper;
71 72
72 @Resource 73 @Resource
  74 + private CrmNoRedisDAO noRedisDAO;
  75 +
  76 + @Resource
73 private CrmPermissionService crmPermissionService; 77 private CrmPermissionService crmPermissionService;
74 @Resource 78 @Resource
75 private CrmProductService productService; 79 private CrmProductService productService;
@@ -94,11 +98,14 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -94,11 +98,14 @@ public class CrmContractServiceImpl implements CrmContractService {
94 List<CrmContractProductDO> contractProducts = validateContractProducts(createReqVO.getProducts()); 98 List<CrmContractProductDO> contractProducts = validateContractProducts(createReqVO.getProducts());
95 // 1.2 校验关联字段 99 // 1.2 校验关联字段
96 validateRelationDataExists(createReqVO); 100 validateRelationDataExists(createReqVO);
97 - // TODO 芋艿:生成 no 101 + // 1.3 生成序号
  102 + String no = noRedisDAO.generate(CrmNoRedisDAO.CONTRACT_NO_PREFIX);
  103 + if (contractMapper.selectByNo(no) != null) {
  104 + throw exception(CONTRACT_NO_EXISTS);
  105 + }
98 106
99 // 2.1 插入合同 107 // 2.1 插入合同
100 - CrmContractDO contract = BeanUtils.toBean(createReqVO, CrmContractDO.class);  
101 - contract.setNo(System.currentTimeMillis() + ""); // TODO 108 + CrmContractDO contract = BeanUtils.toBean(createReqVO, CrmContractDO.class).setNo(no);
102 calculateTotalPrice(contract, contractProducts); 109 calculateTotalPrice(contract, contractProducts);
103 contractMapper.insert(contract); 110 contractMapper.insert(contract);
104 // 2.2 插入合同关联商品 111 // 2.2 插入合同关联商品
@@ -247,7 +254,7 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -247,7 +254,7 @@ public class CrmContractServiceImpl implements CrmContractService {
247 crmPermissionService.transferPermission(new CrmPermissionTransferReqBO(userId, CrmBizTypeEnum.CRM_CONTRACT.getType(), 254 crmPermissionService.transferPermission(new CrmPermissionTransferReqBO(userId, CrmBizTypeEnum.CRM_CONTRACT.getType(),
248 reqVO.getId(), reqVO.getNewOwnerUserId(), reqVO.getOldOwnerPermissionLevel())); 255 reqVO.getId(), reqVO.getNewOwnerUserId(), reqVO.getOldOwnerPermissionLevel()));
249 // 2.2 设置负责人 256 // 2.2 设置负责人
250 - contractMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId()); 257 + contractMapper.updateById(new CrmContractDO().setId(reqVO.getId()).setOwnerUserId(reqVO.getNewOwnerUserId()));
251 258
252 // 3. 记录转移日志 259 // 3. 记录转移日志
253 LogRecordContext.putVariable("contract", contract); 260 LogRecordContext.putVariable("contract", contract);
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanServiceImpl.java
@@ -23,7 +23,7 @@ import com.mzt.logapi.context.LogRecordContext; @@ -23,7 +23,7 @@ import com.mzt.logapi.context.LogRecordContext;
23 import com.mzt.logapi.service.impl.DiffParseFunction; 23 import com.mzt.logapi.service.impl.DiffParseFunction;
24 import com.mzt.logapi.starter.annotation.LogRecord; 24 import com.mzt.logapi.starter.annotation.LogRecord;
25 import jakarta.annotation.Resource; 25 import jakarta.annotation.Resource;
26 -import org.hibernate.validator.internal.util.stereotypes.Lazy; 26 +import org.springframework.context.annotation.Lazy;
27 import org.springframework.stereotype.Service; 27 import org.springframework.stereotype.Service;
28 import org.springframework.transaction.annotation.Transactional; 28 import org.springframework.transaction.annotation.Transactional;
29 import org.springframework.validation.annotation.Validated; 29 import org.springframework.validation.annotation.Validated;
@@ -57,6 +57,7 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService { @@ -57,6 +57,7 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService {
57 private CrmCustomerService customerService; 57 private CrmCustomerService customerService;
58 @Resource 58 @Resource
59 private CrmPermissionService permissionService; 59 private CrmPermissionService permissionService;
  60 +
60 @Resource 61 @Resource
61 private AdminUserApi adminUserApi; 62 private AdminUserApi adminUserApi;
62 63
@@ -72,15 +73,16 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService { @@ -72,15 +73,16 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService {
72 int period = (int) (count + 1); 73 int period = (int) (count + 1);
73 createReqVO.setPeriod(createReqVO.getPeriod() != period ? period : createReqVO.getPeriod()); // 如果期数不对则纠正 74 createReqVO.setPeriod(createReqVO.getPeriod() != period ? period : createReqVO.getPeriod()); // 如果期数不对则纠正
74 75
75 - // 2.1 插入 76 + // 2. 插入还款计划
76 CrmReceivablePlanDO receivablePlan = BeanUtils.toBean(createReqVO, CrmReceivablePlanDO.class).setId(null).setFinishStatus(false); 77 CrmReceivablePlanDO receivablePlan = BeanUtils.toBean(createReqVO, CrmReceivablePlanDO.class).setId(null).setFinishStatus(false);
77 receivablePlanMapper.insert(receivablePlan); 78 receivablePlanMapper.insert(receivablePlan);
78 - // 2.2 创建数据权限 79 +
  80 + // 3. 创建数据权限
79 permissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(createReqVO.getOwnerUserId()) 81 permissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(createReqVO.getOwnerUserId())
80 .setBizType(CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType()).setBizId(receivablePlan.getId()) 82 .setBizType(CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType()).setBizId(receivablePlan.getId())
81 .setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); 83 .setLevel(CrmPermissionLevelEnum.OWNER.getLevel()));
82 84
83 - // 3. 记录操作日志上下文 85 + // 4. 记录操作日志上下文
84 LogRecordContext.putVariable("receivablePlan", receivablePlan); 86 LogRecordContext.putVariable("receivablePlan", receivablePlan);
85 return receivablePlan.getId(); 87 return receivablePlan.getId();
86 } 88 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java
@@ -31,6 +31,7 @@ import com.mzt.logapi.service.impl.DiffParseFunction; @@ -31,6 +31,7 @@ import com.mzt.logapi.service.impl.DiffParseFunction;
31 import com.mzt.logapi.starter.annotation.LogRecord; 31 import com.mzt.logapi.starter.annotation.LogRecord;
32 import jakarta.annotation.Resource; 32 import jakarta.annotation.Resource;
33 import lombok.extern.slf4j.Slf4j; 33 import lombok.extern.slf4j.Slf4j;
  34 +import org.springframework.context.annotation.Lazy;
34 import org.springframework.stereotype.Service; 35 import org.springframework.stereotype.Service;
35 import org.springframework.transaction.annotation.Transactional; 36 import org.springframework.transaction.annotation.Transactional;
36 import org.springframework.validation.annotation.Validated; 37 import org.springframework.validation.annotation.Validated;
@@ -66,10 +67,12 @@ public class CrmReceivableServiceImpl implements CrmReceivableService { @@ -66,10 +67,12 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
66 private CrmContractService contractService; 67 private CrmContractService contractService;
67 @Resource 68 @Resource
68 private CrmCustomerService customerService; 69 private CrmCustomerService customerService;
69 - @Resource 70 +// @Resource
  71 + @Lazy // 延迟加载,避免循环依赖
70 private CrmReceivablePlanService receivablePlanService; 72 private CrmReceivablePlanService receivablePlanService;
71 @Resource 73 @Resource
72 private CrmPermissionService permissionService; 74 private CrmPermissionService permissionService;
  75 +
73 @Resource 76 @Resource
74 private AdminUserApi adminUserApi; 77 private AdminUserApi adminUserApi;
75 @Resource 78 @Resource
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/util/CrmAuditStatusUtils.java
1 package cn.iocoder.yudao.module.crm.util; 1 package cn.iocoder.yudao.module.crm.util;
2 2
3 import cn.hutool.core.lang.Assert; 3 import cn.hutool.core.lang.Assert;
4 -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;  
5 import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; 4 import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
6 import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum; 5 import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum;
7 6
@@ -18,23 +17,11 @@ public class CrmAuditStatusUtils { @@ -18,23 +17,11 @@ public class CrmAuditStatusUtils {
18 * @param bpmResult BPM 审批结果 17 * @param bpmResult BPM 审批结果
19 */ 18 */
20 public static Integer convertBpmResultToAuditStatus(Integer bpmResult) { 19 public static Integer convertBpmResultToAuditStatus(Integer bpmResult) {
21 - Assert.isTrue(isEndResult(bpmResult), "BPM 审批结果({}) 转换失败, 流程状态不是最终结果", bpmResult);  
22 Integer auditStatus = BpmProcessInstanceResultEnum.APPROVE.getResult().equals(bpmResult) ? CrmAuditStatusEnum.APPROVE.getStatus() 20 Integer auditStatus = BpmProcessInstanceResultEnum.APPROVE.getResult().equals(bpmResult) ? CrmAuditStatusEnum.APPROVE.getStatus()
23 : BpmProcessInstanceResultEnum.REJECT.getResult().equals(bpmResult) ? CrmAuditStatusEnum.REJECT.getStatus() 21 : BpmProcessInstanceResultEnum.REJECT.getResult().equals(bpmResult) ? CrmAuditStatusEnum.REJECT.getStatus()
24 - : BpmProcessInstanceResultEnum.CANCEL.getResult(); 22 + : BpmProcessInstanceResultEnum.CANCEL.getResult().equals(bpmResult) ? BpmProcessInstanceResultEnum.CANCEL.getResult() : null;
25 Assert.notNull(auditStatus, "BPM 审批结果({}) 转换失败", bpmResult); 23 Assert.notNull(auditStatus, "BPM 审批结果({}) 转换失败", bpmResult);
26 return auditStatus; 24 return auditStatus;
27 } 25 }
28 26
29 - /**  
30 - * 判断该结果是否处于 End 最终结果  
31 - *  
32 - * @param bpmResult BPM 审批结果  
33 - * @return 是否  
34 - */  
35 - public static boolean isEndResult(Integer bpmResult) {  
36 - return ObjectUtils.equalsAny(bpmResult, BpmProcessInstanceResultEnum.APPROVE.getResult(),  
37 - BpmProcessInstanceResultEnum.REJECT.getResult(), BpmProcessInstanceResultEnum.CANCEL.getResult());  
38 - }  
39 -  
40 } 27 }
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/redis/RedisKeyConstants.java
@@ -13,6 +13,6 @@ public interface RedisKeyConstants { @@ -13,6 +13,6 @@ public interface RedisKeyConstants {
13 * KEY 格式:trade_no:{prefix} 13 * KEY 格式:trade_no:{prefix}
14 * VALUE 数据格式:编号自增 14 * VALUE 数据格式:编号自增
15 */ 15 */
16 - String NO = "seq_no:"; 16 + String NO = "erp:seq_no:";
17 17
18 } 18 }
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/redis/no/ErpNoRedisDAO.java
@@ -12,7 +12,7 @@ import java.time.LocalDateTime; @@ -12,7 +12,7 @@ import java.time.LocalDateTime;
12 12
13 13
14 /** 14 /**
15 - * 订单序号的 Redis DAO 15 + * Erp 订单序号的 Redis DAO
16 * 16 *
17 * @author HUIHUI 17 * @author HUIHUI
18 */ 18 */
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/dict/DictDataApi.java
@@ -5,6 +5,8 @@ import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO; @@ -5,6 +5,8 @@ import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO;
5 import java.util.Collection; 5 import java.util.Collection;
6 import java.util.List; 6 import java.util.List;
7 7
  8 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  9 +
8 /** 10 /**
9 * 字典数据 API 接口 11 * 字典数据 API 接口
10 * 12 *
@@ -41,11 +43,22 @@ public interface DictDataApi { @@ -41,11 +43,22 @@ public interface DictDataApi {
41 DictDataRespDTO parseDictData(String type, String label); 43 DictDataRespDTO parseDictData(String type, String label);
42 44
43 /** 45 /**
  46 + * 获得指定字典类型的字典数据列表
  47 + *
  48 + * @param dictType 字典类型
  49 + * @return 字典数据列表
  50 + */
  51 + List<DictDataRespDTO> getDictDataList(String dictType);
  52 +
  53 + /**
44 * 获得字典数据标签列表 54 * 获得字典数据标签列表
45 * 55 *
46 * @param dictType 字典类型 56 * @param dictType 字典类型
47 * @return 字典数据标签列表 57 * @return 字典数据标签列表
48 */ 58 */
49 - List<String> getDictDataLabelList(String dictType); 59 + default List<String> getDictDataLabelList(String dictType) {
  60 + List<DictDataRespDTO> list = getDictDataList(dictType);
  61 + return convertList(list, DictDataRespDTO::getLabel);
  62 + }
50 63
51 } 64 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/dict/DictDataApiImpl.java
1 package cn.iocoder.yudao.module.system.api.dict; 1 package cn.iocoder.yudao.module.system.api.dict;
2 2
3 -import cn.hutool.core.collection.CollUtil;  
4 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 3 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
5 import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO; 4 import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO;
6 import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO; 5 import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
@@ -9,11 +8,8 @@ import jakarta.annotation.Resource; @@ -9,11 +8,8 @@ import jakarta.annotation.Resource;
9 import org.springframework.stereotype.Service; 8 import org.springframework.stereotype.Service;
10 9
11 import java.util.Collection; 10 import java.util.Collection;
12 -import java.util.Collections;  
13 import java.util.List; 11 import java.util.List;
14 12
15 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;  
16 -  
17 /** 13 /**
18 * 字典数据 API 实现类 14 * 字典数据 API 实现类
19 * 15 *
@@ -43,12 +39,9 @@ public class DictDataApiImpl implements DictDataApi { @@ -43,12 +39,9 @@ public class DictDataApiImpl implements DictDataApi {
43 } 39 }
44 40
45 @Override 41 @Override
46 - public List<String> getDictDataLabelList(String dictType) {  
47 - List<DictDataDO> dictDataList = dictDataService.getDictDataListByDictType(dictType);  
48 - if (CollUtil.isEmpty(dictDataList)) {  
49 - return Collections.emptyList();  
50 - }  
51 - return convertList(dictDataList, DictDataDO::getLabel); 42 + public List<DictDataRespDTO> getDictDataList(String dictType) {
  43 + List<DictDataDO> list = dictDataService.getDictDataListByDictType(dictType);
  44 + return BeanUtils.toBean(list, DictDataRespDTO.class);
52 } 45 }
53 46
54 } 47 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java
@@ -29,7 +29,7 @@ public class AreaController { @@ -29,7 +29,7 @@ public class AreaController {
29 @GetMapping("/tree") 29 @GetMapping("/tree")
30 @Operation(summary = "获得地区树") 30 @Operation(summary = "获得地区树")
31 public CommonResult<List<AreaNodeRespVO>> getAreaTree() { 31 public CommonResult<List<AreaNodeRespVO>> getAreaTree() {
32 - Area area = AreaUtils.getArea(Area.ID_CHINA); 32 + Area area = AreaUtils.parseArea(Area.ID_CHINA);
33 Assert.notNull(area, "获取不到中国"); 33 Assert.notNull(area, "获取不到中国");
34 return success(BeanUtils.toBean(area.getChildren(), AreaNodeRespVO.class)); 34 return success(BeanUtils.toBean(area.getChildren(), AreaNodeRespVO.class));
35 } 35 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/ip/AppAreaController.java
@@ -26,7 +26,7 @@ public class AppAreaController { @@ -26,7 +26,7 @@ public class AppAreaController {
26 @GetMapping("/tree") 26 @GetMapping("/tree")
27 @Operation(summary = "获得地区树") 27 @Operation(summary = "获得地区树")
28 public CommonResult<List<AppAreaNodeRespVO>> getAreaTree() { 28 public CommonResult<List<AppAreaNodeRespVO>> getAreaTree() {
29 - Area area = AreaUtils.getArea(Area.ID_CHINA); 29 + Area area = AreaUtils.parseArea(Area.ID_CHINA);
30 Assert.notNull(area, "获取不到中国"); 30 Assert.notNull(area, "获取不到中国");
31 return success(BeanUtils.toBean(area.getChildren(), AppAreaNodeRespVO.class)); 31 return success(BeanUtils.toBean(area.getChildren(), AppAreaNodeRespVO.class));
32 } 32 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictDataService.java
@@ -100,7 +100,7 @@ public interface DictDataService { @@ -100,7 +100,7 @@ public interface DictDataService {
100 DictDataDO parseDictData(String dictType, String label); 100 DictDataDO parseDictData(String dictType, String label);
101 101
102 /** 102 /**
103 - * 获得字典数据列表 103 + * 获得指定数据类型的字典数据列表
104 * 104 *
105 * @param dictType 字典类型 105 * @param dictType 字典类型
106 * @return 字典数据列表 106 * @return 字典数据列表
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictDataServiceImpl.java
@@ -171,7 +171,9 @@ public class DictDataServiceImpl implements DictDataService { @@ -171,7 +171,9 @@ public class DictDataServiceImpl implements DictDataService {
171 171
172 @Override 172 @Override
173 public List<DictDataDO> getDictDataListByDictType(String dictType) { 173 public List<DictDataDO> getDictDataListByDictType(String dictType) {
174 - return dictDataMapper.selectList(DictDataDO::getDictType, dictType); 174 + List<DictDataDO> list = dictDataMapper.selectList(DictDataDO::getDictType, dictType);
  175 + list.sort(Comparator.comparing(DictDataDO::getSort));
  176 + return list;
175 } 177 }
176 178
177 } 179 }