Commit b26eb6266fa1b5195c4510d4b12f55afdc394c37

Authored by puhui999
1 parent 1ad5602a

CRM:新增客户导入模版所属行业、客户等级、客户来源、客户地区单元格下拉选择

yudao-framework/yudao-spring-boot-starter-biz-ip/src/main/java/cn/iocoder/yudao/framework/ip/core/utils/AreaUtils.java
@@ -4,6 +4,7 @@ import cn.hutool.core.io.resource.ResourceUtil; @@ -4,6 +4,7 @@ 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.StrUtil;
7 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; 8 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
8 import cn.iocoder.yudao.framework.ip.core.Area; 9 import cn.iocoder.yudao.framework.ip.core.Area;
9 import cn.iocoder.yudao.framework.ip.core.enums.AreaTypeEnum; 10 import cn.iocoder.yudao.framework.ip.core.enums.AreaTypeEnum;
@@ -75,6 +76,32 @@ public class AreaUtils { @@ -75,6 +76,32 @@ public class AreaUtils {
75 } 76 }
76 77
77 /** 78 /**
  79 + * 获取所有节点的全路径名称如:河南省/石家庄市/新华区
  80 + *
  81 + * @param areas 地区树
  82 + * @return 所有节点的全路径名称
  83 + */
  84 + public static List<String> getAllAreaNodePaths(List<Area> areas) {
  85 + return convertList(areas, AreaUtils::buildTreePath);
  86 + }
  87 +
  88 + // TODO @puhui999: 展开树再构建全路径
  89 + private static String buildTreePath(Area node) {
  90 + if (node.getParent() == null || Area.ID_CHINA.equals(node.getParent().getId())) { // 忽略中国
  91 + // 已经是根节点,直接返回节点名称
  92 + return node.getName();
  93 + } else {
  94 + // 递归拼接上级节点的名称
  95 + Area parent = getArea(node.getParent().getId());
  96 + if (parent != null) {
  97 + String parentPath = buildTreePath(parent);
  98 + return parentPath + "/" + node.getName();
  99 + }
  100 + }
  101 + return StrUtil.EMPTY;
  102 + }
  103 +
  104 + /**
78 * 格式化区域 105 * 格式化区域
79 * 106 *
80 * @param id 区域编号 107 * @param id 区域编号
@@ -88,13 +115,13 @@ public class AreaUtils { @@ -88,13 +115,13 @@ public class AreaUtils {
88 * 格式化区域 115 * 格式化区域
89 * 116 *
90 * 例如说: 117 * 例如说:
91 - * 1. id = “静安区”时:上海 上海市 静安区  
92 - * 2. id = “上海市”时:上海 上海市  
93 - * 3. id = “上海”时:上海  
94 - * 4. id = “美国”时:美国 118 + * 1. id = “静安区”时:上海 上海市 静安区
  119 + * 2. id = “上海市”时:上海 上海市
  120 + * 3. id = “上海”时:上海
  121 + * 4. id = “美国”时:美国
95 * 当区域在中国时,默认不显示中国 122 * 当区域在中国时,默认不显示中国
96 * 123 *
97 - * @param id 区域编号 124 + * @param id 区域编号
98 * @param separator 分隔符 125 * @param separator 分隔符
99 * @return 格式化后的区域 126 * @return 格式化后的区域
100 */ 127 */
yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/SelectSheetWriteHandler.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.excel.core.handler;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.common.core.KeyValue;
  5 +import com.alibaba.excel.write.handler.SheetWriteHandler;
  6 +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
  7 +import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
  8 +import org.apache.poi.hssf.usermodel.HSSFDataValidation;
  9 +import org.apache.poi.ss.usermodel.*;
  10 +import org.apache.poi.ss.util.CellRangeAddressList;
  11 +
  12 +import java.util.List;
  13 +
  14 +/**
  15 + * 基于固定 sheet 实现下拉框
  16 + *
  17 + * @author HUIHUI
  18 + */
  19 +public class SelectSheetWriteHandler implements SheetWriteHandler {
  20 +
  21 + private List<KeyValue<Integer, List<String>>> selectMap;
  22 +
  23 + private final char[] alphabet = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
  24 + 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
  25 +
  26 + public SelectSheetWriteHandler(List<KeyValue<Integer, List<String>>> selectMap) {
  27 + this.selectMap = selectMap;
  28 + }
  29 +
  30 + @Override
  31 + public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
  32 + if (selectMap == null || CollUtil.isEmpty(selectMap)) {
  33 + return;
  34 + }
  35 + // 需要设置下拉框的sheet页
  36 + Sheet curSheet = writeSheetHolder.getSheet();
  37 + DataValidationHelper helper = curSheet.getDataValidationHelper();
  38 + String dictSheetName = "字典sheet";
  39 + Workbook workbook = writeWorkbookHolder.getWorkbook();
  40 + // 数据字典的sheet页
  41 + Sheet dictSheet = workbook.createSheet(dictSheetName);
  42 + for (KeyValue<Integer, List<String>> keyValue : selectMap) {
  43 + // 设置下拉单元格的首行、末行、首列、末列
  44 + CellRangeAddressList rangeAddressList = new CellRangeAddressList(1, 65533, keyValue.getKey(), keyValue.getKey());
  45 + int rowLen = keyValue.getValue().size();
  46 + // 设置字典sheet页的值 每一列一个字典项
  47 + for (int i = 0; i < rowLen; i++) {
  48 + Row row = dictSheet.getRow(i);
  49 + if (row == null) {
  50 + row = dictSheet.createRow(i);
  51 + }
  52 + row.createCell(keyValue.getKey()).setCellValue(keyValue.getValue().get(i));
  53 + }
  54 + String excelColumn = getExcelColumn(keyValue.getKey());
  55 + // 下拉框数据来源 eg:字典sheet!$B1:$B2
  56 + String refers = dictSheetName + "!$" + excelColumn + "$1:$" + excelColumn + "$" + rowLen;
  57 + // 创建可被其他单元格引用的名称
  58 + Name name = workbook.createName();
  59 + // 设置名称的名字
  60 + name.setNameName("dict" + keyValue.getKey());
  61 + // 设置公式
  62 + name.setRefersToFormula(refers);
  63 + // 设置引用约束
  64 + DataValidationConstraint constraint = helper.createFormulaListConstraint("dict" + keyValue.getKey());
  65 + // 设置约束
  66 + DataValidation validation = helper.createValidation(constraint, rangeAddressList);
  67 + if (validation instanceof HSSFDataValidation) {
  68 + validation.setSuppressDropDownArrow(false);
  69 + } else {
  70 + validation.setSuppressDropDownArrow(true);
  71 + validation.setShowErrorBox(true);
  72 + }
  73 + // 阻止输入非下拉框的值
  74 + validation.setErrorStyle(DataValidation.ErrorStyle.STOP);
  75 + validation.createErrorBox("提示", "此值不存在于下拉选择中!");
  76 + // 添加下拉框约束
  77 + writeSheetHolder.getSheet().addValidationData(validation);
  78 + }
  79 + }
  80 +
  81 + /**
  82 + * 将数字列转化成为字母列
  83 + *
  84 + * @param num 数字
  85 + * @return 字母
  86 + */
  87 + private String getExcelColumn(int num) {
  88 + String column = "";
  89 + int len = alphabet.length - 1;
  90 + int first = num / len;
  91 + int second = num % len;
  92 + if (num <= len) {
  93 + column = alphabet[num] + "";
  94 + } else {
  95 + column = alphabet[first - 1] + "";
  96 + if (second == 0) {
  97 + column = column + alphabet[len] + "";
  98 + } else {
  99 + column = column + alphabet[second - 1] + "";
  100 + }
  101 + }
  102 + return column;
  103 + }
  104 +
  105 +}
