Merge remote-tracking branch 'origin/feature/REQ-1609' into feature/REQ-1609
This commit is contained in:
commit
8c5b378bcf
@ -52,7 +52,7 @@ public interface BpmnConstants {
|
||||
|
||||
String NUMBER_OF_INSTANCES = "nrOfInstances";
|
||||
String MULTI_INSTANCE_LOOP_COUNTER = "loopCounter";
|
||||
|
||||
String TASK_COMPLETE_OPERATION_TYPE = "_TASK_COMPLETE_TYPE";
|
||||
/**
|
||||
* 会签表达式
|
||||
*/
|
||||
|
||||
@ -0,0 +1,86 @@
|
||||
package cn.axzo.workflow.common.model.request.bpmn;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* 流程定义中的按钮配置
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2023/11/13 13:44
|
||||
*/
|
||||
@ApiModel("JSON 版本的 BPMN 协议模型中的按钮管理")
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
public class BpmnButtonConf {
|
||||
|
||||
/**
|
||||
* 发起人的按钮配置信息, JSON 格式
|
||||
*/
|
||||
@ApiModelProperty(value = "发起人的按钮配置信息, JSON 格式", example = "{\"agree\": true, \"reject\": true, \"delegate\": " +
|
||||
"true, \"cancel\": true, \"withdraw\": true, \"revoke\": true\" }")
|
||||
@NotBlank(message = "发起人的按钮配置信息不能为空")
|
||||
private String initiator;
|
||||
|
||||
/**
|
||||
* 当前审批人的按钮配置信息, JSON 格式
|
||||
*/
|
||||
@ApiModelProperty(value = "当前审批人的按钮配置信息, JSON 格式", example = "{\"agree\": true, \"reject\": true, \"delegate\": " +
|
||||
"true, \"cancel\": true, \"withdraw\": true, \"revoke\": true\" }")
|
||||
@NotBlank(message = "当前审批人的按钮配置信息不能为空")
|
||||
private String current;
|
||||
|
||||
/**
|
||||
* 历史审批人的按钮配置信息, JSON 格式
|
||||
*/
|
||||
@ApiModelProperty(value = "历史审批人的按钮配置信息, JSON 格式", example = "{\"agree\": true, \"reject\": true, \"delegate\": " +
|
||||
"true, \"cancel\": true, \"withdraw\": true, \"revoke\": true\" }")
|
||||
@NotBlank(message = "历史审批人的按钮配置信息不能为空")
|
||||
private String history;
|
||||
|
||||
/**
|
||||
* 抄送人的按钮配置信息, JSON 格式
|
||||
*/
|
||||
@ApiModelProperty(value = "抄送人的按钮配置信息, JSON 格式", example = "{\"agree\": true, \"reject\": true, \"delegate\": " +
|
||||
"true, \"cancel\": true, \"withdraw\": true, \"revoke\": true\" }")
|
||||
@NotBlank(message = "抄送人的按钮配置信息不能为空")
|
||||
private String carbonCopy;
|
||||
|
||||
public String getInitiator() {
|
||||
return initiator;
|
||||
}
|
||||
|
||||
public void setInitiator(String initiator) {
|
||||
this.initiator = initiator;
|
||||
}
|
||||
|
||||
public String getCurrent() {
|
||||
return current;
|
||||
}
|
||||
|
||||
public void setCurrent(String current) {
|
||||
this.current = current;
|
||||
}
|
||||
|
||||
public String getHistory() {
|
||||
return history;
|
||||
}
|
||||
|
||||
public void setHistory(String history) {
|
||||
this.history = history;
|
||||
}
|
||||
|
||||
public String getCarbonCopy() {
|
||||
return carbonCopy;
|
||||
}
|
||||
|
||||
public void setCarbonCopy(String carbonCopy) {
|
||||
this.carbonCopy = carbonCopy;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,154 @@
|
||||
package cn.axzo.workflow.common.model.request.bpmn;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 条件
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2023/11/13 20:33
|
||||
*/
|
||||
@ApiModel("JSON 版本的 BPMN 协议模型中的条件")
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
public class BpmnCondition {
|
||||
|
||||
/**
|
||||
* string(字符串)/number(数字)/radio(单选)/checkbox(复选)
|
||||
*/
|
||||
@ApiModelProperty(value = "基础属性:字段类型", notes = "string, number, radio, checkbox", example = "string")
|
||||
private String filedDateType;
|
||||
|
||||
/**
|
||||
* 字段 code
|
||||
*/
|
||||
@ApiModelProperty(value = "基础属性:字段 code", notes = "字段管理中字段的 Code", example = "fieldCode")
|
||||
private String fieldCode;
|
||||
|
||||
/**
|
||||
* 操作符(与字段类型有关)
|
||||
* <p>
|
||||
* 当字段类型为 string 时, 操作符为 contains, notContains
|
||||
* 当字段类型为 number 时, 操作符为 eq, ne, gt, ge, lt, le, between
|
||||
* 当字段类型为 radio 时, 操作符为 eq
|
||||
* 当字段类型为 checkbox 时, 操作符为 in
|
||||
*/
|
||||
@ApiModelProperty(value = "基础属性:操作符", notes = "操作符", example = "eq")
|
||||
private String operator;
|
||||
|
||||
/**
|
||||
* 默认的比较值
|
||||
*/
|
||||
@ApiModelProperty(value = "基础属性:默认的比较值", notes = "同时也用于 fieldDateType = radio", example = "1")
|
||||
private String defaultValue;
|
||||
|
||||
|
||||
/**
|
||||
* 只有 fieldDateType = checkbox 才有值
|
||||
*/
|
||||
@ApiModelProperty(value = "当 fieldDateType = checkbox时, 选中的值")
|
||||
private List<String> defaultValues;
|
||||
|
||||
/**
|
||||
* 只有 operator = between 才有值
|
||||
*/
|
||||
@ApiModelProperty(value = "当 fieldDateType = number 并且 operator = between 时, 左侧操作符")
|
||||
private String leftOperator;
|
||||
|
||||
/**
|
||||
* 只有 operator = between 才有值
|
||||
*/
|
||||
@ApiModelProperty(value = "当 fieldDateType = number 并且 operator = between 时, 右侧操作符")
|
||||
private String rightOperator;
|
||||
|
||||
/**
|
||||
* 只有 operator = between 才有值
|
||||
*/
|
||||
@ApiModelProperty(value = "当 fieldDateType = number 并且 operator = between 时, 左侧比较值")
|
||||
private String leftValue;
|
||||
|
||||
/**
|
||||
* 只有 operator = between 才有值
|
||||
*/
|
||||
@ApiModelProperty(value = "当 fieldDateType = number 并且 operator = between 时, 右侧比较值")
|
||||
private String rightValue;
|
||||
|
||||
public String getFiledDateType() {
|
||||
return filedDateType;
|
||||
}
|
||||
|
||||
public void setFiledDateType(String filedDateType) {
|
||||
this.filedDateType = filedDateType;
|
||||
}
|
||||
|
||||
public String getFieldCode() {
|
||||
return fieldCode;
|
||||
}
|
||||
|
||||
public void setFieldCode(String fieldCode) {
|
||||
this.fieldCode = fieldCode;
|
||||
}
|
||||
|
||||
public String getOperator() {
|
||||
return operator;
|
||||
}
|
||||
|
||||
public void setOperator(String operator) {
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
public String getDefaultValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public void setDefaultValue(String defaultValue) {
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
public List<String> getDefaultValues() {
|
||||
return defaultValues;
|
||||
}
|
||||
|
||||
public void setDefaultValues(List<String> defaultValues) {
|
||||
this.defaultValues = defaultValues;
|
||||
}
|
||||
|
||||
public String getLeftOperator() {
|
||||
return leftOperator;
|
||||
}
|
||||
|
||||
public void setLeftOperator(String leftOperator) {
|
||||
this.leftOperator = leftOperator;
|
||||
}
|
||||
|
||||
public String getRightOperator() {
|
||||
return rightOperator;
|
||||
}
|
||||
|
||||
public void setRightOperator(String rightOperator) {
|
||||
this.rightOperator = rightOperator;
|
||||
}
|
||||
|
||||
public String getLeftValue() {
|
||||
return leftValue;
|
||||
}
|
||||
|
||||
public void setLeftValue(String leftValue) {
|
||||
this.leftValue = leftValue;
|
||||
}
|
||||
|
||||
public String getRightValue() {
|
||||
return rightValue;
|
||||
}
|
||||
|
||||
public void setRightValue(String rightValue) {
|
||||
this.rightValue = rightValue;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
package cn.axzo.workflow.common.model.request.bpmn;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 条件组
|
||||
* <p>
|
||||
* 目前条件中的所有项都是"并且",所以没有第二个属性,如果以后有"或者"的情况,再加
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2023/11/13 19:58
|
||||
*/
|
||||
@ApiModel("JSON 版本的 BPMN 协议模型中的条件组")
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
public class BpmnConditionGroup {
|
||||
|
||||
@ApiModelProperty(value = "条件组")
|
||||
private List<BpmnCondition> conditions;
|
||||
|
||||
/**
|
||||
* 条件间模式,默认为"and"
|
||||
*/
|
||||
private String mode = "and";
|
||||
|
||||
public List<BpmnCondition> getConditions() {
|
||||
return conditions;
|
||||
}
|
||||
|
||||
public void setConditions(List<BpmnCondition> conditions) {
|
||||
this.conditions = conditions;
|
||||
}
|
||||
|
||||
public String getMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
public void setMode(String mode) {
|
||||
this.mode = mode;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,91 @@
|
||||
package cn.axzo.workflow.common.model.request.bpmn;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 流程定义中的字段管理
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2023/11/13 13:53
|
||||
*/
|
||||
@ApiModel("JSON 版本的 BPMN 协议模型中的字段管理")
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
public class BpmnFieldConf {
|
||||
|
||||
/**
|
||||
* 字段的 code
|
||||
*/
|
||||
@ApiModelProperty(value = "字段的 code", example = "fieldCode", notes = "字段的 code 必须唯一")
|
||||
@NotBlank(message = "字段的 code 不能为空")
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 字段的名称
|
||||
*/
|
||||
@ApiModelProperty(value = "字段的名称", example = "字段名称")
|
||||
@NotBlank(message = "字段的名称不能为空")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 字段的类型
|
||||
*/
|
||||
@ApiModelProperty(value = "字段的类型", example = "string", notes = "string, number, date, datetime, boolean, " +
|
||||
"select, radio, checkbox, textarea, file, image, editor")
|
||||
@NotBlank(message = "字段的类型不能为空")
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 单选或多选的下拉选择框中的数据, 只有单选或多选的时候才会有值,并且内部的属性不应该为空
|
||||
*/
|
||||
@ApiModelProperty(value = "单选或多选的下拉选择框中的数据")
|
||||
@Valid
|
||||
private List<BpmnFieldOptionConf> options;
|
||||
}
|
||||
|
||||
/**
|
||||
* 单选/多选的选项配置
|
||||
*/
|
||||
@Accessors(chain = true)
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
class BpmnFieldOptionConf {
|
||||
/**
|
||||
* 选项的名称
|
||||
*/
|
||||
@ApiModelProperty(value = "选项的名称", example = "选项1")
|
||||
@NotBlank(message = "选项的名称不能为空")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 选项的值
|
||||
*/
|
||||
@ApiModelProperty(value = "选项的值", example = "1")
|
||||
@NotBlank(message = "选项的值不能为空")
|
||||
private String value;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
@ -1,11 +1,15 @@
|
||||
package cn.axzo.workflow.common.model.request.bpmn;
|
||||
|
||||
import cn.axzo.workflow.common.enums.BpmnFlowNodeMode;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* JSON 版本的 BPMN 协议中 UserTask 节点的属性扩展模型
|
||||
*/
|
||||
@ -13,47 +17,71 @@ import lombok.Data;
|
||||
@Data
|
||||
public class BpmnJsonNodeProperty {
|
||||
|
||||
//************* 审批方式Start **************//
|
||||
/**
|
||||
* 发起人节点审批人规则类型
|
||||
* 审批方式: human(人工审批), autoPassed(自动通过), autoRejection(自动拒绝), nobody(不审批[仅业务节点可能有该值])
|
||||
*/
|
||||
@ApiModelProperty(value = "发起人节点: 发起人规则类型 ASSIGN_USER/POSITION/ROLE")
|
||||
private String initiatorType;
|
||||
@ApiModelProperty(value = "任务节点: 审批方式", notes = "human: 人工审批, autoPassed: 自动通过, autoRejection: 自动拒绝, nobody: " +
|
||||
"不审批[仅业务节点可能有该值]")
|
||||
@NotBlank(message = "审批方式不能为空")
|
||||
private String approvalMethod;
|
||||
//************* 审批方式End **************//
|
||||
|
||||
|
||||
//************* 审批人所在范围Start **************//
|
||||
/**
|
||||
* 审批人所在范围: EntWorkspace(企业工作台), projectWorkspace(项目工作台), preTaskUserEnt(上节点审批人所在单位)
|
||||
*/
|
||||
@ApiModelProperty(value = "任务节点: 审批人所在范围", notes = "EntWorkspace: 企业工作台, projectWorkspace: 项目工作台, preTaskUserEnt:" +
|
||||
" 上节点审批人所在单位")
|
||||
private String approverScope;
|
||||
//************* 审批人所在范围End **************//
|
||||
|
||||
|
||||
//************* 审批人指定Start **************//
|
||||
/**
|
||||
* 审批人指定: position(指定岗位), role(指定角色), identity(指定身份), initiatorLeader(发起人主管)
|
||||
*/
|
||||
@ApiModelProperty(value = "任务节点: 审批人指定", notes = "position: 指定岗位, role: 指定角色, identity: 指定身份, initiatorLeader: " +
|
||||
"发起人主管")
|
||||
@NotBlank(message = "审批人指定不能为空")
|
||||
private String approverSpecify;
|
||||
|
||||
/**
|
||||
* 非指定人时, 发起人和任务节点审批人具体的规则值
|
||||
* 具体的配置值
|
||||
*/
|
||||
@ApiModelProperty(value = "发起人节点/任务节点: 非 ASSIGN_USER 外的规则具体表达式")
|
||||
private String assigneeExpression;
|
||||
@ApiModelProperty(value = "任务节点: 审批人指定的具体值")
|
||||
@NotEmpty(message = "审批人指定的具体值不能为空")
|
||||
private List<String> specifyValue;
|
||||
//************* 审批人指定End **************//
|
||||
|
||||
|
||||
//************* 多人审批时审批方式Start **************//
|
||||
/**
|
||||
* 是否是多实例Task节点;
|
||||
* 是否是多实例Task节点, 在安心筑业务中, 所有节点应该都是多实例节点
|
||||
*/
|
||||
@ApiModelProperty("任务节点: 是否是多实例Task节点")
|
||||
private Boolean isMultiTask;
|
||||
@ApiModelProperty(value = "任务节点: 是否是多实例Task节点", notes = "在安心筑业务中, 所有节点应该都是多实例节点")
|
||||
private Boolean isMultiTask = true;
|
||||
|
||||
/**
|
||||
* Task 多实例模式;OR:"或签",AND:"会签"
|
||||
*/
|
||||
@ApiModelProperty(value = "任务节点: 多实例模式;OR:或签,AND:会签")
|
||||
@NotNull(message = "多实例模式不能为空")
|
||||
private BpmnFlowNodeMode multiMode;
|
||||
//************* 多人审批时审批方式End **************//
|
||||
|
||||
|
||||
//************* 审批人为空时Start **************//
|
||||
/**
|
||||
* 审批人为空是否允许自动跳过
|
||||
*/
|
||||
@ApiModelProperty(value = "任务节点: 审批人为空是否允许自动跳过")
|
||||
private Boolean allowSkip = false;
|
||||
@ApiModelProperty(value = "任务节点: 审批人为空处理方式", notes = "autoPassed: 自动通过, autoSkipped: 自动跳过, transferToAdmin: 转交给管理员")
|
||||
@NotBlank(message = "审批人为空处理方式不能为空")
|
||||
private String approverEmptyHandleType;
|
||||
//************* 审批人为空时的策略End **************//
|
||||
|
||||
/**
|
||||
* 任务节点审批人规则类型
|
||||
*/
|
||||
@ApiModelProperty(value = "任务节点: 审批人规则类型 ASSIGN_USER/POSITION/ROLE")
|
||||
private String assignedType;
|
||||
|
||||
/**
|
||||
* 指定审批人或发起人时,传入的信息
|
||||
*/
|
||||
@ApiModelProperty(value = "发起人节点/任务节点: 指定审批人")
|
||||
private BpmnTaskDelegateAssigner assigner;
|
||||
|
||||
/**
|
||||
* 表单字段权限
|
||||
@ -67,23 +95,17 @@ public class BpmnJsonNodeProperty {
|
||||
@ApiModelProperty(value = "发起人节点/任务节点: 按钮权限集合", notes = "后端不做任何解析, 前端给什么样,就返什么样")
|
||||
private String buttonPermission;
|
||||
|
||||
|
||||
//************* 条件节点Start **************//
|
||||
/**
|
||||
* 条件节点中是否是默认分支,可以都不传;
|
||||
*/
|
||||
@ApiModelProperty(value = "条件节点: 是否是默认条件分支")
|
||||
private Boolean defaultBranch;
|
||||
|
||||
/**
|
||||
* 条件分支的Key
|
||||
*/
|
||||
@ApiModelProperty(value = "条件节点: 条件分支的Key", notes = "枢智业务使用的极简条件判断方式")
|
||||
private String conditionBranchKey;
|
||||
|
||||
/**
|
||||
* 条件节点当ConditionKey的值是多少,走该分支
|
||||
*/
|
||||
@ApiModelProperty(value = "条件节点: 当ConditionKey的值是多少,走该分支", notes = "枢智业务使用的极简条件判断方式")
|
||||
private Integer conditionBranchValue;
|
||||
@ApiModelProperty(value = "条件节点: 条件分组集合")
|
||||
private List<BpmnConditionGroup> groups;
|
||||
//************* 条件节点End **************//
|
||||
|
||||
/**
|
||||
* 发起时使用的表单 key
|
||||
|
||||
@ -0,0 +1,66 @@
|
||||
package cn.axzo.workflow.common.model.request.bpmn;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* 流程定义中的通知配置
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2023/11/13 13:38
|
||||
*/
|
||||
@ApiModel("JSON 版本的 BPMN 协议模型中的通知管理")
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
public class BpmnNoticeConf {
|
||||
|
||||
/**
|
||||
* 待办消息模板 ID
|
||||
*/
|
||||
@ApiModelProperty(value = "待办消息模板 ID")
|
||||
@NotBlank(message = "待办消息模板 ID 不能为空")
|
||||
private String pendingMessageId;
|
||||
|
||||
/**
|
||||
* 通知消息模板 ID
|
||||
*/
|
||||
@ApiModelProperty(value = "通知消息模板 ID")
|
||||
@NotBlank(message = "通知消息模板 ID 不能为空")
|
||||
private String noticeMessageId;
|
||||
|
||||
/**
|
||||
* 短信模板 ID
|
||||
*/
|
||||
@ApiModelProperty(value = "短信模板 ID")
|
||||
private String smsId;
|
||||
|
||||
public String getPendingMessageId() {
|
||||
return pendingMessageId;
|
||||
}
|
||||
|
||||
public void setPendingMessageId(String pendingMessageId) {
|
||||
this.pendingMessageId = pendingMessageId;
|
||||
}
|
||||
|
||||
public String getNoticeMessageId() {
|
||||
return noticeMessageId;
|
||||
}
|
||||
|
||||
public void setNoticeMessageId(String noticeMessageId) {
|
||||
this.noticeMessageId = noticeMessageId;
|
||||
}
|
||||
|
||||
public String getSmsId() {
|
||||
return smsId;
|
||||
}
|
||||
|
||||
public void setSmsId(String smsId) {
|
||||
this.smsId = smsId;
|
||||
}
|
||||
}
|
||||
@ -1,12 +1,16 @@
|
||||
package cn.axzo.workflow.common.model.request.bpmn.model;
|
||||
|
||||
import cn.axzo.workflow.common.model.request.bpmn.BpmnButtonConf;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.BpmnFieldConf;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.BpmnJsonNode;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.BpmnNoticeConf;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
@ -33,7 +37,8 @@ public class BpmnModelCreateDTO {
|
||||
/**
|
||||
* 自定义分类
|
||||
*/
|
||||
@ApiModelProperty(value = "自定义分类", notes = "由业务自定义", example = "1")
|
||||
@ApiModelProperty(value = "自定义分类", notes = "由业务自定义")
|
||||
@NotBlank(message = "自定义分类不能为空")
|
||||
private String category;
|
||||
|
||||
/**
|
||||
@ -45,9 +50,30 @@ public class BpmnModelCreateDTO {
|
||||
/**
|
||||
* 流程的Json 结构
|
||||
*/
|
||||
@ApiModelProperty(value = "流程的Json 结构", example = "1")
|
||||
@ApiModelProperty(value = "流程的 Json 结构")
|
||||
private BpmnJsonNode node;
|
||||
|
||||
/**
|
||||
* 通知管理配置
|
||||
*/
|
||||
@ApiModelProperty(value = "通知管理配置")
|
||||
@Valid
|
||||
private BpmnNoticeConf noticeConf;
|
||||
|
||||
/**
|
||||
* 流程定义的全局默认按钮权限数据
|
||||
*/
|
||||
@ApiModelProperty(value = "流程按钮配置")
|
||||
@Valid
|
||||
private BpmnButtonConf buttonConf;
|
||||
|
||||
/**
|
||||
* 流程定义的全局字段管理数据
|
||||
*/
|
||||
@ApiModelProperty(value = "流程字段配置")
|
||||
@Valid
|
||||
private BpmnFieldConf fieldConf;
|
||||
|
||||
/**
|
||||
* 租户Id
|
||||
*/
|
||||
|
||||
@ -43,7 +43,7 @@ public enum BpmnErrorCode implements IProjectRespCode {
|
||||
PROCESS_OPERATION_PARAM_VALID_ERROR("05001", "参数缺失, 请确保传入了 ID 或 businessKey 对流程实例进行操作"),
|
||||
PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS("05002", "流程取消失败,流程不处于运行中"),
|
||||
PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF("05003", "流程取消失败,该流程不是你发起的"),
|
||||
PROCESS_INSTANCE_NOT_EXISTS("05004", "流程实例不存在"),
|
||||
PROCESS_INSTANCE_NOT_EXISTS("05004", "流程实例不存在或已结束"),
|
||||
PROCESS_INSTANCE_ID_NOT_EXISTS("05005", "流程实例【{}】不存在"),
|
||||
PROCESS_INSTANCE_CANCELLED("05006", "流程实例已取消"),
|
||||
// ========== bpmn task 06-001 ==========
|
||||
|
||||
@ -77,7 +77,9 @@ public class EngineExecutionStartListener implements ExecutionListener {
|
||||
// UserTask 非多实例
|
||||
if (!userTask.hasMultiInstanceLoopCharacteristics()) {
|
||||
//TODO by zuoqinbo assigneeIdList.size==0情况
|
||||
userTask.setAssignee(assigneeIdList.get(0));
|
||||
if (!CollectionUtils.isEmpty(assigneeIdList)) {
|
||||
userTask.setAssignee(assigneeIdList.get(0));
|
||||
}
|
||||
// remove by wangli, 暂时去除审批人变量, 通过上面直接赋值
|
||||
// execution.setVariable("assigneeUserId", assigneeIdList.get(0));
|
||||
|
||||
|
||||
@ -285,7 +285,8 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
|
||||
public Boolean cancelProcessInstance(BpmnProcessInstanceCancelDTO dto) {
|
||||
HistoricProcessInstance instance = null;
|
||||
if (StringUtils.isNotBlank(dto.getId())) {
|
||||
instance = getProcessInstance(dto.getId(), dto.getInitiator().getTenantId(), false);
|
||||
instance = getProcessInstance(dto.getId(), null, false);
|
||||
// instance = getProcessInstance(dto.getId(), dto.getInitiator().getTenantId(), false);
|
||||
} else if (StringUtils.isNotBlank(dto.getBusinessKey())) {
|
||||
instance = getProcessInstanceByBusinessKey(dto.getBusinessKey(), dto.getInitiator().getTenantId(), false);
|
||||
} else {
|
||||
|
||||
@ -1,8 +1,13 @@
|
||||
package cn.axzo.workflow.core.service.impl;
|
||||
|
||||
import cn.axzo.workflow.common.enums.BpmnCountersignType;
|
||||
import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.*;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAssigneeDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAttachmentDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCommentDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCountersignDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskPageSearchDTO;
|
||||
import cn.axzo.workflow.common.model.response.BpmPageResult;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceGroupVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceVO;
|
||||
@ -72,8 +77,8 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_SPECIFY_NE
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_INFO_SNAPSHOT;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.MULTI_INSTANCE_LOOP_COUNTER;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.NUMBER_OF_INSTANCES;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERATION_TYPE;
|
||||
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.APPROVED;
|
||||
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.CANCELLED;
|
||||
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.PROCESSING;
|
||||
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.REJECTED;
|
||||
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.valueOfStatus;
|
||||
@ -204,7 +209,7 @@ public class BpmnTaskServiceImpl implements BpmnTaskService {
|
||||
NativeHistoricTaskInstanceQuery nativeQuery = historyService.createNativeHistoricTaskInstanceQuery();
|
||||
String tableName = managementService.getTableName(HistoricTaskInstance.class);
|
||||
baseQuerySql.append("SELECT a.* FROM ").append(tableName).append(" a JOIN " +
|
||||
"ACT_HI_PROCINST b")
|
||||
"ACT_HI_PROCINST b")
|
||||
.append(" ON b.PROC_INST_ID_ = a.PROC_INST_ID_");
|
||||
|
||||
if (StringUtils.hasLength(dto.getTenantId())) {
|
||||
@ -286,7 +291,7 @@ public class BpmnTaskServiceImpl implements BpmnTaskService {
|
||||
Task task = checkTask(dto.getApprover().getTenantId(), dto.getApprover().buildAssigneeId(), dto.getTaskId());
|
||||
// 校验流程实例存在
|
||||
HistoricProcessInstance instance = processInstanceService.getProcessInstance(
|
||||
task.getProcessInstanceId(), dto.getApprover().getTenantId(), true);
|
||||
task.getProcessInstanceId(), null, true);
|
||||
if (instance == null) {
|
||||
throw new WorkflowEngineException(PROCESS_INSTANCE_NOT_EXISTS);
|
||||
}
|
||||
@ -374,7 +379,9 @@ public class BpmnTaskServiceImpl implements BpmnTaskService {
|
||||
query.taskTenantId(tenantId);
|
||||
}
|
||||
HistoricProcessInstanceQuery instanceQuery =
|
||||
historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId);
|
||||
historyService.createHistoricProcessInstanceQuery()
|
||||
.includeProcessVariables()
|
||||
.processInstanceId(processInstanceId);
|
||||
if (StringUtils.hasLength(tenantId)) {
|
||||
instanceQuery.processInstanceTenantId(tenantId);
|
||||
}
|
||||
@ -394,20 +401,16 @@ public class BpmnTaskServiceImpl implements BpmnTaskService {
|
||||
Map<String, HistoricVariableInstance> variableInstanceMap =
|
||||
historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId).list()
|
||||
.stream().collect(Collectors.toMap(HistoricVariableInstance::getVariableName,
|
||||
Function.identity(), (s, t) -> s));
|
||||
Function.identity(), (s, t) -> s));
|
||||
|
||||
Set<String> taskDefinitionKeys = new HashSet<>();
|
||||
int count = 0;
|
||||
BpmnProcessInstanceResultEnum finalBusinessStatus = valueOfStatus(instance.getBusinessStatus());
|
||||
BpmnProcessInstanceResultEnum processBusinessStatus = valueOfStatus(instance.getBusinessStatus());
|
||||
for (BpmnHistoricTaskInstanceVO vo : vos) {
|
||||
if (count == 0 || taskDefinitionKeys.contains(vo.getTaskDefinitionKey())) {
|
||||
vo.setResult(finalBusinessStatus);
|
||||
if (Objects.nonNull(vo.getEndTime()) && !Objects.equals(finalBusinessStatus, REJECTED)
|
||||
&& !Objects.equals(finalBusinessStatus, CANCELLED)) {
|
||||
vo.setResult(APPROVED);
|
||||
}
|
||||
} else {
|
||||
vo.setResult(APPROVED);
|
||||
vo.setResult(processBusinessStatus);
|
||||
if (Objects.nonNull(vo.getEndTime())) {
|
||||
// 只有拒绝时, 为指定的 taskId 设置过拒绝变量
|
||||
vo.setResult((BpmnProcessInstanceResultEnum) instance.getProcessVariables().getOrDefault(TASK_COMPLETE_OPERATION_TYPE + vo.getTaskId(), APPROVED));
|
||||
}
|
||||
taskDefinitionKeys.add(vo.getTaskDefinitionKey());
|
||||
List<Comment> taskComments = commentByTaskIdMap.getOrDefault(vo.getTaskId(), Collections.emptyList());
|
||||
@ -482,9 +485,20 @@ public class BpmnTaskServiceImpl implements BpmnTaskService {
|
||||
List<BpmnTaskInstanceVO> vos = bpmnTaskConverter.toVos(query.list());
|
||||
List<String> snapshotTaskIds =
|
||||
vos.stream().map(i -> INTERNAL_TASK_RELATION_ASSIGNEE_INFO_SNAPSHOT + i.getTaskId()).collect(Collectors.toList());
|
||||
ProcessInstance processInstance =
|
||||
runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
|
||||
if (Objects.isNull(processInstance)) {
|
||||
throw new WorkflowEngineException(PROCESS_INSTANCE_NOT_EXISTS);
|
||||
}
|
||||
Map<String, VariableInstance> instanceMap = runtimeService.getVariableInstances(processInstanceId,
|
||||
snapshotTaskIds);
|
||||
vos.forEach(i -> i.setAssigner((BpmnTaskDelegateAssigner) instanceMap.get(INTERNAL_TASK_RELATION_ASSIGNEE_INFO_SNAPSHOT + i.getTaskId()).getValue()));
|
||||
vos.forEach(i -> {
|
||||
VariableInstance variableInstance =
|
||||
instanceMap.get(INTERNAL_TASK_RELATION_ASSIGNEE_INFO_SNAPSHOT + i.getTaskId());
|
||||
if (!Objects.isNull(variableInstance)) {
|
||||
i.setAssigner((BpmnTaskDelegateAssigner) variableInstance.getValue());
|
||||
}
|
||||
});
|
||||
return vos;
|
||||
}
|
||||
|
||||
@ -497,13 +511,11 @@ public class BpmnTaskServiceImpl implements BpmnTaskService {
|
||||
* @param taskId 任务ID
|
||||
*/
|
||||
private Task checkTask(String tenantId, String assignee, String taskId) {
|
||||
|
||||
Task task = getTask(taskId, assignee, tenantId);
|
||||
if (Objects.nonNull(task) && !Objects.equals(assignee, task.getAssignee())) {
|
||||
throw new WorkflowEngineException(TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF);
|
||||
}
|
||||
Task task = getTask(taskId, null, null);
|
||||
if (Objects.isNull(task)) {
|
||||
throw new WorkflowEngineException(TASK_COMPLETE_FAIL_NOT_EXISTS);
|
||||
} else if (!Objects.equals(assignee, task.getAssignee()) && !Objects.equals(tenantId, task.getTenantId())) {
|
||||
throw new WorkflowEngineException(TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF);
|
||||
}
|
||||
return task;
|
||||
}
|
||||
|
||||
74
workflow-engine-core/src/main/resources/test.bpmn20.xml
Normal file
74
workflow-engine-core/src/main/resources/test.bpmn20.xml
Normal file
@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
|
||||
xmlns:flowable="http://flowable.org/bpmn"
|
||||
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
|
||||
xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"
|
||||
typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath"
|
||||
targetNamespace="http://www.flowable.org/test">
|
||||
<process id="DESC1234616312350093314" name="文档借阅" isExecutable="true">
|
||||
<startEvent id="startEventNode"></startEvent>
|
||||
<userTask id="NODE1639041346796_0.5413743892974803_0" name="发起">
|
||||
<extensionElements>
|
||||
<flowable:executionListener event="start"
|
||||
delegateExpression="${engineExecutionStartListener}"></flowable:executionListener>
|
||||
<flowable:taskListener event="all"
|
||||
delegateExpression="${engineTaskEventListener}"></flowable:taskListener>
|
||||
</extensionElements>
|
||||
</userTask>
|
||||
<sequenceFlow id="sequenceFlow_b3da60bc0b404ddf9b871d2c2ed2d396" sourceRef="startEventNode"
|
||||
targetRef="NODE1639041346796_0.5413743892974803_0"></sequenceFlow>
|
||||
<userTask id="NODE1687933854432_0.45762305710855467_1" name="审批人">
|
||||
<extensionElements>
|
||||
<flowable:executionListener event="start"
|
||||
delegateExpression="${engineExecutionStartListener}"></flowable:executionListener>
|
||||
<flowable:taskListener event="all"
|
||||
delegateExpression="${engineTaskEventListener}"></flowable:taskListener>
|
||||
</extensionElements>
|
||||
</userTask>
|
||||
<sequenceFlow id="sequenceFlow_5c4c308bd9b144cd9440a6f2dfd6af99"
|
||||
sourceRef="NODE1639041346796_0.5413743892974803_0"
|
||||
targetRef="NODE1687933854432_0.45762305710855467_1"></sequenceFlow>
|
||||
<endEvent id="endEventNode"></endEvent>
|
||||
<sequenceFlow id="sequenceFlow_b6ebf56f49bf43f295533ab8e10d09a7"
|
||||
sourceRef="NODE1687933854432_0.45762305710855467_1" targetRef="endEventNode"></sequenceFlow>
|
||||
</process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_DESC1234616312350093314">
|
||||
<bpmndi:BPMNPlane bpmnElement="DESC1234616312350093314" id="BPMNPlane_DESC1234616312350093314">
|
||||
<bpmndi:BPMNShape bpmnElement="NODE1687933854432_0.45762305710855467_1"
|
||||
id="BPMNShape_NODE1687933854432_0.45762305710855467_1">
|
||||
<omgdc:Bounds height="60.0" width="100.0" x="230.0" y="0.0"></omgdc:Bounds>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape bpmnElement="startEventNode" id="BPMNShape_startEventNode">
|
||||
<omgdc:Bounds height="30.0" width="30.0" x="0.0" y="15.0"></omgdc:Bounds>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape bpmnElement="NODE1639041346796_0.5413743892974803_0"
|
||||
id="BPMNShape_NODE1639041346796_0.5413743892974803_0">
|
||||
<omgdc:Bounds height="60.0" width="100.0" x="80.0" y="0.0"></omgdc:Bounds>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape bpmnElement="endEventNode" id="BPMNShape_endEventNode">
|
||||
<omgdc:Bounds height="30.0" width="30.0" x="380.0" y="15.0"></omgdc:Bounds>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_b3da60bc0b404ddf9b871d2c2ed2d396"
|
||||
id="BPMNEdge_sequenceFlow_b3da60bc0b404ddf9b871d2c2ed2d396">
|
||||
<omgdi:waypoint x="30.0" y="30.0"></omgdi:waypoint>
|
||||
<omgdi:waypoint x="42.0" y="30.0"></omgdi:waypoint>
|
||||
<omgdi:waypoint x="42.0" y="30.000000000000007"></omgdi:waypoint>
|
||||
<omgdi:waypoint x="80.0" y="30.000000000000007"></omgdi:waypoint>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_b6ebf56f49bf43f295533ab8e10d09a7"
|
||||
id="BPMNEdge_sequenceFlow_b6ebf56f49bf43f295533ab8e10d09a7">
|
||||
<omgdi:waypoint x="330.0" y="30.0"></omgdi:waypoint>
|
||||
<omgdi:waypoint x="342.0" y="30.0"></omgdi:waypoint>
|
||||
<omgdi:waypoint x="342.0" y="30.000000000000004"></omgdi:waypoint>
|
||||
<omgdi:waypoint x="380.0" y="30.000000000000004"></omgdi:waypoint>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_5c4c308bd9b144cd9440a6f2dfd6af99"
|
||||
id="BPMNEdge_sequenceFlow_5c4c308bd9b144cd9440a6f2dfd6af99">
|
||||
<omgdi:waypoint x="180.0" y="30.0"></omgdi:waypoint>
|
||||
<omgdi:waypoint x="192.0" y="30.0"></omgdi:waypoint>
|
||||
<omgdi:waypoint x="192.0" y="30.000000000000007"></omgdi:waypoint>
|
||||
<omgdi:waypoint x="230.0" y="30.000000000000007"></omgdi:waypoint>
|
||||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</definitions>
|
||||
@ -94,6 +94,27 @@ public class BpmnDefaultTaskDelegateImpl implements BpmnTaskDelegate {
|
||||
assigners.add(assigner2);
|
||||
}
|
||||
}
|
||||
|
||||
if (CollectionUtils.isEmpty(assigners) && Objects.equals("69", delegateTask.getTenantId())) {
|
||||
if (Objects.equals("NODE1639041346796_0.5413743892974803_0", delegateTask.getTaskDefinitionKey())) {
|
||||
BpmnTaskDelegateAssigner assigner1 = new BpmnTaskDelegateAssigner();
|
||||
assigner1.setAssignee("1");
|
||||
assigner1.setAssigneeType("5");
|
||||
assigner1.setAssignerName("或签人1");
|
||||
assigner1.setPersonId("100001");
|
||||
assigner1.setTenantId("296");
|
||||
assigners.add(assigner1);
|
||||
}
|
||||
if (Objects.equals("NODE1687933854432_0.45762305710855467_1", delegateTask.getTaskDefinitionKey())) {
|
||||
BpmnTaskDelegateAssigner assigner1 = new BpmnTaskDelegateAssigner();
|
||||
assigner1.setAssignee("1");
|
||||
assigner1.setAssigneeType("5");
|
||||
assigner1.setAssignerName("或签人1");
|
||||
assigner1.setPersonId("100001");
|
||||
assigner1.setTenantId("296");
|
||||
assigners.add(assigner1);
|
||||
}
|
||||
}
|
||||
return assigners;
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ spring:
|
||||
server-addr: ${NACOS_HOST:https://dev-nacos.axzo.cn}:${NACOS_PORT:443}
|
||||
file-extension: yaml
|
||||
# namespace: ${NACOS_NAMESPACE_ID:1b5d2a22-b340-4503-8464-7d7fc2059d39}
|
||||
namespace: ${NACOS_NAMESPACE_ID:35eada10-9574-4db8-9fea-bc6a4960b6c7}
|
||||
namespace: ${NACOS_NAMESPACE_ID:f82179f1-81a9-41a1-a489-4f9ab5660a6e}
|
||||
|
||||
---
|
||||
#开发环境
|
||||
|
||||
Loading…
Reference in New Issue
Block a user