Merge branch 'develop' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into master-jdk17
This commit is contained in:
@@ -17,6 +17,7 @@ uv run --with simple-ddl-parser convertor.py dm8 > ../dm/ruoyi-vue-pro-dm8.sql
|
||||
import argparse
|
||||
import pathlib
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Dict, Generator, Optional, Tuple, Union
|
||||
@@ -293,8 +294,10 @@ class Convertor(ABC):
|
||||
|
||||
# 将parse失败的脚本打印出来
|
||||
if error_scripts:
|
||||
print("!!! 以下内容无法正常解析", file=sys.stderr)
|
||||
for script in error_scripts:
|
||||
print(script)
|
||||
# print to stderr
|
||||
print(script, file=sys.stderr)
|
||||
|
||||
|
||||
class PostgreSQLConvertor(Convertor):
|
||||
|
||||
@@ -6,6 +6,8 @@ import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.servlet.JakartaServletUtil;
|
||||
import cn.iocoder.yudao.framework.common.biz.infra.logger.ApiErrorLogCommonApi;
|
||||
import cn.iocoder.yudao.framework.common.biz.infra.logger.dto.ApiErrorLogCreateReqDTO;
|
||||
import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
||||
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
@@ -14,8 +16,6 @@ import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
|
||||
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
|
||||
import cn.iocoder.yudao.framework.common.biz.infra.logger.ApiErrorLogCommonApi;
|
||||
import cn.iocoder.yudao.framework.common.biz.infra.logger.dto.ApiErrorLogCreateReqDTO;
|
||||
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.validation.ConstraintViolation;
|
||||
@@ -29,6 +29,7 @@ import org.springframework.util.Assert;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.validation.FieldError;
|
||||
import org.springframework.validation.ObjectError;
|
||||
import org.springframework.web.HttpMediaTypeNotSupportedException;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.MissingServletRequestParameterException;
|
||||
@@ -101,6 +102,9 @@ public class GlobalExceptionHandler {
|
||||
if (ex instanceof HttpRequestMethodNotSupportedException) {
|
||||
return httpRequestMethodNotSupportedExceptionHandler((HttpRequestMethodNotSupportedException) ex);
|
||||
}
|
||||
if (ex instanceof HttpMediaTypeNotSupportedException) {
|
||||
return httpMediaTypeNotSupportedExceptionHandler((HttpMediaTypeNotSupportedException) ex);
|
||||
}
|
||||
if (ex instanceof ServiceException) {
|
||||
return serviceExceptionHandler((ServiceException) ex);
|
||||
}
|
||||
@@ -179,9 +183,11 @@ public class GlobalExceptionHandler {
|
||||
if (ex.getCause() instanceof InvalidFormatException) {
|
||||
InvalidFormatException invalidFormatException = (InvalidFormatException) ex.getCause();
|
||||
return CommonResult.error(BAD_REQUEST.getCode(), String.format("请求参数类型错误:%s", invalidFormatException.getValue()));
|
||||
}else {
|
||||
return defaultExceptionHandler(ServletUtils.getRequest(), ex);
|
||||
}
|
||||
if (StrUtil.startWith(ex.getMessage(), "Required request body is missing")) {
|
||||
return CommonResult.error(BAD_REQUEST.getCode(), "请求参数类型错误: request body 缺失");
|
||||
}
|
||||
return defaultExceptionHandler(ServletUtils.getRequest(), ex);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -237,6 +243,17 @@ public class GlobalExceptionHandler {
|
||||
return CommonResult.error(METHOD_NOT_ALLOWED.getCode(), String.format("请求方法不正确:%s", ex.getMessage()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理 SpringMVC 请求的 Content-Type 不正确
|
||||
*
|
||||
* 例如说,A 接口的 Content-Type 为 application/json,结果请求的 Content-Type 为 application/octet-stream,导致不匹配
|
||||
*/
|
||||
@ExceptionHandler(HttpMediaTypeNotSupportedException.class)
|
||||
public CommonResult<?> httpMediaTypeNotSupportedExceptionHandler(HttpMediaTypeNotSupportedException ex) {
|
||||
log.warn("[httpMediaTypeNotSupportedExceptionHandler]", ex);
|
||||
return CommonResult.error(BAD_REQUEST.getCode(), String.format("请求类型不正确:%s", ex.getMessage()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理 Spring Security 权限不足的异常
|
||||
*
|
||||
|
||||
@@ -71,6 +71,9 @@ public class BpmSimpleModelNodeVO {
|
||||
@Schema(description = "是否填写审批意见", example = "false")
|
||||
private Boolean reasonRequire;
|
||||
|
||||
@Schema(description = "跳过表达式", example = "{true}")
|
||||
private String skipExpression; // 用于审批节点
|
||||
|
||||
/**
|
||||
* 审批节点拒绝处理
|
||||
*/
|
||||
|
||||
@@ -14,6 +14,7 @@ import lombok.Getter;
|
||||
@AllArgsConstructor
|
||||
public enum BpmTaskStatusEnum {
|
||||
|
||||
SKIP(-2, "跳过"),
|
||||
NOT_START(-1, "未开始"),
|
||||
RUNNING(1, "审批中"),
|
||||
APPROVE(2, "审批通过"),
|
||||
|
||||
@@ -800,9 +800,10 @@ public class BpmnModelUtils {
|
||||
|| currentElement instanceof EndEvent
|
||||
|| currentElement instanceof UserTask
|
||||
|| currentElement instanceof ServiceTask) {
|
||||
// 添加元素
|
||||
// 添加节点
|
||||
FlowNode flowNode = (FlowNode) currentElement;
|
||||
resultElements.add(flowNode);
|
||||
|
||||
// 遍历子节点
|
||||
flowNode.getOutgoingFlows().forEach(
|
||||
nextElement -> simulateNextFlowElements(nextElement.getTargetFlowElement(), variables, resultElements, visitElements));
|
||||
@@ -835,6 +836,31 @@ public class BpmnModelUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否跳过此节点
|
||||
*
|
||||
* @param flowNode 节点
|
||||
* @param variables 流程变量
|
||||
*/
|
||||
public static boolean isSkipNode(FlowElement flowNode, Map<String, Object> variables) {
|
||||
// 1. 检查节点是否有跳过表达式(支持多种任务节点类型)
|
||||
String skipExpression = null;
|
||||
if (flowNode instanceof UserTask) {
|
||||
skipExpression = ((UserTask) flowNode).getSkipExpression();
|
||||
} else if (flowNode instanceof ServiceTask) {
|
||||
skipExpression = ((ServiceTask) flowNode).getSkipExpression();
|
||||
} else if (flowNode instanceof ScriptTask) {
|
||||
skipExpression = ((ScriptTask) flowNode).getSkipExpression();
|
||||
}
|
||||
|
||||
if (StrUtil.isEmpty(skipExpression)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. 计算跳过表达式的值
|
||||
return evalConditionExpress(variables, skipExpression);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据当前节点,获取下一个节点
|
||||
*
|
||||
@@ -997,7 +1023,7 @@ public class BpmnModelUtils {
|
||||
* @return 是否满足条件
|
||||
*/
|
||||
public static boolean evalConditionExpress(Map<String, Object> variables, String expression) {
|
||||
if (expression == null) {
|
||||
if (StrUtil.isEmpty(expression)) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
// 如果 variables 为空,则创建一个的原因?可能 expression 的计算,不依赖于 variables
|
||||
|
||||
@@ -464,6 +464,10 @@ public class SimpleModelUtils {
|
||||
addReasonRequire(node.getReasonRequire(), userTask);
|
||||
// 节点类型
|
||||
addNodeType(node.getType(), userTask);
|
||||
// 添加跳过表达式
|
||||
if (StrUtil.isNotEmpty(node.getSkipExpression())) {
|
||||
userTask.setSkipExpression(node.getSkipExpression());
|
||||
}
|
||||
return userTask;
|
||||
}
|
||||
|
||||
@@ -968,7 +972,7 @@ public class SimpleModelUtils {
|
||||
|| nodeType == BpmSimpleModelNodeTypeEnum.COPY_NODE
|
||||
|| nodeType == BpmSimpleModelNodeTypeEnum.CHILD_PROCESS
|
||||
|| nodeType == BpmSimpleModelNodeTypeEnum.END_NODE) {
|
||||
// 添加元素
|
||||
// 添加此节点
|
||||
resultNodes.add(currentNode);
|
||||
}
|
||||
|
||||
@@ -1014,6 +1018,16 @@ public class SimpleModelUtils {
|
||||
simulateNextNode(currentNode.getChildNode(), variables, resultNodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据跳过表达式,判断是否跳过此节点
|
||||
*/
|
||||
public static boolean isSkipNode(BpmSimpleModelNodeVO currentNode, Map<String, Object> variables) {
|
||||
if (StrUtil.isEmpty(currentNode.getSkipExpression())) {
|
||||
return false;
|
||||
}
|
||||
return BpmnModelUtils.evalConditionExpress(variables, currentNode.getSkipExpression());
|
||||
}
|
||||
|
||||
public static boolean evalConditionExpress(Map<String, Object> variables, BpmSimpleModelNodeVO.ConditionSetting conditionSetting) {
|
||||
return BpmnModelUtils.evalConditionExpress(variables, buildConditionExpression(conditionSetting));
|
||||
}
|
||||
|
||||
@@ -398,7 +398,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
||||
? BpmSimpleModelNodeTypeEnum.START_USER_NODE.getType()
|
||||
: ObjUtil.defaultIfNull(parseNodeType(flowNode), // 目的:解决“办理节点”的识别
|
||||
BpmSimpleModelNodeTypeEnum.APPROVE_NODE.getType()))
|
||||
.setStatus(FlowableUtils.getTaskStatus(task))
|
||||
.setStatus(getEndActivityNodeStatus(task))
|
||||
.setCandidateStrategy(BpmnModelUtils.parseCandidateStrategy(flowNode))
|
||||
.setStartTime(DateUtils.of(task.getCreateTime())).setEndTime(DateUtils.of(task.getEndTime()))
|
||||
.setTasks(singletonList(BpmProcessInstanceConvert.INSTANCE.buildApprovalTaskInfo(task)));
|
||||
@@ -462,6 +462,18 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
||||
return approvalNodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取结束节点的状态
|
||||
*/
|
||||
private Integer getEndActivityNodeStatus(HistoricTaskInstance task) {
|
||||
Integer status = FlowableUtils.getTaskStatus(task);
|
||||
if (status != null) {
|
||||
return status;
|
||||
}
|
||||
// 结束节点未获取到状态,为跳过状态。可见 bpmn 或者 simple 的 skipExpression
|
||||
return BpmTaskStatusEnum.SKIP.getStatus();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得【进行中】的活动节点们
|
||||
*/
|
||||
@@ -565,10 +577,14 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
||||
if (runActivityIds.contains(node.getId())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Integer status = BpmTaskStatusEnum.NOT_START.getStatus();
|
||||
// 如果节点被跳过。设置状态为跳过
|
||||
if (SimpleModelUtils.isSkipNode(node, processVariables)) {
|
||||
status = BpmTaskStatusEnum.SKIP.getStatus();
|
||||
}
|
||||
ActivityNode activityNode = new ActivityNode().setId(node.getId()).setName(node.getName())
|
||||
.setNodeType(node.getType()).setCandidateStrategy(node.getCandidateStrategy())
|
||||
.setStatus(BpmTaskStatusEnum.NOT_START.getStatus());
|
||||
.setStatus(status);
|
||||
|
||||
// 1. 开始节点/审批节点
|
||||
if (ObjectUtils.equalsAny(node.getType(),
|
||||
@@ -608,8 +624,13 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
||||
if (runActivityIds.contains(node.getId())) {
|
||||
return null;
|
||||
}
|
||||
Integer status = BpmTaskStatusEnum.NOT_START.getStatus();
|
||||
// 如果节点被跳过,状态设置为跳过
|
||||
if(BpmnModelUtils.isSkipNode(node, processVariables)){
|
||||
status = BpmTaskStatusEnum.SKIP.getStatus();
|
||||
}
|
||||
ActivityNode activityNode = new ActivityNode().setId(node.getId())
|
||||
.setStatus(BpmTaskStatusEnum.NOT_START.getStatus());
|
||||
.setStatus(status);
|
||||
|
||||
// 1. 开始节点
|
||||
if (node instanceof StartEvent) {
|
||||
|
||||
@@ -947,7 +947,10 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||
BpmCommentTypeEnum.DELEGATE_START.formatComment(currentUser.getNickname(), delegateUser.getNickname(), reqVO.getReason()));
|
||||
|
||||
// 3.1 设置任务所有人 (owner) 为原任务的处理人 (assignee)
|
||||
// 特殊:如果已经被委派(owner 非空),则不需要更新 owner:https://gitee.com/zhijiantianya/yudao-cloud/issues/ICJ153
|
||||
if (StrUtil.isEmpty(task.getOwner())) {
|
||||
taskService.setOwner(taskId, task.getAssignee());
|
||||
}
|
||||
// 3.2 执行委派,将任务委派给 delegateUser
|
||||
taskService.delegateTask(taskId, reqVO.getDelegateUserId().toString());
|
||||
// 补充说明:委托不单独设置状态。如果需要,可通过 Task 的 DelegationState 字段,判断是否为 DelegationState.PENDING 委托中
|
||||
@@ -973,7 +976,10 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||
BpmCommentTypeEnum.TRANSFER.formatComment(currentUser.getNickname(), assigneeUser.getNickname(), reqVO.getReason()));
|
||||
|
||||
// 3.1 设置任务所有人 (owner) 为原任务的处理人 (assignee)
|
||||
// 特殊:如果已经被转派(owner 非空),则不需要更新 owner:https://gitee.com/zhijiantianya/yudao-cloud/issues/ICJ153
|
||||
if (StrUtil.isEmpty(task.getOwner())) {
|
||||
taskService.setOwner(taskId, task.getAssignee());
|
||||
}
|
||||
// 3.2 执行转派(审批人),将任务转派给 assigneeUser
|
||||
// 委托( delegate)和转派(transfer)的差别,就在这块的调用!!!!
|
||||
taskService.setAssignee(taskId, reqVO.getAssigneeUserId().toString());
|
||||
|
||||
Reference in New Issue
Block a user