0 \ No newline at end of file 106 \ No newline at end of file
yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java
1 package cn.iocoder.yudao.framework.excel.core.util; 1 package cn.iocoder.yudao.framework.excel.core.util;
2 2
  3 +import cn.iocoder.yudao.framework.common.core.KeyValue;
  4 +import cn.iocoder.yudao.framework.excel.core.handler.SelectSheetWriteHandler;
3 import com.alibaba.excel.EasyExcel; 5 import com.alibaba.excel.EasyExcel;
4 import com.alibaba.excel.converters.longconverter.LongStringConverter; 6 import com.alibaba.excel.converters.longconverter.LongStringConverter;
5 import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy; 7 import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
  8 +import jakarta.servlet.http.HttpServletResponse;
6 import org.springframework.web.multipart.MultipartFile; 9 import org.springframework.web.multipart.MultipartFile;
7 10
8 -import jakarta.servlet.http.HttpServletResponse;  
9 import java.io.IOException; 11 import java.io.IOException;
10 import java.net.URLEncoder; 12 import java.net.URLEncoder;
11 import java.nio.charset.StandardCharsets; 13 import java.nio.charset.StandardCharsets;
@@ -21,12 +23,12 @@ public class ExcelUtils { @@ -21,12 +23,12 @@ public class ExcelUtils {
21 /** 23 /**
22 * 将列表以 Excel 响应给前端 24 * 将列表以 Excel 响应给前端
23 * 25 *
24 - * @param response 响应  
25 - * @param filename 文件名 26 + * @param response 响应
  27 + * @param filename 文件名
26 * @param sheetName Excel sheet 名 28 * @param sheetName Excel sheet 名
27 - * @param head Excel head 头  
28 - * @param data 数据列表哦  
29 - * @param <T> 泛型,保证 head 和 data 类型的一致性 29 + * @param head Excel head 头
  30 + * @param data 数据列表哦
  31 + * @param <T> 泛型,保证 head 和 data 类型的一致性
30 * @throws IOException 写入失败的情况 32 * @throws IOException 写入失败的情况
31 */ 33 */
32 public static <T> void write(HttpServletResponse response, String filename, String sheetName, 34 public static <T> void write(HttpServletResponse response, String filename, String sheetName,
@@ -38,12 +40,37 @@ public class ExcelUtils { @@ -38,12 +40,37 @@ public class ExcelUtils {
38 .registerConverter(new LongStringConverter()) // 避免 Long 类型丢失精度 40 .registerConverter(new LongStringConverter()) // 避免 Long 类型丢失精度
39 .sheet(sheetName).doWrite(data); 41 .sheet(sheetName).doWrite(data);
40 // 设置 header 和 contentType。写在最后的原因是,避免报错时,响应 contentType 已经被修改了 42 // 设置 header 和 contentType。写在最后的原因是,避免报错时,响应 contentType 已经被修改了
41 - response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, StandardCharsets.UTF_8)); 43 + response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, StandardCharsets.UTF_8.name()));
  44 + response.setContentType("application/vnd.ms-excel;charset=UTF-8");
  45 + }
  46 +
  47 + /**
  48 + * 将列表以 Excel 响应给前端
  49 + *
  50 + * @param response 响应
  51 + * @param filename 文件名
  52 + * @param sheetName Excel sheet 名
  53 + * @param head Excel head 头
  54 + * @param data 数据列表哦
  55 + * @param selectMap 下拉选择数据 Map
  56 + * @throws IOException 写入失败的情况
  57 + */
  58 + public static <T> void write(HttpServletResponse response, String filename, String sheetName,
  59 + Class<T> head, List<T> data, List<KeyValue<Integer, List<String>>> selectMap) throws IOException {
  60 + // 输出 Excel
  61 + EasyExcel.write(response.getOutputStream(), head)
  62 + .autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理
  63 + .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 基于 column 长度,自动适配。最大 255 宽度
  64 + .registerWriteHandler(new SelectSheetWriteHandler(selectMap)) // 基于固定 sheet 实现下拉框
  65 + .registerConverter(new LongStringConverter()) // 避免 Long 类型丢失精度
  66 + .sheet(sheetName).doWrite(data);
  67 + // 设置 header 和 contentType。写在最后的原因是,避免报错时,响应 contentType 已经被修改了
  68 + response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, StandardCharsets.UTF_8.name()));
