Emil.Zhang 0ff533e6b5 feat(增加自动创建级联选项功能):
1.DropDownOptions中增加自动创建级联选项的方法
2.示例方法中增加调用示例
2023-06-09 18:31:59 +08:00

150 lines
5.7 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.ruoyi.common.excel;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.common.exception.ServiceException;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* <h1>Excel下拉可选项</h1>
* 注意为确保下拉框解析正确传值务必使用createOptionValue()做为值的拼接
*
* @author Emil.Zhang
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@SuppressWarnings("unused")
public class DropDownOptions {
/**
* 一级下拉所在列index从0开始算
*/
private int index = 0;
/**
* 二级下拉所在的index从0开始算不能与一级相同
*/
private int nextIndex = 0;
/**
* 一级下拉所包含的数据
*/
private List<String> options = new ArrayList<>();
/**
* 二级下拉所包含的数据Map
* <p>以每一个一级选项值为Key每个一级选项对应的二级数据为Value</p>
*/
private Map<String, List<String>> nextOptions = new HashMap<>();
/**
* 分隔符
*/
private static final String DELIMITER = "_";
/**
* 创建只有一级的下拉选
*/
public DropDownOptions(int index, List<String> options) {
this.index = index;
this.options = options;
}
/**
* <h2>创建每个选项可选值</h2>
* <p>注意:不能以数字,特殊符号开头,选项中不可以包含任何运算符号</p>
*
* @param vars 可选值内包含的参数
* @return 合规的可选值
*/
public static String createOptionValue(Object... vars) {
StringBuilder stringBuffer = new StringBuilder();
String regex = "^[\\S\\d\\u4e00-\\u9fa5]+$";
for (int i = 0; i < vars.length; i++) {
String var = StrUtil.trimToEmpty(String.valueOf(vars[i]));
if (!var.matches(regex)) {
throw new ServiceException("选项数据不符合规则,仅允许使用中英文字符以及数字");
}
stringBuffer.append(var);
if (i < vars.length - 1) {
// 直至最后一个前都以_作为切割线
stringBuffer.append(DELIMITER);
}
}
if (stringBuffer.toString().matches("^\\d_*$")) {
throw new ServiceException("禁止以数字开头");
}
return stringBuffer.toString();
}
/**
* 将处理后合理的可选值解析为原始的参数
*
* @param option 经过处理后的合理的可选项
* @return 原始的参数
*/
public static List<String> analyzeOptionValue(String option) {
return StrUtil.split(option, DELIMITER, true, true);
}
/**
* 创建级联下拉选项
*
* @param parentList 父实体可选项原始数据
* @param parentIndex 父下拉选位置
* @param sonList 子实体可选项原始数据
* @param sonIndex 子下拉选位置
* @param parentHowToGetIdFunction 父类如何获取唯一标识
* @param sonHowToGetParentIdFunction 子类如何获取父类的唯一标识
* @param howToBuildEveryOption 如何生成下拉选内容
* @return 级联下拉选项
*/
public static <T> DropDownOptions buildLinkedOptions(List<T> parentList,
int parentIndex,
List<T> sonList,
int sonIndex,
Function<T, Number> parentHowToGetIdFunction,
Function<T, Number> sonHowToGetParentIdFunction,
Function<T, String> howToBuildEveryOption) {
DropDownOptions parentLinkSonOptions = new DropDownOptions();
// 先创建父类的下拉
parentLinkSonOptions.setIndex(parentIndex);
parentLinkSonOptions.setOptions(
parentList.stream()
.map(howToBuildEveryOption)
.collect(Collectors.toList())
);
// 提取父-子级联下拉
Map<String, List<String>> sonOptions = new HashMap<>();
// 父级依据自己的ID分组
Map<Number, List<T>> parentGroupByIdMap =
parentList.stream().collect(Collectors.groupingBy(parentHowToGetIdFunction));
// 遍历每个子集提取到Map中
sonList.forEach(everySon -> {
if (parentGroupByIdMap.containsKey(sonHowToGetParentIdFunction.apply(everySon))) {
// 找到对应的上级
T parentObj = parentGroupByIdMap.get(sonHowToGetParentIdFunction.apply(everySon)).get(0);
// 提取名称和ID作为Key
String key = howToBuildEveryOption.apply(parentObj);
// Key对应的Value
List<String> thisParentSonOptionList;
if (sonOptions.containsKey(key)) {
thisParentSonOptionList = sonOptions.get(key);
} else {
thisParentSonOptionList = new ArrayList<>();
sonOptions.put(key, thisParentSonOptionList);
}
// 往Value中添加当前子集选项
thisParentSonOptionList.add(howToBuildEveryOption.apply(everySon));
}
});
parentLinkSonOptions.setNextIndex(sonIndex);
parentLinkSonOptions.setNextOptions(sonOptions);
return parentLinkSonOptions;
}
}