修改:整体问题基本修改完毕
This commit is contained in:
parent
1a8dbb0617
commit
dbfabe83be
@ -15,6 +15,8 @@ public class MyResponse {
|
||||
private Boolean flag;
|
||||
// 报错信息
|
||||
private String message;
|
||||
// 数据
|
||||
private String data;
|
||||
|
||||
|
||||
// 模板导入的错误列表
|
||||
|
||||
@ -5,6 +5,7 @@ import com.definesys.mpaas.common.http.Response;
|
||||
import com.xdap.self_development.controller.form.ApprovalUserNodeDTO;
|
||||
import com.xdap.self_development.controller.form.HandleApprovalRequest;
|
||||
import com.xdap.self_development.controller.form.HandleReturnNodeForm;
|
||||
import com.xdap.self_development.controller.form.UpdateNodeForm;
|
||||
import com.xdap.self_development.controller.request.ApprovalNodeRequest;
|
||||
import com.xdap.self_development.controller.request.EngineReviewListRequest;
|
||||
import com.xdap.self_development.exception.CommonException;
|
||||
@ -36,6 +37,34 @@ public class ActivitiProcessController {
|
||||
@Autowired
|
||||
private EngineReviewListService engineReviewListService;
|
||||
|
||||
// 修改后继续流程
|
||||
@GetMapping("/continueApproval")
|
||||
public Response continueApproval(
|
||||
@NotBlank @RequestParam String flowId,
|
||||
@NotBlank @RequestParam String userId
|
||||
) {
|
||||
activitiProcessService.continueApproval(flowId, userId);
|
||||
return Response.ok();
|
||||
}
|
||||
|
||||
// 获取可修改节点
|
||||
@GetMapping("/getEditableNodes")
|
||||
public Response getEditableNodes(
|
||||
@NotBlank @RequestParam String flowId
|
||||
) {
|
||||
List<String> nodes = activitiProcessService.getEditableNodes(flowId);
|
||||
return Response.ok().data(nodes);
|
||||
}
|
||||
|
||||
// 修改节点
|
||||
@PostMapping("/updateNode")
|
||||
public Response updateNode(
|
||||
@RequestBody UpdateNodeForm form
|
||||
) {
|
||||
activitiProcessService.updateNode(form);
|
||||
return Response.ok();
|
||||
}
|
||||
|
||||
// 修改流程主题
|
||||
@PostMapping(value = "/updateFlowTitle")
|
||||
public Response updateFlowTitle(
|
||||
|
||||
@ -25,6 +25,16 @@ public class BenchmarkingReportController {
|
||||
@Resource
|
||||
private BenchmarkingReportService benchmarkingReportService;
|
||||
|
||||
// 修改后继续流程
|
||||
@GetMapping("/continueApproval")
|
||||
public Response continueApproval(
|
||||
@NotBlank @RequestParam String flowId,
|
||||
@NotBlank @RequestParam String userId
|
||||
) {
|
||||
benchmarkingReportService.continueApproval(flowId, userId);
|
||||
return Response.ok();
|
||||
}
|
||||
|
||||
// 上传附件
|
||||
@PostMapping("/uploadFile")
|
||||
public Response uploadFile(
|
||||
|
||||
@ -37,7 +37,6 @@ public class TemplateApprovalController {
|
||||
return Response.ok();
|
||||
}
|
||||
|
||||
|
||||
// 获取可修改节点
|
||||
@GetMapping("/getEditableNodes")
|
||||
public Response getEditableNodes(
|
||||
|
||||
@ -11,8 +11,6 @@ import java.util.List;
|
||||
public class UpdateBenchmarkingReportForm {
|
||||
@NotBlank(message = "原对标报告不能为空")
|
||||
private String reportId;
|
||||
@NotBlank(message = "流程不能为空")
|
||||
private String flowId;
|
||||
|
||||
private String title;
|
||||
private String manufacturerName;
|
||||
@ -32,12 +30,6 @@ public class UpdateBenchmarkingReportForm {
|
||||
private String partsName;
|
||||
private String fileUrl;
|
||||
|
||||
@NotBlank(message = "流程标题不能为空")
|
||||
private String processTitle;
|
||||
@NotEmpty(message = "流程节点不能为空")
|
||||
private List<ApprovalNodeDTO> nodeList;
|
||||
private String explanation;
|
||||
|
||||
@NotBlank(message = "发起人不能为空")
|
||||
private String userId;
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import java.util.List;
|
||||
|
||||
@Data
|
||||
public class UpdateNodeForm {
|
||||
private String title;
|
||||
@NotBlank(message = "用户不能为空")
|
||||
private String userId;
|
||||
@NotBlank(message = "流程不能为空")
|
||||
|
||||
@ -116,7 +116,7 @@ public class EngineModelListener implements ReadListener<DataEntryEngineModelExc
|
||||
}
|
||||
log.info("所有数据解析完成!");
|
||||
}
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public void saveData() {
|
||||
|
||||
ArrayList<DataEntryEngineModelPojo> modelPojos = new ArrayList<>();
|
||||
|
||||
@ -168,7 +168,7 @@ public class EngineParamDetailListener implements ReadListener<EngineParamDetail
|
||||
// batchInsert(engineParamDetailPojos);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class) // 发生任何异常都回滚
|
||||
@Transactional // 发生任何异常都回滚
|
||||
public void batchInsert(List<EngineParamDetailPojo> engineParamDetailPojos) {
|
||||
sw.buildFromDatasource("xdap_app_223770822127386625").doBatchInsert(engineParamDetailPojos);
|
||||
}
|
||||
|
||||
@ -10,4 +10,5 @@ public class ApprovalNodesDTO {
|
||||
private String processTitle;
|
||||
private List<ApprovalUserNodeDTO> nodeList;
|
||||
private String explanation;
|
||||
private String flowId;
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ import java.util.Date;
|
||||
*/
|
||||
@SQLQuery(value = {
|
||||
@SQL(view = "selectVersionByConditionPage",
|
||||
sql = "WITH ranked_models AS ( SELECT deem.*, epd.major_version AS parameterVersion, ROW_NUMBER() OVER (PARTITION BY deem.model_name, epd.major_version ORDER BY deem.id) AS rn FROM data_entry_engine_model deem JOIN engine_param_detail epd ON deem.id = epd.engine_model_id ) SELECT * FROM ranked_models WHERE rn = 1 ORDER BY model_name, parameterVersion")
|
||||
sql = "WITH ranked_models AS ( SELECT deem.*, epd.major_version AS parameterVersion, ROW_NUMBER() OVER (PARTITION BY deem.id, epd.major_version ORDER BY deem.id) AS rn FROM data_entry_engine_model deem JOIN engine_param_detail epd ON deem.id = epd.engine_model_id ) SELECT * FROM ranked_models WHERE rn = 1 ORDER BY model_name, parameterVersion")
|
||||
})
|
||||
@Data
|
||||
public class DataEntryEngineModelDto extends MpaasBasePojo {
|
||||
|
||||
@ -6,6 +6,7 @@ import com.xdap.self_development.exception.CommonException;
|
||||
import com.xdap.self_development.pojo.ClassificationAttribute;
|
||||
import com.xdap.self_development.pojo.EnginePartsCollection;
|
||||
import com.xdap.self_development.pojo.view.CalculationParameterView;
|
||||
import com.xdap.self_development.utils.FormulaValidator;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@ -21,7 +22,6 @@ import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@Transactional(rollbackFor = CommonException.class)
|
||||
public class ParameterValueCalculationTimer {
|
||||
@Resource
|
||||
private BusinessDatabase bd;
|
||||
@ -37,6 +37,7 @@ public class ParameterValueCalculationTimer {
|
||||
|
||||
// 每天凌晨执行一次
|
||||
// @Scheduled(cron = "0 0 0 * * ?")
|
||||
@Transactional
|
||||
public MyResponse dailyCalculate() {
|
||||
MyResponse myResponse = new MyResponse();
|
||||
myResponse.setErrors(new ArrayList<>());
|
||||
@ -129,10 +130,10 @@ public class ParameterValueCalculationTimer {
|
||||
String formula = parameterValue.getNumberOrFormula();
|
||||
String modelId = parameterValue.getModelId();
|
||||
try {
|
||||
String replacedFormula = replaceParametersInFormula(formula, parameterNames, originalValueMap, modelId);
|
||||
String replacedFormula = replaceParametersInFormula(formula, parameterNames, originalValueMap, modelId, parameterValue.getParameterName());
|
||||
log.debug("机型【{}】的参数【{}】替换公式:{} -> {}",parameterValue.getProductNumber(), parameterValue.getParameterName(), formula, replacedFormula);
|
||||
Double result = calculateExpression(replacedFormula);
|
||||
String formattedResult = String.format("%.6f", result);
|
||||
String formattedResult = String.format("%.2f", result);
|
||||
parameterValue.setParameterValue(formattedResult);
|
||||
toUpdate.add(parameterValue);
|
||||
log.info("机型【{}】的参数【{}】计算结果:{}",parameterValue.getProductNumber(), parameterValue.getParameterName(), formattedResult);
|
||||
@ -159,18 +160,18 @@ public class ParameterValueCalculationTimer {
|
||||
for (CalculationParameterView parameterValue : toUpdate) {
|
||||
try {
|
||||
if (parameterValue.getParameterValue() != null) {
|
||||
// bd.getBusinessDatabase()
|
||||
// .table("engine_param_detail")
|
||||
// .eq("id", parameterValue.getId())
|
||||
// .update("parameter_value", parameterValue.getParameterValue())
|
||||
// .doUpdate();
|
||||
bd.getBusinessDatabase()
|
||||
.table("engine_param_detail")
|
||||
.eq("id", parameterValue.getId())
|
||||
.update("parameter_value", parameterValue.getParameterValue())
|
||||
.doUpdate();
|
||||
} else {
|
||||
// 对于计算失败的参数,也更新为null值
|
||||
// bd.getBusinessDatabase()
|
||||
// .table("engine_param_detail")
|
||||
// .eq("id", parameterValue.getId())
|
||||
// .update("parameter_value", null)
|
||||
// .doUpdate();
|
||||
bd.getBusinessDatabase()
|
||||
.table("engine_param_detail")
|
||||
.eq("id", parameterValue.getId())
|
||||
.update("parameter_value", null)
|
||||
.doUpdate();
|
||||
}
|
||||
updatedCount++;
|
||||
} catch (Exception e) {
|
||||
@ -198,11 +199,14 @@ public class ParameterValueCalculationTimer {
|
||||
}
|
||||
|
||||
private String replaceParametersInFormula(String formula, List<String> parameterNames,
|
||||
Map<String, Map<String, String>> valueMap, String modelId) {
|
||||
Map<String, Map<String, String>> valueMap, String modelId, String currentParameterName) {
|
||||
List<String> formulaParams = FormulaValidator.extractParameters(formula);
|
||||
String result = formula;
|
||||
result = result.replace("π", "PI").replace("PI", "Math.PI");
|
||||
result = result.replace("e", "Math.E");
|
||||
for (String paramName : parameterNames) {
|
||||
for (String paramName : formulaParams) {
|
||||
if (!parameterNames.contains(paramName)) continue;
|
||||
if (Objects.equals(paramName, currentParameterName)) continue;
|
||||
String pattern = "\\b" + Pattern.quote(paramName) + "\\b";
|
||||
String value = getParameterValue(valueMap, paramName, modelId);
|
||||
result = result.replaceAll(pattern, value);
|
||||
@ -218,7 +222,7 @@ public class ParameterValueCalculationTimer {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return "0";
|
||||
return paramName;
|
||||
}
|
||||
|
||||
private Double calculateExpression(String expression) throws RuntimeException {
|
||||
@ -275,7 +279,7 @@ public class ParameterValueCalculationTimer {
|
||||
CalculationParameterView::getParameterName,
|
||||
Collectors.toMap(
|
||||
CalculationParameterView::getModelId,
|
||||
item -> item.getParameterValue() != null ? item.getParameterValue() : "0",
|
||||
item -> item.getParameterValue() != null ? item.getParameterValue() : item.getParameterName(),
|
||||
(existing, replacement) -> replacement
|
||||
)
|
||||
));
|
||||
|
||||
@ -4,6 +4,7 @@ package com.xdap.self_development.service;
|
||||
import com.xdap.self_development.controller.form.ApprovalUserNodeDTO;
|
||||
import com.xdap.self_development.controller.form.HandleApprovalRequest;
|
||||
import com.xdap.self_development.controller.form.HandleReturnNodeForm;
|
||||
import com.xdap.self_development.controller.form.UpdateNodeForm;
|
||||
import com.xdap.self_development.controller.request.ApprovalByPlatformRequest;
|
||||
import com.xdap.self_development.controller.request.ApprovalNodeRequest;
|
||||
import com.xdap.self_development.enums.ParamValueVersionEnum;
|
||||
@ -71,4 +72,10 @@ public interface ActivitiProcessService {
|
||||
);
|
||||
|
||||
void updateFlowTitle(@NotBlank String flowId, @NotBlank String title);
|
||||
|
||||
void continueApproval(@NotBlank String flowId, @NotBlank String userId);
|
||||
|
||||
List<String> getEditableNodes(@NotBlank String flowId);
|
||||
|
||||
void updateNode(UpdateNodeForm form);
|
||||
}
|
||||
|
||||
@ -24,6 +24,8 @@ public interface BenchmarkingReportService {
|
||||
|
||||
void startReportApproval(ApprovalPersonForm form);
|
||||
|
||||
void continueApproval(@NotBlank String flowId, @NotBlank String userId);
|
||||
|
||||
void restartReportApproval(@Valid RestartReportApprovalForm form);
|
||||
|
||||
void directSendingApproval(@NotBlank String reportId, @NotBlank String userId);
|
||||
|
||||
@ -60,4 +60,6 @@ public interface TemplateApprovalService {
|
||||
List<String> getEditableNodes(@NotBlank String flowId);
|
||||
|
||||
void updateNode(UpdateNodeForm form);
|
||||
|
||||
void updateNodeConfig(UpdateNodeForm form);
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import com.xdap.self_development.common.BusinessDatabase;
|
||||
import com.xdap.self_development.controller.form.ApprovalUserNodeDTO;
|
||||
import com.xdap.self_development.controller.form.HandleApprovalRequest;
|
||||
import com.xdap.self_development.controller.form.HandleReturnNodeForm;
|
||||
import com.xdap.self_development.controller.form.UpdateNodeForm;
|
||||
import com.xdap.self_development.controller.request.ApprovalByPlatformRequest;
|
||||
import com.xdap.self_development.controller.request.ApprovalNodeRequest;
|
||||
import com.xdap.self_development.enums.ApprovalOrderEnum;
|
||||
@ -43,6 +44,8 @@ public class ActivitiProcessServiceImpl implements ActivitiProcessService {
|
||||
@Resource
|
||||
private XdapDeptUsersService xdapDeptUsersService;
|
||||
@Resource
|
||||
private TemplateApprovalService templateApprovalService;
|
||||
@Resource
|
||||
private BusinessDatabase bd;
|
||||
@Resource
|
||||
private RedisLockUtil redisLockUtil;
|
||||
@ -61,7 +64,7 @@ public class ActivitiProcessServiceImpl implements ActivitiProcessService {
|
||||
* @return 包含审批数据的DTO列表
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public List<ActivitiDataDTO> initiateApproval(String modelID, String userID) {
|
||||
// 通过机型ID查找参数过滤更新的
|
||||
List<EngineParamDetailPojo> engineParamDetailPojos;
|
||||
@ -295,7 +298,7 @@ public class ActivitiProcessServiceImpl implements ActivitiProcessService {
|
||||
* @return 审批结果描述
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public String handleApproval(HandleApprovalDTO handleApprovalDTO) {
|
||||
String approvalId = handleApprovalDTO.getApprovalId();
|
||||
String approver = handleApprovalDTO.getUserId();
|
||||
@ -518,7 +521,7 @@ public class ActivitiProcessServiceImpl implements ActivitiProcessService {
|
||||
bd.getBusinessDatabase()
|
||||
.update("current_node", status)
|
||||
.update("last_update_date", new Date())
|
||||
.update("current_processor", currentNode == null ? "" : currentNode.getAssignees())
|
||||
.update("current_processor", currentNode == null ? "" : JSON.toJSONString(currentNode.getAssignees().split(",")))
|
||||
.eq("document_no", flow.getId())
|
||||
.update("enable_return", enableReturn)
|
||||
.doUpdate(InitiatedTaskPojo.class);
|
||||
@ -526,7 +529,7 @@ public class ActivitiProcessServiceImpl implements ActivitiProcessService {
|
||||
bd.getBusinessDatabase()
|
||||
.update("current_node", status)
|
||||
.update("last_update_date", new Date())
|
||||
.update("current_processor", currentNode == null ? "" : currentNode.getAssignees())
|
||||
.update("current_processor", currentNode == null ? "" : JSON.toJSONString(currentNode.getAssignees().split(",")))
|
||||
.eq("document_no", flow.getId())
|
||||
.doUpdate(CompletedTaskPojo.class);
|
||||
}
|
||||
@ -652,7 +655,7 @@ public class ActivitiProcessServiceImpl implements ActivitiProcessService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public void updateFlowTitle(String flowId, String title) {
|
||||
EngineReviewListPojo flow = bd.getBusinessDatabase()
|
||||
.eq("id", flowId)
|
||||
@ -686,6 +689,99 @@ public class ActivitiProcessServiceImpl implements ActivitiProcessService {
|
||||
.doUpdate(InitiatedTaskPojo.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void continueApproval(String flowId, String userId) {
|
||||
EngineReviewListPojo reviewListPojo = bd.getBusinessDatabase()
|
||||
.eq("id", flowId)
|
||||
.doQueryFirst(EngineReviewListPojo.class);
|
||||
if (reviewListPojo == null) {
|
||||
throw new CommonException("流程不存在");
|
||||
}
|
||||
|
||||
// 清除原流程节点的所有待办
|
||||
bd.getBusinessDatabase()
|
||||
.eq("document_no", reviewListPojo.getId())
|
||||
.update("is_delete", 1)
|
||||
.update("last_update_date", Timestamp.valueOf(LocalDateTime.now()))
|
||||
.doUpdate(TodoTaskPojo.class);
|
||||
|
||||
// 修改非进行中的流程为进行中
|
||||
ApprovalConfigPojo firstNode = bd.getBusinessDatabase()
|
||||
.eq("approval_id", reviewListPojo.getId())
|
||||
.orderBy("node_order", "asc")
|
||||
.doQueryFirst(ApprovalConfigPojo.class);
|
||||
if (!Objects.equals(reviewListPojo.getStatusCode(), ParamValueVersionEnum.UNDER.getCode())) {
|
||||
reviewListPojo.setPreNode(-1);
|
||||
reviewListPojo.setStatusCode(ParamValueVersionEnum.UNDER.getCode());
|
||||
reviewListPojo.setNodeName(firstNode.getNodeName());
|
||||
|
||||
// 这一批数据改成审核中,
|
||||
bd.getBusinessDatabase()
|
||||
.update("version_status", ParamValueVersionEnum.UNDER.getCode())
|
||||
.update("last_update_date", new Date())
|
||||
.eq("approval_id", reviewListPojo.getId())
|
||||
.doUpdate(EngineParamDetailPojo.class);
|
||||
// 审批流改为审核中
|
||||
bd.getBusinessDatabase()
|
||||
.update("status_code", ParamValueVersionEnum.UNDER.getCode())
|
||||
.update("status_description", ParamValueVersionEnum.UNDER.getDesc())
|
||||
.update("last_update_date", new Date())
|
||||
.eq("id", reviewListPojo.getId()).doUpdate(EngineReviewListPojo.class);
|
||||
}
|
||||
|
||||
// 添加新待办
|
||||
myself.addNodeTodo(
|
||||
reviewListPojo,
|
||||
firstNode,
|
||||
userId,
|
||||
1
|
||||
);
|
||||
|
||||
ApprovalRecord lastedRecord = bd.getBusinessDatabase()
|
||||
.eq("flow_id", reviewListPojo.getId())
|
||||
.orderBy("approval_time", "desc")
|
||||
.doQueryFirst(ApprovalRecord.class);
|
||||
bd.getBusinessDatabase().doInsert(
|
||||
new ApprovalRecord(
|
||||
reviewListPojo.getId(),
|
||||
"重新发起",
|
||||
xdapDeptUsersService.selectUserByID(userId).getUsername(),
|
||||
"重新发起",
|
||||
"MSG",
|
||||
Timestamp.valueOf(LocalDateTime.now()),
|
||||
lastedRecord.getApprovalLevel() + 1
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getEditableNodes(String flowId) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNode(UpdateNodeForm form) {
|
||||
// 检查流程
|
||||
EngineReviewListPojo reviewListPojo = bd.getBusinessDatabase()
|
||||
.eq("id", form.getFlowId())
|
||||
.ne("status_code", ParamValueVersionEnum.PASSED.getCode())
|
||||
.doQueryFirst(EngineReviewListPojo.class);
|
||||
|
||||
if (reviewListPojo == null) {
|
||||
throw new CommonException("流程不存在");
|
||||
}
|
||||
|
||||
templateApprovalService.updateNodeConfig(form);
|
||||
|
||||
// 更新流程状态
|
||||
if (!Objects.equals(reviewListPojo.getProcessTopic(), form.getTitle())) {
|
||||
bd.getBusinessDatabase()
|
||||
.eq("id", reviewListPojo.getId())
|
||||
.update("process_topic", form.getTitle())
|
||||
.doUpdate(EngineReviewListPojo.class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 平台发起审批流程
|
||||
* 从外部平台发起审批时,在本地系统创建相应的审批流程记录
|
||||
@ -735,17 +831,17 @@ public class ActivitiProcessServiceImpl implements ActivitiProcessService {
|
||||
List<ApprovalUserNodeDTO> list = new ArrayList<>();
|
||||
|
||||
// 获取到模板最近一次未完成的流程
|
||||
EngineReviewListPojo flow = bd.getBusinessDatabase()
|
||||
EngineReviewListPojo engineReviewList = bd.getBusinessDatabase()
|
||||
.eq("id", flowId)
|
||||
.doQueryFirst(EngineReviewListPojo.class);
|
||||
if (flow == null) {
|
||||
if (engineReviewList == null) {
|
||||
nodes.setNodeList(list);
|
||||
return nodes;
|
||||
}
|
||||
|
||||
// 获取流程节点
|
||||
List<ApprovalConfigPojo> approvalConfigs = bd.getBusinessDatabase()
|
||||
.eq("approval_id", flow.getId())
|
||||
.eq("approval_id", engineReviewList.getId())
|
||||
.doQuery(ApprovalConfigPojo.class);
|
||||
|
||||
approvalConfigs.forEach(node -> {
|
||||
@ -760,8 +856,8 @@ public class ActivitiProcessServiceImpl implements ActivitiProcessService {
|
||||
);
|
||||
list.add(dto);
|
||||
});
|
||||
nodes.setProcessTitle(flow.getProcessTopic());
|
||||
nodes.setExplanation(flow.getReviewComment());
|
||||
nodes.setProcessTitle(engineReviewList.getProcessTopic());
|
||||
nodes.setExplanation(engineReviewList.getReviewComment());
|
||||
nodes.setNodeList(list);
|
||||
return nodes;
|
||||
}
|
||||
@ -1020,7 +1116,7 @@ public class ActivitiProcessServiceImpl implements ActivitiProcessService {
|
||||
*
|
||||
* @param engineParamDetailPojos 参数明细POJO列表
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class) // 发生任何异常都回滚
|
||||
@Transactional // 发生任何异常都回滚
|
||||
public void batchInsertParamDetail(List<EngineParamDetailPojo> engineParamDetailPojos) {
|
||||
bd.getBusinessDatabase().doBatchInsert(engineParamDetailPojos);
|
||||
}
|
||||
|
||||
@ -211,7 +211,7 @@ public class AnalysisCommonParametersServiceImpl implements AnalysisCommonParame
|
||||
|
||||
// 按 modelId 分组
|
||||
Map<String, List<EngineParamDetailPojo>> engineParamDetailMap = allEngineParamDetails.stream()
|
||||
.collect(Collectors.groupingBy(EngineParamDetailPojo::getEngineModelId));
|
||||
.collect(Collectors.groupingBy(pojo -> pojo.getEngineModelId() + "_" + pojo.getMajorVersion()));
|
||||
|
||||
// 批量查询 TC 数据
|
||||
List<EngineParamDetailPojo> allTcData = tcDataQueryService.tcDataSelectAllByproductNumberBatch(engineModelPojos);
|
||||
@ -223,7 +223,6 @@ public class AnalysisCommonParametersServiceImpl implements AnalysisCommonParame
|
||||
// 构建结果
|
||||
AnalysisModelParamterViewAndParam andParam = new AnalysisModelParamterViewAndParam();
|
||||
List<AnalysisModelParamterView> analysisModelParamterViews = new ArrayList<>();
|
||||
Set<String> allParamNames = new HashSet<>();
|
||||
|
||||
for (DataEntryEngineModelPojo engineModelPojo : engineModelPojos) {
|
||||
AnalysisModelParamterView analysisModelParamterView = new AnalysisModelParamterView();
|
||||
@ -232,33 +231,23 @@ public class AnalysisCommonParametersServiceImpl implements AnalysisCommonParame
|
||||
BeanUtils.copyProperties(engineModelPojo, analysisModelParamterView);
|
||||
|
||||
// 获取 EngineParamDetailPojo 列表
|
||||
List<EngineParamDetailPojo> pojoList = engineParamDetailMap.getOrDefault(engineModelPojo.getId(), Collections.emptyList());
|
||||
|
||||
// 过滤版本号
|
||||
Integer versionNumber = engineModelPojo.getVersionNumber();
|
||||
pojoList = pojoList.stream()
|
||||
.filter(x -> Objects.equals(x.getMajorVersion(), versionNumber))
|
||||
.collect(Collectors.toList());
|
||||
String groupKey = engineModelPojo.getId() + "_" + engineModelPojo.getVersionNumber();
|
||||
List<EngineParamDetailPojo> pojoList = engineParamDetailMap.getOrDefault(groupKey, Collections.emptyList());
|
||||
|
||||
// 添加 TC 数据
|
||||
List<EngineParamDetailPojo> tcData = tcDataMap.getOrDefault(engineModelPojo.getId(), Collections.emptyList());
|
||||
pojoList.addAll(tcData);
|
||||
|
||||
// 过滤非数字参数值
|
||||
pojoList = pojoList.stream()
|
||||
.filter(x -> ObjectUtils.isNotEmpty(x.getParameterValue()) && isNumber(x.getParameterValue()))
|
||||
// 合并原列表和TC数据,一次过滤+收集,避免创建中间列表
|
||||
pojoList = Stream.concat(pojoList.stream(), tcData.stream())
|
||||
.filter(x ->
|
||||
ObjectUtils.isNotEmpty(x.getParameterValue()) && isNumber(x.getParameterValue()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
analysisModelParamterView.setPojos(pojoList);
|
||||
analysisModelParamterViews.add(analysisModelParamterView);
|
||||
|
||||
// 收集所有参数名
|
||||
pojoList.stream()
|
||||
.map(EngineParamDetailPojo::getParameterName)
|
||||
.forEach(allParamNames::add);
|
||||
}
|
||||
|
||||
andParam.setParamList(new ArrayList<>(allParamNames));
|
||||
andParam.setParamList(new ArrayList<>());
|
||||
andParam.setPojos(analysisModelParamterViews);
|
||||
return andParam;
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public void insertReport(SaveBenchmarkingReportForm form) {
|
||||
// 创建报告
|
||||
BenchmarkingReport report = new BenchmarkingReport();
|
||||
@ -123,42 +123,10 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
|
||||
bd.getBusinessDatabase()
|
||||
.eq("id", report.getId())
|
||||
.doUpdate(report);
|
||||
|
||||
// 修改流程
|
||||
ApprovalFlow flow = bd.getBusinessDatabase()
|
||||
.eq("id", form.getFlowId())
|
||||
.doQueryFirst(ApprovalFlow.class);
|
||||
flow.setExplanation(form.getExplanation());
|
||||
flow.setProcessTitle(form.getProcessTitle());
|
||||
bd.getBusinessDatabase()
|
||||
.eq("id", flow.getId())
|
||||
.update("explanation", flow.getExplanation())
|
||||
.update("process_title", flow.getProcessTitle())
|
||||
.doUpdate(ApprovalFlow.class);
|
||||
// 修改流程节点
|
||||
List<String> ids = bd.getBusinessDatabase()
|
||||
.eq("approval_id", flow.getId())
|
||||
.orderBy("node_order", "asc")
|
||||
.doQuery(ApprovalConfigPojo.class)
|
||||
.stream().map(ApprovalConfigPojo::getId)
|
||||
.collect(Collectors.toList());
|
||||
bd.getBusinessDatabase()
|
||||
.in("id", ids)
|
||||
.doDelete(ApprovalConfigPojo.class);
|
||||
List<ApprovalConfigPojo> approvalConfigs = new ArrayList<>();
|
||||
for (ApprovalNodeDTO node : form.getNodeList()) {
|
||||
ApprovalConfigPojo config = new ApprovalConfigPojo();
|
||||
config.setNodeName(node.getNodeName());
|
||||
config.setNodeOrder(node.getNodeOrder());
|
||||
config.setAssignees(JSON.toJSONString(node.getAssignees()));
|
||||
config.setApprovalId(flow.getId());
|
||||
approvalConfigs.add(config);
|
||||
}
|
||||
bd.getBusinessDatabase().doBatchInsert(approvalConfigs);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public void deleteReport(String reportId) {
|
||||
BenchmarkingReport report = bd.getBusinessDatabase()
|
||||
.eq("id", reportId)
|
||||
@ -212,7 +180,7 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public void startReportApproval(ApprovalPersonForm form) {
|
||||
// 验证能否发起审批
|
||||
BenchmarkingReport report = bd.getBusinessDatabase()
|
||||
@ -315,7 +283,73 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public void continueApproval(String flowId, String userId) {
|
||||
ApprovalFlow flow = bd.getBusinessDatabase()
|
||||
.eq("id", flowId)
|
||||
.doQueryFirst(ApprovalFlow.class);
|
||||
if (flow == null) {
|
||||
throw new CommonException("流程不存在");
|
||||
}
|
||||
|
||||
// 清除原流程节点的所有待办
|
||||
bd.getBusinessDatabase()
|
||||
.eq("document_no", flow.getId())
|
||||
.update("is_delete", 1)
|
||||
.update("last_update_date", Timestamp.valueOf(LocalDateTime.now()))
|
||||
.doUpdate(TodoTaskPojo.class);
|
||||
|
||||
// 修改非进行中的流程为进行中
|
||||
ApprovalConfigPojo firstNode = bd.getBusinessDatabase()
|
||||
.eq("approval_id", flow.getId())
|
||||
.orderBy("node_order", "asc")
|
||||
.doQueryFirst(ApprovalConfigPojo.class);
|
||||
if (!Objects.equals(flow.getFlowStatus(), "APPROVING")) {
|
||||
flow.setPreNode(-1);
|
||||
flow.setFlowStatus("APPROVING");
|
||||
flow.setCurrentNode(firstNode.getNodeOrder());
|
||||
|
||||
bd.getBusinessDatabase()
|
||||
.eq("id", flow.getId())
|
||||
.update("flow_status", "APPROVING")
|
||||
.update("current_node", firstNode.getNodeOrder())
|
||||
.update("pre_node", -1)
|
||||
.doUpdate(ApprovalFlow.class);
|
||||
}
|
||||
|
||||
// 获取当前节点和模板
|
||||
BenchmarkingReport report = bd.getBusinessDatabase()
|
||||
.eq("id", flow.getTemplateId())
|
||||
.doQueryFirst(BenchmarkingReport.class);
|
||||
|
||||
// 添加新待办
|
||||
myself.addNodeTodo(
|
||||
flow,
|
||||
firstNode,
|
||||
report,
|
||||
userId,
|
||||
1
|
||||
);
|
||||
|
||||
ApprovalRecord lastedRecord = bd.getBusinessDatabase()
|
||||
.eq("flow_id", flow.getId())
|
||||
.orderBy("approval_time", "desc")
|
||||
.doQueryFirst(ApprovalRecord.class);
|
||||
bd.getBusinessDatabase().doInsert(
|
||||
new ApprovalRecord(
|
||||
flow.getId(),
|
||||
"重新发起",
|
||||
xdapDeptUsersService.selectUserByID(userId).getUsername(),
|
||||
"重新发起",
|
||||
"MSG",
|
||||
Timestamp.valueOf(LocalDateTime.now()),
|
||||
lastedRecord.getApprovalLevel() + 1
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void restartReportApproval(RestartReportApprovalForm form) {
|
||||
// 获取报告
|
||||
BenchmarkingReport report = bd.getBusinessDatabase()
|
||||
@ -458,7 +492,7 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public void directSendingApproval(String reportId, String userId) {
|
||||
// 获取报告
|
||||
BenchmarkingReport report = bd.getBusinessDatabase()
|
||||
@ -547,7 +581,7 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public void handleReturnToNode(HandleReturnNodeForm form) {
|
||||
// 查找流程
|
||||
ApprovalFlow flow = bd.getBusinessDatabase()
|
||||
@ -638,7 +672,7 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public void handleReturn(HandleApprovalRequest request) {
|
||||
ApprovalFlow flow = bd.getBusinessDatabase()
|
||||
.eq("id", request.getFlowId())
|
||||
@ -751,7 +785,7 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public void handleReportApproval(HandleApprovalRequest request) {
|
||||
// 验证流程状态和用户权限
|
||||
ApprovalFlow flow = bd.getBusinessDatabase()
|
||||
|
||||
@ -62,7 +62,7 @@ public class CommonParameterServiceImpl implements CommonParameterService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = CommonException.class)
|
||||
@Transactional
|
||||
public void insertModelCommonParameter(ModelCommonParameterInsertForm form) {
|
||||
// 检查名字是否重复
|
||||
List<CommonParameter> modelCommonParameters1 = bd.getBusinessDatabase()
|
||||
@ -86,7 +86,7 @@ public class CommonParameterServiceImpl implements CommonParameterService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = CommonException.class)
|
||||
@Transactional
|
||||
public void updateModelCommonParameter(ModelCommonParameterUpdateForm form) {
|
||||
CommonParameter commonParameter = bd.getBusinessDatabase()
|
||||
.eq("id", form.getCommonId()).doQueryFirst(CommonParameter.class);
|
||||
@ -110,7 +110,7 @@ public class CommonParameterServiceImpl implements CommonParameterService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = CommonException.class)
|
||||
@Transactional
|
||||
public void insertAnalysisCommonParameter(AnalysisCommonParameterInsertForm form) {
|
||||
// 检查名字是否重复
|
||||
List<CommonParameter> modelCommonParameters1 = bd.getBusinessDatabase()
|
||||
@ -133,7 +133,7 @@ public class CommonParameterServiceImpl implements CommonParameterService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = CommonException.class)
|
||||
@Transactional
|
||||
public void updateAnalysisCommonParameter(AnalysisCommonParameterUpdateForm form) {
|
||||
CommonParameter commonParameter = bd.getBusinessDatabase()
|
||||
.eq("id", form.getCommonId()).doQueryFirst(CommonParameter.class);
|
||||
|
||||
@ -147,6 +147,7 @@ public class DataEntryEngineModelServiceImpl implements DataEntryEngineModelServ
|
||||
.like("brand", request.getBrand())
|
||||
.in("responsible_person_id", resPerIds)
|
||||
.eq("distribute_status", status)
|
||||
.orderBy("creation_date", "desc")
|
||||
.doPageQuery(page, size, DataEntryEngineModelPojo.class);
|
||||
|
||||
for (DataEntryEngineModelPojo modelPojo : pageQueryResult.getResult()) {
|
||||
@ -175,7 +176,7 @@ public class DataEntryEngineModelServiceImpl implements DataEntryEngineModelServ
|
||||
|
||||
|
||||
@Override
|
||||
// @Transactional(rollbackFor = Exception.class)
|
||||
// @Transactional
|
||||
public void excelImport(MultipartFile file, String userId, String ycOrOt) {
|
||||
if (ObjectUtils.isEmpty(userId)) {
|
||||
throw new ExcelImportException("执行上传操作的用户查不到,无法上传");
|
||||
@ -200,7 +201,7 @@ public class DataEntryEngineModelServiceImpl implements DataEntryEngineModelServ
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public int insert(DataEntryEngineModelPageRequest request, String userId) {/*
|
||||
DateTime date = DateUtil.date();
|
||||
String createdBy = "添加机型";
|
||||
@ -299,7 +300,7 @@ public class DataEntryEngineModelServiceImpl implements DataEntryEngineModelServ
|
||||
//模板管理审批完成触发更新 参数版本
|
||||
//遍历所有机型 把所有机型的版本加一 状态为未分发 绑定新版参数新版参数版本加一 所有新参数值为空 重新走分发
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public void updateModelForNewVersion() {
|
||||
List<Parameter> parameters = engineParamDetailService.selectAllByNewVersion();
|
||||
DistributeStatusEnum byDesc = DistributeStatusEnum.getByDesc("未分发");
|
||||
|
||||
@ -687,12 +687,12 @@ public class EngineParamDetailServiceImpl implements EngineParamDetailService {
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class) // 发生任何异常都回滚
|
||||
@Transactional // 发生任何异常都回滚
|
||||
public void batchInsertTodoTask(List<TodoTaskPojo> todoTaskPojos) {
|
||||
sw.buildFromDatasource("xdap_app_223770822127386625").doBatchInsert(todoTaskPojos);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class) // 发生任何异常都回滚
|
||||
@Transactional // 发生任何异常都回滚
|
||||
public void batchInsertInitiatedTask(List<InitiatedTaskPojo> taskPojos) {
|
||||
sw.buildFromDatasource("xdap_app_223770822127386625").doBatchInsert(taskPojos);
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ public class ModelRoleServiceImpl implements ModelRoleService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = CommonException.class)
|
||||
@Transactional
|
||||
public void updatePerForRole(List<RolePerJoinRequest> requests) {
|
||||
|
||||
//将老权限置为未启用
|
||||
@ -231,7 +231,7 @@ public class ModelRoleServiceImpl implements ModelRoleService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public void removeRoles(String roleID, String userID) {
|
||||
if (ObjectUtils.isEmpty(roleID)) {
|
||||
throw new RuntimeException("删除的角色为空");
|
||||
@ -252,7 +252,7 @@ public class ModelRoleServiceImpl implements ModelRoleService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public void userRoleBinding(UserRoleBindingRequest userRoleBindingRequest) {
|
||||
//将角色绑定的老版本人员置为未启用
|
||||
String roleId = userRoleBindingRequest.getRoleId();
|
||||
|
||||
@ -70,7 +70,7 @@ public class ParameterServiceImpl implements ParameterService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public TemplateInfoView maintenanceParameters(UpdateParameterForm form) {
|
||||
// 公式格式检查
|
||||
for (ParameterForm parameter : form.getParameterForms()) {
|
||||
|
||||
@ -278,7 +278,7 @@ public class ResponsiblePersonServiceImpl implements ResponsiblePersonService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public void importAllPerson(List<ResponsiblePerson> cachedDataList, MyResponse problems) {
|
||||
cachedDataList.forEach(item -> {
|
||||
List<ResponsiblePerson> responsiblePeople = bd.getBusinessDatabase()
|
||||
|
||||
@ -787,6 +787,17 @@ public class TcDataQueryServiceImpl implements TcDataQueryService {
|
||||
.collect(Collectors.groupingBy(Parameter::getPartsName));
|
||||
|
||||
Set<String> partsNames = stringListMap.keySet();
|
||||
// 预处理参数名集合
|
||||
Map<String, Set<String>> partsParamNameMap = new HashMap<>(partsNames.size());
|
||||
for (String partsName : partsNames) {
|
||||
List<Parameter> parameterList = stringListMap.get(partsName);
|
||||
if (parameterList != null) {
|
||||
Set<String> paramNameSet = parameterList.stream()
|
||||
.map(Parameter::getParameterName)
|
||||
.collect(Collectors.toSet());
|
||||
partsParamNameMap.put(partsName, paramNameSet);
|
||||
}
|
||||
}
|
||||
|
||||
// 一次性查询所有 EnginePartsCollection
|
||||
List<EnginePartsCollection> allPartsCollections = bd.getTCDatabase()
|
||||
@ -820,6 +831,27 @@ public class TcDataQueryServiceImpl implements TcDataQueryService {
|
||||
Map<String, List<ClassificationAttribute>> classificationMap = allClassifications.stream()
|
||||
.collect(Collectors.groupingBy(ClassificationAttribute::getPitemId));
|
||||
|
||||
Map<String, Map<String, List<String>>> productPartsLbjthMap = new HashMap<>();
|
||||
for (Map.Entry<String, Map<String, List<EnginePartsCollection>>> productEntry : partsCollectionsMap.entrySet()) {
|
||||
String productNumber = productEntry.getKey();
|
||||
Map<String, List<EnginePartsCollection>> partsMap = productEntry.getValue();
|
||||
|
||||
Map<String, List<String>> partsLbjthMap = new HashMap<>();
|
||||
for (Map.Entry<String, List<EnginePartsCollection>> partsEntry : partsMap.entrySet()) {
|
||||
String partsName = partsEntry.getKey();
|
||||
List<EnginePartsCollection> partsCollections = partsEntry.getValue();
|
||||
|
||||
// 提前过滤并收集图号
|
||||
List<String> lbjths = partsCollections.stream()
|
||||
.map(EnginePartsCollection::getLbjth)
|
||||
.filter(ObjectUtils::isNotEmpty)
|
||||
.filter(classificationMap::containsKey)
|
||||
.collect(Collectors.toList());
|
||||
partsLbjthMap.put(partsName, lbjths);
|
||||
}
|
||||
productPartsLbjthMap.put(productNumber, partsLbjthMap);
|
||||
}
|
||||
|
||||
// 构建结果
|
||||
List<EngineParamDetailPojo> result = new ArrayList<>();
|
||||
|
||||
@ -834,25 +866,22 @@ public class TcDataQueryServiceImpl implements TcDataQueryService {
|
||||
continue;
|
||||
}
|
||||
|
||||
Map<String, List<String>> partsLbjthMap = productPartsLbjthMap.get(productNumber);
|
||||
if (partsLbjthMap == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (String partsName : partsNames) {
|
||||
List<Parameter> parameterList = stringListMap.get(partsName);
|
||||
if (parameterList == null) {
|
||||
Set<String> parameterNameSet = partsParamNameMap.get(partsName);
|
||||
if (parameterNameSet == null || parameterNameSet.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Set<String> parameterNameSet = parameterList.stream()
|
||||
.map(Parameter::getParameterName).collect(Collectors.toSet());
|
||||
|
||||
List<EnginePartsCollection> partsCollections = partsMap.get(partsName);
|
||||
if (partsCollections == null) {
|
||||
List<String> lbjths = partsLbjthMap.get(partsName);
|
||||
if (lbjths == null || lbjths.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<String> lbjths = partsCollections.stream()
|
||||
.map(EnginePartsCollection::getLbjth)
|
||||
.filter(ObjectUtils::isNotEmpty)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (String lbjth : lbjths) {
|
||||
List<ClassificationAttribute> classifications = classificationMap.get(lbjth);
|
||||
if (classifications == null) {
|
||||
|
||||
@ -25,8 +25,10 @@ import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@ -46,7 +48,7 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
|
||||
private static final int FLOW_LOCK_EXPIRE_SECONDS = 5;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public String startApproval(StartApprovalRequest request) {
|
||||
// 验证能否发起审批
|
||||
Template template = bd.getBusinessDatabase()
|
||||
@ -194,7 +196,7 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public void continueApproval(String flowId, String userId) {
|
||||
ApprovalFlow flow = bd.getBusinessDatabase()
|
||||
.eq("id", flowId)
|
||||
@ -211,11 +213,11 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
|
||||
.doUpdate(TodoTaskPojo.class);
|
||||
|
||||
// 修改非进行中的流程为进行中
|
||||
if (!Objects.equals(flow.getFlowStatus(), "APPROVING")) {
|
||||
ApprovalConfigPojo firstNode = bd.getBusinessDatabase()
|
||||
.eq("approval_id", flow.getId())
|
||||
.orderBy("node_order", "asc")
|
||||
.doQueryFirst(ApprovalConfigPojo.class);
|
||||
if (!Objects.equals(flow.getFlowStatus(), "APPROVING")) {
|
||||
flow.setPreNode(-1);
|
||||
flow.setFlowStatus("APPROVING");
|
||||
flow.setCurrentNode(firstNode.getNodeOrder());
|
||||
@ -232,18 +234,14 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
|
||||
Template template = bd.getBusinessDatabase()
|
||||
.eq("id", flow.getTemplateId())
|
||||
.doQueryFirst(Template.class);
|
||||
ApprovalConfigPojo currentNode = bd.getBusinessDatabase()
|
||||
.eq("approval_id", flow.getId())
|
||||
.eq("node_order", flow.getCurrentNode())
|
||||
.doQueryFirst(ApprovalConfigPojo.class);
|
||||
|
||||
// 添加新待办
|
||||
List<TodoTaskPojo> list = new ArrayList<>();
|
||||
for (String person : JSON.parseArray(currentNode.getAssignees()).toJavaList(String.class)) {
|
||||
for (String person : JSON.parseArray(firstNode.getAssignees()).toJavaList(String.class)) {
|
||||
TodoTaskPojo todoTask = new TodoTaskPojo();
|
||||
todoTask.setCreatedById(userId);
|
||||
todoTask.setCreatedBy(xdapDeptUsersService.selectUserByID(userId).getUsername());
|
||||
todoTask.setCurrentNode(currentNode.getNodeName());
|
||||
todoTask.setCurrentNode(firstNode.getNodeName());
|
||||
todoTask.setDataType("模板审核");
|
||||
todoTask.setDocumentNo(flow.getId());
|
||||
todoTask.setCreationDate(Timestamp.valueOf(LocalDateTime.now()));
|
||||
@ -254,16 +252,32 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
|
||||
todoTask.setStatusCode(flow.getFlowStatus());
|
||||
todoTask.setVersionNumber(template.getVersion());
|
||||
todoTask.setOwnerId(person);
|
||||
todoTask.setCurrentProcessor(JSON.toJSONString(currentNode.getAssignees()));
|
||||
todoTask.setCurrentProcessor(JSON.toJSONString(firstNode.getAssignees()));
|
||||
list.add(todoTask);
|
||||
}
|
||||
bd.getBusinessDatabase().doBatchInsert(list);
|
||||
|
||||
myself.updateTasks(flow, currentNode.getNodeName(), 0, currentNode);
|
||||
ApprovalRecord lastedRecord = bd.getBusinessDatabase()
|
||||
.eq("flow_id", flow.getId())
|
||||
.orderBy("approval_time", "desc")
|
||||
.doQueryFirst(ApprovalRecord.class);
|
||||
bd.getBusinessDatabase().doInsert(
|
||||
new ApprovalRecord(
|
||||
flow.getId(),
|
||||
"重新发起",
|
||||
xdapDeptUsersService.selectUserByID(userId).getUsername(),
|
||||
"重新发起",
|
||||
"MSG",
|
||||
Timestamp.valueOf(LocalDateTime.now()),
|
||||
lastedRecord.getApprovalLevel() + 1
|
||||
)
|
||||
);
|
||||
|
||||
myself.updateTasks(flow, firstNode.getNodeName(), 0, firstNode);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public void directSendingApproval(String templateId, String userId) {
|
||||
// 获取模板
|
||||
Template template = bd.getBusinessDatabase()
|
||||
@ -383,7 +397,7 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public void handleApproval(HandleApprovalRequest request) {
|
||||
// 验证流程状态和用户权限
|
||||
ApprovalFlow flow = bd.getBusinessDatabase()
|
||||
@ -691,6 +705,7 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
|
||||
ApprovalNodesDTO nodes = new ApprovalNodesDTO();
|
||||
nodes.setProcessTitle("");
|
||||
nodes.setExplanation("");
|
||||
nodes.setFlowId(null);
|
||||
List<ApprovalUserNodeDTO> list = new ArrayList<>();
|
||||
|
||||
// 获取到模板最近一次未完成的流程
|
||||
@ -704,6 +719,7 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
|
||||
nodes.setNodeList(list);
|
||||
return nodes;
|
||||
}
|
||||
nodes.setFlowId(flow.getId());
|
||||
|
||||
// 获取流程节点
|
||||
List<ApprovalConfigPojo> approvalConfigs = bd.getBusinessDatabase()
|
||||
@ -742,7 +758,7 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public void updateFlowTitle(String flowId, String title) {
|
||||
ApprovalFlow flow = bd.getBusinessDatabase()
|
||||
.eq("id", flowId)
|
||||
@ -800,7 +816,7 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public void updateNode(UpdateNodeForm form) {
|
||||
// 检查流程
|
||||
ApprovalFlow flow = bd.getBusinessDatabase()
|
||||
@ -812,10 +828,31 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
|
||||
throw new CommonException("流程不存在");
|
||||
}
|
||||
|
||||
myself.updateNodeConfig(form);
|
||||
|
||||
if (!Objects.equals(flow.getProcessTitle(), form.getTitle())) {
|
||||
bd.getBusinessDatabase()
|
||||
.eq("id", flow.getId())
|
||||
.update("process_title", form.getTitle())
|
||||
.doUpdate(ApprovalFlow.class);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNodeConfig(UpdateNodeForm form) {
|
||||
// 获取可更新流程节点名称
|
||||
List<String> enableEditNodes = getEditableNodes(form.getFlowId());
|
||||
List<ApprovalConfigPojo> nodes = bd.getBusinessDatabase()
|
||||
.eq("approval_id", form.getFlowId())
|
||||
.doQuery(ApprovalConfigPojo.class);
|
||||
|
||||
// 将节点列表转换为 Map,方便后续查找
|
||||
Map<String, ApprovalNodeDTO> map = form.getNodeList().stream()
|
||||
Map<String, ApprovalConfigPojo> currentNodeMap = nodes.stream()
|
||||
.collect(Collectors.toMap(
|
||||
ApprovalConfigPojo::getNodeName,
|
||||
node -> node,
|
||||
(oldValue, newValue) -> oldValue
|
||||
));
|
||||
Map<String, ApprovalNodeDTO> newNodeMap = form.getNodeList().stream()
|
||||
.collect(Collectors.toMap(
|
||||
ApprovalNodeDTO::getNodeName,
|
||||
node -> node,
|
||||
@ -829,21 +866,72 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
|
||||
.update("is_delete", 1)
|
||||
.doUpdate(TodoTaskPojo.class);
|
||||
|
||||
// 遍历更新节点
|
||||
enableEditNodes.forEach(nodeName -> {
|
||||
if (map.containsKey(nodeName)) {
|
||||
ApprovalNodeDTO nodeForm = map.get(nodeName);
|
||||
boolean addNode = false;
|
||||
int orderOffset = 0;
|
||||
List<ApprovalNodeDTO> sorted = form.getNodeList().stream()
|
||||
.sorted(Comparator.comparing(ApprovalNodeDTO::getNodeOrder))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 更新可选的会签节点
|
||||
ApprovalConfigPojo signNode = currentNodeMap.get("会签");
|
||||
ApprovalNodeDTO newSignNode = newNodeMap.get("会签");
|
||||
if (newSignNode != null) {
|
||||
// 新增节点
|
||||
if (!newSignNode.getAssignees().isEmpty() && signNode == null) {
|
||||
// 找到新增节点的插入位置
|
||||
int insertOrder = newSignNode.getNodeOrder();
|
||||
// 新增会签节点
|
||||
ApprovalConfigPojo addNewNode = new ApprovalConfigPojo();
|
||||
addNewNode.setApprovalId(form.getFlowId());
|
||||
addNewNode.setNodeName(newSignNode.getNodeName());
|
||||
addNewNode.setNodeOrder(insertOrder);
|
||||
addNewNode.setAssignees(JSON.toJSONString(newSignNode.getAssignees()));
|
||||
bd.getBusinessDatabase().doInsert(addNewNode);
|
||||
// 新增节点后,后续节点序号需要+1
|
||||
orderOffset = 1;
|
||||
addNode = true;
|
||||
}
|
||||
// 删除节点
|
||||
else if (newSignNode.getAssignees().isEmpty() && signNode != null) {
|
||||
// 删除会签节点
|
||||
bd.getBusinessDatabase()
|
||||
.eq("approval_id", form.getFlowId())
|
||||
.eq("node_order", nodeForm.getNodeOrder())
|
||||
.eq("node_name", nodeForm.getNodeName())
|
||||
.update("assignees", JSON.toJSONString(nodeForm.getAssignees()))
|
||||
.eq("id", signNode.getId())
|
||||
.doDelete(ApprovalConfigPojo.class);
|
||||
// 删除节点后,后续节点序号需要-1
|
||||
orderOffset = -1;
|
||||
addNode = true;
|
||||
}
|
||||
}
|
||||
|
||||
// 遍历所有节点,更新序号和处理人信息
|
||||
for (ApprovalNodeDTO newNode : sorted) {
|
||||
// 获取当前节点
|
||||
ApprovalConfigPojo node = currentNodeMap.get(newNode.getNodeName());
|
||||
if (node == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 计算新序号:原始序号 + 偏移量
|
||||
int finalOrder = node.getNodeOrder() + orderOffset;
|
||||
// 更新节点信息
|
||||
if (addNode) {
|
||||
bd.getBusinessDatabase()
|
||||
.eq("id", node.getId())
|
||||
.update("node_order", finalOrder)
|
||||
.update("assignees", JSON.toJSONString(newNode.getAssignees()))
|
||||
.doUpdate(ApprovalConfigPojo.class);
|
||||
} else {
|
||||
// 无节点增减时,只更新处理人
|
||||
bd.getBusinessDatabase()
|
||||
.eq("id", node.getId())
|
||||
.update("assignees", JSON.toJSONString(newNode.getAssignees()))
|
||||
.doUpdate(ApprovalConfigPojo.class);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateTasks(ApprovalFlow flow, String status, Integer enableReturn, ApprovalConfigPojo currentNode) {
|
||||
@Override
|
||||
public void updateTasks(ApprovalFlow flow, String status, Integer enableReturn, ApprovalConfigPojo currentNode) {
|
||||
// 更新已办和发起的节点状态
|
||||
bd.getBusinessDatabase()
|
||||
.eq("document_no", flow.getId())
|
||||
@ -1090,7 +1178,7 @@ public void updateTasks(ApprovalFlow flow, String status, Integer enableReturn,
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public void handleReturn(HandleApprovalRequest request) {
|
||||
ApprovalFlow flow = bd.getBusinessDatabase()
|
||||
.eq("id", request.getFlowId())
|
||||
@ -1142,7 +1230,7 @@ public void updateTasks(ApprovalFlow flow, String status, Integer enableReturn,
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public void handleReturnToNode(HandleReturnNodeForm form) {
|
||||
// 查找流程
|
||||
ApprovalFlow flow = bd.getBusinessDatabase()
|
||||
|
||||
@ -71,7 +71,7 @@ public class TemplateServiceImpl implements TemplateService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public void updateTemplate(UpdateTemplateForm form) {
|
||||
Template template = bd.getBusinessDatabase()
|
||||
.viewQueryMode(true)
|
||||
@ -133,7 +133,7 @@ public class TemplateServiceImpl implements TemplateService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public MyResponse importTemplate(MultipartFile file, String templateRowId, String userId) {
|
||||
// 验证文件是否为工作表
|
||||
if (file == null || file.isEmpty()) {
|
||||
@ -239,7 +239,7 @@ public class TemplateServiceImpl implements TemplateService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public void processSheetData(List<Parameter> dataList, String sheetName,
|
||||
String templateRowId, String createBy, MyResponse problems) {
|
||||
if (dataList.isEmpty()) {
|
||||
|
||||
@ -294,7 +294,7 @@ public class TodoTaskServiceImpl implements TodoTaskService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Transactional
|
||||
public void todoReturn(TodoReturnRequest todoReturnRequest) {
|
||||
String todoTaskId = todoReturnRequest.getTodoTaskId();
|
||||
if (ObjectUtils.isEmpty(todoTaskId)) {
|
||||
@ -491,12 +491,12 @@ public class TodoTaskServiceImpl implements TodoTaskService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class) // 发生任何异常都回滚
|
||||
@Transactional // 发生任何异常都回滚
|
||||
public void batchInsertTodoTask(List<TodoTaskPojo> todoTaskPojos) {
|
||||
sw.buildFromDatasource("xdap_app_223770822127386625").doBatchInsert(todoTaskPojos);
|
||||
}
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class) // 发生任何异常都回滚
|
||||
@Transactional // 发生任何异常都回滚
|
||||
public void batchInsertInitiatedTask(List<InitiatedTaskPojo> taskPojos) {
|
||||
sw.buildFromDatasource("xdap_app_223770822127386625").doBatchInsert(taskPojos);
|
||||
}
|
||||
|
||||
@ -27,19 +27,18 @@ public class FormulaValidator {
|
||||
return result;
|
||||
}
|
||||
|
||||
// 清理公式:移除所有空格,统一格式
|
||||
formula = formula.replaceAll("\\s+", "");
|
||||
|
||||
// 2. 仅对英文括号进行匹配检查(中文括号视为参数字符)
|
||||
// 2. 仅对英文括号进行匹配检查
|
||||
if (!isEnglishParenthesesBalanced(formula)) {
|
||||
result.put("isValid", false);
|
||||
result.put("errorMessage", String.format("英文括号不匹配 [原始公式:%s]", originalFormula));
|
||||
return result;
|
||||
}
|
||||
|
||||
// 3. 语法结构校验(核心)
|
||||
// 3. 语法结构校验
|
||||
try {
|
||||
// 解析公式并验证运算逻辑(新增顶层括号处理)
|
||||
// 解析公式并验证运算逻辑
|
||||
validateTopLevelFormula(formula, originalFormula);
|
||||
} catch (IllegalArgumentException e) {
|
||||
result.put("isValid", false);
|
||||
@ -47,7 +46,7 @@ public class FormulaValidator {
|
||||
return result;
|
||||
}
|
||||
|
||||
// 4. 数字格式校验(适配参数+数字混合场景)
|
||||
// 4. 数字格式校验
|
||||
String numberFormatError = checkNumberFormatDetailed(formula, originalFormula);
|
||||
if (numberFormatError != null) {
|
||||
result.put("isValid", false);
|
||||
@ -64,10 +63,10 @@ public class FormulaValidator {
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证顶层公式语法(处理以括号开头的场景)
|
||||
* 验证顶层公式语法
|
||||
*/
|
||||
private static void validateTopLevelFormula(String formula, String originalFormula) {
|
||||
// 移除所有空格(已提前清理,此处双重保障)
|
||||
// 移除所有空格
|
||||
String cleaned = formula.replaceAll("\\s+", "");
|
||||
|
||||
// 处理空公式
|
||||
@ -78,18 +77,18 @@ public class FormulaValidator {
|
||||
// 递归解析括号表达式,将括号块视为整体操作数
|
||||
String parsedFormula = parseParenthesesBlocks(cleaned, originalFormula);
|
||||
|
||||
// 验证解析后的公式(括号块已替换为占位符,变为普通运算式)
|
||||
// 验证解析后的公式
|
||||
validateSubFormula(parsedFormula, cleaned, originalFormula);
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归解析括号块,将每对匹配的括号内内容视为整体操作数
|
||||
* @param formula 待解析公式
|
||||
* @param originalFormula 原始公式(用于错误提示)
|
||||
* @param originalFormula 原始公式
|
||||
* @return 替换括号块为占位符的公式
|
||||
*/
|
||||
private static String parseParenthesesBlocks(String formula, String originalFormula) {
|
||||
// 匹配最外层括号对(非嵌套)
|
||||
// 匹配最外层括号对
|
||||
Pattern outerBracketPattern = Pattern.compile("\\(([^()]*)\\)");
|
||||
Matcher matcher = outerBracketPattern.matcher(formula);
|
||||
|
||||
@ -102,13 +101,13 @@ public class FormulaValidator {
|
||||
throw new IllegalArgumentException(String.format("英文括号内不能为空 [错误片段:()][原始公式:%s]", originalFormula));
|
||||
}
|
||||
|
||||
// 递归解析括号内的子内容(处理嵌套括号)
|
||||
// 递归解析括号内的子内容
|
||||
String parsedInner = parseParenthesesBlocks(innerContent, originalFormula);
|
||||
|
||||
// 验证括号内的子公式
|
||||
validateSubFormula(parsedInner, innerContent, originalFormula);
|
||||
|
||||
// 替换括号块为占位符(使用特殊标记,避免与正常内容冲突)
|
||||
// 替换括号块为占位符
|
||||
matcher.appendReplacement(sb, "OPERAND_PLACEHOLDER");
|
||||
}
|
||||
matcher.appendTail(sb);
|
||||
@ -128,7 +127,7 @@ public class FormulaValidator {
|
||||
return;
|
||||
}
|
||||
|
||||
// 拆分运算单元(参数/数字/常量/占位符 + 运算符)
|
||||
// 拆分运算单元
|
||||
List<String> tokens = tokenizeFormula(subFormula);
|
||||
|
||||
// 验证运算单元的合法性
|
||||
@ -196,7 +195,7 @@ public class FormulaValidator {
|
||||
for (int i = 0; i < formula.length(); i++) {
|
||||
char c = formula.charAt(i);
|
||||
|
||||
// 处理占位符(整体作为操作数)
|
||||
// 处理占位符
|
||||
if (c == 'O' && formula.startsWith("OPERAND_PLACEHOLDER", i)) {
|
||||
if (currentOperand.length() > 0) {
|
||||
tokens.add(currentOperand.toString());
|
||||
@ -207,7 +206,7 @@ public class FormulaValidator {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 处理运算符(特殊处理开头/括号后的负号)
|
||||
// 处理运算符
|
||||
if (OPERATORS.contains(c)) {
|
||||
// 负号不是运算符的情况:开头、运算符后、英文括号后
|
||||
boolean isNegativeSign = (c == '-') && (i == 0 ||
|
||||
@ -256,15 +255,15 @@ public class FormulaValidator {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 2. 纯数字(整数/小数)
|
||||
// 2. 纯数字
|
||||
if (checkOperand.matches("\\d+(\\.\\d+)?")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 3. 中文参数名(核心优化:支持中文、数字、字母、中文括号的任意组合)
|
||||
// 3. 中文参数名
|
||||
// 正则说明:[\u4e00-\u9fa5] 中文 | [0-9] 数字 | [a-zA-Z] 字母 | [()] 中文括号
|
||||
if (checkOperand.matches("[\\u4e00-\\u9fa50-9a-zA-Z()]+")) {
|
||||
// 确保参数名至少包含一个中文(避免纯字母/数字被误判为参数)
|
||||
// 确保参数名至少包含一个中文
|
||||
return checkOperand.matches(".*[\\u4e00-\\u9fa5]+.*");
|
||||
}
|
||||
|
||||
@ -300,7 +299,7 @@ public class FormulaValidator {
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查数字格式是否正确(优化错误提示)
|
||||
* 检查数字格式是否正确
|
||||
* @return 错误信息,无错误返回null
|
||||
*/
|
||||
private static String checkNumberFormatDetailed(String formula, String originalFormula) {
|
||||
@ -316,7 +315,7 @@ public class FormulaValidator {
|
||||
errorPart, formula, originalFormula);
|
||||
}
|
||||
|
||||
// 2. 检查小数点前后是否有非法字符(排除英文括号)
|
||||
// 2. 检查小数点前后是否有非法字符
|
||||
Pattern invalidDotPattern = Pattern.compile("\\.[\\u4e00-\\u9fa5()]|([^0-9.])\\.([^0-9.])");
|
||||
Matcher invalidDotMatcher = invalidDotPattern.matcher(cleanFormula);
|
||||
if (invalidDotMatcher.find()) {
|
||||
@ -335,7 +334,7 @@ public class FormulaValidator {
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取公式中的所有参数(支持带字母/数字/中文括号的参数名)
|
||||
* 提取公式中的所有参数
|
||||
*/
|
||||
public static List<String> extractParameters(String formula) {
|
||||
List<String> parameters = new ArrayList<>();
|
||||
@ -343,7 +342,7 @@ public class FormulaValidator {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
// 匹配中文参数名(核心优化:支持中文+数字+字母+中文括号)
|
||||
// 匹配中文参数名
|
||||
Pattern paramPattern = Pattern.compile("[\\u4e00-\\u9fa5][\\u4e00-\\u9fa50-9a-zA-Z()]*");
|
||||
Matcher matcher = paramPattern.matcher(formula);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user