42 response.setContentType("application/vnd.ms-excel;charset=UTF-8"); 69 response.setContentType("application/vnd.ms-excel;charset=UTF-8");
43 } 70 }
44 71
45 public static <T> List<T> read(MultipartFile file, Class<T> head) throws IOException { 72 public static <T> List<T> read(MultipartFile file, Class<T> head) throws IOException {
46 - return EasyExcel.read(file.getInputStream(), head, null) 73 + return EasyExcel.read(file.getInputStream(), head, null)
47 .autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理 74 .autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理
48 .doReadAllSync(); 75 .doReadAllSync();
49 } 76 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.controller.admin.customer; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.controller.admin.customer;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.map.MapUtil; 4 import cn.hutool.core.map.MapUtil;
  5 +import cn.iocoder.yudao.framework.common.core.KeyValue;
5 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 6 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 8 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
@@ -10,6 +11,7 @@ import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; @@ -10,6 +11,7 @@ import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
10 import cn.iocoder.yudao.framework.common.util.number.NumberUtils; 11 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
11 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 12 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
12 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; 13 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  14 +import cn.iocoder.yudao.framework.ip.core.Area;
13 import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; 15 import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
14 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; 16 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
15 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.customer.*; 17 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.customer.*;
@@ -19,6 +21,7 @@ import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerPoolConfigService @@ -19,6 +21,7 @@ import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerPoolConfigService
19 import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; 21 import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
20 import cn.iocoder.yudao.module.system.api.dept.DeptApi; 22 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
21 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; 23 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
  24 +import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
22 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 25 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
23 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 26 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
24 import io.swagger.v3.oas.annotations.Operation; 27 import io.swagger.v3.oas.annotations.Operation;
@@ -34,9 +37,7 @@ import org.springframework.web.bind.annotation.*; @@ -34,9 +37,7 @@ import org.springframework.web.bind.annotation.*;
34 37
35 import java.io.IOException; 38 import java.io.IOException;
36 import java.time.LocalDateTime; 39 import java.time.LocalDateTime;
37 -import java.util.Arrays;  
38 -import java.util.List;  
39 -import java.util.Map; 40 +import java.util.*;
40 import java.util.stream.Stream; 41 import java.util.stream.Stream;
41 42
42 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 43 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -44,6 +45,7 @@ import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE; @@ -44,6 +45,7 @@ import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
44 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; 45 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
45 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; 46 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
46 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; 47 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  48 +import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.*;
47 import static java.util.Collections.singletonList; 49 import static java.util.Collections.singletonList;
48 50
49 @Tag(name = "管理后台 - CRM 客户") 51 @Tag(name = "管理后台 - CRM 客户")
@@ -61,6 +63,8 @@ public class CrmCustomerController { @@ -61,6 +63,8 @@ public class CrmCustomerController {
61 private DeptApi deptApi; 63 private DeptApi deptApi;
62 @Resource 64 @Resource
63 private AdminUserApi adminUserApi; 65 private AdminUserApi adminUserApi;
  66 + @Resource
  67 + private DictDataApi dictDataApi;
64 68
65 @PostMapping("/create") 69 @PostMapping("/create")
66 @Operation(summary = "创建客户") 70 @Operation(summary = "创建客户")
@@ -258,7 +262,7 @@ public class CrmCustomerController { @@ -258,7 +262,7 @@ public class CrmCustomerController {
258 .areaId(null).detailAddress("").remark("").build() 262 .areaId(null).detailAddress("").remark("").build()
259 ); 263 );
260 // 输出 264 // 输出
261 - ExcelUtils.write(response, "客户导入模板.xls", "客户列表", CrmCustomerImportExcelVO.class, list); 265 + ExcelUtils.write(response, "客户导入模板.xls", "客户列表", CrmCustomerImportExcelVO.class, list, builderSelectMap());
262 } 266 }
263 267
264 @PostMapping("/import") 268 @PostMapping("/import")
@@ -314,4 +318,23 @@ public class CrmCustomerController { @@ -314,4 +318,23 @@ public class CrmCustomerController {
314 return success(true); 318 return success(true);
315 } 319 }
316 320
  321 + private List<KeyValue<Integer, List<String>>> builderSelectMap() {
  322 + List<KeyValue<Integer, List<String>>> selectMap = new ArrayList<>();
  323 + // 获取地区下拉数据
  324 + Area area = AreaUtils.getArea(Area.ID_CHINA);
  325 + selectMap.add(new KeyValue<>(6, AreaUtils.getAllAreaNodePaths(area.getChildren())));
  326 + // 获取客户所属行业
  327 + List<String> customerIndustries = dictDataApi.getDictDataLabelList(CRM_CUSTOMER_INDUSTRY);
  328 + selectMap.add(new KeyValue<>(8, customerIndustries));
  329 + // 获取客户等级
  330 + List<String> customerLevels = dictDataApi.getDictDataLabelList(CRM_CUSTOMER_LEVEL);
  331 + selectMap.add(new KeyValue<>(9, customerLevels));
  332 + // 获取客户来源
  333 + List<String> customerSources = dictDataApi.getDictDataLabelList(CRM_CUSTOMER_SOURCE);
  334 + selectMap.add(new KeyValue<>(10, customerSources));
  335 + // 升序不然创建下拉会报错
  336 + selectMap.sort(Comparator.comparing(item -> item.getValue().size()));
  337 + return selectMap;
  338 + }
  339 +
317 } 340 }
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/dict/DictDataApi.java
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.system.api.dict; @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.system.api.dict;
3 import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO; 3 import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO;
4 4
5 import java.util.Collection; 5 import java.util.Collection;
  6 +import java.util.List;
