first commit

This commit is contained in:
那些花儿
2025-07-14 08:45:13 +08:00
commit 3e86198a82
2710 changed files with 610330 additions and 0 deletions
@@ -0,0 +1,122 @@
package com.budwk.app.base.utils;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternUtils;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.util.StringUtils;
import org.springframework.util.SystemPropertyUtils;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
public class ClassScannerUtil implements ResourceLoaderAware {
private final List<TypeFilter> includeFilters = new LinkedList<TypeFilter>();
private final List<TypeFilter> excludeFilters = new LinkedList<TypeFilter>();
private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
private MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(this.resourcePatternResolver);
public static Set<Class> scan(String[] basePackages,
Class<? extends Annotation>... annotations) {
ClassScannerUtil cs = new ClassScannerUtil();
if (ArrayUtils.isNotEmpty(annotations)) {
for (Class anno : annotations) {
cs.addIncludeFilter(new AnnotationTypeFilter(anno));
}
}
Set<Class> classes = new HashSet<Class>();
for (String s : basePackages) {
classes.addAll(cs.doScan(s));
}
return classes;
}
public static Set<Class> scan(String basePackages, Class<? extends Annotation>... annotations) {
return ClassScannerUtil.scan(StringUtils.tokenizeToStringArray(basePackages, ",; \t\n"), annotations);
}
public final ResourceLoader getResourceLoader() {
return this.resourcePatternResolver;
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourcePatternResolver = ResourcePatternUtils
.getResourcePatternResolver(resourceLoader);
this.metadataReaderFactory = new CachingMetadataReaderFactory(
resourceLoader);
}
public void addIncludeFilter(TypeFilter includeFilter) {
this.includeFilters.add(includeFilter);
}
public void addExcludeFilter(TypeFilter excludeFilter) {
this.excludeFilters.add(0, excludeFilter);
}
public void resetFilters(boolean useDefaultFilters) {
this.includeFilters.clear();
this.excludeFilters.clear();
}
public Set<Class> doScan(String basePackage) {
Set<Class> classes = new HashSet<Class>();
try {
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
+ org.springframework.util.ClassUtils
.convertClassNameToResourcePath(SystemPropertyUtils
.resolvePlaceholders(basePackage))
+ "/**/*.class";
Resource[] resources = this.resourcePatternResolver
.getResources(packageSearchPath);
for (Resource resource : resources) {
if (resource.isReadable()) {
MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource);
if ((includeFilters.size() == 0 && excludeFilters.size() == 0)
|| matches(metadataReader)) {
try {
classes.add(Class.forName(metadataReader
.getClassMetadata().getClassName()));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
} catch (IOException ex) {
throw new BeanDefinitionStoreException(
"I/O failure during classpath scanning", ex);
}
return classes;
}
protected boolean matches(MetadataReader metadataReader) throws IOException {
for (TypeFilter tf : this.excludeFilters) {
if (tf.match(metadataReader, this.metadataReaderFactory)) {
return false;
}
}
for (TypeFilter tf : this.includeFilters) {
if (tf.match(metadataReader, this.metadataReaderFactory)) {
return true;
}
}
return false;
}
}
@@ -0,0 +1,92 @@
/*
* Copyright [2022] [https://www.xiaonuo.vip]
*
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
*
* 1.请不要删除和修改根目录下的LICENSE文件。
* 2.请不要删除和修改Snowy源码头部的版权声明。
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
*/
package com.budwk.app.base.utils;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.URLUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
/**
* 文件下载工具类,使用本类前,对参数校验的异常使用CommonResponseUtil.renderError()方法进行渲染
*
* @author xuyuxiang
* @date 2020/8/5 21:45
*/
@Slf4j
public class CommonDownloadUtil {
/**
* 下载文件
*
* @param file 要下载的文件
* @param response 响应
* @author xuyuxiang
* @date 2020/8/5 21:46
*/
public static void download(File file, HttpServletResponse response) {
download(file.getName(), FileUtil.readBytes(file), response);
}
/**
* 下载文件
*
* @param fileName
* @param workbook
* @param response
*/
public static void download(String fileName, Workbook workbook, HttpServletResponse response) {
ByteArrayOutputStream byteOs = new ByteArrayOutputStream();
try {
workbook.write(byteOs);
} catch (IOException e) {
e.printStackTrace();
log.error(">>> 文件下载异常:", e);
} finally {
try {
workbook.close();
} catch (IOException e) {
e.printStackTrace();
}
IoUtil.close(byteOs);
}
download(fileName, byteOs.toByteArray(), response);
}
/**
* 下载文件
*
* @author xuyuxiang
* @date 2022/7/31 10:57
*/
public static void download(String fileName, byte[] fileBytes, HttpServletResponse response) {
try {
response.setHeader("Content-Disposition", "attachment;filename=" + URLUtil.encode(fileName));
response.addHeader("Content-Length", "" + fileBytes.length);
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
response.setContentType("application/octet-stream;charset=UTF-8");
IoUtil.write(response.getOutputStream(), true, fileBytes);
} catch (IOException e) {
log.error(">>> 文件下载异常:", e);
}
}
}
@@ -0,0 +1,159 @@
package com.budwk.app.base.utils;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.param.Condition;
import com.budwk.app.base.param.ConditionGroup;
import com.budwk.app.sys.param.SysDataUserUpdateParam;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Cnd;
import org.nutz.dao.util.cri.SqlExpressionGroup;
/**
* 条件组处理工具类
* 用于处理复杂的条件组和条件,生成对应的SQL条件
*/
@Slf4j
public class ConditionGroupUtil {
/**
* 处理条件组,将条件组转换为Cnd条件
*
* @param cnd 原始条件
* @param group 条件组
* @return 处理后的条件
*/
public static Cnd applyConditionGroup(Cnd cnd, ConditionGroup group) {
if (group == null) {
return cnd;
}
SqlExpressionGroup expGroup = new SqlExpressionGroup();
// 处理条件列表
if (group.getConditions() != null && !group.getConditions().isEmpty()) {
for (Condition condition : group.getConditions()) {
expGroup = applyCondition(expGroup, condition, group.getLogic());
}
}
// 处理嵌套条件组
if (group.getGroups() != null && !group.getGroups().isEmpty()) {
for (ConditionGroup nestedGroup : group.getGroups()) {
// 创建子条件
Cnd subCnd = Cnd.NEW();
subCnd = applyConditionGroup(subCnd, nestedGroup);
// 将子条件的表达式组添加到当前表达式组
if ("OR".equalsIgnoreCase(group.getLogic())) {
expGroup.or(subCnd.where());
} else {
expGroup.and(subCnd.where());
}
}
}
// 将表达式组添加到主条件
cnd.and(expGroup);
return cnd;
}
/**
* 处理单个条件
*
* @param expGroup 表达式组
* @param condition 条件
* @param logic 逻辑类型 (AND/OR)
* @return 处理后的表达式组
*/
public static SqlExpressionGroup applyCondition(SqlExpressionGroup expGroup, Condition condition, String logic) {
String field = condition.getField();
String operator = condition.getOperator();
Object value = condition.getValue();
// 根据操作符处理条件
switch (operator.toUpperCase()) {
case "=":
if ("OR".equalsIgnoreCase(logic)) {
expGroup.or(field, "=", value);
} else {
expGroup.and(field, "=", value);
}
break;
case "!=":
if ("OR".equalsIgnoreCase(logic)) {
expGroup.or(field, "!=", value);
} else {
expGroup.and(field, "!=", value);
}
break;
case ">":
if ("OR".equalsIgnoreCase(logic)) {
expGroup.or(field, ">", value);
} else {
expGroup.and(field, ">", value);
}
break;
case "<":
if ("OR".equalsIgnoreCase(logic)) {
expGroup.or(field, "<", value);
} else {
expGroup.and(field, "<", value);
}
break;
case ">=":
if ("OR".equalsIgnoreCase(logic)) {
expGroup.or(field, ">=", value);
} else {
expGroup.and(field, ">=", value);
}
break;
case "<=":
if ("OR".equalsIgnoreCase(logic)) {
expGroup.or(field, "<=", value);
} else {
expGroup.and(field, "<=", value);
}
break;
case "LIKE":
if ("OR".equalsIgnoreCase(logic)) {
expGroup.or(field, "LIKE", "%" + value + "%");
} else {
expGroup.and(field, "LIKE", "%" + value + "%");
}
break;
case "IN":
if ("OR".equalsIgnoreCase(logic)) {
expGroup.or(field, "IN", ObjectUtil.isNotNull(value) ? value.toString().split(",") : new String[0]);
} else {
expGroup.and(field, "IN", ObjectUtil.isNotNull(value) ? value.toString().split(",") : new String[0]);
}
break;
case "NOT IN":
if ("OR".equalsIgnoreCase(logic)) {
expGroup.or(field, "NOT IN", ObjectUtil.isNotNull(value) ? value.toString().split(",") : new String[0]);
} else {
expGroup.and(field, "NOT IN", ObjectUtil.isNotNull(value) ? value.toString().split(",") : new String[0]);
}
break;
case "IS NULL":
if ("OR".equalsIgnoreCase(logic)) {
expGroup.or(field, "IS", null);
} else {
expGroup.and(field, "IS", null);
}
break;
case "IS NOT NULL":
if ("OR".equalsIgnoreCase(logic)) {
expGroup.or(field, "IS NOT", null);
} else {
expGroup.and(field, "IS NOT", null);
}
break;
default:
log.warn("不支持的操作符: {}", operator);
}
return expGroup;
}
}
@@ -0,0 +1,139 @@
package com.budwk.app.base.utils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.nutz.lang.Times;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
/**
* Created by wizzer on 2016/6/24.
*/
public class DateUtil {
private static final Locale DEFAULT_LOCALE = Locale.CHINA;
private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
/**
* 获取当前时间(HH:mm:ss)
*
* @return
*/
public static String getDate() {
return DateFormatUtils.format(new Date(), "yyyy-MM-dd", DEFAULT_LOCALE);
}
/**
* 获取当前时间(HH:mm:ss)
*
* @return
*/
public static String getTime() {
return DateFormatUtils.format(new Date(), "HH:mm:ss", DEFAULT_LOCALE);
}
/**
* 获取当前时间(yyyy-MM-dd HH:mm:ss)
*
* @return
*/
public static String getDateTime() {
return DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss", DEFAULT_LOCALE);
}
/**
* 转换日期格式(yyyy-MM-dd HH:mm:ss)
*
* @param date
* @return
*/
public static String formatDateTime(Date date) {
if (date == null) return "";
return DateFormatUtils.format(date, "yyyy-MM-dd HH:mm:ss", DEFAULT_LOCALE);
}
/**
* 转换日期格式(yyyy-MM-dd HH:mm:ss)
*
* @param date
* @param f
* @return
*/
public static String format(Date date, String f) {
if (date == null) return "";
return DateFormatUtils.format(date, f, DEFAULT_LOCALE);
}
/**
* 时间戳日期
*
* @param time
* @return
*/
public static String getDate(long time) {
return DateFormatUtils.format(new Date(time * 1000), "yyyy-MM-dd HH:mm:ss", DEFAULT_LOCALE);
}
/**
* 时间戳日期
*
* @param time
* @param f
* @return
*/
public static String getDate(long time, String f) {
return DateFormatUtils.format(new Date(time * 1000), f, DEFAULT_LOCALE);
}
/**
* 通过字符串时间获取时间戳 nutzwk5.0改为long
*
* @param date
* @return
*/
public static long getTime(String date) {
try {
return Times.parse(sdf, date).getTime() / 1000;
} catch (ParseException e) {
return 0;
}
}
/**
* 通过字符串时间获取时间戳 nutzwk5.0改为long
*
* @param date
* @return
*/
public static long getTime(SimpleDateFormat sdf, String date) {
try {
return Times.parse(sdf, date).getTime() / 1000;
} catch (ParseException e) {
return 0;
}
}
/**
* 计算两个时间差
*/
public static String getDatePoor(Date endDate, Date nowDate) {
long nd = 1000 * 24 * 60 * 60;
long nh = 1000 * 60 * 60;
long nm = 1000 * 60;
// long ns = 1000;
// 获得两个时间的毫秒时间差异
long diff = endDate.getTime() - nowDate.getTime();
// 计算差多少天
long day = diff / nd;
// 计算差多少小时
long hour = diff % nd / nh;
// 计算差多少分钟
long min = diff % nd % nh / nm;
// 计算差多少秒//输出结果
// long sec = diff % nd % nh % nm / ns;
return day + "" + hour + "小时" + min + "分钟";
}
}
@@ -0,0 +1,449 @@
package com.budwk.app.base.utils;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.HashBasedTable;
import lombok.Data;
import java.util.*;
import java.util.stream.Collectors;
public class DynamicFormFieldParserUtil {
@Data
public static class FieldInfo {
private String key; // key
private String title; // 标题
private String type; // 字段类型 text,number,date,select,checkbox,radio,textarea,file,tableForm
private Object value; // 字段值 原始值,处理selectcheckboxradiotableForm 等负责情况
private String info; // 字段说明
private Boolean required; // 是否必填
private String displayValue; // 用于显示的值(label) 基本类型使用该字段
private JSONObject props; //属性
private String parentId = ""; // 父级字段id
private Map<String, Object> tableData; // 存储tableForm类型的columns和rows
}
/**
* 解析表单规则和数据
*
* @param config 表单规则JSON对象
* @param formDataJson 表单数据JSON字符串
* @return 字段信息Map
*/
public static Map<String, FieldInfo> parseFormFields(JSONObject config, String formDataJson) {
Map<String, FieldInfo> fieldInfoMap = new HashMap<>();
// 解析表单数据
// 用户数据
JSONObject formData = JSONUtil.parseObj(formDataJson);
//表单配置
JSONArray rules = JSONUtil.parseArray(config.getStr("rule"));
Map<String, Map<String, String>> optionsMap = new HashMap<>();
Map<String, List<TreeNode>> treeDataMap = new HashMap<>();
extractFieldInfoAndOptions(rules, fieldInfoMap, optionsMap, treeDataMap, null);
// 解析表单值
for (Map.Entry<String, Object> entry : formData.entrySet()) {
String field = entry.getKey();
Object value = entry.getValue();
if (fieldInfoMap.containsKey(field)) {
FieldInfo fieldInfo = fieldInfoMap.get(field);
fieldInfo.setKey(field);
fieldInfo.setValue(value);
// 处理值及显示值
processFieldValue(fieldInfo, value, optionsMap, treeDataMap, fieldInfoMap);
}
}
return fieldInfoMap;
}
private static void processFieldValue(FieldInfo fieldInfo, Object value,
Map<String, Map<String, String>> optionsMap,
Map<String, List<TreeNode>> treeDataMap,
Map<String, FieldInfo> fieldInfoMap) { // 添加 fieldInfoMap 参数
// 处理 tableForm 类型
if (fieldInfo.getType().equals("tableForm") && value instanceof List) {
List<Map<String, Object>> rows = (List<Map<String, Object>>) value;
// 初始化 tableData
Map<String, Object> tableData = new HashMap<>();
List<FieldInfo> columns = new ArrayList<>();
// 获取并存储列信息
if (fieldInfoMap.containsKey(fieldInfo.getKey())) {
// 假设 columns 是一个包含 FieldInfo 的结构
for (Map.Entry<String, FieldInfo> entry : fieldInfoMap.entrySet()) {
if (!entry.getKey().equals(fieldInfo.getKey()) && StrUtil.isNotBlank(entry.getValue().getParentId()) && entry.getValue().getParentId().equals(fieldInfo.getKey())) {
FieldInfo columnFieldInfo = entry.getValue();
columnFieldInfo.setKey(entry.getKey());
//找老爹要table的label属性
FieldInfo parentFieldInfo = fieldInfoMap.get(columnFieldInfo.getParentId());
if(null != parentFieldInfo){
columnFieldInfo.setTitle(parentFieldInfo.getTitle());
}
columns.add(columnFieldInfo);
}
}
}
tableData.put("columns", columns); // 存储列信息
tableData.put("rows", rows); // 存储行数据
fieldInfo.setTableData(tableData); // 设置 tableData
StringBuilder displayValueBuilder = new StringBuilder();
for (Map<String, Object> row : rows) {
StringBuilder rowDisplay = new StringBuilder();
for (Map.Entry<String, Object> entry : row.entrySet()) {
String columnField = entry.getKey();
Object columnValue = entry.getValue();
// 获取字段信息
FieldInfo columnFieldInfo = fieldInfoMap.get(columnField);
if (columnFieldInfo != null) {
// 设置原始值
columnFieldInfo.setValue(columnValue);
// 处理显示值
processColumnValue(columnFieldInfo, columnValue, optionsMap, treeDataMap);
// 追加到行显示值
rowDisplay.append(columnFieldInfo.getTitle())
.append(": ")
.append(columnFieldInfo.getDisplayValue())
.append(", ");
}
}
// 去除末尾的逗号和空格
if (rowDisplay.length() > 0) {
rowDisplay.setLength(rowDisplay.length() - 2);
}
displayValueBuilder.append("行: [").append(rowDisplay.toString()).append("]").append("\n");
}
fieldInfo.setDisplayValue(displayValueBuilder.toString());
}
// 处理复选框和选择器
else if (value instanceof List && optionsMap.containsKey(fieldInfo.getKey())) {
List<String> values = (List<String>) value;
Map<String, String> options = optionsMap.get(fieldInfo.getKey());
List<String> labels = values.stream()
.map(v -> options.getOrDefault(v, v))
.collect(Collectors.toList());
fieldInfo.setDisplayValue(String.join(", ", labels));
}
// 处理单选框
else if (value instanceof String && optionsMap.containsKey(fieldInfo.getTitle())) {
Map<String, String> options = optionsMap.get(fieldInfo.getTitle());
String valueStr = (String) value;
fieldInfo.setDisplayValue(options.getOrDefault(valueStr, valueStr));
}
// 处理树形控件
else if (value instanceof List && treeDataMap.containsKey(fieldInfo.getTitle())) {
List<String> selectedIds = (List<String>) value;
List<TreeNode> treeNodes = treeDataMap.get(fieldInfo.getTitle());
Map<String, String> idToLabelMap = new HashMap<>();
buildIdToLabelMap(treeNodes, idToLabelMap);
List<String> labels = selectedIds.stream()
.map(id -> idToLabelMap.getOrDefault(id, id))
.collect(Collectors.toList());
fieldInfo.setDisplayValue(String.join(", ", labels));
}
// 处理普通文本字段
else {
fieldInfo.setDisplayValue(value != null ? value.toString() : "");
}
}
/**
* 树节点结构
*/
@Data
private static class TreeNode {
private String id;
private String label;
private List<TreeNode> children;
}
/**
* 递归构建ID到Label的映射
*/
private static void buildIdToLabelMap(List<TreeNode> nodes, Map<String, String> idToLabelMap) {
if (nodes == null) return;
for (TreeNode node : nodes) {
if (node.getId() != null && node.getLabel() != null) {
idToLabelMap.put(node.getId(), node.getLabel());
}
buildIdToLabelMap(node.getChildren(), idToLabelMap);
}
}
/**
* 递归解析树节点
*/
private static List<TreeNode> parseTreeData(JSONArray treeData) {
List<TreeNode> result = new ArrayList<>();
for (int i = 0; i < treeData.size(); i++) {
JSONObject item = treeData.getJSONObject(i);
TreeNode node = new TreeNode();
node.setId(item.getStr("id"));
node.setLabel(item.getStr("label"));
if (item.containsKey("children") && item.get("children") instanceof JSONArray) {
node.setChildren(parseTreeData(item.getJSONArray("children")));
}
result.add(node);
}
return result;
}
/**
* 递归提取字段信息和选项映射
*/
private static void extractFieldInfoAndOptions(JSONArray items, Map<String, FieldInfo> fieldInfoMap,
Map<String, Map<String, String>> optionsMap,
Map<String, List<TreeNode>> treeDataMap, String parentId) {
for (int i = 0; i < items.size(); i++) {
JSONObject item = items.getJSONObject(i);
// 如果有子元素,递归处理
if (item.containsKey("children")) {
extractFieldInfoAndOptions(item.getJSONArray("children"), fieldInfoMap, optionsMap, treeDataMap, item.getStr("field"));
}
// 如果是表单,递归处理
if(item.containsKey("props") && item.getJSONObject("props").containsKey("columns") && !item.getJSONObject("props").getJSONArray("columns").isEmpty()){
extractFieldInfoAndOptions(item.getJSONObject("props").getJSONArray("columns"), fieldInfoMap, optionsMap, treeDataMap, item.getStr("field"));
}
// 提取字段信息
if (item.containsKey("field") && item.containsKey("title")) {
String field = item.getStr("field");
String type = item.getStr("type");
FieldInfo fieldInfo = new FieldInfo();
fieldInfo.setTitle(item.getStr("title"));
fieldInfo.setType(type);
fieldInfo.setInfo(item.getStr("info"));
fieldInfo.setParentId(parentId);
fieldInfo.setProps(item.getJSONObject("props"));
// 处理必填字段
Object required = item.get("$required");
if (required != null) {
fieldInfo.setRequired(required instanceof Boolean ? (Boolean) required : true);
}
fieldInfoMap.put(field, fieldInfo);
// 处理表格类型
// if ("tableForm".equals(type) && item.containsKey("props")) {
// JSONObject props = item.getJSONObject("props");
// if (props.containsKey("columns") && props.get("columns") instanceof JSONArray) {
// JSONArray columns = props.getJSONArray("columns");
// for (int j = 0; j < columns.size(); j++) {
// JSONObject column = columns.getJSONObject(j);
// if (column.containsKey("rule") && column.get("rule") instanceof JSONArray) {
// extractFieldInfoAndOptions(column.getJSONArray("rule"), fieldInfoMap, optionsMap, treeDataMap, field);
// }
// }
// }
// }
// 处理带选项的字段(如checkbox、radio、select等)
if (item.containsKey("options") && item.get("options") instanceof JSONArray) {
JSONArray options = item.getJSONArray("options");
Map<String, String> valueToLabelMap = new HashMap<>();
for (int j = 0; j < options.size(); j++) {
JSONObject option = options.getJSONObject(j);
if (option.containsKey("value") && option.containsKey("label")) {
String value = option.getStr("value");
String label = option.getStr("label");
valueToLabelMap.put(value, label);
}
}
if (!valueToLabelMap.isEmpty()) {
optionsMap.put(field, valueToLabelMap);
}
}
// 处理树形控件
if ("tree".equals(type) && item.containsKey("props")) {
JSONObject props = item.getJSONObject("props");
if (props.containsKey("data") && props.get("data") instanceof JSONArray) {
List<TreeNode> treeNodes = parseTreeData(props.getJSONArray("data"));
treeDataMap.put(field, treeNodes);
}
}
}
}
}
/**
* 从formConfig JSONObject中提取所有表单字段的详细信息
*
* @param formConfigJson formConfig JSONObject对象
* @return 字段信息列表,每个字段包含其所有属性
* @throws Exception 解析异常
*/
public static List<Map<String, Object>> extractFormFields(JSONObject formConfigJson) throws Exception {
ObjectMapper mapper = new ObjectMapper();
// 从JSONObject获取rule字符串
String ruleStr = formConfigJson.getStr("rule");
// 解析rule
JsonNode ruleNode = mapper.readTree(ruleStr);
// 提取字段信息
List<Map<String, Object>> fieldsList = new ArrayList<>();
traverseAndCollectFields(ruleNode, fieldsList);
return fieldsList;
}
/**
* 递归遍历表单规则结构,收集所有的字段信息
*
* @param node 当前节点
* @param fieldsList 收集字段的列表
*/
private static void traverseAndCollectFields(JsonNode node, List<Map<String, Object>> fieldsList) {
if (node.isArray()) {
// 处理数组节点
for (JsonNode item : node) {
traverseAndCollectFields(item, fieldsList);
}
} else if (node.isObject()) {
// 检查是否是表单字段(具有field和title属性的节点)
if (node.has("field") && node.has("title")) {
Map<String, Object> fieldInfo = new HashMap<>();
// 遍历当前节点的所有属性并保存
node.fields().forEachRemaining(entry -> {
String key = entry.getKey();
JsonNode value = entry.getValue();
if (value.isTextual()) {
fieldInfo.put(key, value.asText());
} else if (value.isBoolean()) {
fieldInfo.put(key, value.asBoolean());
} else if (value.isInt()) {
fieldInfo.put(key, value.asInt());
} else if (value.isObject() || value.isArray()) {
// 对于复杂对象,转换为字符串
fieldInfo.put(key, value.toString());
}
});
fieldsList.add(fieldInfo);
}
// 递归处理子节点
if (node.has("children")) {
traverseAndCollectFields(node.get("children"), fieldsList);
}
}
}
private static void processColumnValue(FieldInfo columnFieldInfo, Object columnValue,
Map<String, Map<String, String>> optionsMap,
Map<String, List<TreeNode>> treeDataMap) {
// 处理复选框和选择器
if (columnValue instanceof List && optionsMap.containsKey(columnFieldInfo.getTitle())) {
List<String> values = (List<String>) columnValue;
Map<String, String> options = optionsMap.get(columnFieldInfo.getTitle());
List<String> labels = values.stream()
.map(v -> options.getOrDefault(v, v))
.collect(Collectors.toList());
columnFieldInfo.setDisplayValue(String.join(", ", labels));
}
// 处理单选框
else if (columnValue instanceof String && optionsMap.containsKey(columnFieldInfo.getKey())) {
Map<String, String> options = optionsMap.get(columnFieldInfo.getTitle());
String valueStr = (String) columnValue;
columnFieldInfo.setDisplayValue(options.getOrDefault(valueStr, valueStr));
}
// 处理树形控件
else if (columnValue instanceof List && treeDataMap.containsKey(columnFieldInfo.getTitle())) {
List<String> selectedIds = (List<String>) columnValue;
List<TreeNode> treeNodes = treeDataMap.get(columnFieldInfo.getTitle());
Map<String, String> idToLabelMap = new HashMap<>();
buildIdToLabelMap(treeNodes, idToLabelMap);
List<String> labels = selectedIds.stream()
.map(id -> idToLabelMap.getOrDefault(id, id))
.collect(Collectors.toList());
columnFieldInfo.setDisplayValue(String.join(", ", labels));
}
// 处理普通文本字段
else {
columnFieldInfo.setDisplayValue(columnValue != null ? columnValue.toString() : "");
}
}
/**
* 使用示例
*/
public static void main(String[] args) {
// 表单数据
String formDataJson = """
{"F7m3m8744w1nb7c": [{"F93zm8744xc3bcc": "1", "Fifam87455auboc": "2", "Fp5mm8745476blc": "1"}, {"F93zm8744xc3bcc": "2", "Fifam87455auboc": "3", "Fp5mm8745476blc": "2"}], "Fc4lm87457knbuc": "2", "Fkdtm87456owbrc": "1"}
""";
// 规则数据 (这里应该是完整的规则JSON字符串)
String ruleJson = """
{"rule": "[{\\"type\\":\\"tableForm\\",\\"field\\":\\"F7m3m8744w1nb7c\\",\\"title\\":\\"表格表单\\",\\"info\\":\\"\\",\\"props\\":{\\"columns\\":[{\\"label\\":\\"自定义名称\\",\\"required\\":false,\\"style\\":{\\"width\\":\\"auto\\"},\\"rule\\":[{\\"type\\":\\"input\\",\\"field\\":\\"F93zm8744xc3bcc\\",\\"title\\":\\"输入框\\",\\"info\\":\\"\\",\\"$required\\":false,\\"_fc_id\\":\\"id_Fklbm8744xc3bdc\\",\\"name\\":\\"ref_F2g2m8744xc3bec\\",\\"display\\":true,\\"hidden\\":false,\\"_fc_drag_tag\\":\\"input\\"}]},{\\"label\\":\\"自定义名称\\",\\"required\\":false,\\"style\\":{\\"width\\":\\"auto\\"},\\"rule\\":[{\\"type\\":\\"input\\",\\"field\\":\\"Fp5mm8745476blc\\",\\"title\\":\\"输入框\\",\\"info\\":\\"\\",\\"$required\\":false,\\"_fc_id\\":\\"id_Fkb2m8745476bmc\\",\\"name\\":\\"ref_F0ntm8745476bnc\\",\\"display\\":true,\\"hidden\\":false,\\"_fc_drag_tag\\":\\"input\\"}]},{\\"label\\":\\"自定义名称\\",\\"required\\":false,\\"style\\":{\\"width\\":\\"auto\\"},\\"rule\\":[{\\"type\\":\\"radio\\",\\"field\\":\\"Fifam87455auboc\\",\\"title\\":\\"单选框\\",\\"info\\":\\"\\",\\"effect\\":{\\"fetch\\":\\"\\"},\\"$required\\":false,\\"options\\":[{\\"label\\":\\"选项01\\",\\"value\\":\\"1\\"},{\\"label\\":\\"选项02\\",\\"value\\":\\"2\\"},{\\"label\\":\\"选项03\\",\\"value\\":\\"3\\"}],\\"_fc_id\\":\\"id_Fl2im87455aubpc\\",\\"name\\":\\"ref_Fz4em87455aubqc\\",\\"display\\":true,\\"hidden\\":false,\\"_fc_drag_tag\\":\\"radio\\"}]}]},\\"_fc_id\\":\\"id_F7eym8744w1nb8c\\",\\"name\\":\\"ref_Fj8jm8744w1nb9c\\",\\"$required\\":false,\\"display\\":true,\\"hidden\\":false,\\"_fc_drag_tag\\":\\"tableForm\\"},{\\"type\\":\\"input\\",\\"field\\":\\"Fkdtm87456owbrc\\",\\"title\\":\\"输入框\\",\\"info\\":\\"\\",\\"$required\\":true,\\"_fc_id\\":\\"id_F1hjm87456owbsc\\",\\"name\\":\\"ref_Fsj4m87456owbtc\\",\\"display\\":true,\\"hidden\\":false,\\"_fc_drag_tag\\":\\"input\\"},{\\"type\\":\\"input\\",\\"field\\":\\"Fc4lm87457knbuc\\",\\"title\\":\\"输入框\\",\\"info\\":\\"\\",\\"$required\\":true,\\"_fc_id\\":\\"id_F592m87457knbvc\\",\\"name\\":\\"ref_Fxu3m87457knbwc\\",\\"display\\":true,\\"hidden\\":false,\\"_fc_drag_tag\\":\\"input\\"}]", "options": "{\\"form\\":{\\"inline\\":false,\\"hideRequiredAsterisk\\":false,\\"labelPosition\\":\\"right\\",\\"size\\":\\"default\\",\\"labelWidth\\":\\"125px\\"},\\"language\\":{},\\"resetBtn\\":{\\"show\\":false,\\"innerText\\":\\"重置\\"},\\"submitBtn\\":{\\"show\\":false,\\"innerText\\":\\"提交\\"}}"}
""";
JSONObject config = JSONUtil.parseObj(ruleJson);
// 解析字段信息
Map<String, FieldInfo> fieldInfoMap = parseFormFields(config, formDataJson);
// 打印结果
for (Map.Entry<String, FieldInfo> entry : fieldInfoMap.entrySet()) {
System.out.println("字段: " + entry.getKey());
System.out.println("标题: " + entry.getValue().getTitle());
System.out.println("类型: " + entry.getValue().getType());
System.out.println("原始值: " + entry.getValue().getValue());
System.out.println("显示值: " + entry.getValue().getDisplayValue());
System.out.println("表格数据: " + entry.getValue().getTableData());
System.out.println("---");
}
}
}
@@ -0,0 +1,321 @@
package com.budwk.app.base.utils;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class DynamicFormFieldParserUtil2 {
@Data
public static class FieldInfo {
private String title; // 标题
private String type; // 字段类型
private Object value; // 字段值
private String info; // 字段说明
private Boolean required; // 是否必填
private String displayValue; // 用于显示的值(label
}
/**
* 解析表单规则和数据
* @param config 表单规则JSON对象
* @param formDataJson 表单数据JSON字符串
* @return 字段信息Map
*/
public static Map<String, FieldInfo> parseFormFields(JSONObject config, String formDataJson) {
Map<String, FieldInfo> fieldInfoMap = new HashMap<>();
// 解析表单数据
JSONObject formData = JSONUtil.parseObj(formDataJson);
// 解析规则
JSONArray rules = JSONUtil.parseArray(config.getStr("rule"));
// 保存字段选项映射(value -> label
Map<String, Map<String, String>> optionsMap = new HashMap<>();
// 保存树形数据
Map<String, List<TreeNode>> treeDataMap = new HashMap<>();
// 先提取字段信息和选项映射
extractFieldInfoAndOptions(rules, fieldInfoMap, optionsMap, treeDataMap);
// 添加表单值并处理显示值
for (Map.Entry<String, Object> entry : formData.entrySet()) {
String field = entry.getKey();
Object value = entry.getValue();
if (fieldInfoMap.containsKey(field)) {
FieldInfo fieldInfo = fieldInfoMap.get(field);
fieldInfo.setValue(value);
// 处理checkbox、select等选项类控件
if (value instanceof List && optionsMap.containsKey(field)) {
List<String> values = (List<String>) value;
Map<String, String> options = optionsMap.get(field);
List<String> labels = values.stream()
.map(v -> options.getOrDefault(v, v))
.collect(Collectors.toList());
fieldInfo.setDisplayValue(String.join(", ", labels));
}
// 处理单选
else if (value instanceof String && optionsMap.containsKey(field)) {
Map<String, String> options = optionsMap.get(field);
String valueStr = (String) value;
fieldInfo.setDisplayValue(options.getOrDefault(valueStr, valueStr));
}
// 处理树形控件
else if (value instanceof List && treeDataMap.containsKey(field)) {
List<String> selectedIds = (List<String>) value;
List<TreeNode> treeNodes = treeDataMap.get(field);
// 构建ID到Label的映射
Map<String, String> idToLabelMap = new HashMap<>();
buildIdToLabelMap(treeNodes, idToLabelMap);
// 将ID转换为对应的Label
List<String> labels = selectedIds.stream()
.map(id -> idToLabelMap.getOrDefault(id, id))
.collect(Collectors.toList());
fieldInfo.setDisplayValue(String.join(", ", labels));
} else {
// 对于普通文本字段,显示值与值相同
fieldInfo.setDisplayValue(value != null ? value.toString() : "");
}
}
}
return fieldInfoMap;
}
/**
* 树节点结构
*/
@Data
private static class TreeNode {
private String id;
private String label;
private List<TreeNode> children;
}
/**
* 递归构建ID到Label的映射
*/
private static void buildIdToLabelMap(List<TreeNode> nodes, Map<String, String> idToLabelMap) {
if (nodes == null) return;
for (TreeNode node : nodes) {
if (node.getId() != null && node.getLabel() != null) {
idToLabelMap.put(node.getId(), node.getLabel());
}
buildIdToLabelMap(node.getChildren(), idToLabelMap);
}
}
/**
* 递归解析树节点
*/
private static List<TreeNode> parseTreeData(JSONArray treeData) {
List<TreeNode> result = new ArrayList<>();
for (int i = 0; i < treeData.size(); i++) {
JSONObject item = treeData.getJSONObject(i);
TreeNode node = new TreeNode();
node.setId(item.getStr("id"));
node.setLabel(item.getStr("label"));
if (item.containsKey("children") && item.get("children") instanceof JSONArray) {
node.setChildren(parseTreeData(item.getJSONArray("children")));
}
result.add(node);
}
return result;
}
/**
* 递归提取字段信息和选项映射
*/
private static void extractFieldInfoAndOptions(JSONArray items, Map<String, FieldInfo> fieldInfoMap,
Map<String, Map<String, String>> optionsMap,
Map<String, List<TreeNode>> treeDataMap) {
for (int i = 0; i < items.size(); i++) {
JSONObject item = items.getJSONObject(i);
// 如果有子元素,递归处理
if (item.containsKey("children")) {
extractFieldInfoAndOptions(item.getJSONArray("children"), fieldInfoMap, optionsMap, treeDataMap);
}
// 提取字段信息
if (item.containsKey("field") && item.containsKey("title")) {
String field = item.getStr("field");
String type = item.getStr("type");
FieldInfo fieldInfo = new FieldInfo();
fieldInfo.setTitle(item.getStr("title"));
fieldInfo.setType(type);
fieldInfo.setInfo(item.getStr("info"));
// 处理必填字段
Object required = item.get("$required");
if (required != null) {
if (required instanceof Boolean) {
fieldInfo.setRequired((Boolean) required);
} else {
fieldInfo.setRequired(true); // 如果$required存在但不是布尔值,视为必填
}
}
fieldInfoMap.put(field, fieldInfo);
// 处理带选项的字段(如checkbox、radio、select等)
if (item.containsKey("options") && item.get("options") instanceof JSONArray) {
JSONArray options = item.getJSONArray("options");
Map<String, String> valueToLabelMap = new HashMap<>();
for (int j = 0; j < options.size(); j++) {
JSONObject option = options.getJSONObject(j);
if (option.containsKey("value") && option.containsKey("label")) {
String value = option.getStr("value");
String label = option.getStr("label");
valueToLabelMap.put(value, label);
}
}
if (!valueToLabelMap.isEmpty()) {
optionsMap.put(field, valueToLabelMap);
}
}
// 处理树形控件
if ("tree".equals(type) && item.containsKey("props")) {
JSONObject props = item.getJSONObject("props");
if (props.containsKey("data") && props.get("data") instanceof JSONArray) {
List<TreeNode> treeNodes = parseTreeData(props.getJSONArray("data"));
treeDataMap.put(field, treeNodes);
}
}
}
}
}
/**
* 从formConfig JSONObject中提取所有表单字段的详细信息
*
* @param formConfigJson formConfig JSONObject对象
* @return 字段信息列表,每个字段包含其所有属性
* @throws Exception 解析异常
*/
public static List<Map<String, Object>> extractFormFields(JSONObject formConfigJson) throws Exception {
ObjectMapper mapper = new ObjectMapper();
// 从JSONObject获取rule字符串
String ruleStr = formConfigJson.getStr("rule");
// 解析rule
JsonNode ruleNode = mapper.readTree(ruleStr);
// 提取字段信息
List<Map<String, Object>> fieldsList = new ArrayList<>();
traverseAndCollectFields(ruleNode, fieldsList);
return fieldsList;
}
/**
* 递归遍历表单规则结构,收集所有的字段信息
*
* @param node 当前节点
* @param fieldsList 收集字段的列表
*/
private static void traverseAndCollectFields(JsonNode node, List<Map<String, Object>> fieldsList) {
if (node.isArray()) {
// 处理数组节点
for (JsonNode item : node) {
traverseAndCollectFields(item, fieldsList);
}
} else if (node.isObject()) {
// 检查是否是表单字段(具有field和title属性的节点)
if (node.has("field") && node.has("title")) {
Map<String, Object> fieldInfo = new HashMap<>();
// 遍历当前节点的所有属性并保存
node.fields().forEachRemaining(entry -> {
String key = entry.getKey();
JsonNode value = entry.getValue();
if (value.isTextual()) {
fieldInfo.put(key, value.asText());
} else if (value.isBoolean()) {
fieldInfo.put(key, value.asBoolean());
} else if (value.isInt()) {
fieldInfo.put(key, value.asInt());
} else if (value.isObject() || value.isArray()) {
// 对于复杂对象,转换为字符串
fieldInfo.put(key, value.toString());
}
});
fieldsList.add(fieldInfo);
}
// 递归处理子节点
if (node.has("children")) {
traverseAndCollectFields(node.get("children"), fieldsList);
}
}
}
/**
* 使用示例
*/
public static void main(String[] args) {
// 表单数据
String formDataJson = """
{
"F0qpm83seg72c8c": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13"],
"F9epm83rypzsazc": ["1", "2"],
"Fctxm83ryd5catc": "1",
"Fdqgm83scr4ebgc": "11",
"Frhum83scsvabjc": "1"
}
""";
// 规则数据 (这里应该是完整的规则JSON字符串)
String ruleJson = """
{
"rule": "[{\\"type\\":\\"input\\",\\"field\\":\\"Fctxm83ryd5catc\\",\\"title\\":\\"孩子身份证\\",\\"info\\":\\"\\",\\"$required\\":false,\\"_fc_id\\":\\"id_F6d7m83ryd5cauc\\",\\"name\\":\\"ref_Filom83ryd5davc\\",\\"display\\":true,\\"hidden\\":false,\\"_fc_drag_tag\\":\\"input\\"},{\\"type\\":\\"checkbox\\",\\"field\\":\\"F9epm83rypzsazc\\",\\"title\\":\\"衣服尺码\\",\\"info\\":\\"\\",\\"effect\\":{\\"fetch\\":\\"\\"},\\"$required\\":true,\\"options\\":[{\\"label\\":\\"M\\",\\"value\\":\\"1\\"},{\\"label\\":\\"L\\",\\"value\\":\\"2\\"},{\\"label\\":\\"XL\\",\\"value\\":\\"3\\"}],\\"_fc_id\\":\\"id_F6zwm83rypzsb0c\\",\\"name\\":\\"ref_F0x3m83rypzsb1c\\",\\"display\\":true,\\"hidden\\":false,\\"_fc_drag_tag\\":\\"checkbox\\"},{\\"type\\":\\"fcRow\\",\\"children\\":[{\\"type\\":\\"col\\",\\"props\\":{\\"span\\":12},\\"children\\":[{\\"type\\":\\"input\\",\\"field\\":\\"Fdqgm83scr4ebgc\\",\\"title\\":\\"输入框\\",\\"info\\":\\"\\",\\"$required\\":false,\\"_fc_id\\":\\"id_F97bm83scr4ebhc\\",\\"name\\":\\"ref_Fbljm83scr4ebic\\",\\"display\\":true,\\"hidden\\":false,\\"_fc_drag_tag\\":\\"input\\"}],\\"_fc_id\\":\\"id_Fip5m83sclr8bcc\\",\\"name\\":\\"ref_Fhxvm83sclr8bdc\\",\\"display\\":true,\\"hidden\\":false,\\"_fc_drag_tag\\":\\"col\\"},{\\"type\\":\\"col\\",\\"props\\":{\\"span\\":12},\\"children\\":[{\\"type\\":\\"input\\",\\"field\\":\\"Frhum83scsvabjc\\",\\"title\\":\\"输入框\\",\\"info\\":\\"\\",\\"$required\\":false,\\"_fc_id\\":\\"id_Fdaqm83scsvabkc\\",\\"name\\":\\"ref_Fagdm83scsvablc\\",\\"display\\":true,\\"hidden\\":false,\\"_fc_drag_tag\\":\\"input\\"}],\\"_fc_id\\":\\"id_Flw4m83sclr8bec\\",\\"name\\":\\"ref_F894m83sclr8bfc\\",\\"display\\":true,\\"hidden\\":false,\\"_fc_drag_tag\\":\\"col\\"}],\\"_fc_id\\":\\"id_Fpqmm83sclr7bac\\",\\"name\\":\\"ref_Fo5ym83sclr7bbc\\",\\"display\\":true,\\"hidden\\":false,\\"_fc_drag_tag\\":\\"fcRow\\"},{\\"type\\":\\"tree\\",\\"field\\":\\"F0qpm83seg72c8c\\",\\"title\\":\\"树形控件\\",\\"info\\":\\"\\",\\"effect\\":{\\"fetch\\":\\"\\"},\\"$required\\":false,\\"props\\":{\\"props\\":{\\"label\\":\\"label\\"},\\"showCheckbox\\":true,\\"nodeKey\\":\\"id\\",\\"data\\":[{\\"label\\":\\"选项201\\",\\"id\\":\\"1\\",\\"children\\":[{\\"label\\":\\"选项101\\",\\"id\\":\\"2\\",\\"children\\":[{\\"label\\":\\"选项01\\",\\"id\\":\\"3\\"},{\\"label\\":\\"选项02\\",\\"id\\":\\"4\\"},{\\"label\\":\\"选项03\\",\\"id\\":\\"5\\"}]},{\\"label\\":\\"选项102\\",\\"id\\":\\"6\\",\\"children\\":[{\\"label\\":\\"选项01\\",\\"id\\":\\"7\\"},{\\"label\\":\\"选项02\\",\\"id\\":\\"8\\"},{\\"label\\":\\"选项03\\",\\"id\\":\\"9\\"}]},{\\"label\\":\\"选项103\\",\\"id\\":\\"10\\",\\"children\\":[{\\"label\\":\\"选项01\\",\\"id\\":\\"11\\"},{\\"label\\":\\"选项02\\",\\"id\\":\\"12\\"},{\\"label\\":\\"选项03\\",\\"id\\":\\"13\\"}]}]},{\\"label\\":\\"选项202\\",\\"id\\":\\"14\\",\\"children\\":[{\\"label\\":\\"选项101\\",\\"id\\":\\"15\\",\\"children\\":[{\\"label\\":\\"选项01\\",\\"id\\":\\"16\\"},{\\"label\\":\\"选项02\\",\\"id\\":\\"17\\"},{\\"label\\":\\"选项03\\",\\"id\\":\\"18\\"}]},{\\"label\\":\\"选项102\\",\\"id\\":\\"19\\",\\"children\\":[{\\"label\\":\\"选项01\\",\\"id\\":\\"20\\"},{\\"label\\":\\"选项02\\",\\"id\\":\\"21\\"},{\\"label\\":\\"选项03\\",\\"id\\":\\"22\\"}]},{\\"label\\":\\"选项103\\",\\"id\\":\\"23\\",\\"children\\":[{\\"label\\":\\"选项01\\",\\"id\\":\\"24\\"},{\\"label\\":\\"选项02\\",\\"id\\":\\"25\\"},{\\"label\\":\\"选项03\\",\\"id\\":\\"26\\"}]}]},{\\"label\\":\\"选项203\\",\\"id\\":\\"27\\",\\"children\\":[{\\"label\\":\\"选项101\\",\\"id\\":\\"28\\",\\"children\\":[{\\"label\\":\\"选项01\\",\\"id\\":\\"29\\"},{\\"label\\":\\"选项02\\",\\"id\\":\\"30\\"},{\\"label\\":\\"选项03\\",\\"id\\":\\"31\\"}]},{\\"label\\":\\"选项102\\",\\"id\\":\\"32\\",\\"children\\":[{\\"label\\":\\"选项01\\",\\"id\\":\\"33\\"},{\\"label\\":\\"选项02\\",\\"id\\":\\"34\\"},{\\"label\\":\\"选项03\\",\\"id\\":\\"35\\"}]},{\\"label\\":\\"选项103\\",\\"id\\":\\"36\\",\\"children\\":[{\\"label\\":\\"选项01\\",\\"id\\":\\"37\\"},{\\"label\\":\\"选项02\\",\\"id\\":\\"38\\"},{\\"label\\":\\"选项03\\",\\"id\\":\\"39\\"}]}]}]},\\"_fc_id\\":\\"id_Fbq9m83seg72c9c\\",\\"name\\":\\"ref_Fkgqm83seg72cac\\",\\"display\\":true,\\"hidden\\":false,\\"_fc_drag_tag\\":\\"tree\\"}]",
"options": "{\\"form\\":{\\"inline\\":false,\\"hideRequiredAsterisk\\":false,\\"labelPosition\\":\\"right\\",\\"size\\":\\"default\\",\\"labelWidth\\":\\"125px\\"},\\"language\\":{},\\"resetBtn\\":{\\"show\\":false,\\"innerText\\":\\"重置\\"},\\"submitBtn\\":{\\"show\\":false,\\"innerText\\":\\"提交\\"}}"
}
""";
JSONObject config = JSONUtil.parseObj(ruleJson);
// 解析字段信息
Map<String, FieldInfo> fieldInfoMap = parseFormFields(config, formDataJson);
// 打印结果
for (Map.Entry<String, FieldInfo> entry : fieldInfoMap.entrySet()) {
System.out.println("字段: " + entry.getKey());
System.out.println("标题: " + entry.getValue().getTitle());
System.out.println("类型: " + entry.getValue().getType());
System.out.println("原始值: " + entry.getValue().getValue());
System.out.println("显示值: " + entry.getValue().getDisplayValue());
System.out.println("---");
}
}
}
@@ -0,0 +1,41 @@
package com.budwk.app.base.utils;
import com.alibaba.excel.EasyExcelFactory;
import org.apache.poi.ss.formula.functions.T;
import java.io.File;
import java.io.InputStream;
import java.util.List;
/**
* @version 1.0
* @Author zzr
* @nameEasyExcelUtil
* @Date 2024/10/14 13:51
* @注释
*/
public class EasyExcelUtil {
public EasyExcelUtil() {
}
public static List<T> syncReadModel(String filePath, Class clazz) {
return EasyExcelFactory.read(filePath).sheet().head(clazz).doReadSync();
}
public static List<T> syncReadModel(String filePath, Class clazz, Integer sheetNo) {
return EasyExcelFactory.read(filePath).sheet(sheetNo).head(clazz).doReadSync();
}
public static List<T> syncReadModel(InputStream inputStream, Class clazz, Integer sheetNo, Integer headRowNum) {
return EasyExcelFactory.read(inputStream).sheet(sheetNo).headRowNumber(headRowNum).head(clazz).doReadSync();
}
public static List<T> syncReadModel(File file, Class clazz, Integer sheetNo, Integer headRowNum) {
return EasyExcelFactory.read(file).sheet(sheetNo).headRowNumber(headRowNum).head(clazz).doReadSync();
}
public static List<T> syncReadModel(String filePath, Class clazz, Integer sheetNo, Integer headRowNum) {
return EasyExcelFactory.read(filePath).sheet(sheetNo).headRowNumber(headRowNum).head(clazz).doReadSync();
}
}
@@ -0,0 +1,46 @@
package com.budwk.app.base.utils;
import cn.hutool.core.util.ReflectUtil;
import org.nutz.lang.util.NutMap;
import org.springframework.util.Assert;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 枚举工具类
*/
public class EnumUtil {
/**
* 将枚举转换为列表
* @param enumClass
* @return
* @param <E>
*/
public static <E> List<Map<String, Object>> transToList(Class<E> enumClass) {
Assert.isTrue(enumClass.isEnum(), String.format("%s not a enum", enumClass.getSimpleName()));
List<Map<String, Object>> result = new ArrayList<>();
E[] enumConstants = enumClass.getEnumConstants();
for (E enumConstant : enumConstants) {
Map<String, Object> map = NutMap.NEW();
// 获取枚举实例的所有字段
// Field[] fields = enumClass.getDeclaredFields();
Field[] fields = ReflectUtil.getFields(enumClass);
for (Field field : fields) {
try {
field.setAccessible(true); // 使私有字段可访问
map.put(field.getName(), field.get(enumConstant)); // 获取字段值并添加到map中
} catch (Exception e) {
// 如果无法访问字段,可以选择忽略或处理异常
e.printStackTrace();
}
}
result.add(map);
}
return result;
}
}
@@ -0,0 +1,61 @@
package com.budwk.app.base.utils;
import org.nutz.lang.util.NutMap;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Stream;
/**
* @author wizzer@qq.com
*/
public class FileUtil {
/**
* 分页获取文件列表
*
* @param basePath 目录
* @param pageNumber 页码
* @param pageSize 页大小
* @param sort 按文件名排序
* @return 列表
* @throws Exception
*/
public static NutMap readListPage(String basePath, Integer pageNumber, Integer pageSize, String sort)
throws Exception {
int offset = (pageNumber - 1) * pageSize;
int limit = pageNumber * pageSize;
long total = 0;
List<NutMap> list = new ArrayList<>();
Comparator<Path> comparator = Comparator.naturalOrder();
if ("desc".equals(sort)) {
comparator = Comparator.reverseOrder();
}
try (Stream<Path> fileList = Files.list(Paths.get(basePath))) {
total = fileList.count();
}
try (Stream<Path> fileList = Files.list(Paths.get(basePath)).sorted(comparator).skip(offset)
.limit(limit)) {
fileList.forEach(file -> {
NutMap nutMap = NutMap.NEW();
String fileName = file.getFileName().toString();
nutMap.addv("fileName", fileName);
if (Files.isDirectory(file.toAbsolutePath())) {
nutMap.addv("folder", true);
nutMap.addv("suffix", "folder");
} else {
String suffix = fileName.substring(fileName.indexOf(".") + 1).toLowerCase();
nutMap.addv("folder", false);
nutMap.addv("suffix", suffix);
}
list.add(nutMap);
});
return NutMap.NEW().addv("total", total).addv("list", list);
}
}
}
@@ -0,0 +1,85 @@
package com.budwk.app.base.utils;
import com.budwk.app.base.config.ThreadPoolConfig;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
/**
* @version 1.0
* @Author zzr
* @nameManyAddOrRenewUtil
* @Date 2024/7/24 16:16
* @注释 多线程批量新增或更新
*/
@IocBean
public class ManyAddOrRenewUtil {
@Inject
private ThreadPoolConfig threadPoolConfig;
/**
* 批量快速插入,异步执行
*
* @param list 泛型list,任意实体类集合
* @param batchSize 期望单次操作的数量,默认200
* @param <T>
*/
public <T> void asyncExecuteFastInsert(List<T> list, Integer batchSize) {
threadPoolConfig.asyncExecute(list, batchSize, "insert", true);
}
/**
* 批量插入(非快速),异步执行
*
* @param list 泛型list,任意实体类集合
* @param batchSize 期望单次操作的数量,默认200
* @param <T>
*/
public <T> void asyncExecuteInsert(List<T> list, Integer batchSize) {
threadPoolConfig.asyncExecute(list, batchSize, "insert", true);
}
/**
* 批量修改(忽略空值),异步执行
*
* @param list 泛型list,任意实体类集合
* @param batchSize 期望单次操作的数量,默认200
* @param <T>
*/
public <T> void asyncExecuteUpdateIgnoreNull(List<T> list, Integer batchSize) {
threadPoolConfig.asyncExecute(list, batchSize, "update", true);
}
/**
* 批量修改(不忽略空值),异步执行
*
* @param list 泛型list,任意实体类集合
* @param batchSize 期望单次操作的数量,默认200
* @param <T>
*/
public <T> void asyncExecuteUpdate(List<T> list, Integer batchSize) {
threadPoolConfig.asyncExecute(list, batchSize, "update", false);
}
/**
* 新增或修改,异步执行
*
* @param list 泛型list,任意实体类集合
* @param batchSize 期望单次操作的数量,默认200
* @param <T>
*/
public <T> void asyncExecuteInsertOrUpdate(List<T> list, Integer batchSize) {
threadPoolConfig.asyncExecute(list, batchSize, "insertOrUpdate", false);
}
}
@@ -0,0 +1,33 @@
package com.budwk.app.base.utils;
import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;
/**
* Created by wizzer on 2017/7/21.
*/
public class MapUtil {
/**
* 使用 Map按key进行排序
*
* @param map
* @return
*/
public static Map<String, Object> sortMapByKey(Map<String, Object> map) {
if (map == null || map.isEmpty()) {
return null;
}
Map<String, Object> sortMap = new TreeMap<>(
new MapKeyComparator());
sortMap.putAll(map);
return sortMap;
}
}
class MapKeyComparator implements Comparator<String> {
@Override
public int compare(String str1, String str2) {
return str1.compareTo(str2);
}
}
@@ -0,0 +1,99 @@
package com.budwk.app.base.utils;
import cn.hutool.core.io.FileUtil;
import com.aspose.cells.PdfSaveOptions;
import com.aspose.cells.Workbook;
import com.aspose.words.Document;
import com.aspose.words.SaveFormat;
import com.budwk.app.base.exception.BaseException;
import lombok.extern.slf4j.Slf4j;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 文档转换
*/
@Slf4j
public class OfficePlusUtil {
/**
* 转换
*
* @param sourcePath 源文件路径
* @param targetPath 目标文件路径
*/
public static void convert(String sourcePath, String targetPath) {
String suffix = FileUtil.getSuffix(sourcePath);
if (suffix.equals("doc") || suffix.equals("docx")) {
wordConvertPdf(sourcePath, targetPath);
} else if (suffix.equals("xls") || suffix.equals("xlsx")) {
excelConvertPdf(sourcePath, targetPath);
} else {
throw new BaseException("不支持的文档格式");
}
}
/**
* excel转pdf
*
* @param sourcePath 源文件路径
* @param targetPath 目标文件路径
*/
public static void excelConvertPdf(String sourcePath, String targetPath) {
FileOutputStream fileOS = null;
try {
Workbook wb = new Workbook(sourcePath);
fileOS = new FileOutputStream(targetPath);
PdfSaveOptions pdfSaveOptions = new PdfSaveOptions();
pdfSaveOptions.setOnePagePerSheet(true);
// for (int i = 0; i < 3; i++) {
// wb.getWorksheets().get(i).getHorizontalPageBreaks().clear();
// wb.getWorksheets().get(i).getVerticalPageBreaks().clear();
// }
// for (int i = 1; i < wb.getWorksheets().getCount(); i++) {
// wb.getWorksheets().get(i).setVisible(false);
// }
wb.getWorksheets().get(0).setVisible(true);
wb.save(fileOS, pdfSaveOptions);
fileOS.flush();
} catch (Exception e) {
log.info("转换pdf报错", e);
} finally {
if (fileOS != null) {
try {
fileOS.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* word转pdf
*
* @param sourcePath 源文件路径
* @param targetPath 目标文件路径
*/
public static void wordConvertPdf(String sourcePath, String targetPath) {
FileOutputStream os = null;
try {
File file = new File(targetPath);
os = new FileOutputStream(file);
Document doc = new Document(sourcePath);
doc.save(os, SaveFormat.PDF);
} catch (Exception e) {
log.info("转换pdf报错", e);
} finally {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@@ -0,0 +1,15 @@
package com.budwk.app.base.utils;
import org.nutz.lang.util.NutMap;
/**
* Created by wizzer on 2018.09
*/
public class PageUtil {
static NutMap map = NutMap.NEW().addv("ascending", "asc").addv("descending", "desc");
public static String getOrder(String key) {
return map.getString(key);
}
}
@@ -0,0 +1,68 @@
package com.budwk.app.base.utils;
import net.sourceforge.pinyin4j.PinyinHelper;
import org.nutz.ioc.loader.annotation.IocBean;
/**
* Created by wizzer on 2017/5/24.
*/
@IocBean
public class PinyinUtil {
/**
* 将汉字转换为全拼
*/
public static String getPingYin(String name) {
char[] charArray = name.toCharArray();
StringBuilder pinyin = new StringBuilder();
for (int i = 0; i < charArray.length; i++) {
if (Character.toString(charArray[i]).matches("[\\u4E00-\\u9FA5]+")) {
pinyin.append(PinyinHelper.toHanyuPinyinStringArray(charArray[i])[0]);
} else {
pinyin.append(charArray[i]);
}
}
return pinyin.toString();
}
/**
* 返回中文的首字母
*
* @param str
* @return
*/
public static String getPinYinHeadChar(String str) {
String convert = "";
for (int j = 0; j < str.length(); j++) {
char word = str.charAt(j);
String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(word);
if (pinyinArray != null) {
convert += pinyinArray[0].charAt(0);
} else {
convert += word;
}
}
return convert;
}
/**
* 将字符串转移为ASCII码
*
* @param cnStr
* @return
*/
public static String getCnASCII(String cnStr) {
StringBuffer strBuf = new StringBuffer();
byte[] bGBK = cnStr.getBytes();
for (int i = 0; i < bGBK.length; i++) {
strBuf.append(Integer.toHexString(bGBK[i] & 0xff));
}
return strBuf.toString();
}
// public static void main(String[] args) {
// System.out.println(getPingYin("綦江qq县"));
// System.out.println(getPinYinHeadChar("綦江县"));
// System.out.println(getCnASCII("綦江县"));
// }
}
@@ -0,0 +1,97 @@
package com.budwk.app.base.utils;
import lombok.extern.slf4j.Slf4j;
import org.nutz.lang.Lang;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* 为老兼容老的密码加密方式
*
* @author wizzer@qq.com
*/
@Slf4j
public class PwdUtil {
private static final String LOWERCASE = "abcdefghijklmnopqrstuvwxyz";
private static final String UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final String DIGITS = "0123456789";
private static final String SPECIAL = "!@#$%^&*()-_=+{};:,<.>";
private static final String ALL = LOWERCASE + UPPERCASE + DIGITS + SPECIAL;
private static final SecureRandom random = new SecureRandom();
public static String getPassword(String passowrd, String salt) {
byte[] bytes = hash(passowrd.getBytes(), salt.getBytes(), 1024);
if (bytes != null) {
return Lang.fixedHexString(bytes);
}
return "";
}
public static byte[] hash(byte[] bytes, byte[] salt, int hashIterations) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
if (salt != null) {
digest.reset();
digest.update(salt);
}
byte[] hashed = digest.digest(bytes);
int iterations = hashIterations - 1;
for (int i = 0; i < iterations; ++i) {
digest.reset();
hashed = digest.digest(hashed);
}
return hashed;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String generate(int length) {
if (length < 8 || length > 20) {
throw new IllegalArgumentException("密码长度必须在8到20之间");
}
List<Character> passwordChars = new ArrayList<>();
// 保证每类字符至少一个
passwordChars.add(randomCharFrom(LOWERCASE));
passwordChars.add(randomCharFrom(UPPERCASE));
passwordChars.add(randomCharFrom(DIGITS));
passwordChars.add(randomCharFrom(SPECIAL));
// 剩余位置随机填充
for (int i = passwordChars.size(); i < length; i++) {
passwordChars.add(randomCharFrom(ALL));
}
// 打乱顺序以避免固定模式
Collections.shuffle(passwordChars);
// 构建字符串
StringBuilder password = new StringBuilder();
for (char ch : passwordChars) {
password.append(ch);
}
return password.toString();
}
private static char randomCharFrom(String chars) {
return chars.charAt(random.nextInt(chars.length()));
}
// 示例主方法
public static void main(String[] args) {
System.out.println("生成的密码: " + generate(12));
}
}
@@ -0,0 +1,32 @@
package com.budwk.app.base.utils;
import org.nutz.lang.Lang;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* Created by wizzer on 2018/6/28.
*/
public class SignUtil {
public static String createSign(String appkey, Map<String, Object> params) {
Map<String, Object> map = MapUtil.sortMapByKey(params);
StringBuffer sb = new StringBuffer();
Set<String> keySet = map.keySet();
Iterator<String> it = keySet.iterator();
while (it.hasNext()) {
String k = it.next();
String v = (String) map.get(k);
if (null != v && !"".equals(v)
&& !"sign".equals(k)) {
sb.append(k + "=" + v + "&");
}
}
sb.append("appkey=" + appkey);
String sign = Lang.md5(sb.toString());
return sign;
}
}
@@ -0,0 +1,86 @@
package com.budwk.app.base.utils;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.json.JsonFormat;
import org.nutz.lang.Strings;
import java.util.Random;
/**
* Created by wizzer on 2018/3/17.
*/
public class StringUtil {
/**
* 去掉URL中?后的路径
*
* @param p
* @return
*/
public static String getPath(String p) {
if (Strings.sNull(p).contains("?")) {
return p.substring(0, p.indexOf("?"));
}
return Strings.sNull(p);
}
/**
* 获得父节点ID
*
* @param s
* @return
*/
public static String getParentId(String s) {
if (!Strings.isEmpty(s) && s.length() > 4) {
return s.substring(0, s.length() - 4);
}
return "";
}
/**
* 得到n位随机数
*
* @param s
* @return
*/
public static String getRndNumber(int s) {
Random ra = new Random();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s; i++) {
sb.append(String.valueOf(ra.nextInt(8)));
}
return sb.toString();
}
/**
* 判断是否以字符串开头
*
* @param str
* @param s
* @return
*/
public boolean startWith(String str, String s) {
return Strings.sNull(str).startsWith(Strings.sNull(s));
}
/**
* 判断是否包含字符串
*
* @param str
* @param s
* @return
*/
public boolean contains(String str, String s) {
return Strings.sNull(str).contains(Strings.sNull(s));
}
/**
* 将对象转为JSON字符串(页面上使用)
*
* @param obj
* @return
*/
public String toJson(Object obj) {
return Json.toJson(obj, JsonFormat.compact());
}
}
@@ -0,0 +1,140 @@
package com.budwk.app.base.utils;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.exception.BaseException;
import com.budwk.app.sys.models.Sys_file;
import com.budwk.app.sys.models.Sys_office_template;
import com.budwk.app.sys.utils.SysFileMinIoUtil;
import com.deepoove.poi.data.ByteArrayPictureRenderData;
import com.deepoove.poi.data.PictureRenderData;
import com.deepoove.poi.data.PictureType;
import com.deepoove.poi.data.style.PictureStyle;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 系统导出模板管理工具类
*/
@Slf4j
@IocBean
public class SysOfficeTemplateUtil {
@Inject
private Dao dao;
/**
* 获取模板文件输入流
*
* @param templateCode 模板编码
*/
public InputStream getTemplate(String templateCode) {
Sys_office_template officeTemplate = dao.fetch(Sys_office_template.class, Cnd.where(Sys_office_template::getTemplateCode, "=", templateCode));
if (ObjectUtil.isNull(officeTemplate)) {
throw new BaseException("代码为:{}的模板不存在", templateCode);
}
String templatePath = officeTemplate.getTemplatePath();
int startIndex = templatePath.indexOf("id=") + "id=".length();
String id = templatePath.substring(startIndex);
Sys_file sysFile = dao.fetch(Sys_file.class, id);
if (ObjectUtil.isEmpty(sysFile)) {
throw new BaseException("模板文件不存在");
}
byte[] fileBytes = SysFileMinIoUtil.getFileBytes(sysFile.getBucket(), sysFile.getStoragePath());
return new ByteArrayInputStream(fileBytes);
}
/**
* 签字url转换为poi的图片对象
*
* @param width 宽度
* @param height 高度
* @param url url
* @return
*/
public PictureRenderData createPictureRenderData(int width, int height, String url) {
try {
byte[] bytes = getFileBytesByUrl(url);
// if (StrUtil.isBlank(url)) {
// return null;
// }
// int startIndex = url.indexOf("id=") + "id=".length();
// String id = url.substring(startIndex);
// Sys_file sysFile = dao.fetch(Sys_file.class, id);
// byte[] bytes = SysFileMinIoUtil.getFileBytes(sysFile.getBucket(), sysFile.getStoragePath());
ByteArrayPictureRenderData pictureRenderData = new ByteArrayPictureRenderData(bytes, PictureType.PNG);
PictureStyle pictureStyle = new PictureStyle();
pictureStyle.setWidth(width);
pictureStyle.setHeight(height);
pictureRenderData.setPictureStyle(pictureStyle);
return pictureRenderData;
} catch (Exception e) {
log.error("文件转换PictureRenderData错误,文件路径:{},{}", url, e.getMessage());
return null;
}
}
public PictureRenderData createPictureRenderData(String url) {
return createPictureRenderData(70, 30, url);
}
/**
* 将富文本转换为doc文本 富文本里的图片是链接 需要转换成base64格式
*
* @return
*/
public String convertRichTextToDocText(String text) {
if (StrUtil.isBlank(text)) {
return text;
}
try {
Pattern pattern = Pattern.compile("(<img\\s+[^>]*src\\s*=\\s*[\"'])(/platform/sys/file/download\\?id=.*?)(\"[^>]*>)", Pattern.CASE_INSENSITIVE);
Matcher briefMatcher = pattern.matcher(text);
StringBuilder briefResult = new StringBuilder();
while (briefMatcher.find()) {
String originalSrc = briefMatcher.group(2);
byte[] image = createPictureRenderData(originalSrc).readPictureData();
String base64 = cn.hutool.core.codec.Base64.encodeStr(image, false, false);
String base64Src = "data:image/png;base64," + base64;
String newImgTag = briefMatcher.group(1) + base64Src + briefMatcher.group(3);
briefMatcher.appendReplacement(briefResult, Matcher.quoteReplacement(newImgTag));
}
briefMatcher.appendTail(briefResult);
return briefResult.toString();
} catch (Exception e) {
log.error("富文本转换为doc文本错误,富文本:{}", text);
return text;
}
}
/**
* 根据url获取文件字节数组 minio
*
* @param url
* @return
*/
public byte[] getFileBytesByUrl(String url) {
try {
if (StrUtil.isBlank(url)) {
return null;
}
int startIndex = url.indexOf("id=") + "id=".length();
String id = url.substring(startIndex);
Sys_file sysFile = dao.fetch(Sys_file.class, id);
return SysFileMinIoUtil.getFileBytes(sysFile.getBucket(), sysFile.getStoragePath());
} catch (Exception e) {
return null;
}
}
}
@@ -0,0 +1,33 @@
package com.budwk.app.base.utils;
import org.nutz.json.JsonFormat;
import org.nutz.lang.Encoding;
import org.nutz.mvc.view.UTF8JsonView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author wizzer@qq.com
*/
public class WebUtil {
public static String AjaxEncode = Encoding.UTF8;
public static boolean isAjax(HttpServletRequest req) {
String value = req.getHeader("X-Requested-With");
return value != null && "XMLHttpRequest".equalsIgnoreCase(value.trim());
}
public static void rendAjaxResp(HttpServletRequest req, HttpServletResponse resp, Object re) {
try {
if (AjaxEncode != null) {
resp.setCharacterEncoding(AjaxEncode);
}
(new UTF8JsonView(JsonFormat.compact())).render(req, resp, re);
} catch (IOException e) {
e.printStackTrace();
}
}
}