修改:大部分修改

This commit is contained in:
zjh 2026-01-13 19:10:31 +08:00
parent 0b704c9977
commit fbba2a0ca4
21 changed files with 830 additions and 319 deletions

View File

@ -99,10 +99,10 @@ public class ActivitiProcessController {
// 直送回退回的节点
@GetMapping("/directSendingApproval")
public Response directSendingApproval(
@RequestParam @NotBlank String templateId,
@RequestParam @NotBlank String flowId,
@RequestParam @NotBlank String userId
) {
activitiProcessService.directSendingApproval(templateId, userId);
activitiProcessService.directSendingApproval(flowId, userId);
return Response.ok();
}
// 获取可退回节点

View File

@ -5,6 +5,7 @@ import com.definesys.mpaas.query.db.PageQueryResult;
import com.xdap.self_development.controller.form.*;
import com.xdap.self_development.exception.CommonException;
import com.xdap.self_development.pojo.BenchmarkingReport;
import com.xdap.self_development.pojo.dto.ApprovalNodesDTO;
import com.xdap.self_development.pojo.view.ApprovalFlowNodeView;
import com.xdap.self_development.pojo.view.TodoAndReportView;
import com.xdap.self_development.service.BenchmarkingReportService;
@ -64,6 +65,21 @@ public class BenchmarkingReportController {
return Response.ok().setMessage("保存成功");
}
// 发起人重新发起流程
@PostMapping("/restartReportApproval")
public Response restartReportApproval(
@Valid @RequestBody RestartReportApprovalForm form,
BindingResult bindingResult
) {
if (bindingResult.hasErrors()) {
bindingResult.getFieldErrors().forEach(error -> {
throw new CommonException(error.getDefaultMessage());
});
}
benchmarkingReportService.restartReportApproval(form);
return Response.ok().setMessage("重新提交成功");
}
// 直送回退回的节点
@GetMapping("/directSendingApproval")
public Response directSendingApproval(
@ -191,4 +207,13 @@ public class BenchmarkingReportController {
ApprovalFlowNodeView approvalFlowView = benchmarkingReportService.getReportProcess(flowId);
return Response.ok().data(approvalFlowView);
}
// 获取流程审批人
@GetMapping("/getApprovalUsers")
public Response getApprovalUsers(
@NotBlank @RequestParam String flowId
) {
ApprovalNodesDTO nodes = benchmarkingReportService.getApprovalUsers(flowId);
return Response.ok().data(nodes);
}
}

View File

@ -9,7 +9,10 @@ import com.xdap.self_development.common.UserPermissionGetter;
import com.xdap.self_development.config.BusinessDatabase;
import com.xdap.self_development.controller.request.ModelComparisonExportRequest;
import com.xdap.self_development.feign.ApaasMyTokenFeign;
import com.xdap.self_development.pojo.ModelDepUserRolePojo;
import com.xdap.self_development.pojo.view.MenuParamView;
import com.xdap.self_development.schedule.ParameterValueCalculationTimer;
import com.xdap.self_development.service.ModelRoleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@ -25,112 +28,5 @@ import java.util.List;
@RestController
@RequestMapping("/custom/delete")
public class DeleteController {
@Resource
private BusinessDatabase bd;
@Resource
private UserPermissionGetter getter;
@Resource
private MpaasQueryFactory queryFactory;
@Autowired
private ApaasMyTokenFeign apaasMyTokenFeign;
@Resource
private RuntimeAppContextService runtimeAppContextService;
@Resource
private SnowflakeIdWorker snowflakeIdWorker;
@Resource
private ParameterValueCalculationTimer timer;
@Value("${apaas.token.clientId}")
private String clientId;
@Value("${apaas.token.clientSecred}")
private String clientSecret;
@Autowired
private StringRedisTemplate redisTemplate;
@GetMapping("/getUserId")
public Response getUserId() {
return Response.ok().data(runtimeAppContextService.getCurrentUserId());
}
@PostMapping("/timer")
public Response timer(
@RequestBody ModelComparisonExportRequest request
) {
StringBuilder sb = new StringBuilder();
for (String modelId : request.getModelIds()) {
try {
String redisKey = request.getUserID() + ":" + modelId + ":" + "ComparisonExport";
log.info("尝试从Redis获取KEY: {}", redisKey);
sb.append(redisKey).append(",");
String cachedData = redisTemplate.opsForValue().get(redisKey);
if (cachedData == null) {
log.warn("Redis中未找到数据KEY: {}", redisKey);
sb.append(modelId).append("未找到数据").append(",");
} else {
log.info("成功获取到数据,长度: {}", cachedData.length());
sb.append(cachedData).append("\n");
}
} catch (Exception e) {
log.error("从Redis获取数据失败", e); // 修正日志信息
sb.append(e.getMessage()).append("\n");
}
}
return Response.ok().data(sb);
}
@PostMapping("/exportCompare")
public void exportTemplateCompare(
// @RequestBody CompareRequest request,
// HttpServletResponse response
) {
// try {
// // 1. 查询对比数据
// List<ParamCompareDTO> data = compareService.compareMultipleTemplates(
// request.getTemplateNames(),
// request.getQueryParams()
// );
//
// // 2. 设置响应头
// String fileName = "模板参数对比_" + System.currentTimeMillis() + ".xlsx";
// response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
// response.setCharacterEncoding("utf-8");
// response.setHeader("Content-disposition",
// "attachment;filename*=utf-8''" + URLEncoder.encode(fileName, "UTF-8"));
//
// // 3. 动态生成表头
// List<List<String>> head = generateDynamicHeader(request.getTemplateNames());
//
// // 4. 使用EasyExcel写入数据
// EasyExcel.write(response.getOutputStream())
// .head(head) // 动态表头
// .sheet("参数对比")
// .doWrite(data);
//
// } catch (Exception e) {
// throw new RuntimeException("导出失败", e);
// }
}
/**
* 动态生成表头
*/
private List<List<String>> generateDynamicHeader(List<String> templateNames) {
List<List<String>> head = new ArrayList<>();
// 固定列
head.add(Collections.singletonList("参数名称"));
head.add(Collections.singletonList("参数编码"));
// 动态模板列
for (String templateName : templateNames) {
head.add(Collections.singletonList(templateName));
}
// 差异标识列
head.add(Collections.singletonList("差异标识"));
return head;
}
}

View File

@ -0,0 +1,38 @@
package com.xdap.self_development.controller.form;
import com.xdap.self_development.pojo.dto.ApprovalNodeDTO;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.util.List;
@Data
public class RestartReportApprovalForm {
private String title;
private String manufacturerName;
private String modelName;
private String manufacturerAbbreviation;
private String modelAbbreviation;
private String productNumber;
private String module;
private String plate;
private String platform;
private String series;
private String marketSegment;
private String projectName;
private String projectNumber;
private String fileUrl;
@NotBlank(message = "报告不能为空")
private String reportId;
@NotBlank(message = "流程标题不能为空")
private String processTitle;
// 审批环节配置列表
@NotEmpty(message = "环节不能为空")
private List<ApprovalNodeDTO> nodeList;
private String explanation;
@NotBlank(message = "发起人不能为空")
private String userId;
}

View File

@ -11,6 +11,9 @@ public class ApprovalNodeRequest {
// 机型基础信息
private String modelId;
// 流程ID
private String flowId;
// 参数列表批量参数
private List<EngineParamDetailPojo> paramList;

View File

@ -7,6 +7,6 @@ import java.util.List;
@Data
public class ModelComparisonExportRequest {
String userID;
List<String> modelIds;
List<ModelItem> models;
List<String> subsystemParts;
}

View File

@ -0,0 +1,9 @@
package com.xdap.self_development.controller.request;
import lombok.Data;
@Data
public class ModelItem {
private String modelId;
private String parameterVersion;
}

View File

@ -1,9 +1,11 @@
package com.xdap.self_development.pojo.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xdap.self_development.pojo.view.FlowNode;
import lombok.Data;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Data
@ -11,6 +13,11 @@ public class ActivitiDataAndRecordDTO {
private String approvalStatus;
private String processTitle;
private String modelName;
private String createBy;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;
private String currentNode;
private String processor;
private ArrayList<ActivitiDataDTO> activitiDataDTOS;
private List<FlowNode> flowNodes;

View File

@ -1,7 +1,9 @@
package com.xdap.self_development.pojo.view;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.sql.Timestamp;
import java.util.List;
@Data
@ -12,6 +14,11 @@ public class ApprovalFlowNodeView {
private String progressTitle;
private String ContentName;
private Integer templateVersion;
private String createBy;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Timestamp createTime;
private String currentNode;
private String processor;
private List<FlowNode> flowNodes;
}

View File

@ -11,6 +11,7 @@ import java.util.List;
// CASE af.flow_status WHEN 'COMPLETE' THEN 1 WHEN 'APPROVING' THEN 2 WHEN 'DRAFT' THEN 3 WHEN 'REJECTED' THEN 4 ELSE 5 END ASC,
@SQLQuery(value = {
// 查询每个报告最新审批流程
@SQL(view = "getAllReportApprovalList",
sql = "WITH RankedFlows AS (SELECT af.id AS flowId, r.id AS reportId, af.process_title AS title, af.flow_status AS status, af.create_by AS createBy, xu.username AS username, af.created_time AS createdTime, ac.assignees AS current_users, ROW_NUMBER() OVER (PARTITION BY af.template_id ORDER BY af.created_time DESC) AS rn FROM yfsjglpt_model_approval_flow af LEFT JOIN approval_config ac ON af.id = ac.approval_id AND af.current_node = ac.node_order LEFT JOIN yfsjglpt_model_benchmarking_report r ON af.template_id = r.id LEFT JOIN xdap_users xu ON xu.id = af.create_by WHERE af.flow_type = 2 and af.flow_status <> 'DRAFT') SELECT flowId, reportId, title, status, createBy, username, createdTime, current_users FROM RankedFlows WHERE rn = 1 AND title LIKE CONCAT('%', #title, '%') AND status LIKE CONCAT('%', #status, '%') AND createdTime LIKE CONCAT('%', #createdTime, '%') AND username LIKE CONCAT('%', #username, '%') ORDER BY createdTime DESC")
})

View File

@ -6,6 +6,7 @@ import com.xdap.self_development.pojo.ApprovalConfigPojo;
import com.xdap.self_development.pojo.ApprovalFlow;
import com.xdap.self_development.pojo.ApprovalRecord;
import com.xdap.self_development.pojo.BenchmarkingReport;
import com.xdap.self_development.pojo.dto.ApprovalNodesDTO;
import com.xdap.self_development.pojo.view.ApprovalFlowNodeView;
import com.xdap.self_development.pojo.view.TodoAndReportListView;
import com.xdap.self_development.pojo.view.TodoAndReportView;
@ -23,6 +24,8 @@ public interface BenchmarkingReportService {
void startReportApproval(ApprovalPersonForm form);
void restartReportApproval(@Valid RestartReportApprovalForm form);
void directSendingApproval(@NotBlank String reportId, @NotBlank String userId);
void handleReturnToNode(@Valid HandleReturnNodeForm form);
@ -53,4 +56,6 @@ public interface BenchmarkingReportService {
void updateTasks(ApprovalFlow flow, String status, Integer enableReturn);
ApprovalNodesDTO getApprovalUsers(@NotBlank String flowId);
}

View File

@ -33,6 +33,10 @@ public interface TodoTaskService {
void todoReturn(TodoReturnRequest todoReturnRequest);
void batchInsertTodoTask(List<TodoTaskPojo> todoTaskPojos);
void batchInsertInitiatedTask(List<InitiatedTaskPojo> taskPojos);
//---------------------------------玉柴调用接口--------------------------------
List<YcTodoTaskResultDTO> returnTodoTask(YcGetTodoTaskRequest ycGetTodoTaskRequest);

View File

@ -1,7 +1,6 @@
package com.xdap.self_development.service.impl;
import com.alibaba.fastjson2.JSON;
import com.definesys.mpaas.query.MpaasQueryFactory;
import com.xdap.api.moudle.user.pojo.XdapUsers;
import com.xdap.self_development.config.BusinessDatabase;
import com.xdap.self_development.controller.form.ApprovalUserNodeDTO;
@ -23,7 +22,6 @@ import groovy.util.logging.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -173,6 +171,16 @@ public class ActivitiProcessServiceImpl implements ActivitiProcessService {
XdapUsers XdapUsers = xdapDeptUsersService.selectUserByID(userId);
String createBy = ObjectUtils.isNotEmpty(XdapUsers) ? XdapUsers.getUsername() : null;
String approvalId = UUID.randomUUID().toString();
if (approvalNodeRequest.getFlowId() != null && !approvalNodeRequest.getFlowId().isEmpty()) {
// 清除拒绝提醒待办
bd.getBusinessDatabase()
.eq("document_no", approvalNodeRequest.getFlowId())
.eq("data_type", "数据拒绝")
.update("is_delete", 1)
.doUpdate(TodoTaskPojo.class);
}
// 创建发动机审核列表POJO对象
EngineReviewListPojo engineReviewListPojo = new EngineReviewListPojo();
engineReviewListPojo.setId(approvalId);
@ -413,7 +421,7 @@ public class ActivitiProcessServiceImpl implements ActivitiProcessService {
myself.cancelProcess(
flow,
currentNode,
ParamValueVersionEnum.DRAFT,
ParamValueVersionEnum.REFUSE,
request.getUserId()
);
return;
@ -431,12 +439,12 @@ public class ActivitiProcessServiceImpl implements ActivitiProcessService {
// 检查节点是否完成
public boolean checkNodeComplete(EngineReviewListPojo flow, ApprovalConfigPojo node) {
ParamApprovalRecordPojo lastedRecord = bd.getBusinessDatabase()
.eq("flow_id", flow.getId())
.orderBy("approval_time", "desc")
.eq("approval_id", flow.getId())
.orderBy("operate_time", "desc")
.doQueryFirst(ParamApprovalRecordPojo.class);
Integer processedCount = bd.getBusinessDatabase()
.eq("flow_id", flow.getId())
.eq("node", node.getNodeName())
.eq("approval_id", flow.getId())
.eq("node_name", node.getNodeName())
.eq("approval_level", lastedRecord.getApprovalLevel())
.doQuery(ParamApprovalRecordPojo.class).size();
if ("会签".equals(node.getNodeName())) {
@ -461,13 +469,13 @@ public class ActivitiProcessServiceImpl implements ActivitiProcessService {
.doUpdate(TodoTaskPojo.class);
// 更改参数状态为草稿
bd.getBusinessDatabase()
.update("version_status", status.getCode())// 改为已拒绝
.update("version_status", ParamValueVersionEnum.DRAFT.getCode())
.update("operation", "")// 清空操作状态
.update("minor_version", "")// 小版本清空
.update("last_update_date", new Date())
.eq("approval_id", flow.getId())
.doUpdate(EngineParamDetailPojo.class);
// 审批流改为已拒绝
// 审批流改为已拒绝或已撤回
bd.getBusinessDatabase()
.update("status_code", status.getCode())
.update("status_description", status.getDesc())
@ -475,6 +483,7 @@ public class ActivitiProcessServiceImpl implements ActivitiProcessService {
.update("last_update_date", new Date())
.update("return_num", flow.getReturnNum() + 1)
.update("pre_node", node.getNodeOrder())
.update("node_name", "")
.eq("id", flow.getId())
.doUpdate(EngineReviewListPojo.class);
// 生成拒绝提醒
@ -495,9 +504,9 @@ public class ActivitiProcessServiceImpl implements ActivitiProcessService {
todoTask.setOwnerId(flow.getCreatedBy());
todoTask.setCurrentProcessor(JSON.toJSONString(Collections.singletonList(flow.getCreatedBy())));
bd.getBusinessDatabase().doInsert(todoTask);
// 更新发起和已办
myself.updateTasks(flow, status.getDesc(), 0);
}
// 更新发起和已办
myself.updateTasks(flow, status.getDesc(), 0);
}
public void updateTasks(
EngineReviewListPojo flow,
@ -599,9 +608,6 @@ public class ActivitiProcessServiceImpl implements ActivitiProcessService {
.eq("id", flow.getId()).doUpdate(EngineReviewListPojo.class);
}
}
else {
return;
}
}
public void addNodeTodo(
@ -745,14 +751,12 @@ public class ActivitiProcessServiceImpl implements ActivitiProcessService {
.doQueryFirst(ApprovalConfigPojo.class);
// 删除当前节点待办
if (currentNode != null) {
bd.getBusinessDatabase()
.eq("document_no", flow.getId())
.eq("current_node", currentNode.getNodeName())
.update("is_delete", 1)
.update("last_update_date", Timestamp.valueOf(LocalDateTime.now()))
.doUpdate(TodoTaskPojo.class);
}
bd.getBusinessDatabase()
.eq("document_no", flow.getId())
.eq("current_node", currentNode.getNodeName())
.update("is_delete", 1)
.update("last_update_date", Timestamp.valueOf(LocalDateTime.now()))
.doUpdate(TodoTaskPojo.class);
// 根据状态不同获取节点和节点层级
ApprovalConfigPojo preNode = bd.getBusinessDatabase()
@ -783,6 +787,7 @@ public class ActivitiProcessServiceImpl implements ActivitiProcessService {
bd.getBusinessDatabase()
.update("status_code", ParamValueVersionEnum.UNDER.getCode())
.update("status_description", ParamValueVersionEnum.UNDER.getDesc())
.update("node_name", currentNode.getNodeName())
.update("approver_persons", "")
.update("last_update_date", new Date())
.eq("id", flow.getId()).doUpdate(EngineReviewListPojo.class);
@ -790,7 +795,7 @@ public class ActivitiProcessServiceImpl implements ActivitiProcessService {
// 清除拒绝提醒待办
bd.getBusinessDatabase()
.eq("document_no", flow.getId())
.eq("data_type", "模板拒绝")
.eq("data_type", "数据拒绝")
.update("is_delete", 1)
.doUpdate(TodoTaskPojo.class);
@ -990,7 +995,6 @@ public class ActivitiProcessServiceImpl implements ActivitiProcessService {
@Override
public ActivitiDataAndRecordDTO showActivitiData(ShowActivitiDTO showActivitiDTO) {
String approvalId = showActivitiDTO.getApprovalId();
String userID = showActivitiDTO.getUserID();
if (approvalId == null) {
throw new RuntimeException("无效的审批记录");
}
@ -1031,7 +1035,7 @@ public class ActivitiProcessServiceImpl implements ActivitiProcessService {
// 查询所有流程记录
List<ParamApprovalRecordPojo> allRecord = bd.getBusinessDatabase()
.eq("approval_id", approvalId)
.orderBy("creation_date", "desc")
.orderBy("operate_time", "desc")
.doQuery(ParamApprovalRecordPojo.class);
//获取配置
List<ApprovalConfigPojo> nodes = bd.getBusinessDatabase()
@ -1079,9 +1083,9 @@ public class ActivitiProcessServiceImpl implements ActivitiProcessService {
} else {
FlowNode flowNode = new FlowNode();
flowNode.setNode(record.getNodeName());
flowNode.setTodoUserName(record.getCreatedBy());
flowNode.setTodoUserName(record.getAssignee());
flowNode.setResult(record.getOperator());
flowNode.setApprovalTime((Timestamp) record.getOperateTime());
flowNode.setApprovalTime(new Timestamp(record.getOperateTime().getTime()));
flowNodes.add(flowNode);
}
});
@ -1098,6 +1102,20 @@ public class ActivitiProcessServiceImpl implements ActivitiProcessService {
EngineReviewListPojo engineReviewListPojos = bd.getBusinessDatabase()
.eq("id", approvalId).doQueryFirst(EngineReviewListPojo.class);
// 查询基础数据
activitiDataAndRecordDTO.setCurrentNode(flow.getNodeName());
activitiDataAndRecordDTO.setCreateBy(
getUserNames(
Arrays.asList(flow.getApplicant().split(","))
)
);
activitiDataAndRecordDTO.setCreateTime(flow.getCreationDate());
activitiDataAndRecordDTO.setProcessor(
!Objects.equals(flow.getStatusCode(), ParamValueVersionEnum.PASSED.getCode()) ?
getUserNames(
Arrays.asList(flow.getApproverPersons().split(","))
) : ""
);
activitiDataAndRecordDTO.setModelName(engineReviewListPojos.getModelName());
activitiDataAndRecordDTO.setApprovalStatus(engineReviewListPojos.getStatusDescription());
activitiDataAndRecordDTO.setProcessTitle(engineReviewListPojos.getProcessTopic());
@ -1138,9 +1156,9 @@ public class ActivitiProcessServiceImpl implements ActivitiProcessService {
nodeView.setNode(node.getNodeName());
nodeView.setUndoUserName(getUserNames(Arrays.asList(node.getAssignees().split(","))));
nodeView.setTodoUserName(getUserNames(Arrays.asList(node.getAssignees().split(","))));
nodeView.setApprovalTime((Timestamp) reversedTime.get(0).getOperateTime());
nodeView.setApprovalTime(new Timestamp(reversedTime.get(0).getOperateTime().getTime()));
nodeView.setOpinions(records.stream().map(approvalRecord ->
getUserNames(Collections.singletonList(approvalRecord.getCreatedBy())) + ":" + approvalRecord.getApprovalComment()).collect(Collectors.toList()));
getUserNames(Collections.singletonList(approvalRecord.getAssignee())) + ":" + approvalRecord.getApprovalComment()).collect(Collectors.toList()));
} else {
// 节点未完成
nodeView.setNodeOrder(node.getNodeOrder());
@ -1153,7 +1171,7 @@ public class ActivitiProcessServiceImpl implements ActivitiProcessService {
} else {
ParamApprovalRecordPojo record = bd.getBusinessDatabase()
.eq("approval_id", flowId)
.eq("node_Name", node.getNodeName())
.eq("node_name", node.getNodeName())
.eq("approval_level", level)
.doQueryFirst(ParamApprovalRecordPojo.class);
nodeView.setNodeOrder(node.getNodeOrder());
@ -1161,9 +1179,9 @@ public class ActivitiProcessServiceImpl implements ActivitiProcessService {
if (record != null) {
// 节点已完成
nodeView.setResult(record.getOperator());
nodeView.setOpinions(Collections.singletonList(getUserNames(Collections.singletonList(record.getCreatedBy())) + ":" + record.getApprovalComment()));
nodeView.setApprovalTime((Timestamp) record.getOperateTime());
nodeView.setTodoUserName(getUserNames(Collections.singletonList(record.getCreatedBy())));
nodeView.setOpinions(Collections.singletonList(getUserNames(Collections.singletonList(record.getAssignee())) + ":" + record.getApprovalComment()));
nodeView.setApprovalTime(new Timestamp(record.getOperateTime().getTime()));
nodeView.setTodoUserName(getUserNames(Collections.singletonList(record.getAssignee())));
} else {
// 节点未完成
nodeView.setResult("待审批");
@ -1177,7 +1195,10 @@ public class ActivitiProcessServiceImpl implements ActivitiProcessService {
private String getUserNames(List<String> userIds) {
StringJoiner joiner = new StringJoiner(" ");
for (String userId : userIds) {
String username = bd.getBusinessDatabase().eq("id", userId).doQueryFirst(XdapUsers.class).getUsername();
String username = bd.getBusinessDatabase()
.eq("id", userId)
.doQueryFirst(XdapUsers.class)
.getUsername();
if (username != null) {
joiner.add(username);
} else {

View File

@ -15,6 +15,7 @@ import com.xdap.self_development.feign.dto.FileUploadDTO;
import com.xdap.self_development.feign.dto.UserTokenDT0;
import com.xdap.self_development.pojo.*;
import com.xdap.self_development.pojo.dto.ApprovalNodeDTO;
import com.xdap.self_development.pojo.dto.ApprovalNodesDTO;
import com.xdap.self_development.pojo.view.*;
import com.xdap.self_development.service.BenchmarkingReportService;
import com.xdap.self_development.service.XdapDeptUsersService;
@ -142,7 +143,7 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
.stream().map(ApprovalConfigPojo::getId)
.collect(Collectors.toList());
bd.getBusinessDatabase()
.in("ids", ids)
.in("id", ids)
.doDelete(ApprovalConfigPojo.class);
List<ApprovalConfigPojo> approvalConfigs = new ArrayList<>();
for (ApprovalNodeDTO node : form.getNodeList()) {
@ -228,6 +229,27 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
throw new CommonException("该报告正在审批中");
}
// 清除拒绝提醒待办
ApprovalFlow historyFlow = bd.getBusinessDatabase()
.eq("template_id", report.getId())
.in("flow_status", "REJECTED", "RETURNED")
.doQueryFirst(ApprovalFlow.class);
if (historyFlow != null) {
bd.getBusinessDatabase()
.eq("document_no", historyFlow.getId())
.eq("data_type", "对标报告拒绝")
.update("is_delete", 1)
.doUpdate(TodoTaskPojo.class);
}
// 更新流程状态
bd.getBusinessDatabase()
.eq("id", approvalFlow.getId())
.update("flow_status", "APPROVING")
.update("current_node", 1)
.update("pre_node", -1)
.doUpdate(ApprovalFlow.class);
// 获取首个节点
ApprovalConfigPojo firstNode = bd.getBusinessDatabase()
.eq("approval_id", approvalFlow.getId())
@ -252,7 +274,7 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
todoTask.setStatusCode(approvalFlow.getFlowStatus());
todoTask.setVersionNumber(1);
todoTask.setOwnerId(person);
todoTask.setCurrentProcessor(JSON.toJSONString(firstNode.getAssignees()));
todoTask.setCurrentProcessor(firstNode.getAssignees());
list.add(todoTask);
}
bd.getBusinessDatabase().doBatchInsert(list);
@ -263,7 +285,7 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
initiatedTask.setCreatedById(form.getUserId());
initiatedTask.setCreatedBy(xdapDeptUsersService.selectUserByID(form.getUserId()).getUsername());
initiatedTask.setCurrentNode(firstNode.getNodeName());
initiatedTask.setCurrentProcessor(JSON.toJSONString(firstNode.getAssignees()));
initiatedTask.setCurrentProcessor(firstNode.getAssignees());
initiatedTask.setDataType("对标报告审核");
initiatedTask.setProcessTitle(approvalFlow.getProcessTitle());
initiatedTask.setCreationDate(Timestamp.valueOf(LocalDateTime.now()));
@ -292,10 +314,153 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
.doUpdate(BenchmarkingReport.class);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void restartReportApproval(RestartReportApprovalForm form) {
// 获取报告
BenchmarkingReport report = bd.getBusinessDatabase()
.eq("id", form.getReportId())
.doQueryFirst(BenchmarkingReport.class);
if (report == null) {
throw new CommonException("报告不存在");
}
ApprovalFlow historyFlow = bd.getBusinessDatabase()
.eq("template_id", report.getId())
.eq("flow_status", "APPROVING")
.doQueryFirst(ApprovalFlow.class);
if (historyFlow != null) {
throw new CommonException("报告正在审批中");
}
// 修改报告
BeanUtils.copyProperties(form, report);
report.setFilePath(form.getFileUrl() == null ? "" : form.getFileUrl());
report.setUploadTime(Timestamp.valueOf(LocalDateTime.now()));
report.setStatus("DRAFT");
bd.getBusinessDatabase()
.eq("id", report.getId())
.doUpdate(report);
// 清除拒绝提醒待办
ApprovalFlow approvalFlow = bd.getBusinessDatabase()
.eq("template_id", report.getId())
.in("flow_status", "REJECTED", "RETURNED")
.doQueryFirst(ApprovalFlow.class);
bd.getBusinessDatabase()
.eq("document_no", approvalFlow.getId())
.eq("data_type", "对标报告拒绝")
.update("is_delete", 1)
.doUpdate(TodoTaskPojo.class);
// 新增流程
ApprovalFlow flow = new ApprovalFlow();
flow.setTemplateId(report.getId());
flow.setCurrentNode(1);
flow.setFlowStatus("APPROVING");
flow.setProcessTitle(form.getProcessTitle());
flow.setCreateBy(form.getUserId());
flow.setCreatedTime(Timestamp.valueOf(LocalDateTime.now()));
flow.setFlowType(2); // 设置为报告审批流程
flow.setExplanation(form.getExplanation());
flow.setReturnNum(0);
flow.setPreNode(-1);
bd.getBusinessDatabase().doInsert(flow);
// 创建审批配置
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);
// 发起流程
ApprovalPersonForm newForm = new ApprovalPersonForm();
newForm.setUserId(form.getUserId());
newForm.setFlowId(flow.getId());
newForm.setReportId(report.getId());
// 更新流程状态
bd.getBusinessDatabase()
.eq("id", newForm.getFlowId())
.update("flow_status", "APPROVING")
.update("current_node", 1)
.update("pre_node", -1)
.doUpdate(ApprovalFlow.class);
// 获取首个节点
ApprovalConfigPojo firstNode = bd.getBusinessDatabase()
.eq("approval_id", newForm.getFlowId())
.eq("node_order", 1)
.doQueryFirst(ApprovalConfigPojo.class);
// 新增我的待办
List<TodoTaskPojo> list = new ArrayList<>();
for (String person : JSON.parseArray(firstNode.getAssignees()).toJavaList(String.class)) {
TodoTaskPojo todoTask = new TodoTaskPojo();
todoTask.setCreatedById(newForm.getUserId());
todoTask.setCreatedBy(xdapDeptUsersService.selectUserByID(newForm.getUserId()).getUsername());
todoTask.setCurrentNode(firstNode.getNodeName());
todoTask.setDataType("对标报告审核");
todoTask.setDocumentNo(newForm.getFlowId());
todoTask.setCreationDate(Timestamp.valueOf(LocalDateTime.now()));
todoTask.setIsDelete(0);
todoTask.setModelId(report.getId());
todoTask.setModelName(report.getProjectName() + "对标报告");
todoTask.setProcessTitle(approvalFlow.getProcessTitle());
todoTask.setStatusCode(approvalFlow.getFlowStatus());
todoTask.setVersionNumber(1);
todoTask.setOwnerId(person);
todoTask.setCurrentProcessor(firstNode.getAssignees());
list.add(todoTask);
}
bd.getBusinessDatabase().doBatchInsert(list);
// 新增我创建的
InitiatedTaskPojo initiatedTask = new InitiatedTaskPojo();
initiatedTask.setDocumentNo(approvalFlow.getId());
initiatedTask.setCreatedById(newForm.getUserId());
initiatedTask.setCreatedBy(xdapDeptUsersService.selectUserByID(newForm.getUserId()).getUsername());
initiatedTask.setCurrentNode(firstNode.getNodeName());
initiatedTask.setCurrentProcessor(firstNode.getAssignees());
initiatedTask.setDataType("对标报告审核");
initiatedTask.setProcessTitle(approvalFlow.getProcessTitle());
initiatedTask.setCreationDate(Timestamp.valueOf(LocalDateTime.now()));
initiatedTask.setIsDelete(0);
initiatedTask.setModelId(approvalFlow.getTemplateId());
initiatedTask.setEnableReturn(1);
bd.getBusinessDatabase().doInsert(initiatedTask);
// 新增发起记录
bd.getBusinessDatabase().doInsert(
new ApprovalRecord(
approvalFlow.getId(),
"发起审批",
xdapDeptUsersService.selectUserByID(newForm.getUserId()).getUsername(),
"发起审批",
"MSG",
Timestamp.valueOf(LocalDateTime.now()),
1
)
);
// 更新报告状态为校对中
bd.getBusinessDatabase()
.eq("id", report.getId())
.update("status", "APPROVING")
.doUpdate(BenchmarkingReport.class);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void directSendingApproval(String reportId, String userId) {
// 获取模板
// 获取报告
BenchmarkingReport report = bd.getBusinessDatabase()
.eq("id", reportId)
.doQueryFirst(BenchmarkingReport.class);
@ -307,7 +472,7 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
ApprovalFlow flow = bd.getBusinessDatabase()
.eq("template_id", reportId)
.ne("pre_node", -1)
.eq("flow_status", "APPROVING")
.ne("flow_status", "COMPLETE")
.orderBy("created_time", "desc")
.doQueryFirst(ApprovalFlow.class);
if (flow == null) {
@ -364,7 +529,7 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
// 清除拒绝提醒待办
bd.getBusinessDatabase()
.eq("document_no", flow.getId())
.eq("data_type", "模板拒绝")
.eq("data_type", "对标报告拒绝")
.update("is_delete", 1)
.doUpdate(TodoTaskPojo.class);
@ -823,6 +988,45 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
.doUpdate(InitiatedTaskPojo.class);
}
@Override
public ApprovalNodesDTO getApprovalUsers(String flowId) {
ApprovalNodesDTO nodes = new ApprovalNodesDTO();
nodes.setProcessTitle("");
nodes.setExplanation("");
List<ApprovalUserNodeDTO> list = new ArrayList<>();
// 获取到模板最近一次未完成的流程
ApprovalFlow flow = bd.getBusinessDatabase()
.eq("id", flowId)
.doQueryFirst(ApprovalFlow.class);
if (flow == null) {
nodes.setNodeList(list);
return nodes;
}
// 获取流程节点
List<ApprovalConfigPojo> approvalConfigs = bd.getBusinessDatabase()
.eq("approval_id", flow.getId())
.doQuery(ApprovalConfigPojo.class);
approvalConfigs.forEach(node -> {
ApprovalUserNodeDTO dto = new ApprovalUserNodeDTO();
List<String> userIds = JSON.parseArray(node.getAssignees()).toJavaList(String.class);
dto.setNodeName(node.getNodeName());
dto.setNodeOrder(node.getNodeOrder());
dto.setAssignees(
bd.getBusinessDatabase()
.in("id", userIds)
.doQuery(XdapUsers.class)
);
list.add(dto);
});
nodes.setProcessTitle(flow.getProcessTitle());
nodes.setExplanation(flow.getExplanation());
nodes.setNodeList(list);
return nodes;
}
@Override
public BenchmarkingReport getReportDetail(String reportId) {
return bd.getBusinessDatabase()
@ -854,12 +1058,29 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
.eq("id", approvalFlow.getTemplateId())
.doQueryFirst(BenchmarkingReport.class);
// 获取节点信息
if (approvalFlow.getCurrentNode() != null) {
ApprovalConfigPojo currentNode = bd.getBusinessDatabase()
.eq("approval_id", approvalFlow.getId())
.eq("node_order", approvalFlow.getCurrentNode())
.doQueryFirst(ApprovalConfigPojo.class);
flowNodeView.setCurrentNode(currentNode.getNodeName());
flowNodeView.setProcessor(getUserNames(
JSON.parseArray(currentNode.getAssignees()).toJavaList(String.class)
));
} else {
flowNodeView.setCurrentNode("");
flowNodeView.setProcessor("");
}
// 获取流程信息
flowNodeView.setProgressTitle(approvalFlow.getProcessTitle());
flowNodeView.setContentName(report.getTitle());
flowNodeView.setTemplateVersion(1);
flowNodeView.setExplanation(approvalFlow.getExplanation());
flowNodeView.setFlowStatus(approvalFlow.getFlowStatus());
flowNodeView.setCreateBy(xdapDeptUsersService.selectUserByID(approvalFlow.getCreateBy()).getUsername());
flowNodeView.setCreateTime(approvalFlow.getCreatedTime());
// 获取节点信息
List<ApprovalConfigPojo> nodes = bd.getBusinessDatabase()

View File

@ -18,6 +18,7 @@ import com.xdap.self_development.controller.request.EngineParamDetailRequest;
import com.xdap.self_development.enums.CurrentNodeEnum;
import com.xdap.self_development.enums.ParamOperation;
import com.xdap.self_development.enums.ParamValueVersionEnum;
import com.xdap.self_development.exception.CommonException;
import com.xdap.self_development.exception.ExcelImportException;
import com.xdap.self_development.listener.EngineParamDetailListener;
import com.xdap.self_development.pojo.*;
@ -381,9 +382,9 @@ public class EngineParamDetailServiceImpl implements EngineParamDetailService {
for (EngineParamDetailPojo detailPojo : detailPojos) {
String filledBy = null;
if (ObjectUtils.isNotEmpty(detailPojo.getFilledBy())) {
XdapUsers XdapUsers =
XdapUsers user =
xdapDeptUsersService.selectUserByID(detailPojo.getFilledBy());
filledBy = ObjectUtils.isEmpty(XdapUsers) ? "" : XdapUsers.getUsername();
filledBy = ObjectUtils.isEmpty(user) ? "" : user.getUsername();
}
EngineParamDetailDTO engineParamDetailDTO = new EngineParamDetailDTO();
BeanUtils.copyProperties(detailPojo, engineParamDetailDTO);
@ -553,6 +554,17 @@ public class EngineParamDetailServiceImpl implements EngineParamDetailService {
return;
}
String engineModelId = engineParamDetailPojos.get(0).getEngineModelId();
TodoTaskPojo todoTaskPojo = sw.buildFromDatasource("xdap_app_223770822127386625")
.eq("owner_id", userID)
.eq("model_id", engineModelId)
.eq("data_type", "任务分解")
.eq("is_delete", 0)
.doQueryFirst(TodoTaskPojo.class);
if (todoTaskPojo == null) {
throw new CommonException("没有分解任务,请刷新重试");
}
DataEntryEngineModelPojo modelPojo = dataEntryEngineModelService.selectBymodelId(engineModelId);
XdapUsers XdapUsers = xdapDeptUsersService.selectUserByID(userID);
@ -568,26 +580,26 @@ public class EngineParamDetailServiceImpl implements EngineParamDetailService {
.doUpdate(engineParamDetailPojo);
}
//为每个填写人分配任务
Set<String> filledBys = engineParamDetailPojos.stream().map(x -> x.getFilledBy()).collect(Collectors.toSet());
Set<String> filledBys = engineParamDetailPojos.stream().map(EngineParamDetailPojo::getFilledBy).collect(Collectors.toSet());
for (String filledBy : filledBys) {
TodoTaskPojo todoTaskPojo = new TodoTaskPojo();
todoTaskPojo.setCreatedById(userID);
todoTaskPojo.setDocumentNo(UUID.randomUUID().toString());
todoTaskPojo.setProcessTitle("填写参数");
todoTaskPojo.setCurrentNode("待维护");
todoTaskPojo.setStatusCode(null);
todoTaskPojo.setModelName(modelPojo.getModelName());
todoTaskPojo.setModelId(modelPojo.getId());
todoTaskPojo.setCreationDate(Timestamp.valueOf(LocalDateTime.now()));
todoTaskPojo.setDataType(CurrentNodeEnum.REPAIR.getDesc());
todoTaskPojo.setVersionNumber(modelPojo.getVersionNumber());
todoTaskPojo.setOwnerId(filledBy);
todoTaskPojo.setCurrentProcessor(JSON.toJSONString(Arrays.asList(filledBy)));
todoTaskPojo.setIsDelete(0);
todoTaskPojo.setCreatedBy(ObjectUtils.isNotEmpty(XdapUsers) ? XdapUsers.getUsername() : "");
todoTaskPojos.add(todoTaskPojo);
TodoTaskPojo todoTask = new TodoTaskPojo();
todoTask.setCreatedById(userID);
todoTask.setDocumentNo(UUID.randomUUID().toString());
todoTask.setProcessTitle("填写参数");
todoTask.setCurrentNode("待维护");
todoTask.setStatusCode(null);
todoTask.setModelName(modelPojo.getModelName());
todoTask.setModelId(modelPojo.getId());
todoTask.setCreationDate(Timestamp.valueOf(LocalDateTime.now()));
todoTask.setDataType(CurrentNodeEnum.REPAIR.getDesc());
todoTask.setVersionNumber(modelPojo.getVersionNumber());
todoTask.setOwnerId(filledBy);
todoTask.setCurrentProcessor(JSON.toJSONString(Arrays.asList(filledBy)));
todoTask.setIsDelete(0);
todoTask.setCreatedBy(ObjectUtils.isNotEmpty(XdapUsers) ? XdapUsers.getUsername() : "");
todoTaskPojos.add(todoTask);
InitiatedTaskPojo initiatedTaskPojo = new InitiatedTaskPojo();
BeanUtils.copyProperties(todoTaskPojo, initiatedTaskPojo);
BeanUtils.copyProperties(todoTask, initiatedTaskPojo);
initiatedTaskPojo.setLastUpdatedBy(filledBy);
taskPojos.add(initiatedTaskPojo);
}
@ -600,10 +612,6 @@ public class EngineParamDetailServiceImpl implements EngineParamDetailService {
.filter(x -> x.getEngineModelId().equals(engineModelId) && ObjectUtils.isEmpty(x.getFilledBy())).collect(Collectors.toList());
if (ObjectUtils.isEmpty(paramDetailPojos) || paramDetailPojos.isEmpty()) {
//软删除这个代办人的任务
TodoTaskPojo todoTaskPojo = sw.buildFromDatasource("xdap_app_223770822127386625")
.eq("owner_id", userID)
.eq("model_id", engineModelId)
.eq("data_type", "任务分解").doQueryFirst(TodoTaskPojo.class);
//更新待办和发起的任务状态
sw.buildFromDatasource("xdap_app_223770822127386625")
.update("is_delete", 1)
@ -685,7 +693,9 @@ public class EngineParamDetailServiceImpl implements EngineParamDetailService {
}
if ("TC分类表".equals(x.getParameterSource())) {
return false;
} else {
}
// TODO:还需排除公式计算的
else {
return true;
}
}).collect(Collectors.toList());

View File

@ -189,12 +189,13 @@ public class ModelRoleServiceImpl implements ModelRoleService {
log.warn("该角色没有权限");
return null;
}
List<String> perids = role.stream().map(x -> x.getPerId()).distinct().collect(Collectors.toList());
List<ModelMenuParameterPojo> menuParameters = businessDatabase.getBusinessDatabase()
.in("id", perids)
.doQuery(ModelMenuParameterPojo.class);
//获取权限
for (ModelMenuParameterPojo menuParameter : menuParameters) {
try {
List<String> perids = role.stream().map(x -> x.getPerId()).distinct().collect(Collectors.toList());
List<ModelMenuParameterPojo> menuParameters = businessDatabase.getBusinessDatabase()
.in("id", perids)
.doQuery(ModelMenuParameterPojo.class);
//获取权限
for (ModelMenuParameterPojo menuParameter : menuParameters) {
/* 权限变更不再管理菜单且不再存参数 改为子系统+零部件
ModelMenuDictionaryPojo modelMenuDictionaryPojo = modelMenuPermissionService.selectMenuById(menuParameter.getMenuId());
String parameterId = menuParameter.getParameterId();
@ -211,17 +212,20 @@ public class ModelRoleServiceImpl implements ModelRoleService {
Parameter parameter = parameters.get(0);*/
ParamPermissionEnum byCode = ParamPermissionEnum.getByCode(menuParameter.getParameterPer());
if (byCode == null) {
throw new RuntimeException("权限异常");
}
MenuParamView menuParamView = new MenuParamView();
menuParamView.setId(menuParameter.getId());
ParamPermissionEnum byCode = ParamPermissionEnum.getByCode(menuParameter.getParameterPer());
if (byCode == null) {
throw new RuntimeException("权限异常");
}
MenuParamView menuParamView = new MenuParamView();
menuParamView.setId(menuParameter.getId());
// menuParamView.setMenuPath(modelMenuDictionaryPojo.getMenuDesc());
// menuParamView.setPartsName(menuParameter.getPartsName());
menuParamView.setPermissionPath(menuParameter.getPermissionPath());
menuParamView.setParameterPer(byCode.getDesc());
menuParamViews.add(menuParamView);
menuParamView.setPermissionPath(menuParameter.getPermissionPath());
menuParamView.setParameterPer(byCode.getDesc());
menuParamViews.add(menuParamView);
}
} catch (Exception e) {
return null;
}
return menuParamViews;

View File

@ -9,6 +9,7 @@ import com.xdap.self_development.config.BusinessDatabase;
import com.xdap.self_development.controller.request.AnalysisRequest;
import com.xdap.self_development.controller.request.AnalysisVerRequest;
import com.xdap.self_development.controller.request.ModelComparisonExportRequest;
import com.xdap.self_development.controller.request.ModelItem;
import com.xdap.self_development.pojo.*;
import com.xdap.self_development.service.DataEntryEngineModelService;
import com.xdap.self_development.service.EngineParamDetailService;
@ -19,6 +20,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
@ -31,7 +33,7 @@ import java.util.stream.Collectors;
@Slf4j
public class TcDataQueryServiceImpl implements TcDataQueryService {
@Autowired
@Resource
private BusinessDatabase bd;
@Autowired
private EngineParamDetailService engineParamDetailService;
@ -412,7 +414,7 @@ public class TcDataQueryServiceImpl implements TcDataQueryService {
@Override
public void modelComparisonExport(ModelComparisonExportRequest request, HttpServletResponse response) {
List<String> modelIds = request.getModelIds();
List<ModelItem> models = request.getModels();
String userID = request.getUserID();
List<String> subsystemParts = request.getSubsystemParts();
@ -422,10 +424,10 @@ public class TcDataQueryServiceImpl implements TcDataQueryService {
// 获取机型名称映射
Map<String, String> modelNames = new HashMap<>();
for (String modelId : modelIds) {
DataEntryEngineModelPojo model = engineModelService.selectBymodelId(modelId);
if (model != null) {
modelNames.put(modelId, model.getModelName());
for (ModelItem model : models) {
DataEntryEngineModelPojo tempModel = engineModelService.selectBymodelId(model.getModelId());
if (tempModel != null) {
modelNames.put(model.getModelId(), tempModel.getModelName());
}
}
@ -435,9 +437,9 @@ public class TcDataQueryServiceImpl implements TcDataQueryService {
Map<String, String[]> parameterSubsystemParts = new HashMap<>();
// 从Redis获取每个机型的数据
for (String modelId : modelIds) {
for (ModelItem model : models) {
try {
String redisKey = userID + ":" + modelId + ":" + "ComparisonExport";
String redisKey = userID + ":" + model.getModelId() + ":" + model.getParameterVersion() + ":" + "ComparisonExport";
String cachedData = redisTemplate.opsForValue().get(redisKey);
if (ObjectUtils.isNotEmpty(cachedData)) {
@ -475,11 +477,11 @@ public class TcDataQueryServiceImpl implements TcDataQueryService {
}
// 设置该机型的参数值
parameterValues.get(paramName).put(modelId, paramValue);
parameterValues.get(paramName).put(model.getModelId(), paramValue);
}
}
} catch (Exception e) {
log.error("从Redis读取机型{}数据失败: {}", modelId, e.getMessage());
log.error("从Redis读取机型{}数据失败: {}", model.getModelId(), e.getMessage());
}
}
@ -491,8 +493,8 @@ public class TcDataQueryServiceImpl implements TcDataQueryService {
header.add("子系统");
header.add("零部件");
header.add("参数");
for (String modelId : modelIds) {
header.add(modelNames.getOrDefault(modelId, "未知机型"));
for (ModelItem model : models) {
header.add(modelNames.getOrDefault(model.getModelId(), "未知机型"));
}
excelData.add(header);
@ -515,8 +517,8 @@ public class TcDataQueryServiceImpl implements TcDataQueryService {
// 每个机型的参数值
Map<String, String> values = entry.getValue();
for (String modelId : modelIds) {
row.add(values.getOrDefault(modelId, ""));
for (ModelItem model : models) {
row.add(values.getOrDefault(model.getModelId(), ""));
}
excelData.add(row);
@ -654,7 +656,7 @@ public class TcDataQueryServiceImpl implements TcDataQueryService {
}
//将allPojos存到Redis,KEY为userID+engineModelID+预操作过期时间24小时
try {
String redisKey = analysisRequest.getUserID() + ":" + analysisRequest.getEngineModelID() + ":" + "ComparisonExport";
String redisKey = analysisRequest.getUserID() + ":" + analysisRequest.getEngineModelID() + ":" + analysisRequest.getParameterVersion() + ":" + "ComparisonExport";
String jsonValue = objectMapper.writeValueAsString(systemDataList);
redisTemplate.opsForValue().set(redisKey, jsonValue, 24, java.util.concurrent.TimeUnit.HOURS);
log.info("成功将数据存储到RedisKEY: {}", redisKey);

View File

@ -76,6 +76,19 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
throw new CommonException("空参数模板不允许发起审批");
}
// 清除拒绝提醒待办
ApprovalFlow historyFlow = bd.getBusinessDatabase()
.eq("template_id", template.getId())
.in("flow_status", "REJECTED", "RETURNED")
.doQueryFirst(ApprovalFlow.class);
if (historyFlow != null) {
bd.getBusinessDatabase()
.eq("document_no", historyFlow.getId())
.eq("data_type", "模板拒绝")
.update("is_delete", 1)
.doUpdate(TodoTaskPojo.class);
}
// 新增流程
ApprovalFlow flow = new ApprovalFlow();
flow.setTemplateId(template.getId());
@ -195,7 +208,7 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
ApprovalFlow flow = bd.getBusinessDatabase()
.eq("template_id", templateId)
.ne("pre_node", -1)
.eq("flow_status", "APPROVING")
.ne("flow_status", "COMPLETE")
.orderBy("created_time", "desc")
.doQueryFirst(ApprovalFlow.class);
if (flow == null) {
@ -727,12 +740,29 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
.eq("id", approvalFlow.getTemplateId())
.doQueryFirst(Template.class);
// 获取节点信息
if (approvalFlow.getCurrentNode() != null) {
ApprovalConfigPojo currentNode = bd.getBusinessDatabase()
.eq("approval_id", approvalFlow.getId())
.eq("node_order", approvalFlow.getCurrentNode())
.doQueryFirst(ApprovalConfigPojo.class);
flowNodeView.setCurrentNode(currentNode.getNodeName());
flowNodeView.setProcessor(getUserNames(
JSON.parseArray(currentNode.getAssignees()).toJavaList(String.class)
));
} else {
flowNodeView.setCurrentNode("");
flowNodeView.setProcessor("");
}
// 获取流程信息
flowNodeView.setProgressTitle(approvalFlow.getProcessTitle());
flowNodeView.setContentName(template.getTemplateName());
flowNodeView.setTemplateVersion(template.getVersion());
flowNodeView.setExplanation(approvalFlow.getExplanation());
flowNodeView.setFlowStatus(approvalFlow.getFlowStatus());
flowNodeView.setCreateBy(xdapDeptUsersService.selectUserByID(approvalFlow.getCreateBy()).getUsername());
flowNodeView.setCreateTime(approvalFlow.getCreatedTime());
// 获取节点信息
List<ApprovalConfigPojo> nodes = bd.getBusinessDatabase()

View File

@ -1,10 +1,10 @@
package com.xdap.self_development.service.impl;
import com.alibaba.fastjson2.JSON;
import com.definesys.mpaas.query.MpaasQueryFactory;
import com.definesys.mpaas.query.db.PageQueryResult;
import com.xdap.api.moudle.user.pojo.XdapUsers;
import com.xdap.self_development.config.BusinessDatabase;
import com.xdap.self_development.controller.request.TodoReturnRequest;
import com.xdap.self_development.controller.request.TodoTaskRequest;
import com.xdap.self_development.controller.request.YcGetTodoTaskRequest;
@ -17,14 +17,12 @@ import com.xdap.self_development.service.EngineParamDetailService;
import com.xdap.self_development.service.TodoTaskService;
import com.xdap.self_development.service.XdapDeptUsersService;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
@ -44,14 +42,18 @@ import java.util.stream.Collectors;
@Service
public class TodoTaskServiceImpl implements TodoTaskService {
@Autowired
@Resource
private MpaasQueryFactory sw;
@Autowired
@Resource
private EngineParamDetailService engineParamDetailService;
@Autowired
@Resource
private XdapDeptUsersService xdapDeptUsersService;
@Autowired
@Resource
private DataEntryEngineModelService dataEntryEngineModelService;
@Resource
private BusinessDatabase bd;
@Resource
private TodoTaskService myself;
private final String SYSTEM = "研发数据管理平台";
@ -103,7 +105,7 @@ public class TodoTaskServiceImpl implements TodoTaskService {
}
}).collect(Collectors.toList());
} catch (Exception e) {
strings = Arrays.asList(currentProcessor);
strings = Collections.singletonList(currentProcessor);
}
}
taskPojo1.setCurrentProcessor(String.join(",", strings));
@ -117,7 +119,7 @@ public class TodoTaskServiceImpl implements TodoTaskService {
@Override
public PageResultDTO<TodoTaskPojo> selectByresPersonTodoPage(TodoTaskRequest todoTaskRequest) {
PageResultDTO<TodoTaskPojo> pageResultDTO = new PageResultDTO<TodoTaskPojo>();
PageResultDTO<TodoTaskPojo> pageResultDTO = new PageResultDTO<>();
PageQueryResult<TodoTaskPojo> queryResult = sw.buildFromDatasource("xdap_app_223770822127386625")
.eq("owner_id", todoTaskRequest.getPersonId())
.eq("is_delete", 0)
@ -143,7 +145,7 @@ public class TodoTaskServiceImpl implements TodoTaskService {
}
}).collect(Collectors.toList());
} catch (Exception e) {
strings = Arrays.asList(currentProcessor);
strings = Collections.singletonList(currentProcessor);
}
}
todoTaskPojo1.setCurrentProcessor(String.join(",", strings));
@ -157,7 +159,7 @@ public class TodoTaskServiceImpl implements TodoTaskService {
@Override
public PageResultDTO<CompletedTaskPojo> selectByresPersonCompletedPage(TodoTaskRequest taskRequest) {
PageResultDTO<CompletedTaskPojo> pageResultDTO = new PageResultDTO<CompletedTaskPojo>();
PageResultDTO<CompletedTaskPojo> pageResultDTO = new PageResultDTO<>();
PageQueryResult<CompletedTaskPojo> queryResult = sw.buildFromDatasource("xdap_app_223770822127386625")
.eq("owner_id", taskRequest.getPersonId())
.eq("is_delete", 0)
@ -183,7 +185,7 @@ public class TodoTaskServiceImpl implements TodoTaskService {
}
}).collect(Collectors.toList());
} catch (Exception e) {
strings = Arrays.asList(currentProcessor);
strings = Collections.singletonList(currentProcessor);
}
}
taskPojo1.setCurrentProcessor(String.join(",", strings));
@ -217,20 +219,23 @@ public class TodoTaskServiceImpl implements TodoTaskService {
.doUpdate(EngineParamDetailPojo.class);
}
//生成分解任务给责任人 参数根据机型+责任人分组 生成数据
List<EngineParamDetailDTO> dtoList = paramDetailPojosAll.stream()
List<EngineParamDetailDTO> dtoList = new ArrayList<>(paramDetailPojosAll.stream()
// 以responsiblePersonId组合作为key元素本身作为value
.collect(Collectors.toMap(dto -> dto.getResPersonId(),
.collect(Collectors.toMap(EngineParamDetailDTO::getResPersonId,
pojo -> pojo,
(existing, replacement) -> existing
))
// 提取去重后的value集合
.values()
.stream()
.collect(Collectors.toList());
.values());
ArrayList<TodoTaskPojo> todoTaskPojos = new ArrayList<>();
ArrayList<InitiatedTaskPojo> taskPojos = new ArrayList<>();
// TODO:清除待办
// 清除待办
bd.getBusinessDatabase()
.eq("model_id", modelId)
.eq("data_type", CurrentNodeEnum.JOBSPLIT.getDesc())
.update("is_delete", 1)
.doUpdate(TodoTaskPojo.class);
XdapUsers xdapUsersPojo = xdapDeptUsersService.selectUserByID(userID);
DataEntryEngineModelPojo modelPojo = dataEntryEngineModelService.selectBymodelId(modelId);
@ -241,7 +246,7 @@ public class TodoTaskServiceImpl implements TodoTaskService {
todoTaskPojo.setDocumentNo(UUID.randomUUID().toString());
todoTaskPojo.setProcessTitle("分发参数填写人");
todoTaskPojo.setCurrentNode("待分解");
todoTaskPojo.setCurrentProcessor(JSON.toJSONString(Arrays.asList(engineParamDetailDTO.getResPersonId())));
todoTaskPojo.setCurrentProcessor(JSON.toJSONString(Collections.singletonList(engineParamDetailDTO.getResPersonId())));
todoTaskPojo.setStatusCode(null/*String.valueOf(ParamValueVersionEnum.DRAFT.getCode())*/);
todoTaskPojo.setModelName(ObjectUtils.isNotEmpty(modelPojo) ? modelPojo.getModelName() : "");
todoTaskPojo.setModelId(modelId);
@ -257,8 +262,8 @@ public class TodoTaskServiceImpl implements TodoTaskService {
initiatedTaskPojo.setLastUpdatedBy(engineParamDetailDTO.getResPersonId());
taskPojos.add(initiatedTaskPojo);
}
batchInsertTodoTask(todoTaskPojos);
batchInsertInitiatedTask(taskPojos);
myself.batchInsertTodoTask(todoTaskPojos);
myself.batchInsertInitiatedTask(taskPojos);
List<EngineParamDetailPojo> detailPojos = engineParamDetailService.selectByModelNewVersion(modelId);
List<EngineParamDetailPojo> paramDetailPojos = detailPojos.stream()
.filter(x -> ObjectUtils.isEmpty(x.getResponsiblePersonId())).collect(Collectors.toList());
@ -318,7 +323,7 @@ public class TodoTaskServiceImpl implements TodoTaskService {
todoTaskPojo.setDataType(CurrentNodeEnum.JOBSPLIT.getDesc());
todoTaskPojo.setVersionNumber(todoTaskPojo1.getVersionNumber());
todoTaskPojo.setIsDelete(0);
todoTaskPojo.setCurrentProcessor(JSON.toJSONString(Arrays.asList(todoTaskPojo1.getCreatedById())));
todoTaskPojo.setCurrentProcessor(JSON.toJSONString(Collections.singletonList(todoTaskPojo1.getCreatedById())));
todoTaskPojo.setOwnerId(todoTaskPojo1.getCreatedById());
todoTaskPojo.setCreatedBy(ObjectUtils.isNotEmpty(xdapUsersPojo) ? xdapUsersPojo.getUsername() : "");
sw.buildFromDatasource("xdap_app_223770822127386625").doInsert(todoTaskPojo);
@ -353,7 +358,7 @@ public class TodoTaskServiceImpl implements TodoTaskService {
if (ObjectUtils.isEmpty(username)) {
return null;
}
ArrayList<YcTodoTaskResultDTO> dtos = new ArrayList<YcTodoTaskResultDTO>();
ArrayList<YcTodoTaskResultDTO> dtos = new ArrayList<>();
XdapUsers xdapUsers = xdapDeptUsersService.selectUserByCode(username);
if (ObjectUtils.isNotEmpty(xdapUsers)) {
String id = xdapUsers.getId();
@ -393,7 +398,7 @@ public class TodoTaskServiceImpl implements TodoTaskService {
}
String userCode = ObjectUtils.isEmpty(ycGetTodoTaskRequest.getUsername()) ? "" : ycGetTodoTaskRequest.getUsername();
String userid = ObjectUtils.isEmpty(xdapDeptUsersService.selectUserByCode(userCode)) ? "" : xdapDeptUsersService.selectUserByCode(userCode).getId();
List<TodoTaskPojo> todoTaskPojos = new ArrayList<>();
List<TodoTaskPojo> todoTaskPojos;
PageResultDTO<YcTodoTaskCommonResultDTO> ycCompletedResultDTOPageResultDTO = new PageResultDTO<>();
ArrayList<YcTodoTaskCommonResultDTO> ycCompletedResultDTOS = new ArrayList<>();
String str = "owner_id";
@ -429,8 +434,8 @@ public class TodoTaskServiceImpl implements TodoTaskService {
) {
String page = ycGetTodoTaskRequest.getPage();
String pageSize = ycGetTodoTaskRequest.getPageSize();
int pageint = 0;
int pageSizeint = 999;
int pageint;
int pageSizeint;
try {
pageint = Integer.parseInt(page);
pageSizeint = Integer.parseInt(pageSize);
@ -477,10 +482,12 @@ public class TodoTaskServiceImpl implements TodoTaskService {
return ycCompletedResultDTOPageResultDTO;
}
@Override
@Transactional(rollbackFor = Exception.class) // 发生任何异常都回滚
public void batchInsertTodoTask(List<TodoTaskPojo> todoTaskPojos) {
sw.buildFromDatasource("xdap_app_223770822127386625").doBatchInsert(todoTaskPojos);
}
@Override
@Transactional(rollbackFor = Exception.class) // 发生任何异常都回滚
public void batchInsertInitiatedTask(List<InitiatedTaskPojo> taskPojos) {
sw.buildFromDatasource("xdap_app_223770822127386625").doBatchInsert(taskPojos);

View File

@ -1,76 +1,289 @@
package com.xdap.self_development.utils;
import java.util.HashMap;
import java.util.Map;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class FormulaValidator {
// 定义支持的数学运算符
private static final Set<Character> OPERATORS = new HashSet<>(Arrays.asList('+', '-', '*', '/'));
// 定义支持的常量
private static final Set<String> CONSTANTS = new HashSet<>(Arrays.asList("π"));
/**
* 详细验证公式合法性基于运算逻辑
* @param formula 待验证的公式
* @return 验证结果是否合法错误信息
*/
public static Map<String, Object> validateFormulaDetailed(String formula) {
Map<String, Object> result = new HashMap<>();
String originalFormula = formula;
// 检查公式是否为空
// 1. 基础空值检查
if (formula == null || formula.trim().isEmpty()) {
result.put("isValid", false);
result.put("errorMessage", "公式不能为空");
result.put("errorMessage", String.format("公式不能为空 [原始公式:%s]", originalFormula));
return result;
}
// 定义允许的字符中文数字英文括号运算符和空格
Pattern allowedPattern = Pattern.compile("^[\\u4e00-\\u9fa50-9()*/+\\-\\s.π]+$");
Matcher matcher = allowedPattern.matcher(formula);
// 清理公式移除所有空格统一格式
formula = formula.replaceAll("\\s+", "");
if (!matcher.matches()) {
// 2. 仅对英文括号进行匹配检查中文括号视为参数字符
if (!isEnglishParenthesesBalanced(formula)) {
result.put("isValid", false);
// 找出非法字符
StringBuilder illegalChars = new StringBuilder();
Pattern illegalPattern = Pattern.compile("[^\\u4e00-\\u9fa50-9()*/+\\-\\s.π]");
Matcher illegalMatcher = illegalPattern.matcher(formula);
while (illegalMatcher.find()) {
String illegalChar = illegalMatcher.group();
if (!illegalChars.toString().contains(illegalChar)) {
if (illegalChars.length() > 0) {
illegalChars.append(", ");
}
illegalChars.append("'").append(illegalChar).append("'");
}
}
result.put("errorMessage", "公式包含非法字符: " + illegalChars.toString());
result.put("errorMessage", String.format("英文括号不匹配 [原始公式:%s]", originalFormula));
return result;
}
// 检查括号是否匹配
if (!isParenthesesBalanced(formula)) {
// 3. 语法结构校验核心
try {
// 解析公式并验证运算逻辑新增顶层括号处理
validateTopLevelFormula(formula, originalFormula);
} catch (IllegalArgumentException e) {
result.put("isValid", false);
result.put("errorMessage", "括号不匹配");
result.put("errorMessage", e.getMessage());
return result;
}
// 检查运算符使用是否合理
if (hasInvalidOperatorUsage(formula)) {
// 4. 数字格式校验适配参数+数字混合场景
String numberFormatError = checkNumberFormatDetailed(formula, originalFormula);
if (numberFormatError != null) {
result.put("isValid", false);
result.put("errorMessage", "运算符使用不合理");
return result;
}
// 检查数字格式是否正确避免多个小数点等
if (hasInvalidNumberFormat(formula)) {
result.put("isValid", false);
result.put("errorMessage", "数字格式不正确");
result.put("errorMessage", numberFormatError);
return result;
}
// 验证通过
result.put("isValid", true);
result.put("errorMessage", "公式格式正确");
result.put("errorMessage", String.format("公式格式正确 [原始公式:%s]", originalFormula));
// 可选返回提取的参数信息
result.put("parameters", extractParameters(originalFormula));
return result;
}
// 检查括号是否匹配
private static boolean isParenthesesBalanced(String formula) {
/**
* 验证顶层公式语法处理以括号开头的场景
*/
private static void validateTopLevelFormula(String formula, String originalFormula) {
// 移除所有空格已提前清理此处双重保障
String cleaned = formula.replaceAll("\\s+", "");
// 处理空公式
if (cleaned.isEmpty()) {
throw new IllegalArgumentException(String.format("公式不能为空 [原始公式:%s]", originalFormula));
}
// 递归解析括号表达式将括号块视为整体操作数
String parsedFormula = parseParenthesesBlocks(cleaned, originalFormula);
// 验证解析后的公式括号块已替换为占位符变为普通运算式
validateSubFormula(parsedFormula, cleaned, originalFormula);
}
/**
* 递归解析括号块将每对匹配的括号内内容视为整体操作数
* @param formula 待解析公式
* @param originalFormula 原始公式用于错误提示
* @return 替换括号块为占位符的公式
*/
private static String parseParenthesesBlocks(String formula, String originalFormula) {
// 匹配最外层括号对非嵌套
Pattern outerBracketPattern = Pattern.compile("\\(([^()]*)\\)");
Matcher matcher = outerBracketPattern.matcher(formula);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String innerContent = matcher.group(1);
// 检查括号内是否为空
if (innerContent.trim().isEmpty()) {
throw new IllegalArgumentException(String.format("英文括号内不能为空 [错误片段:()][原始公式:%s]", originalFormula));
}
// 递归解析括号内的子内容处理嵌套括号
String parsedInner = parseParenthesesBlocks(innerContent, originalFormula);
// 验证括号内的子公式
validateSubFormula(parsedInner, innerContent, originalFormula);
// 替换括号块为占位符使用特殊标记避免与正常内容冲突
matcher.appendReplacement(sb, "OPERAND_PLACEHOLDER");
}
matcher.appendTail(sb);
return sb.toString();
}
/**
* 验证子公式的运算逻辑操作数+运算符交替规则
* @param subFormula 无嵌套括号的子公式或括号已替换为占位符
* @param currentFormula 当前处理的公式片段
* @param originalFormula 原始公式用于错误提示
* @throws IllegalArgumentException 语法错误时抛出异常
*/
private static void validateSubFormula(String subFormula, String currentFormula, String originalFormula) {
if (subFormula.isEmpty()) {
return;
}
// 拆分运算单元参数/数字/常量/占位符 + 运算符
List<String> tokens = tokenizeFormula(subFormula);
// 验证运算单元的合法性
for (int i = 0; i < tokens.size(); i++) {
String token = tokens.get(i);
// 占位符直接视为合法操作数
if (token.equals("OPERAND_PLACEHOLDER")) {
continue;
}
// 第一个token可以是参数/数字/常量/负号/占位符
if (i == 0) {
if (token.equals("-")) {
// 负号开头检查下一个token是否为有效值
if (tokens.size() < 2 || !isValidOperand(tokens.get(1)) && !tokens.get(1).equals("OPERAND_PLACEHOLDER")) {
throw new IllegalArgumentException(String.format("负号后必须跟有效参数/数字/常量 [错误片段:-%s][原始公式:%s]",
tokens.size() >= 2 ? tokens.get(1) : "", originalFormula));
}
} else if (!isValidOperand(token)) {
throw new IllegalArgumentException(String.format("公式开头必须是参数/数字/常量,当前为无效字符:%s [错误片段:%s][原始公式:%s]",
token, currentFormula, originalFormula));
}
} else {
// 偶数位必须是运算符奇数位必须是操作数/占位符
if (i % 2 == 0) { // 操作数位置
if (!isValidOperand(token)) {
throw new IllegalArgumentException(String.format("运算符后必须跟有效参数/数字/常量,当前为无效字符:%s [错误片段:%s][原始公式:%s]",
token, currentFormula, originalFormula));
}
} else { // 运算符位置
if (!isValidOperator(token)) {
throw new IllegalArgumentException(String.format("非法运算符或连续运算符:%s [错误片段:%s][原始公式:%s]",
token, currentFormula, originalFormula));
}
// 检查除法分母不能为0
if (token.equals("/") && i + 1 < tokens.size()) {
String nextToken = tokens.get(i + 1);
if (!nextToken.equals("OPERAND_PLACEHOLDER") && nextToken.matches("^-?0+(\\.0+)?$")) {
throw new IllegalArgumentException(String.format("除法运算分母不能为0 [错误片段:/%s][原始公式:%s]",
nextToken, originalFormula));
}
}
}
}
}
// 验证公式不能以运算符结尾
if (!tokens.isEmpty() && isValidOperator(tokens.get(tokens.size() - 1))) {
throw new IllegalArgumentException(String.format("公式不能以运算符[%s]结尾 [错误片段:%s][原始公式:%s]",
tokens.get(tokens.size() - 1), currentFormula, originalFormula));
}
}
/**
* 将公式拆分为运算单元操作数+运算符
* 优化确保带字母/数字的中文参数名被完整识别
* @param formula 无嵌套括号的子公式或含占位符
* @return 拆分后的token列表
*/
private static List<String> tokenizeFormula(String formula) {
List<String> tokens = new ArrayList<>();
StringBuilder currentOperand = new StringBuilder();
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());
currentOperand.setLength(0);
}
tokens.add("OPERAND_PLACEHOLDER");
i += "OPERAND_PLACEHOLDER".length() - 1;
continue;
}
// 处理运算符特殊处理开头/括号后的负号
if (OPERATORS.contains(c)) {
// 负号不是运算符的情况开头运算符后英文括号后
boolean isNegativeSign = (c == '-') && (i == 0 ||
OPERATORS.contains(formula.charAt(i - 1)) ||
formula.charAt(i - 1) == '(');
if (isNegativeSign) {
currentOperand.append(c);
} else {
// 运算符先保存当前操作数
if (currentOperand.length() > 0) {
tokens.add(currentOperand.toString());
currentOperand.setLength(0);
}
tokens.add(String.valueOf(c));
}
} else {
// 操作数字符中文中文括号数字字母小数点π
currentOperand.append(c);
}
}
// 添加最后一个操作数
if (currentOperand.length() > 0) {
tokens.add(currentOperand.toString());
}
return tokens;
}
/**
* 检查是否为合法操作数核心优化支持中文+数字+字母+中文括号
* @param operand 待检查的操作数
* @return 是否合法
*/
private static boolean isValidOperand(String operand) {
if (operand == null || operand.isEmpty()) {
return false;
}
// 处理负号开头的情况
String checkOperand = operand.startsWith("-") ? operand.substring(1) : operand;
// 1. 常量π
if (CONSTANTS.contains(checkOperand)) {
return true;
}
// 2. 纯数字整数/小数
if (checkOperand.matches("\\d+(\\.\\d+)?")) {
return true;
}
// 3. 中文参数名核心优化支持中文数字字母中文括号的任意组合
// 正则说明[\u4e00-\u9fa5] 中文 | [0-9] 数字 | [a-zA-Z] 字母 | [] 中文括号
if (checkOperand.matches("[\\u4e00-\\u9fa50-9a-zA-Z]+")) {
// 确保参数名至少包含一个中文避免纯字母/数字被误判为参数
return checkOperand.matches(".*[\\u4e00-\\u9fa5]+.*");
}
return false;
}
/**
* 检查是否为合法运算符
* @param operator 待检查的运算符
* @return 是否合法
*/
private static boolean isValidOperator(String operator) {
return operator != null && operator.length() == 1 && OPERATORS.contains(operator.charAt(0));
}
/**
* 仅检查英文括号是否匹配
*/
private static boolean isEnglishParenthesesBalanced(String formula) {
int balance = 0;
for (char c : formula.toCharArray()) {
if (c == '(') {
@ -81,62 +294,66 @@ public class FormulaValidator {
return false; // 闭括号多于开括号
}
}
// 忽略中文括号
}
return balance == 0;
}
// 检查运算符使用是否合理
private static boolean hasInvalidOperatorUsage(String formula) {
// 移除所有空格以便检查
String cleaned = formula.replaceAll("\\s+", "");
/**
* 检查数字格式是否正确优化错误提示
* @return 错误信息无错误返回null
*/
private static String checkNumberFormatDetailed(String formula, String originalFormula) {
// 先移除中文括号避免干扰数字格式检查
String cleanFormula = formula.replaceAll("[]", "");
// 检查开头和结尾的运算符除了开头的负号
if (cleaned.matches("^[*/+].*") || cleaned.matches(".*[*/+\\-]$")) {
return true;
// 1. 检查多个小数点
Pattern multiDotPattern = Pattern.compile("\\d+\\.\\d*\\.");
Matcher multiDotMatcher = multiDotPattern.matcher(cleanFormula);
if (multiDotMatcher.find()) {
String errorPart = multiDotMatcher.group();
return String.format("数字格式错误:存在多个小数点 [%s] [错误片段:%s][原始公式:%s]",
errorPart, formula, originalFormula);
}
// 检查连续的运算符允许负号的情况
Pattern operatorPattern = Pattern.compile("[*/+\\-]{2,}");
Matcher matcher = operatorPattern.matcher(cleaned);
// 2. 检查小数点前后是否有非法字符排除英文括号
Pattern invalidDotPattern = Pattern.compile("\\.[\\u4e00-\\u9fa5()]|([^0-9.])\\.([^0-9.])");
Matcher invalidDotMatcher = invalidDotPattern.matcher(cleanFormula);
if (invalidDotMatcher.find()) {
String errorPart = invalidDotMatcher.group();
return String.format("数字格式错误:小数点位置非法 [%s] [错误片段:%s][原始公式:%s]",
errorPart, formula, originalFormula);
}
// 3. 检查以小数点开头/结尾的孤立小数点
if (cleanFormula.matches("^\\..*|.*[^0-9]\\.$")) {
return String.format("数字格式错误:不能以孤立小数点开头或结尾 [错误片段:%s][原始公式:%s]",
formula, originalFormula);
}
return null;
}
/**
* 提取公式中的所有参数支持带字母/数字/中文括号的参数名
*/
public static List<String> extractParameters(String formula) {
List<String> parameters = new ArrayList<>();
if (formula == null || formula.trim().isEmpty()) {
return parameters;
}
// 匹配中文参数名核心优化支持中文+数字+字母+中文括号
Pattern paramPattern = Pattern.compile("[\\u4e00-\\u9fa5][\\u4e00-\\u9fa50-9a-zA-Z]*");
Matcher matcher = paramPattern.matcher(formula);
while (matcher.find()) {
String operators = matcher.group();
// 允许的运算符组合*- /- +- -- (负号情况)
if (!operators.matches("\\*\\-|/\\-|\\+\\-|\\-\\-")) {
return true;
String param = matcher.group();
if (!parameters.contains(param)) {
parameters.add(param);
}
}
return false;
}
// 检查数字格式是否正确
private static boolean hasInvalidNumberFormat(String formula) {
// 匹配数字模式包括小数
Pattern numberPattern = Pattern.compile("\\d+\\.\\d*\\.|\\.[\\u4e00-\\u9fa5]|\\.\\.[\\d\\u4e00-\\u9fa5]");
Matcher matcher = numberPattern.matcher(formula);
if (matcher.find()) {
return true; // 找到无效的数字格式
}
// 检查以小数点开头或结尾的数字
if (formula.matches("^\\..*|.*[^0-9]\\.$")) {
return true;
}
return false;
}
// 提取公式中的所有参数中文参数名和数字
public static void extractParameters(String formula) {
// 匹配中文参数名和数字
Pattern paramPattern = Pattern.compile("[\\u4e00-\\u9fa5]+|\\d+(?:\\.\\d+)?");
Matcher matcher = paramPattern.matcher(formula);
System.out.println("公式中的参数:");
while (matcher.find()) {
System.out.println(" - " + matcher.group());
}
return parameters;
}
}

View File

@ -402,6 +402,10 @@ from engine_param_detail;
delete
from todo_task;
delete
from initiated_task;
delete
from completed_task;
delete
from data_change_comment;
delete
from approval_config;