6 7
7 /** 8 /**
8 * 字典数据 API 接口 9 * 字典数据 API 接口
@@ -39,4 +40,12 @@ public interface DictDataApi { @@ -39,4 +40,12 @@ public interface DictDataApi {
39 */ 40 */
40 DictDataRespDTO parseDictData(String type, String label); 41 DictDataRespDTO parseDictData(String type, String label);
41 42
  43 + /**
  44 + * 获得字典数据标签列表
  45 + *
  46 + * @param dictType 字典类型
  47 + * @return 字典数据标签列表
  48 + */
  49 + List<String> getDictDataLabelList(String dictType);
  50 +
42 } 51 }
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;
3 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 4 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
4 import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO; 5 import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO;
5 import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO; 6 import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
6 import cn.iocoder.yudao.module.system.service.dict.DictDataService; 7 import cn.iocoder.yudao.module.system.service.dict.DictDataService;
  8 +import jakarta.annotation.Resource;
7 import org.springframework.stereotype.Service; 9 import org.springframework.stereotype.Service;
8 10
9 -import jakarta.annotation.Resource;  
10 import java.util.Collection; 11 import java.util.Collection;
  12 +import java.util.Collections;
  13 +import java.util.List;
  14 +
  15 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
11 16
12 /** 17 /**
13 * 字典数据 API 实现类 18 * 字典数据 API 实现类
@@ -37,4 +42,13 @@ public class DictDataApiImpl implements DictDataApi { @@ -37,4 +42,13 @@ public class DictDataApiImpl implements DictDataApi {
37 return BeanUtils.toBean(dictData, DictDataRespDTO.class); 42 return BeanUtils.toBean(dictData, DictDataRespDTO.class);
38 } 43 }
39 44
  45 + @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);
  52 + }
  53 +
40 } 54 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictDataService.java
@@ -99,4 +99,12 @@ public interface DictDataService { @@ -99,4 +99,12 @@ public interface DictDataService {
99 */ 99 */
100 DictDataDO parseDictData(String dictType, String label); 100 DictDataDO parseDictData(String dictType, String label);
101 101
  102 + /**
  103 + * 获得字典数据列表
  104 + *
  105 + * @param dictType 字典类型
  106 + * @return 字典数据列表
  107 + */
  108 + List<DictDataDO> getDictDataListByDictType(String dictType);
  109 +
