统一ForkJoinPool调用

This commit is contained in:
WeiXiao
2026-06-26 11:36:31 +08:00
parent 778923de37
commit 4263c23147
7 changed files with 196 additions and 265 deletions

View File

@@ -32,8 +32,6 @@ import com.jeelowcode.framework.utils.utils.FuncBase;
import org.apache.commons.collections4.map.LinkedMap;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.stream.Collectors;
/**
@@ -83,30 +81,20 @@ public class ButtonReceiverBase {
Set<String> webViewFieldSet = new HashSet<>(formService.getWebViewFieldList(dbFormId));
Map<String, DbFormRoleFieldVo> finalRoleDisableMap = roleDisableMap;
ForkJoinPool pool = null;
try {
pool = FuncBase.jeelowcodeForkJoinPool();
pool.submit(() -> records.parallelStream().forEach(recordMap -> recordMap.keySet().removeIf(key -> {
if(Func.equals(key,"jeelowcode_subtable_data") || Func.equals(key,"hasChildren") || Func.equals(key,"leaf")){
return false;
}
boolean noRoleFlag=false;
if(Func.isNotEmpty(finalRoleDisableMap) && finalRoleDisableMap.containsKey(key)){
DbFormRoleFieldVo roleVo = finalRoleDisableMap.get(key);
//如果全部为空话,看最大的那个,最大的那个为N说明是没有权限需要剔除
if(Func.isEmpty(roleVo.getFormIsEdit()) && Func.isEmpty(roleVo.getFormIsView()) && Func.isEmpty(roleVo.getListIsView())&&Func.equals(roleVo.getEnableState(),YNEnum.N.getCode())){
noRoleFlag=true;
}
}
return !webViewFieldSet.contains(key) || noRoleFlag;
}))).get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e.getMessage());
} finally {
if (pool != null) {
pool.shutdown();
FuncBase.parallelExecute(() -> records.parallelStream().forEach(recordMap -> recordMap.keySet().removeIf(key -> {
if(Func.equals(key,"jeelowcode_subtable_data") || Func.equals(key,"hasChildren") || Func.equals(key,"leaf")){
return false;
}
}
boolean noRoleFlag=false;
if(Func.isNotEmpty(finalRoleDisableMap) && finalRoleDisableMap.containsKey(key)){
DbFormRoleFieldVo roleVo = finalRoleDisableMap.get(key);
//如果全部为空话,看最大的那个,最大的那个为N说明是没有权限需要剔除
if(Func.isEmpty(roleVo.getFormIsEdit()) && Func.isEmpty(roleVo.getFormIsView()) && Func.isEmpty(roleVo.getListIsView())&&Func.equals(roleVo.getEnableState(),YNEnum.N.getCode())){
noRoleFlag=true;
}
}
return !webViewFieldSet.contains(key) || noRoleFlag;
})));
}
/**

View File

@@ -37,8 +37,6 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
@Tag(name = "低代码框架-公共框架接口")
public class BaseController {
@@ -328,32 +326,22 @@ public class BaseController {
protected void formatFormEntityPageVo(List<FormEntityPageVo> records, IFormService dbFormService){
ForkJoinPool pool = null;
try {
pool = FuncBase.jeelowcodeForkJoinPool();
pool.submit(() -> records.parallelStream().forEach(vo ->{
Map<String, Object> couMap = dbFormService.getFormCou(vo.getId());
Integer js_cou = Func.getMap2IntDefault(couMap, "js_cou",0);
Integer scss_cou = Func.getMap2IntDefault(couMap, "scss_cou",0);
Integer button_cou = Func.getMap2IntDefault(couMap, "button_cou",0);
Integer java_cou = Func.getMap2IntDefault(couMap, "java_cou",0);
Integer sql_cou = Func.getMap2IntDefault(couMap, "sql_cou",0);
Integer field_cou = Func.getMap2IntDefault(couMap, "field_cou",0);
FuncBase.parallelExecute(() -> records.parallelStream().forEach(vo ->{
Map<String, Object> couMap = dbFormService.getFormCou(vo.getId());
Integer js_cou = Func.getMap2IntDefault(couMap, "js_cou",0);
Integer scss_cou = Func.getMap2IntDefault(couMap, "scss_cou",0);
Integer button_cou = Func.getMap2IntDefault(couMap, "button_cou",0);
Integer java_cou = Func.getMap2IntDefault(couMap, "java_cou",0);
Integer sql_cou = Func.getMap2IntDefault(couMap, "sql_cou",0);
Integer field_cou = Func.getMap2IntDefault(couMap, "field_cou",0);
vo.setJsCou(js_cou);
vo.setScssCou(scss_cou);
vo.setButtonCou(button_cou);
vo.setJavaCou(java_cou);
vo.setSqlCou(sql_cou);
vo.setFieldCou(field_cou);
})).get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e.getMessage());
} finally {
if (pool != null) {
pool.shutdown();
}
}
vo.setJsCou(js_cou);
vo.setScssCou(scss_cou);
vo.setButtonCou(button_cou);
vo.setJavaCou(java_cou);
vo.setSqlCou(sql_cou);
vo.setFieldCou(field_cou);
}));
}
//导出Excel数据

View File

@@ -65,8 +65,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.stream.Collectors;
@Tag(name = "低代码框架-框架接口")
@@ -233,60 +231,50 @@ public class DbFormController extends BaseController {
}
Map<String, List<Map<String, Object>>> resultMap = new ConcurrentHashMap<>();
ForkJoinPool pool = null;
try {
pool = FuncBase.jeelowcodeForkJoinPool();
pool.submit(() -> labelParamList.parallelStream().forEach(labelParam ->{
Long dbformId = labelParam.getDbformId();
List<String> fieldList = labelParam.getFieldList();
String code = labelParam.getCode();
String label = labelParam.getLabel();
List<String> dataList = labelParam.getDataList();
List<Long> userIdList = labelParam.getUserIdList();//用户id
List<Long> deptIdList = labelParam.getDeptIdList();//部门id
FuncBase.parallelExecute(() -> labelParamList.parallelStream().forEach(labelParam ->{
Long dbformId = labelParam.getDbformId();
List<String> fieldList = labelParam.getFieldList();
String code = labelParam.getCode();
String label = labelParam.getLabel();
List<String> dataList = labelParam.getDataList();
List<Long> userIdList = labelParam.getUserIdList();//用户id
List<Long> deptIdList = labelParam.getDeptIdList();//部门id
if (Func.isNotEmpty(dbformId)) { //自定义表
String mapKey = dbformId + "&" + label;
if (FuncBase.isEmpty(dataList)) {
List<Map<String, Object>> resultList = new ArrayList<>();
resultMap.put(FuncBase.toStr(dbformId), resultList);
return;
if (Func.isNotEmpty(dbformId)) { //自定义表
String mapKey = dbformId + "&" + label;
if (FuncBase.isEmpty(dataList)) {
List<Map<String, Object>> resultList = new ArrayList<>();
resultMap.put(FuncBase.toStr(dbformId), resultList);
return;
}
List<Map<String, Object>> resultList =new ArrayList<>();
for(String dataId:dataList){
Map<String, Object> params =new HashMap<>();
params.put(ParamEnum.DICT_TABLE_FIELD.getCode(),fieldList);
params.put(code,dataId);//id=1
params.put(ParamEnum.PAGE_NO.getCode(),1);
params.put(ParamEnum.PAGE_SIZE.getCode(),1000);
params.put(ParamEnum.ALL_QUERY_FIELD.getCode(),"Y");
ResultDataModel model = frameService.getDataList(dbformId, params);
List<Map<String, Object>> tmpList = model.getRecords();
if(Func.isEmpty(tmpList)){
continue;
}
resultList.addAll(tmpList);
}
List<Map<String, Object>> resultList =new ArrayList<>();
for(String dataId:dataList){
Map<String, Object> params =new HashMap<>();
params.put(ParamEnum.DICT_TABLE_FIELD.getCode(),fieldList);
params.put(code,dataId);//id=1
params.put(ParamEnum.PAGE_NO.getCode(),1);
params.put(ParamEnum.PAGE_SIZE.getCode(),1000);
params.put(ParamEnum.ALL_QUERY_FIELD.getCode(),"Y");
ResultDataModel model = frameService.getDataList(dbformId, params);
List<Map<String, Object>> tmpList = model.getRecords();
if(Func.isEmpty(tmpList)){
continue;
}
resultList.addAll(tmpList);
}
resultMap.put(mapKey, resultList);
}
if (Func.isNotEmpty(userIdList)) {//用户表回显
List<Map<String, Object>> userViewList = jeeLowCodeAdapter.getUserViewList(userIdList);
resultMap.put("userList", userViewList);
}
if (Func.isNotEmpty(deptIdList)) {//部门表回显
List<Map<String, Object>> deptViewList = jeeLowCodeAdapter.getDeptViewList(deptIdList);
resultMap.put("deptList", deptViewList);
}
})).get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e.getMessage());
} finally {
if (pool != null) {
pool.shutdown();
resultMap.put(mapKey, resultList);
}
}
if (Func.isNotEmpty(userIdList)) {//用户表回显
List<Map<String, Object>> userViewList = jeeLowCodeAdapter.getUserViewList(userIdList);
resultMap.put("userList", userViewList);
}
if (Func.isNotEmpty(deptIdList)) {//部门表回显
List<Map<String, Object>> deptViewList = jeeLowCodeAdapter.getDeptViewList(deptIdList);
resultMap.put("deptList", deptViewList);
}
}));
return BaseWebResult.success(resultMap);
}

View File

@@ -32,7 +32,7 @@ import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
@Tag(name = "低代码框架-报表接口")
@@ -60,25 +60,15 @@ public class ReportDataController extends BaseController {
Map<String, Object> params = FuncWeb.getParameterBodyMap(req);
List<String> reportCodeList = Func.toStrList(reportCodeListStr);
Map<String, ResultDataModel> resultMap = new ConcurrentHashMap<>();
ForkJoinPool pool = null;
try {
pool = FuncBase.jeelowcodeForkJoinPool();
pool.submit(() -> reportCodeList.parallelStream().forEach(reportCode -> {
// 处理代码
Map<String, Object> subParam = (Map) params.get(reportCode);
if (Func.isEmpty(subParam)) {
subParam = new HashMap<>();
}
ResultDataModel pages = getReportDataList(reportCode, subParam);
resultMap.put(reportCode, pages);
})).get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e.getMessage());
} finally {
if (pool != null) {
pool.shutdown();
FuncBase.parallelExecute(() -> reportCodeList.parallelStream().forEach(reportCode -> {
// 处理代码
Map<String, Object> subParam = (Map) params.get(reportCode);
if (Func.isEmpty(subParam)) {
subParam = new HashMap<>();
}
}
ResultDataModel pages = getReportDataList(reportCode, subParam);
resultMap.put(reportCode, pages);
}));
return BaseWebResult.success(resultMap);
}

View File

@@ -62,8 +62,6 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
@@ -362,46 +360,36 @@ public class FrameServiceImpl implements IFrameService {
if (Func.isNotEmpty(summaryTopList)) {
Map<Long, SummaryTopModel> topMap = new ConcurrentHashMap();
//并行流处理
ForkJoinPool pool = null;
try {
pool = FuncBase.jeelowcodeForkJoinPool();
pool.submit(() -> summaryTopList.parallelStream().forEach(summaryEntity -> {
Long id = summaryEntity.getId();
String summarySql = summaryEntity.getSummarySql();
String summaryLabel = summaryEntity.getSummaryLabel();
String summaryJson = summaryEntity.getSummaryJson();
if (Func.isEmpty(summarySql)) {
return;
}
SqlInfoQueryWrapper.Wrapper wrapper = getDataQueryWrapper(formEntity, params, false);
//拿到原sql,也就是数据源
SqlFormatModel sqlFormatModel = wrapper.buildSql();
String sql = sqlFormatModel.getSql();
Map<String, Object> sqlParams = sqlFormatModel.getDataMap();
String newSql = "";
if (summarySql.contains(JeeLowCodeConstant.JEELOWCODE_SUMMARY_TABLE)) {//需要替换数据源
newSql = summarySql.replace(JeeLowCodeConstant.JEELOWCODE_SUMMARY_TABLE, sql);
} else {//直接运行自定义sql
newSql = SqlHelper.getPublicSql(summarySql);
}
List<Map<String, Object>> dataMapList = sqlService.getDataListByPlus(newSql, sqlParams);
SummaryTopModel topModel = new SummaryTopModel();
topModel.setSummaryLabel(summaryLabel);
topModel.setSummaryJson(summaryJson);
topModel.setDataMapList(dataMapList);
topMap.put(id, topModel);
})).get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e.getMessage());
} finally {
if (pool != null) {
pool.shutdown();
FuncBase.parallelExecute(() -> summaryTopList.parallelStream().forEach(summaryEntity -> {
Long id = summaryEntity.getId();
String summarySql = summaryEntity.getSummarySql();
String summaryLabel = summaryEntity.getSummaryLabel();
String summaryJson = summaryEntity.getSummaryJson();
if (Func.isEmpty(summarySql)) {
return;
}
}
SqlInfoQueryWrapper.Wrapper wrapper = getDataQueryWrapper(formEntity, params, false);
//拿到原sql,也就是数据源
SqlFormatModel sqlFormatModel = wrapper.buildSql();
String sql = sqlFormatModel.getSql();
Map<String, Object> sqlParams = sqlFormatModel.getDataMap();
String newSql = "";
if (summarySql.contains(JeeLowCodeConstant.JEELOWCODE_SUMMARY_TABLE)) {//需要替换数据源
newSql = summarySql.replace(JeeLowCodeConstant.JEELOWCODE_SUMMARY_TABLE, sql);
} else {//直接运行自定义sql
newSql = SqlHelper.getPublicSql(summarySql);
}
List<Map<String, Object>> dataMapList = sqlService.getDataListByPlus(newSql, sqlParams);
SummaryTopModel topModel = new SummaryTopModel();
topModel.setSummaryLabel(summaryLabel);
topModel.setSummaryJson(summaryJson);
topModel.setDataMapList(dataMapList);
topMap.put(id, topModel);
}));
//按顺序取出来
summaryTopList.stream().forEach(summaryEntity -> {
Long id = summaryEntity.getId();
@@ -572,68 +560,58 @@ public class FrameServiceImpl implements IFrameService {
AtomicReference<Integer> importState = new AtomicReference<>(1);//成功
String redisKey = "excel:import:task_" + fieldId;//判断是否
AtomicReference<Boolean> breakFlag = new AtomicReference<>(false);
ForkJoinPool pool = null;
try {
pool = FuncBase.jeelowcodeForkJoinPool();
pool.submit(() -> entityList.parallelStream().forEach(entity -> {
if (breakFlag.get()) {//说明退出
return;
}
String errorReason = "";
String handleResult = "";
try {
//单条入库
Map<String, Object> dataMap = Func.json2Bean(entity.getDataJson(), Map.class);
Map<String, Object> saveDataMap = dataMap.entrySet().stream().filter(item -> fieldCodeSet.contains(item.getKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));//移除不属于数据库的列
this.handleDict(dictModel, saveDataMap);//处理字典,字典值回显
//新增入库
proxyFrameService.saveImportData(dbFormId,saveDataMap);
handleResult = "SUCCESS";
} catch (JeeLowCodeException e) {
errorReason = e.getMessage();
handleResult = "FAIL";
} catch (Exception e) {
errorReason = "数据格式有误";
handleResult = "FAIL";
}
String redisKeyData = "excel:import_data:task_" + fieldId + ":" + handleResult + ":" + entity.getId();
jeeLowCodeRedisUtils.set(redisKeyData, handleResult, 2, TimeUnit.DAYS);//存2天
//更新表
ExcelFileDataEntity updateEntity = new ExcelFileDataEntity();
updateEntity.setId(entity.getId());
updateEntity.setHandleState(YNEnum.Y.getCode());//已处理
updateEntity.setHandleResult(handleResult);
updateEntity.setHandleTime(DateUtil.date());
updateEntity.setErrorReason(errorReason);
excelDataService.updateById(updateEntity);
//判断是否存在暂停,取消
if (!jeeLowCodeRedisUtils.hasKey(redisKey)) {
return;
}
String redisVal = (String) jeeLowCodeRedisUtils.get(redisKey);
if (Func.equals(redisVal, "STOP_TASK")) {//暂停
jeeLowCodeRedisUtils.del(redisKey);
breakFlag.set(true);
} else if (Func.equals(redisVal, "CANCLE_TASK")) {//取消
jeeLowCodeRedisUtils.del(redisKey);
log.error("手动取消导入任务:" + fieldId);
breakFlag.set(true);
importState.set(-2);
}
})).get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e.getMessage());
} finally {
if (pool != null) {
pool.shutdown();
FuncBase.parallelExecute(() -> entityList.parallelStream().forEach(entity -> {
if (breakFlag.get()) {//说明退出
return;
}
}
String errorReason = "";
String handleResult = "";
try {
//单条入库
Map<String, Object> dataMap = Func.json2Bean(entity.getDataJson(), Map.class);
Map<String, Object> saveDataMap = dataMap.entrySet().stream().filter(item -> fieldCodeSet.contains(item.getKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));//移除不属于数据库的列
this.handleDict(dictModel, saveDataMap);//处理字典,字典值回显
//新增入库
proxyFrameService.saveImportData(dbFormId,saveDataMap);
handleResult = "SUCCESS";
} catch (JeeLowCodeException e) {
errorReason = e.getMessage();
handleResult = "FAIL";
} catch (Exception e) {
errorReason = "数据格式有误";
handleResult = "FAIL";
}
String redisKeyData = "excel:import_data:task_" + fieldId + ":" + handleResult + ":" + entity.getId();
jeeLowCodeRedisUtils.set(redisKeyData, handleResult, 2, TimeUnit.DAYS);//存2天
//更新表
ExcelFileDataEntity updateEntity = new ExcelFileDataEntity();
updateEntity.setId(entity.getId());
updateEntity.setHandleState(YNEnum.Y.getCode());//已处理
updateEntity.setHandleResult(handleResult);
updateEntity.setHandleTime(DateUtil.date());
updateEntity.setErrorReason(errorReason);
excelDataService.updateById(updateEntity);
//判断是否存在暂停,取消
if (!jeeLowCodeRedisUtils.hasKey(redisKey)) {
return;
}
String redisVal = (String) jeeLowCodeRedisUtils.get(redisKey);
if (Func.equals(redisVal, "STOP_TASK")) {//暂停
jeeLowCodeRedisUtils.del(redisKey);
breakFlag.set(true);
} else if (Func.equals(redisVal, "CANCLE_TASK")) {//取消
jeeLowCodeRedisUtils.del(redisKey);
log.error("手动取消导入任务:" + fieldId);
breakFlag.set(true);
importState.set(-2);
}
}));
//如果是取消的话,需要回滚事务
Integer importStateInt = importState.get();
@@ -1396,31 +1374,21 @@ public class FrameServiceImpl implements IFrameService {
if (Func.isEmpty(treeDataList)) {
return;
}
ForkJoinPool pool = null;
try {
pool = FuncBase.jeelowcodeForkJoinPool();
pool.submit(() -> treeDataList.parallelStream().forEach(dataMap -> {
Long id = Func.getMap2Long(dataMap, "id");
FuncBase.parallelExecute(() -> treeDataList.parallelStream().forEach(dataMap -> {
Long id = Func.getMap2Long(dataMap, "id");
SqlInfoQueryWrapper.Wrapper wrapper = SqlHelper.getQueryWrapper()
.setTableName(tableName)
.select("id")
.setWhere(where -> {
where.eq("is_deleted", 0);
where.eq("pid", id);
}).build();
Map<String, Object> subMap = sqlService.getDataOneByPlus(wrapper);
boolean hasChildren = Func.isNotEmpty(subMap);
dataMap.put("hasChildren", hasChildren);
dataMap.put("leaf", !hasChildren);
})).get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e.getMessage());
} finally {
if (pool != null) {
pool.shutdown();
}
}
SqlInfoQueryWrapper.Wrapper wrapper = SqlHelper.getQueryWrapper()
.setTableName(tableName)
.select("id")
.setWhere(where -> {
where.eq("is_deleted", 0);
where.eq("pid", id);
}).build();
Map<String, Object> subMap = sqlService.getDataOneByPlus(wrapper);
boolean hasChildren = Func.isNotEmpty(subMap);
dataMap.put("hasChildren", hasChildren);
dataMap.put("leaf", !hasChildren);
}));
}
//处理字典

View File

@@ -64,9 +64,6 @@ import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinWorkerThread;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@@ -402,19 +399,9 @@ public class Func extends FuncBase {
public static void handlePlusDataList(List<Map<String, Object>> records, Map<String, JeeLowCodeFieldTypeEnum> fieldTypeEnumMap) {
ForkJoinPool pool = null;
try {
pool = FuncBase.jeelowcodeForkJoinPool();
pool.submit(() -> records.parallelStream().forEach(recordMap -> {
handlePlusDataMap(recordMap, fieldTypeEnumMap);
})).get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e.getMessage());
} finally {
if (pool != null) {
pool.shutdown();
}
}
FuncBase.parallelExecute(() -> records.parallelStream().forEach(recordMap -> {
handlePlusDataMap(recordMap, fieldTypeEnumMap);
}));
}

View File

@@ -33,6 +33,7 @@ import java.math.BigDecimal;
import java.sql.Time;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinWorkerThread;
import java.util.stream.Collectors;
@@ -1072,4 +1073,25 @@ public class FuncBase {
return new ForkJoinPool(poolSize, factory, null, false);
}
/**
* 并行执行任务使用自定义ForkJoinPool
* 封装了ForkJoinPool的创建、提交、等待和关闭生命周期
* 统一管理线程池,避免重复的 try-catch-finally 模板代码
*
* @param task 要并行执行的任务
*/
public static void parallelExecute(Runnable task) {
ForkJoinPool pool = null;
try {
pool = jeelowcodeForkJoinPool();
pool.submit(task).get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e.getMessage());
} finally {
if (pool != null) {
pool.shutdown();
}
}
}
}