From 110df3a175ad580743e4833468ff583a906a88c1 Mon Sep 17 00:00:00 2001
From: "Emil.Zhang"
Date: Sat, 6 May 2023 11:46:51 +0800
Subject: [PATCH] =?UTF-8?q?feat(=E4=BC=98=E5=8C=96=E6=B3=A8=E8=A7=A3|?=
=?UTF-8?q?=E5=8F=8D=E5=90=91=E8=A7=A3=E6=9E=90=E5=A4=B1=E6=95=88):?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
1.去除DropDown注解,改为使用DictDataFormat注解
2.修复DictEnumFormat注解Excel转Java时解析失效的问题
---
.../com/ruoyi/common/annotation/DropDown.java | 21 ------
.../common/convert/ExcelEnumConvert.java | 30 ++++++--
.../common/core/service/DictService.java | 11 +++
.../ruoyi/common/excel/DropDownOptions.java | 16 ++++-
.../ruoyi/common/excel/ExcelDownHandler.java | 60 ++++++++++++++--
.../demo/controller/TestExcelController.java | 21 ++++--
.../ruoyi/demo/domain/vo/ExportDemoVo.java | 60 +++++++++++-----
.../demo/listener/ExportDemoListener.java | 68 +++++++++++++++++++
.../service/impl/ExportExcelServiceImpl.java | 19 +++---
.../system/service/ISysDictTypeService.java | 11 +--
.../service/impl/SysDictTypeServiceImpl.java | 2 +-
11 files changed, 243 insertions(+), 76 deletions(-)
delete mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/annotation/DropDown.java
create mode 100644 ruoyi-demo/src/main/java/com/ruoyi/demo/listener/ExportDemoListener.java
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/DropDown.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/DropDown.java
deleted file mode 100644
index f474b3cd1..000000000
--- a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/DropDown.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.ruoyi.common.annotation;
-
-import java.lang.annotation.*;
-
-/**
- * Excel下拉注解
- * 注解在实体类中的属性上,与@ExcelProperty同级
- *
- * @author slYe
- * @author Emil.Zhang
- */
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ElementType.FIELD})
-public @interface DropDown {
- /**
- * 下拉框可选值,用于简单的指定可选值
- * 例如: @DropDown({"选项1","选项2"})
- */
- String[] value();
-}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/convert/ExcelEnumConvert.java b/ruoyi-common/src/main/java/com/ruoyi/common/convert/ExcelEnumConvert.java
index c69d90cfb..2069c154f 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/convert/ExcelEnumConvert.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/convert/ExcelEnumConvert.java
@@ -37,14 +37,34 @@ public class ExcelEnumConvert implements Converter
+ * 使用ExcelEnumFormat注解需要进行下拉选的部分
+ */
+ @ExcelProperty(value = "用户类型", index = 1, converter = ExcelEnumConvert.class)
+ @ExcelEnumFormat(enumClass = UserStatus.class, textField = "info")
+ @NotEmpty(message = "用户类型不能为空", groups = AddGroup.class)
+ private String userStatus;
+
/**
* 性别
*
- * 使用DropDown形式注入的下拉选可以使用任意形式,自己能解析出来就行
+ * 使用ExcelDictFormat注解需要进行下拉选的部分
*/
- @ExcelProperty(value = "性别", index = 1)
- @DropDown({"1=男", "2=女"})
- private String genderStr;
-
- /**
- * 数据库中的性别
- */
- private Integer gender;
+ @ExcelProperty(value = "性别", index = 2, converter = ExcelDictConvert.class)
+ @ExcelDictFormat(dictType = "sys_user_sex")
+ @NotEmpty(message = "性别不能为空", groups = AddGroup.class)
+ private String gender;
/**
* 手机号
*/
- @ExcelProperty(value = "手机号", index = 2)
+ @ExcelProperty(value = "手机号", index = 3)
+ @NotEmpty(message = "手机号不能为空", groups = AddGroup.class)
private String phoneNumber;
/**
* Email
*/
- @ExcelProperty(value = "Email", index = 3)
+ @ExcelProperty(value = "Email", index = 4)
+ @NotEmpty(message = "Email不能为空", groups = AddGroup.class)
private String email;
/**
* 省
*
- * 级联下拉
+ * 级联下拉,仅判断是否选了
*/
- @ExcelProperty(value = "省", index = 25)
+ @ExcelProperty(value = "省", index = 5)
+ @NotNull(message = "省不能为空", groups = AddGroup.class)
private String province;
/**
* 数据库中的省ID
+ *
+ * 处理完毕后再判断是否市正确的值
*/
+ @NotNull(message = "请勿手动输入", groups = EditGroup.class)
private Integer provinceId;
/**
@@ -70,12 +92,14 @@ public class ExportDemoVo {
*
* 级联下拉
*/
- @ExcelProperty(value = "市", index = 26)
+ @ExcelProperty(value = "市", index = 6)
+ @NotNull(message = "市不能为空", groups = AddGroup.class)
private String city;
/**
* 数据库中的市ID
*/
+ @NotNull(message = "请勿手动输入", groups = EditGroup.class)
private Integer cityId;
/**
@@ -83,11 +107,13 @@ public class ExportDemoVo {
*
* 级联下拉
*/
- @ExcelProperty(value = "县", index = 27)
+ @ExcelProperty(value = "县", index = 7)
+ @NotNull(message = "县不能为空", groups = AddGroup.class)
private String area;
/**
* 数据库中的县ID
*/
+ @NotNull(message = "请勿手动输入", groups = EditGroup.class)
private Integer areaId;
}
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/listener/ExportDemoListener.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/listener/ExportDemoListener.java
new file mode 100644
index 000000000..95d7093f2
--- /dev/null
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/listener/ExportDemoListener.java
@@ -0,0 +1,68 @@
+package com.ruoyi.demo.listener;
+
+import cn.hutool.core.util.NumberUtil;
+import com.alibaba.excel.context.AnalysisContext;
+import com.ruoyi.common.core.validate.AddGroup;
+import com.ruoyi.common.core.validate.EditGroup;
+import com.ruoyi.common.excel.DefaultExcelListener;
+import com.ruoyi.common.excel.DropDownOptions;
+import com.ruoyi.common.utils.ValidatorUtils;
+import com.ruoyi.demo.domain.vo.ExportDemoVo;
+
+import java.util.List;
+
+/**
+ * Excel带下拉框的解析处理器
+ *
+ * @author Emil.Zhang
+ */
+public class ExportDemoListener extends DefaultExcelListener {
+
+ public ExportDemoListener() {
+ // 显示使用构造函数,否则将导致空指针
+ super(true);
+ }
+
+ @Override
+ public void invoke(ExportDemoVo data, AnalysisContext context) {
+ // 先校验必填
+ ValidatorUtils.validate(data, AddGroup.class);
+
+ // 处理级联下拉的部分
+ String province = data.getProvince();
+ String city = data.getCity();
+ String area = data.getArea();
+ // 本行用户选择的省
+ List thisRowSelectedProvinceOption = DropDownOptions.analyzeOptionValue(province);
+ if (thisRowSelectedProvinceOption.size() == 2) {
+ String provinceIdStr = thisRowSelectedProvinceOption.get(1);
+ if (NumberUtil.isNumber(provinceIdStr)) {
+ // 严格要求数据的话可以在这里做与数据库相关的判断
+ // 例如判断省信息是否在数据库中存在等,建议结合RedisCache做缓存10s,减少数据库调用
+ data.setProvinceId(Integer.parseInt(provinceIdStr));
+ }
+ }
+ // 本行用户选择的市
+ List thisRowSelectedCityOption = DropDownOptions.analyzeOptionValue(city);
+ if (thisRowSelectedCityOption.size() == 2) {
+ String cityIdStr = thisRowSelectedCityOption.get(1);
+ if (NumberUtil.isNumber(cityIdStr)) {
+ data.setCityId(Integer.parseInt(cityIdStr));
+ }
+ }
+ // 本行用户选择的县
+ List thisRowSelectedAreaOption = DropDownOptions.analyzeOptionValue(area);
+ if (thisRowSelectedAreaOption.size() == 2) {
+ String areaIdStr = thisRowSelectedAreaOption.get(1);
+ if (NumberUtil.isNumber(areaIdStr)) {
+ data.setAreaId(Integer.parseInt(areaIdStr));
+ }
+ }
+
+ // 处理完毕以后判断是否符合规则
+ ValidatorUtils.validate(data, EditGroup.class);
+
+ // 添加到处理结果中
+ getExcelResult().getList().add(data);
+ }
+}
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/ExportExcelServiceImpl.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/ExportExcelServiceImpl.java
index 14f982c45..a0da4e69b 100644
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/ExportExcelServiceImpl.java
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/ExportExcelServiceImpl.java
@@ -1,5 +1,6 @@
package com.ruoyi.demo.service.impl;
+import com.ruoyi.common.enums.UserStatus;
import com.ruoyi.common.excel.DropDownOptions;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.demo.domain.vo.ExportDemoVo;
@@ -32,7 +33,8 @@ public class ExportExcelServiceImpl implements IExportExcelService {
// 模拟数据库中的一条数据
ExportDemoVo everyRowData = new ExportDemoVo();
everyRowData.setNickName("用户-" + i);
- everyRowData.setGender(1);
+ everyRowData.setUserStatus(UserStatus.OK.getCode());
+ everyRowData.setGender("1");
everyRowData.setPhoneNumber(String.format("175%08d", i));
everyRowData.setEmail(String.format("175%08d", i) + "@163.com");
everyRowData.setProvinceId(i);
@@ -105,17 +107,17 @@ public class ExportExcelServiceImpl implements IExportExcelService {
// 创建省-市级联
DropDownOptions provinceToCity = new DropDownOptions();
// 以省为一级
- provinceToCity.setIndex(25);
+ provinceToCity.setIndex(5);
// 以市为二级
- provinceToCity.setNextIndex(26);
+ provinceToCity.setNextIndex(6);
// 补充省的内容以及市的内容
provinceToCity.setOptions(provinceOptions);
provinceToCity.setNextOptions(provinceToCityOptions);
// 创建市-县级联
DropDownOptions cityToArea = new DropDownOptions();
- cityToArea.setIndex(26);
- cityToArea.setNextIndex(27);
+ cityToArea.setIndex(6);
+ cityToArea.setNextIndex(7);
cityToArea.setOptions(cityOptions);
cityToArea.setNextOptions(cityToAreaOptions);
@@ -128,12 +130,7 @@ public class ExportExcelServiceImpl implements IExportExcelService {
// 接下来需要将Excel中的展示数据转换为对应的下拉选
List outList = excelDataList.stream().map(everyRowData -> {
- // 首先转换性别,性别是通过注解的,则自行提取为对应的值
- // 业务逻辑中一般会使用枚举的形式,这里直接通过判断值的形式拼接
- Integer gender = everyRowData.getGender();
- everyRowData.setGenderStr(gender == 1 ? "1=男" : "2=女");
-
- // 下面处理下拉框的问题,对于数据本身只需要将对应的下拉值转换为下拉选以选中的选项
+ // 只需要处理没有使用@ExcelDictFormat注解的下拉框
// 一般来说,可以直接在数据库查询即查询出省市县信息,这里通过模拟操作赋值
everyRowData.setProvince(buildOptions(provinceList, everyRowData.getProvinceId()));
everyRowData.setCity(buildOptions(cityList, everyRowData.getCityId()));
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictTypeService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictTypeService.java
index 0e3d94dab..fe53005bf 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictTypeService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictTypeService.java
@@ -4,6 +4,7 @@ import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.domain.entity.SysDictType;
import com.ruoyi.common.core.page.TableDataInfo;
+import com.ruoyi.common.core.service.DictService;
import java.util.List;
@@ -12,7 +13,7 @@ import java.util.List;
*
* @author Lion Li
*/
-public interface ISysDictTypeService {
+public interface ISysDictTypeService extends DictService {
TableDataInfo selectPageDictTypeList(SysDictType dictType, PageQuery pageQuery);
@@ -32,14 +33,6 @@ public interface ISysDictTypeService {
*/
List selectDictTypeAll();
- /**
- * 根据字典类型查询字典数据
- *
- * @param dictType 字典类型
- * @return 字典数据集合信息
- */
- List selectDictDataByType(String dictType);
-
/**
* 根据字典类型ID查询信息
*
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java
index 0c897df61..d0f03ad98 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java
@@ -38,7 +38,7 @@ import java.util.stream.Collectors;
*/
@RequiredArgsConstructor
@Service
-public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService {
+public class SysDictTypeServiceImpl implements ISysDictTypeService {
private final SysDictTypeMapper baseMapper;
private final SysDictDataMapper dictDataMapper;