102 } 110 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictDataServiceImpl.java
@@ -11,10 +11,10 @@ import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO; @@ -11,10 +11,10 @@ import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
11 import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictTypeDO; 11 import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictTypeDO;
12 import cn.iocoder.yudao.module.system.dal.mysql.dict.DictDataMapper; 12 import cn.iocoder.yudao.module.system.dal.mysql.dict.DictDataMapper;
13 import com.google.common.annotations.VisibleForTesting; 13 import com.google.common.annotations.VisibleForTesting;
  14 +import jakarta.annotation.Resource;
14 import lombok.extern.slf4j.Slf4j; 15 import lombok.extern.slf4j.Slf4j;
15 import org.springframework.stereotype.Service; 16 import org.springframework.stereotype.Service;
16 17
17 -import jakarta.annotation.Resource;  
18 import java.util.Collection; 18 import java.util.Collection;
19 import java.util.Comparator; 19 import java.util.Comparator;
20 import java.util.List; 20 import java.util.List;
@@ -169,4 +169,9 @@ public class DictDataServiceImpl implements DictDataService { @@ -169,4 +169,9 @@ public class DictDataServiceImpl implements DictDataService {
169 return dictDataMapper.selectByDictTypeAndLabel(dictType, label); 169 return dictDataMapper.selectByDictTypeAndLabel(dictType, label);
170 } 170 }
171 171
  172 + @Override
  173 + public List<DictDataDO> getDictDataListByDictType(String dictType) {
  174 + return dictDataMapper.selectList(DictDataDO::getDictType, dictType);
  175 + }
  176 +
172 } 177 }