From 48aecf5235fa5c1eb83373f31595ed9942561a9c Mon Sep 17 00:00:00 2001 From: pengqiang <1067496116@qq.com> Date: Wed, 21 Dec 2022 11:13:42 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E6=B5=81=E7=A8=8B=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../work/config/activiti/ActConstant.java | 15 + .../backend/ActModelController.java | 13 +- .../java/cn/palmte/work/model/ActTaskDef.java | 14 +- .../work/model/ProjectInstanceRelation.java | 14 + .../ProjectInstanceRelationRepository.java | 9 +- .../palmte/work/model/ProjectTaskRecord.java | 6 + .../palmte/work/service/AccountService.java | 27 + .../work/service/ActListenerService.java | 74 +- .../palmte/work/service/ActModelService.java | 44 +- .../work/service/ActProcDefService.java | 2 +- .../work/service/ActTaskDefService.java | 55 +- .../work/service/ProjectInstanceService.java | 113 ++- .../service/ProjectTaskRecordService.java | 11 +- .../java/cn/palmte/work/utils/ActUtil.java | 13 + .../editor-app/popups/save-model.html | 2 +- src/main/resources/stencilset.json | 686 +----------------- .../templates/admin/act_model_list.ftl | 4 +- .../templates/admin/act_task_def.ftl | 30 +- 18 files changed, 354 insertions(+), 778 deletions(-) diff --git a/src/main/java/cn/palmte/work/config/activiti/ActConstant.java b/src/main/java/cn/palmte/work/config/activiti/ActConstant.java index b769d78..6d28ba0 100644 --- a/src/main/java/cn/palmte/work/config/activiti/ActConstant.java +++ b/src/main/java/cn/palmte/work/config/activiti/ActConstant.java @@ -85,4 +85,19 @@ public class ActConstant { public static final String KEY_PROJECT_ID = "projectId"; public static final String KEY_PROJECT_TYPE = "projectType"; + + public static final String PROCESS_DEFKEY_SALE_CONTRACT = "saleContract"; + public static final String PROCESS_DEFKEY_BUSINESS_PURCHASE = "businessPurchase"; + + + //发起人部门主管 + public static final int CANDIDATE_TYPE_START_USER_LEADER = 1; + + + //四算项目 + public static final int PROJECT_TYPE_FOURCAL = 0; + //销售合同 + public static final int PROJECT_TYPE_SALE_CONTRACT = 1; + //业务采购 + public static final int PROJECT_TYPE_BUSINESS_PURCHASE = 2; } diff --git a/src/main/java/cn/palmte/work/controller/backend/ActModelController.java b/src/main/java/cn/palmte/work/controller/backend/ActModelController.java index 51f5e56..0cdf1bf 100644 --- a/src/main/java/cn/palmte/work/controller/backend/ActModelController.java +++ b/src/main/java/cn/palmte/work/controller/backend/ActModelController.java @@ -4,6 +4,7 @@ package cn.palmte.work.controller.backend; import cn.palmte.work.bean.ResponseMsg; import cn.palmte.work.service.ActModelService; +import cn.palmte.work.utils.ActUtil; import cn.palmte.work.utils.InterfaceUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -24,6 +25,9 @@ public class ActModelController extends BaseController { private static final Logger logger = LoggerFactory.getLogger(ActModelController.class); + @Autowired + ActUtil actUtil; + @Autowired private ActModelService activitiModelService; @@ -45,9 +49,14 @@ public class ActModelController extends BaseController { } @RequestMapping("/save") - public String save(HttpServletRequest request) { + public String save(HttpServletRequest request, Map model) { + String procDefKey = request.getParameter("procDefKey"); + if (activitiModelService.findByProcDefKey(procDefKey) != null) { + model.put("errorMessage", "流程标识已经存在!"); + return "/common/error"; + } try { - activitiModelService.createModel(request.getParameter("procDefKey"), request.getParameter("modelName")); + activitiModelService.createModel(procDefKey, request.getParameter("modelName")); } catch (Exception e) { logger.error("", e); } diff --git a/src/main/java/cn/palmte/work/model/ActTaskDef.java b/src/main/java/cn/palmte/work/model/ActTaskDef.java index 3e78f9c..7d97e47 100644 --- a/src/main/java/cn/palmte/work/model/ActTaskDef.java +++ b/src/main/java/cn/palmte/work/model/ActTaskDef.java @@ -69,16 +69,11 @@ public class ActTaskDef { /** - * 审批通过执行的脚本 act_script(弃用)表id 弃用 + * 按类型查询 */ - @Column(name = "end_script") - private int endScript; + @Column(name = "candidate_types") + private String candidateTypes; - /** - * 审批驳回执行的脚本 act_script(弃用)表id 弃用 - */ - @Column(name = "rollback_script") - private int rollbackScript; @Column(name = "created_time") private Date createdTime; @@ -94,4 +89,7 @@ public class ActTaskDef { @Transient private List candidateRoleList; + @Transient + private List candidateTypeList; + } diff --git a/src/main/java/cn/palmte/work/model/ProjectInstanceRelation.java b/src/main/java/cn/palmte/work/model/ProjectInstanceRelation.java index 710bbfe..351e996 100644 --- a/src/main/java/cn/palmte/work/model/ProjectInstanceRelation.java +++ b/src/main/java/cn/palmte/work/model/ProjectInstanceRelation.java @@ -22,6 +22,12 @@ public class ProjectInstanceRelation { @Column(name = "project_id") private int projectId; + /** + * 项目类型 0-四算项目 1-销售合同流程 2-业务采购流程 + */ + @Column(name = "project_type") + private int projectType = 0; + /** * 流程类型:estimate、budget、settle、final */ @@ -77,4 +83,12 @@ public class ProjectInstanceRelation { public void setCreateTime(Date createTime) { this.createTime = createTime; } + + public int getProjectType() { + return projectType; + } + + public void setProjectType(int projectType) { + this.projectType = projectType; + } } \ No newline at end of file diff --git a/src/main/java/cn/palmte/work/model/ProjectInstanceRelationRepository.java b/src/main/java/cn/palmte/work/model/ProjectInstanceRelationRepository.java index 59128d4..e49dcf5 100644 --- a/src/main/java/cn/palmte/work/model/ProjectInstanceRelationRepository.java +++ b/src/main/java/cn/palmte/work/model/ProjectInstanceRelationRepository.java @@ -1,14 +1,15 @@ package cn.palmte.work.model; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import java.util.List; public interface ProjectInstanceRelationRepository extends JpaRepository { - /** - * 根据项目id和类型找到流程实例id - */ - List findAllByProjectIdEqualsAndProcessTypeEqualsOrderByCreateTimeDesc(int projectId, String processType); + @Query(value = "select * from project_instance_relation where project_id = ? and project_type=0 order by create_time desc", nativeQuery = true) List findByProjectIdOrderByCreateTimeDesc(int projectId); + + @Query(value = "select * from project_instance_relation where project_id = ? and project_type=? order by create_time desc limit 1", nativeQuery = true) + ProjectInstanceRelation findByProjectIdAndProjectType(int projectId, int projectType); } diff --git a/src/main/java/cn/palmte/work/model/ProjectTaskRecord.java b/src/main/java/cn/palmte/work/model/ProjectTaskRecord.java index a818aaa..34e3b04 100644 --- a/src/main/java/cn/palmte/work/model/ProjectTaskRecord.java +++ b/src/main/java/cn/palmte/work/model/ProjectTaskRecord.java @@ -22,6 +22,12 @@ public class ProjectTaskRecord { @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; + /** + * 项目类型 0-四算项目 1-销售合同流程 2-业务采购流程 + */ + @Column(name = "project_type") + private int projectType = 0; + @Column(name = "project_id") private int projectId; diff --git a/src/main/java/cn/palmte/work/service/AccountService.java b/src/main/java/cn/palmte/work/service/AccountService.java index ab01917..9dc0850 100644 --- a/src/main/java/cn/palmte/work/service/AccountService.java +++ b/src/main/java/cn/palmte/work/service/AccountService.java @@ -472,4 +472,31 @@ public class AccountService { } return userIds; } + + + /** + * 查询部门主管(一级部门领导) + * + * @param userId + * @return + */ + public int getOneLevelDeptManagerId(int userId) { + Admin admin = adminRepository.findOne(userId); + Record record = getDept(admin.getDeptId()); + if (record == null) { + return 0; + } + + while (1 != record.getInt("level")) { + //不是一级 往上找 + record = getDept(record.getInt("parnter_id")); + } + + return record.getInt("manager_id"); + } + + private Record getDept(int deptId) { + String sql = "SELECT level, manager_id, parnter_id from dept where id=?"; + return pagination.findFirst(sql, deptId); + } } diff --git a/src/main/java/cn/palmte/work/service/ActListenerService.java b/src/main/java/cn/palmte/work/service/ActListenerService.java index 0314b8e..89c0aae 100644 --- a/src/main/java/cn/palmte/work/service/ActListenerService.java +++ b/src/main/java/cn/palmte/work/service/ActListenerService.java @@ -16,6 +16,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; +import java.util.stream.Collectors; /** @@ -47,7 +48,7 @@ public class ActListenerService { * @param delegateTask * @throws Exception */ - public void create(DelegateTask delegateTask) throws Exception { + public void create(DelegateTask delegateTask) { String procInsId = delegateTask.getProcessInstanceId(); logger.info("--节点创建后监听-- procInsId:{}, {}", procInsId, delegateTask); logger.info("**** rwcjjt【{}】任务创建监听 procInsId:{} **** ", delegateTask, procInsId); @@ -58,44 +59,69 @@ public class ActListenerService { logger.info("**** rwcjjt 任务创建监听 查询候选人 procInsId:{},任务名称:{},候选人:{} **** ", procInsId, delegateTask.getName(), candidateUsers); ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(procInsId).singleResult(); - updateProjectApprover(candidateUsers, processInstance, procDefId, taskDefKey); + if (processInstance != null) { + try { + updateProjectApprover(candidateUsers, processInstance, procDefId, taskDefKey); + } catch (Exception e) { + logger.error("updateProjectApproverError", e); + } + } delegateTask.addCandidateUsers(candidateUsers); } /** - * 更新项目审批人 四算业务需要 + * 流程结束监听 更新项目状态为审批通过 + * + * @param delegateExecution + */ + public void end(DelegateExecution delegateExecution) { + String procInsId = delegateExecution.getProcessInstanceId(); + ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(procInsId).singleResult(); + int projectId = Integer.parseInt(processInstance.getBusinessKey()); + + String procDefId = processInstance.getProcessDefinitionId(); + if (actUtil.isNewProcess(procDefId)) { + logger.info("**** lcjsjt 流程结束监听 更新项目状态为审批通过 **** procInsId:{}, procDefId:{}, projectId:{}", procInsId, procDefId, projectId); + //todo updateNewProcess 更新项目状态为审批通过 + } + } + + + /** + * 更新项目审批人 * * @param candidateUsers * @param processInstance */ - private void updateProjectApprover(List candidateUsers, ProcessInstance processInstance, String procDefId, String taskDefKey) { - if (processInstance == null) { - return; - } + private void updateProjectApprover(List candidateUsers, ProcessInstance processInstance, + String procDefId, String taskDefKey) { + String businessKey = processInstance.getBusinessKey(); + ActTaskDef actTaskDef = actTaskDefService.findFirstByProcDefIdAndTaskKey(procDefId, taskDefKey); + //找到当前有效的用户 + List enableUsers = currentEnableUsers(candidateUsers); + boolean isFirstUserTask = actTaskDef != null && actTaskDef.getTaskIndex() != ActConstant.TASK_INDEX_FIRST_USER_TASK; - try { - String businessKey = processInstance.getBusinessKey(); - ActTaskDef actTaskDef = actTaskDefService.findFirstByProcDefIdAndTaskKey(procDefId, taskDefKey); - int adminId = 0; - if (!candidateUsers.isEmpty() && actTaskDef!=null && actTaskDef.getTaskIndex() != ActConstant.TASK_INDEX_FIRST_USER_TASK) { - //回退到发起节点 审批人设置为空 - for (String id : candidateUsers) { - Admin one = adminRepository.findOne(Integer.parseInt(id)); - if (!one.isDeleted() && one.getEnabled() == 1) { - //找到有效账号 发送任务 - adminId = one.getId(); - break; - } - } + if (actUtil.isFourcalProcess(procDefId)) { + int adminId = 0;//默认审批人设置为空 + if (!isFirstUserTask && !enableUsers.isEmpty()) { + adminId = enableUsers.get(0);//四算项目只支持一个审批人 } - logger.info("**** rwcjjt 任务创建监听 更新审批人 procInsId:{}, projectId:{}, adminId:{} **** ", + logger.info("**** rwcjjt 任务创建监听 更新审批人1 procInsId:{}, projectId:{}, adminId:{} **** ", processInstance.getProcessInstanceId(), businessKey, adminId); projectInstanceService.updateApprover(Integer.parseInt(businessKey), adminId); - } catch (Exception e) { - logger.error("", e); + } else if (actUtil.isNewProcess(procDefId)) { + //todo updateNewProcess 更新流程审批人 + logger.info("**** rwcjjt 任务创建监听 更新审批2 procInsId:{}, projectId:{}, enableUsers:{} **** ", + processInstance.getProcessInstanceId(), businessKey, enableUsers); } + } + private List currentEnableUsers(List candidateUsers) { + return candidateUsers.stream().map(ele -> adminRepository.findOne(Integer.parseInt(ele))) + .filter(ele -> !ele.isDeleted() && ele.getEnabled() == 1) + .map(Admin::getId) + .collect(Collectors.toList()); } } diff --git a/src/main/java/cn/palmte/work/service/ActModelService.java b/src/main/java/cn/palmte/work/service/ActModelService.java index ade2cb9..fd876c0 100644 --- a/src/main/java/cn/palmte/work/service/ActModelService.java +++ b/src/main/java/cn/palmte/work/service/ActModelService.java @@ -12,6 +12,7 @@ import org.activiti.bpmn.model.*; import org.activiti.bpmn.model.Process; import org.activiti.editor.language.json.converter.BpmnJsonConverter; import org.activiti.engine.RepositoryService; +import org.activiti.engine.delegate.BaseExecutionListener; import org.activiti.engine.delegate.TaskListener; import org.activiti.engine.repository.Deployment; import org.activiti.engine.repository.DeploymentBuilder; @@ -55,6 +56,10 @@ public class ActModelService { return pagination.paginate(queryHelper.getSql(), ActModel.class, pageNumber, pageSize); } + public ActModel findByProcDefKey(String procDefKey) { + return pagination.findFirst("select * from act_re_model where KEY_=? ", ActModel.class, procDefKey); + } + public void createModel(String processId, String modelName) throws Exception { ObjectMapper objectMapper = new ObjectMapper(); ObjectNode editorNode = objectMapper.createObjectNode(); @@ -114,18 +119,13 @@ public class ActModelService { BpmnJsonConverter jsonConverter = new BpmnJsonConverter(); BpmnModel model = jsonConverter.convertToBpmnModel(modelNode); - //任务创建后监听器 - ActivitiListener activitiListener = new ActivitiListener(); - activitiListener.setEvent(TaskListener.EVENTNAME_CREATE); - activitiListener.setImplementation("${actListenerService.create(task)}"); - activitiListener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_EXPRESSION); - List activitiListenerList = new ArrayList<>(1); - activitiListenerList.add(activitiListener); - List taskList = new ArrayList<>(); Process process = model.getMainProcess(); Collection flowElements = process.getFlowElements(); + //设置流程监听器 + setExecutionListener(process); + int i = 0; ActTaskDef taskDef; ActTaskDef first = null; @@ -139,16 +139,12 @@ public class ActModelService { MultiInstanceLoopCharacteristics loopCharacteristics = userTaskElement.getLoopCharacteristics(); if (loopCharacteristics != null) { //多实列 - loopCharacteristics.setInputDataItem("${actListenerService.getMultiCandidateUsers(execution)}"); - loopCharacteristics.setElementVariable("assignee"); - userTaskElement.setAssignee("${assignee}"); - taskDef.setTaskType(ActConstant.TASK_TYPE_MULTI); }else { - userTaskElement.setTaskListeners(activitiListenerList); - taskDef.setTaskType(ActConstant.TASK_TYPE_SINGE); } + //任务监听器 + setTaskListener(userTaskElement); if (i == 1) {//画流程图时,要保证第一个用户任务一定要先画 taskDef.setTaskIndex(ActConstant.TASK_INDEX_FIRST_USER_TASK); @@ -183,4 +179,24 @@ public class ActModelService { logger.info("deploy success: deploymentId:{}, procDefName:{}, procDefKey:{}", deployment.getId(), processDefinition.getName(), processDefinition.getKey()); } + + private void setTaskListener(UserTask userTaskElement) { + ActivitiListener taskListener = new ActivitiListener(); + taskListener.setEvent(TaskListener.EVENTNAME_CREATE); + taskListener.setImplementation("${actListenerService.create(task)}"); + taskListener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_EXPRESSION); + List taskListenerList = new ArrayList<>(1); + taskListenerList.add(taskListener); + userTaskElement.setTaskListeners(taskListenerList); + } + + private void setExecutionListener(Process process) { + ActivitiListener executionListener = new ActivitiListener(); + executionListener.setEvent(BaseExecutionListener.EVENTNAME_END); + executionListener.setImplementation("${actListenerService.end(execution)}"); + executionListener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_EXPRESSION); + List executionListenerList = new ArrayList<>(1); + executionListenerList.add(executionListener); + process.setExecutionListeners(executionListenerList); + } } diff --git a/src/main/java/cn/palmte/work/service/ActProcDefService.java b/src/main/java/cn/palmte/work/service/ActProcDefService.java index 4f21580..57ec9f1 100644 --- a/src/main/java/cn/palmte/work/service/ActProcDefService.java +++ b/src/main/java/cn/palmte/work/service/ActProcDefService.java @@ -41,7 +41,7 @@ public class ActProcDefService { QueryHelper queryHelper = new QueryHelper(select, " act_re_procdef p LEFT JOIN act_re_deployment d on p.DEPLOYMENT_ID_ = d.ID_"); String name = searchInfo.get("name"); queryHelper.addCondition(StringUtils.isNotEmpty(name), "(p.NAME_=? or p.KEY_=?)", name, name); - queryHelper.addOrderProperty("p.VERSION_", false); + queryHelper.addOrderProperty("d.DEPLOY_TIME_", false); return pagination.paginate(queryHelper.getSql(), ActProcDef.class, pageNumber, pageSize); } diff --git a/src/main/java/cn/palmte/work/service/ActTaskDefService.java b/src/main/java/cn/palmte/work/service/ActTaskDefService.java index 6718edd..8900b2b 100644 --- a/src/main/java/cn/palmte/work/service/ActTaskDefService.java +++ b/src/main/java/cn/palmte/work/service/ActTaskDefService.java @@ -11,7 +11,6 @@ import cn.palmte.work.utils.InterfaceUtil; import com.alibaba.fastjson.JSONObject; import org.activiti.engine.*; import org.activiti.engine.impl.identity.Authentication; -import org.activiti.engine.impl.persistence.entity.TaskEntity; import org.activiti.engine.runtime.ProcessInstance; import org.activiti.engine.task.Task; import org.apache.commons.lang.StringUtils; @@ -99,6 +98,7 @@ public class ActTaskDefService { /** * 预算跳过剩下审批任务直接到执行董事节点 + * * @param procInsId */ public ResponseMsg skipTaskByProcInsId(String procInsId, String fileUrl, String comment) { @@ -176,8 +176,10 @@ public class ActTaskDefService { //审批通过 taskService.complete(taskId); - //最后一个任务完成后 更新项目状态为审批通过 - updateProjectPassed(processInstance, actTaskDef, procDefKey); + if (actUtil.isFourcalProcess(processInstance.getProcessDefinitionId())) { + //四算项目 最后一个任务完成后 更新项目状态为审批通过 其他项目通过监听器更新 + updateProjectPassed(processInstance, actTaskDef, procDefKey); + } } else if (ApproveStatusEnum.APPROVAL_UNPASS.getApproveStatus() == type) { //驳回 String rollbackTaskKey = actTaskDef.getRollbackTaskKey(); @@ -185,7 +187,11 @@ public class ActTaskDefService { //驳回后 更新项目状态为审批不通过 int projectId = Integer.parseInt(processInstance.getBusinessKey()); - projectInstanceService.updateApproveStatus(projectId, procDefKey, ApproveStatusEnum.APPROVAL_UNPASS); + if (actUtil.isFourcalProcess(processInstance.getProcessDefinitionId())) { + projectInstanceService.updateApproveStatus(projectId, procDefKey, ApproveStatusEnum.APPROVAL_UNPASS); + } else if (actUtil.isNewProcess(processInstance.getProcessDefinitionId())) { + //todo updateNewProcess 更新流程状态为不通过 + } logger.info("updateProjectUnPassed projectId:{}, proDefKey:{}", projectId, procDefKey); } @@ -295,7 +301,8 @@ public class ActTaskDefService { ActTaskDef one = actTaskDefRepository.findOne(taskDef.getId()); one.setCandidateUsers(taskDef.getCandidateUsers()); one.setCandidateRoles(taskDef.getCandidateRoles()); - one.setRollbackTaskKey(taskDef.getRollbackTaskKey()); + one.setCandidateTypes(taskDef.getCandidateTypes()); + //one.setRollbackTaskKey(taskDef.getRollbackTaskKey()); one.setLastUpdatedTime(new Date()); actTaskDefRepository.save(one); @@ -341,11 +348,40 @@ public class ActTaskDefService { res.addAll(list); } + //通过特殊类型查询 + List candidateTypeList = taskDef.getCandidateTypeList(); + logger.info("findCandidateUsers-type-task:{}, typeList:{}", taskDef.getTaskName(), candidateTypeList); + List userListByType = queryCandidatesByTypes(candidateRoleList, procInsId); + logger.info("findCandidateUsers-type-task:{}, userListByType:{}", taskDef.getTaskName(), userListByType); + if (!userListByType.isEmpty()) { + res.addAll(userListByType); + } + List resList = new ArrayList<>(res); logger.info("findCandidateUsers-4-task:{}, resIds:{}", taskDef.getTaskName(), resList); return resList; } + private List queryCandidatesByTypes(List types, String procInsId) { + if (types == null || types.isEmpty()) { + return Collections.emptyList(); + } + + List userIdList = new ArrayList<>(); + for (String typeStr : types) { + if (ActConstant.CANDIDATE_TYPE_START_USER_LEADER == Integer.parseInt(typeStr)) { + //查找发起人部门主管 + String startUserId = actUtil.getStartUserId(procInsId); + int leaderId = accountService.getOneLevelDeptManagerId(Integer.parseInt(startUserId)); + if (leaderId != 0) { + userIdList.add(String.valueOf(leaderId)); + } + } + } + + return userIdList; + } + /** * 任务审批人列表从sring转成list @@ -366,6 +402,13 @@ public class ActTaskDefService { roleIdList = Arrays.asList(candidateRoles.split("#")); } actTaskDef.setCandidateRoleList(roleIdList); + + String candidateTypes = actTaskDef.getCandidateTypes(); + List typeIdList = new ArrayList<>(); + if (StringUtils.isNotBlank(candidateTypes)) { + typeIdList = Arrays.asList(candidateTypes.split("#")); + } + actTaskDef.setCandidateTypeList(typeIdList); } @@ -409,7 +452,7 @@ public class ActTaskDefService { //保存一条指定承接人记录 projectTaskRecordService.saveTaskRecord(projectId, currentTask, ProjectTaskRecord.STATUS_RE_ASSIGNEE, ActConstant.TASK_INDEX_OTHER, "指定承接人【" + targetAdmin.getRealName() + "]"); - }else{ + } else { logger.error("setTaskAssignAndSaveRecordError task is null, projectId:{}", projectId); } } diff --git a/src/main/java/cn/palmte/work/service/ProjectInstanceService.java b/src/main/java/cn/palmte/work/service/ProjectInstanceService.java index 653cca9..c2eff43 100644 --- a/src/main/java/cn/palmte/work/service/ProjectInstanceService.java +++ b/src/main/java/cn/palmte/work/service/ProjectInstanceService.java @@ -1,20 +1,15 @@ package cn.palmte.work.service; import cn.palmte.work.bean.ApproveStatusEnum; -import cn.palmte.work.bean.StatusEnum; import cn.palmte.work.config.activiti.ActConstant; import cn.palmte.work.model.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import top.jfunc.common.utils.CollectionUtil; - -import java.util.Collections; import java.util.Date; import java.util.HashMap; -import java.util.List; -import java.util.stream.Collectors; +import java.util.Map; /** * @author xiongshiyan at 2021/10/29 , contact me with email yanshixiong@126.com or phone 15208384257 @@ -30,6 +25,8 @@ public class ProjectInstanceService { private ActProcInsService actProcInsService; @Autowired private ProjectInstanceRelationRepository projectInstanceRelationRepository; + @Autowired + private ActTaskDefService actTaskDefService; /** @@ -39,25 +36,12 @@ public class ProjectInstanceService { startProcess(project, admin, ActConstant.PROCESS_DEFKEY_ESTIMATE); } - /** - * 返回概算的所有的实例id,没有则空集合 - */ - public List getEstimateProcessInsIds(Project project){ - return getApproveInstanceIds(project, ActConstant.PROCESS_DEFKEY_ESTIMATE); - } - /** * 开启一个预算流程实例 */ public void startBudgetProcessInstance(Project project, Admin admin) throws Exception { startProcess(project, admin, ActConstant.PROCESS_DEFKEY_BUDGET); } - /** - * 返回预算的所有的实例id,没有则空集合 - */ - public List getBudgetProcessInsIds(Project project){ - return getApproveInstanceIds(project, ActConstant.PROCESS_DEFKEY_BUDGET); - } /** * 开启一个结算流程实例 @@ -65,12 +49,6 @@ public class ProjectInstanceService { public void startSettleProcessInstance(Project project, Admin admin) throws Exception { startProcess(project, admin, ActConstant.PROCESS_DEFKEY_SETTLE); } - /** - * 返回结算的所有的实例id,没有则空集合 - */ - public List getSettleProcessInsIds(Project project){ - return getApproveInstanceIds(project, ActConstant.PROCESS_DEFKEY_SETTLE); - } /** * 开启一个决算流程实例 */ @@ -78,18 +56,87 @@ public class ProjectInstanceService { Project project = projectRepository.findOne(projectId); startProcess(project, admin, ActConstant.PROCESS_DEFKEY_FINAL); } + /** - * 返回决算的所有的实例id,没有则空集合 + * 发起销售合同流程实例 + * + * @param projectId 项目唯一id + * @param map 流程变量 + * @throws Exception */ - public List getFinalProcessInsIds(Project project){ - return getApproveInstanceIds(project, ActConstant.PROCESS_DEFKEY_FINAL); + public void startSaleContractProcess(int projectId, Map map) throws Exception { + String processDefkey = ActConstant.PROCESS_DEFKEY_SALE_CONTRACT; + String businessKey = String.valueOf(projectId); + logger.info("startSaleContractProcess processDefkey:{}, businessKey:{}", processDefkey, businessKey); + String processInstanceId = actProcInsService.startProcessInstance(processDefkey, businessKey, map); + saveRelation(projectId, processDefkey, processInstanceId); + } - private List getApproveInstanceIds(Project project, String processDefkey) { - List all = projectInstanceRelationRepository.findAllByProjectIdEqualsAndProcessTypeEqualsOrderByCreateTimeDesc(project.getId(), processDefkey); - if (CollectionUtil.isEmpty(all)) { - return Collections.emptyList(); + + + + /** + * 发起业务采购流程实例 + * + * @param projectId 项目唯一id + * @param map 流程变量 + * @throws Exception + */ + public void startBusinessPurchaseProcess(int projectId, Map map) throws Exception { + String processDefkey = ActConstant.PROCESS_DEFKEY_BUSINESS_PURCHASE; + String businessKey = String.valueOf(projectId); + logger.info("startBusinessPurchaseProcess processDefkey:{}, businessKey:{}", processDefkey, businessKey); + String processInstanceId = actProcInsService.startProcessInstance(processDefkey, businessKey, map); + + //保存流程实例id与项目的关联关系 + saveRelation(projectId, processDefkey, processInstanceId); + } + + /** + * 销售合同流程 审批(通过或者不通过) + * + * @param projectId 项目唯一id + * @param approveType 2-通过 3-不通过 + * @param message 审批意见 + * @return + */ + public boolean completeSaleContractTask(int projectId, int approveType, String message) { + ProjectInstanceRelation projectInstance = projectInstanceRelationRepository.findByProjectIdAndProjectType(projectId, ActConstant.PROJECT_TYPE_SALE_CONTRACT); + if (projectInstance == null) { + return false; } - return all.stream().map(ProjectInstanceRelation::getProcessInsId).collect(Collectors.toList()); + actTaskDefService.completeTaskByProcInsId(projectInstance.getProcessInsId(), approveType, message); + return true; + } + + + /** + * 业务采购流程 审批(通过或者不通过) + * + * @param projectId 项目唯一id + * @param approveType 2-通过 3-不通过 + * @param message 审批意见 + * @return + */ + public boolean completeBusinessPurchaseTask(int projectId, int approveType, String message) { + ProjectInstanceRelation projectInstance = projectInstanceRelationRepository.findByProjectIdAndProjectType(projectId, ActConstant.PROJECT_TYPE_SALE_CONTRACT); + if (projectInstance == null) { + return false; + } + actTaskDefService.completeTaskByProcInsId(projectInstance.getProcessInsId(), approveType, message); + return true; + } + + + private void saveRelation(int projectId, String processDefkey, String processInstanceId) { + //保存流程实例id与项目的关联关系 + ProjectInstanceRelation relation = new ProjectInstanceRelation(); + relation.setProjectId(projectId); + relation.setProjectType(ActConstant.PROJECT_TYPE_SALE_CONTRACT); + relation.setProcessType(processDefkey); + relation.setProcessInsId(processInstanceId); + relation.setCreateTime(new Date()); + projectInstanceRelationRepository.saveAndFlush(relation); } private void startProcess(Project project, Admin admin, String processDefkey) throws Exception { diff --git a/src/main/java/cn/palmte/work/service/ProjectTaskRecordService.java b/src/main/java/cn/palmte/work/service/ProjectTaskRecordService.java index be2660f..d7acec6 100644 --- a/src/main/java/cn/palmte/work/service/ProjectTaskRecordService.java +++ b/src/main/java/cn/palmte/work/service/ProjectTaskRecordService.java @@ -80,8 +80,17 @@ public class ProjectTaskRecordService { private ProjectTaskRecord getProjectTaskRecord(int projectId, Task task, int status, int taskIndex, String comment) { ProjectTaskRecord record = new ProjectTaskRecord(); record.setProjectId(projectId); - record.setProcDefId(task.getProcessDefinitionId()); + String procDefId = task.getProcessDefinitionId(); + record.setProcDefId(procDefId); record.setProcInsId(task.getProcessInstanceId()); + + int projectType = ActConstant.PROJECT_TYPE_FOURCAL; + if (procDefId.startsWith(ActConstant.PROCESS_DEFKEY_SALE_CONTRACT)) { + projectType = ActConstant.PROJECT_TYPE_SALE_CONTRACT; + } else if (procDefId.startsWith(ActConstant.PROCESS_DEFKEY_BUSINESS_PURCHASE)) { + projectType = ActConstant.PROJECT_TYPE_BUSINESS_PURCHASE; + } + record.setProjectType(projectType); record.setTaskDefKey(task.getTaskDefinitionKey()); record.setTaskName(task.getName()); record.setTaskComment(comment); diff --git a/src/main/java/cn/palmte/work/utils/ActUtil.java b/src/main/java/cn/palmte/work/utils/ActUtil.java index cc5cdcc..fe71a1f 100644 --- a/src/main/java/cn/palmte/work/utils/ActUtil.java +++ b/src/main/java/cn/palmte/work/utils/ActUtil.java @@ -52,6 +52,19 @@ public class ActUtil { @Autowired private ProjectInstanceRelationRepository projectInstanceRelationRepository; + + public boolean isFourcalProcess(String procDefId) { + return procDefId.startsWith(ActConstant.PROCESS_DEFKEY_ESTIMATE) + || procDefId.startsWith(ActConstant.PROCESS_DEFKEY_BUDGET) + || procDefId.startsWith(ActConstant.PROCESS_DEFKEY_SETTLE) + || procDefId.startsWith(ActConstant.PROCESS_DEFKEY_FINAL); + } + + public boolean isNewProcess(String procDefId) { + return procDefId.startsWith(ActConstant.PROCESS_DEFKEY_SALE_CONTRACT) + || procDefId.startsWith(ActConstant.PROCESS_DEFKEY_BUSINESS_PURCHASE); + } + /** * 判断两个节点间顺序 * diff --git a/src/main/resources/static/activiti-editor/editor-app/popups/save-model.html b/src/main/resources/static/activiti-editor/editor-app/popups/save-model.html index b031f1c..bd5a3ed 100644 --- a/src/main/resources/static/activiti-editor/editor-app/popups/save-model.html +++ b/src/main/resources/static/activiti-editor/editor-app/popups/save-model.html @@ -26,7 +26,7 @@
- +
diff --git a/src/main/resources/stencilset.json b/src/main/resources/stencilset.json index c05ad66..dc12be5 100644 --- a/src/main/resources/stencilset.json +++ b/src/main/resources/stencilset.json @@ -3,26 +3,6 @@ "namespace" : "http://b3mn.org/stencilset/bpmn2.0#", "description" : "BPMN流程编辑器", "propertyPackages" : [ { - "name" : "process_idpackage", - "properties" : [ { - "id" : "process_id", - "type" : "String", - "title" : "流程唯一标识", - "value" : "未定义", - "description" : "流程定义唯一的标识", - "popular" : true - } ] - }, { - "name" : "overrideidpackage", - "properties" : [ { - "id" : "overrideid", - "type" : "String", - "title" : "ID", - "value" : "", - "description" : "元素的唯一标识", - "popular" : true - } ] - }, { "name" : "namepackage", "properties" : [ { "id" : "name", @@ -33,157 +13,7 @@ "popular" : true, "refToView" : "text_name" } ] - }, { - "name" : "documentationpackage", - "properties" : [ { - "id" : "documentation", - "type" : "Text", - "title" : "文档", - "value" : "", - "description" : "BPMN元素的描述名称.", - "popular" : true - } ] - }, { - "name" : "process_authorpackage", - "properties" : [ { - "id" : "process_author", - "type" : "String", - "title" : "流程作者", - "value" : "", - "description" : "流程定义的作者.", - "popular" : true - } ] - }, { - "name" : "process_versionpackage", - "properties" : [ { - "id" : "process_version", - "type" : "String", - "title" : "流程版本字符串(仅限于文档)", - "value" : "", - "description" : "文档的目的为版本标识", - "popular" : true - } ] - }, { - "name" : "process_namespacepackage", - "properties" : [ { - "id" : "process_namespace", - "type" : "String", - "title" : "目标命名空间", - "value" : "http://www.insight.com/", - "description" : "流程定义的目标命名空间.", - "popular" : true - } ] - }, { - "name" : "asynchronousdefinitionpackage", - "properties" : [ { - "id" : "asynchronousdefinition", - "type" : "Boolean", - "title" : "异步", - "value" : "false", - "description" : "定义异步的活动.", - "popular" : true - } ] - }, { - "name" : "exclusivedefinitionpackage", - "properties" : [ { - "id" : "exclusivedefinition", - "type" : "Boolean", - "title" : "排它性", - "value" : "false", - "description" : "定义排它的活动.", - "popular" : true - } ] - }, { - "name" : "executionlistenerspackage", - "properties" : [ { - "id" : "executionlisteners", - "type" : "multiplecomplex", - "title" : "执行监听器", - "value" : "", - "description" : "活动、流程、流程跳转,开始、结事事件的监听器", - "popular" : true - } ] - }, { - "name" : "tasklistenerspackage", - "properties" : [ { - "id" : "tasklisteners", - "type" : "multiplecomplex", - "title" : "任务监听器", - "value" : "", - "description" : "人工任务的监听器", - "popular" : true - } ] - }, { - "name" : "eventlistenerspackage", - "properties" : [ { - "id" : "eventlisteners", - "type" : "multiplecomplex", - "title" : "事件监听器", - "value" : "", - "description" : "监听Activiti引擎的任何发生的事件. 同样可能是任何抛出的信号、信息、出错的事件。", - "popular" : true - } ] - }, { - "name" : "usertaskassignmentpackage", - "properties" : [ { - "id" : "usertaskassignment", - "type" : "Complex", - "title" : "任务派遣", - "value" : "", - "description" : "人工任务的派遣的定义", - "popular" : true - } ] - }, { - "name" : "formpropertiespackage", - "properties" : [ { - "id" : "formproperties", - "type" : "Complex", - "title" : "表单属性", - "value" : "", - "description" : "定义带有属性列表的表单", - "popular" : true - } ] - }, { - "name" : "formkeydefinitionpackage", - "properties" : [ { - "id" : "formkeydefinition", - "type" : "String", - "title" : "表单的标识Key", - "value" : "", - "description" : "表单的Key(指向定义的Form).", - "popular" : true - } ] - }, { - "name" : "duedatedefinitionpackage", - "properties" : [ { - "id" : "duedatedefinition", - "type" : "String", - "title" : "到期的日期", - "value" : "", - "description" : "人工任务的到期日期", - "popular" : true - } ] - }, { - "name" : "prioritydefinitionpackage", - "properties" : [ { - "id" : "prioritydefinition", - "type" : "String", - "title" : "优先级", - "value" : "", - "description" : "人工任务的优先级.", - "popular" : true - } ] - }, { - "name" : "duedatedefinitionpackage", - "properties" : [ { - "id" : "duedatedefinition", - "type" : "String", - "title" : "到期的日期", - "value" : "", - "description" : "人工任务的到期日期.", - "popular" : true - } ] - }, { + }, { "name" : "servicetaskclasspackage", "properties" : [ { "id" : "servicetaskclass", @@ -463,18 +293,7 @@ "description" : "流程跳线的条件定义", "popular" : true } ] - }, { - "name" : "defaultflowpackage", - "properties" : [ { - "id" : "defaultflow", - "type" : "Boolean", - "title" : "默认跳线", - "value" : "false", - "description" : "定义默认为顺序跳转", - "popular" : true, - "refToView" : "default" - } ] - }, { + }, { "name" : "conditionalflowpackage", "properties" : [ { "id" : "conditionalflow", @@ -586,99 +405,7 @@ "popular" : true, "refToView" : "text" } ] - }, { - "name" : "multiinstance_typepackage", - "properties" : [ { - "id" : "multiinstance_type", - "type" : "kisbpm-multiinstance", - "title" : "多实例类型", - "value" : "None", - "description" : "通过不同的循环类型,重复的活动执行(并行、串行)可显示", - "popular" : true, - "refToView" : "multiinstance" - } ] - }, { - "name" : "multiinstance_cardinalitypackage", - "properties" : [ { - "id" : "multiinstance_cardinality", - "type" : "String", - "title" : "基数 (多实例)", - "value" : "", - "description" : "定义多实例的基数.", - "popular" : true - } ] - }, { - "name" : "multiinstance_collectionpackage", - "properties" : [ { - "id" : "multiinstance_collection", - "type" : "String", - "title" : "集合(多实例)", - "value" : "", - "description" : "定义多实例的集合.", - "popular" : true - } ] - }, { - "name" : "multiinstance_variablepackage", - "properties" : [ { - "id" : "multiinstance_variable", - "type" : "String", - "title" : "元素的变量(多实例)", - "value" : "", - "description" : "为多实例定义变量元素", - "popular" : true - } ] - }, { - "name" : "multiinstance_conditionpackage", - "properties" : [ { - "id" : "multiinstance_condition", - "type" : "String", - "title" : "完成条件(多实例)", - "value" : "", - "description" : "定义多实例的完成条件.", - "popular" : true - } ] - }, { - "name" : "isforcompensationpackage", - "properties" : [ { - "id" : "isforcompensation", - "type" : "Boolean", - "title" : "作为修正", - "value" : "false", - "description" : "标识当前活动为修正执行活动。", - "popular" : true, - "refToView" : "compensation" - } ] - }, { - "name" : "sequencefloworderpackage", - "properties" : [ { - "id" : "sequencefloworder", - "type" : "Complex", - "title" : "流程顺序", - "value" : "", - "description" : "流程跳出线的顺序", - "popular" : true - } ] - }, { - "name" : "signaldefinitionspackage", - "properties" : [ { - "id" : "signaldefinitions", - "type" : "multiplecomplex", - "title" : "信号定义", - "value" : "", - "description" : "信号定义", - "popular" : true - } ] - }, { - "name" : "messagedefinitionspackage", - "properties" : [ { - "id" : "messagedefinitions", - "type" : "multiplecomplex", - "title" : "消息定义", - "value" : "", - "description" : "消息定义", - "popular" : true - } ] - }, { + }, { "name" : "istransactionpackage", "properties" : [ { "id" : "istransaction", @@ -714,51 +441,7 @@ "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "executionlistenerspackage", "initiatorpackage", "formkeydefinitionpackage", "formpropertiespackage" ], "hiddenPropertyPackages" : [ ], "roles" : [ "sequence_start", "Startevents_all", "StartEventsMorph", "all" ] - }, { - "type" : "node", - "id" : "StartTimerEvent", - "title" : "开始事件(触发器)", - "description" : "带定时器触发的开始事件", - "view" : "\n\n \n \n \t\n \n \n \n \n \n \n \n\t\n \n", - "icon" : "startevent/timer.png", - "groups" : [ "开始事件" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "executionlistenerspackage", "timercycledefinitionpackage", "timerdatedefinitionpackage", "timerdurationdefinitionpackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "sequence_start", "Startevents_all", "StartEventsMorph", "all" ] - }, { - "type" : "node", - "id" : "StartSignalEvent", - "title" : "开始事件(信号)", - "description" : "通过信号触发开始事件", - "view" : "\n\n \n \n \t\n \n \n\n \n \n \n\t\n \n", - "icon" : "startevent/signal.png", - "groups" : [ "开始事件" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "executionlistenerspackage", "signalrefpackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "sequence_start", "Startevents_all", "StartEventsMorph", "all" ] - }, { - "type" : "node", - "id" : "StartMessageEvent", - "title" : "开始事件(消息)", - "description" : "通过消息触发开始事件", - "view" : "\n\n \n \n \t\n \n \n \n \n \n \n \n\t\n \n", - "icon" : "startevent/message.png", - "groups" : [ "开始事件" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "executionlistenerspackage", "messagerefpackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "sequence_start", "Startevents_all", "StartEventsMorph", "all" ] - }, { - "type" : "node", - "id" : "StartErrorEvent", - "title" : "开始事件(错误)", - "description" : "用于捕获BPMN抛出的错误的开始事件", - "view" : "\n\n \n \n \t\n \n \n \n \n \n \n\t\n \n", - "icon" : "startevent/error.png", - "groups" : [ "开始事件" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "executionlistenerspackage", "errorrefpackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "sequence_start", "Startevents_all", "StartEventsMorph", "all" ] - }, { + }, { "type" : "node", "id" : "UserTask", "title" : "人工任务", @@ -769,139 +452,7 @@ "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "executionlistenerspackage", "multiinstance_typepackage", "multiinstance_cardinalitypackage", "multiinstance_collectionpackage", "multiinstance_variablepackage", "multiinstance_conditionpackage", "isforcompensationpackage", "usertaskassignmentpackage", "formkeydefinitionpackage", "duedatedefinitionpackage", "prioritydefinitionpackage", "formpropertiespackage", "tasklistenerspackage" ], "hiddenPropertyPackages" : [ ], "roles" : [ "Activity", "sequence_start", "sequence_end", "ActivitiesMorph", "all" ] - }, { - "type" : "node", - "id" : "ServiceTask", - "title" : "服务任务", - "description" : "带有服务逻辑的自动任务", - "view" : "\n\n \n \n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \n \n\t\n\t\n\t\t\n\t\t\n\t\n\t\n\t\n\t\n \n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n \n", - "icon" : "activity/list/type.service.png", - "groups" : [ "活动" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "executionlistenerspackage", "multiinstance_typepackage", "multiinstance_cardinalitypackage", "multiinstance_collectionpackage", "multiinstance_variablepackage", "multiinstance_conditionpackage", "isforcompensationpackage", "servicetaskclasspackage", "servicetaskexpressionpackage", "servicetaskdelegateexpressionpackage", "servicetaskfieldspackage", "servicetaskresultvariablepackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "Activity", "sequence_start", "sequence_end", "ActivitiesMorph", "all" ] - }, { - "type" : "node", - "id" : "ScriptTask", - "title" : "脚本任务", - "description" : "带有脚本逻辑的自动任务", - "view" : "\n\n \n \n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \n \n\t\n\t\n\t\t\n\t\t\n\t\n\t\n\t\t\n\t\n \n\t\n\t\t\n\t\n\t\n\t\t\n\t\n\t\n\n\t\n\t\t\n\t\n \n", - "icon" : "activity/list/type.script.png", - "groups" : [ "活动" ], - "propertyPackages" : [ "scriptformatpackage", "scripttextpackage", "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "executionlistenerspackage", "multiinstance_typepackage", "multiinstance_cardinalitypackage", "multiinstance_collectionpackage", "multiinstance_variablepackage", "multiinstance_conditionpackage", "isforcompensationpackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "Activity", "sequence_start", "sequence_end", "ActivitiesMorph", "all" ] - }, { - "type" : "node", - "id" : "BusinessRule", - "title" : "业务规则的任务", - "description" : "带有业务规则的自动任务", - "view" : "\n\n \n \n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \n \n \t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\n\t\n\t\n\t\n\t\t\n\t\t\n \n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\n\t\n\t\t\n\t\n \n", - "icon" : "activity/list/type.business.rule.png", - "groups" : [ "活动" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "executionlistenerspackage", "multiinstance_typepackage", "multiinstance_cardinalitypackage", "multiinstance_collectionpackage", "multiinstance_variablepackage", "multiinstance_conditionpackage", "isforcompensationpackage", "ruletask_rulespackage", "ruletask_variables_inputpackage", "ruletask_excludepackage", "ruletask_resultpackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "Activity", "sequence_start", "sequence_end", "ActivitiesMorph", "all" ] - }, { - "type" : "node", - "id" : "ReceiveTask", - "title" : "接收任务", - "description" : "等待接收信号来触发的任务", - "view" : "\n\n \n \n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \n \n\t\n\t\n\t\t\n\t\t\n \n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\n\t\n\t\t\n\t\n \n", - "icon" : "activity/list/type.receive.png", - "groups" : [ "活动" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "executionlistenerspackage", "multiinstance_typepackage", "multiinstance_cardinalitypackage", "multiinstance_collectionpackage", "multiinstance_variablepackage", "multiinstance_conditionpackage", "isforcompensationpackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "Activity", "sequence_start", "sequence_end", "ActivitiesMorph", "all" ] - }, { - "type" : "node", - "id" : "ManualTask", - "title" : "手工任务", - "description" : "不带任何逻辑的自动任务", - "view" : "\n\n \n \n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \n \n\t\n\t\n\t\t\n\t\t\n \n \t\n\t\n\t\n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\n\t\n\t\t\n\t\n \n", - "icon" : "activity/list/type.manual.png", - "groups" : [ "活动" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "executionlistenerspackage", "multiinstance_typepackage", "multiinstance_cardinalitypackage", "multiinstance_collectionpackage", "multiinstance_variablepackage", "multiinstance_conditionpackage", "isforcompensationpackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "Activity", "sequence_start", "sequence_end", "ActivitiesMorph", "all" ] - }, { - "type" : "node", - "id" : "MailTask", - "title" : "邮件任务", - "description" : "邮箱任务", - "view" : "\n\n \n \n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \n \n\t\n\t\n\t\t\n\t\t\n \n\t\n\t\n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\n\t\n\t\t\n\t\n \n", - "icon" : "activity/list/type.send.png", - "groups" : [ "活动" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "executionlistenerspackage", "multiinstance_typepackage", "multiinstance_cardinalitypackage", "multiinstance_collectionpackage", "multiinstance_variablepackage", "multiinstance_conditionpackage", "isforcompensationpackage", "mailtasktopackage", "mailtaskfrompackage", "mailtasksubjectpackage", "mailtaskccpackage", "mailtaskbccpackage", "mailtasktextpackage", "mailtaskhtmlpackage", "mailtaskcharsetpackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "Activity", "sequence_start", "sequence_end", "ActivitiesMorph", "all" ] - }, { - "type" : "node", - "id" : "CamelTask", - "title" : "Camel任务", - "description" : "发送消息给Camel容器的任务", - "view" : "\n\n \n \n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \n \n\t\n\t\n\t\t\n\t\t\n\t\n\t\n\t\t\n\t\n \n\t\n\t\t\n\t\n\t\n\t\t\n\t\n\t\n\n\t\n\t\t\n\t\n \n", - "icon" : "activity/list/type.camel.png", - "groups" : [ "活动" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "executionlistenerspackage", "multiinstance_typepackage", "multiinstance_cardinalitypackage", "multiinstance_collectionpackage", "multiinstance_variablepackage", "multiinstance_conditionpackage", "isforcompensationpackage", "cameltaskcamelcontextpackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "Activity", "sequence_start", "sequence_end", "ActivitiesMorph", "all" ] - }, { - "type" : "node", - "id" : "MuleTask", - "title" : "Mule 任务", - "description" : "发送消息给Mule容器的任务", - "view" : "\n\n \n \n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \n \n\t\n\t\n\t\t\n\t\t\n\t\n\t\n\t\t\n\t\n \n\t\n\t\t\n\t\n\t\n\t\t\n\t\n\t\n\n\t\n\t\t\n\t\n \n", - "icon" : "activity/list/type.mule.png", - "groups" : [ "活动" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "executionlistenerspackage", "multiinstance_typepackage", "multiinstance_cardinalitypackage", "multiinstance_collectionpackage", "multiinstance_variablepackage", "multiinstance_conditionpackage", "isforcompensationpackage", "muletaskendpointurlpackage", "muletasklanguagepackage", "muletaskpayloadexpressionpackage", "muletaskresultvariablepackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "Activity", "sequence_start", "sequence_end", "ActivitiesMorph", "all" ] - }, { - "type" : "node", - "id" : "SendTask", - "title" : "发送任务", - "description" : "发送消息的任务", - "view" : "\n\n \n \n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \n \n\t\n\t\n\t\t\n\t\t\n \n\t\n\t\n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\n\t\n\t\t\n\t\n \n", - "icon" : "activity/list/type.send.png", - "groups" : [ "活动" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "executionlistenerspackage", "multiinstance_typepackage", "multiinstance_cardinalitypackage", "multiinstance_collectionpackage", "multiinstance_variablepackage", "multiinstance_conditionpackage", "isforcompensationpackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "Activity", "sequence_start", "sequence_end", "ActivitiesMorph", "all" ] - }, { - "type" : "node", - "id" : "SubProcess", - "title" : "子流程", - "description" : "子流程范围的流程", - "view" : "\n\n \n \n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \n \n \n\t\n\t\n\t\n\t\n\t\n\t\n\t\t\n\t\n\t\n\t\t\n\t\n \n", - "icon" : "activity/expanded.subprocess.png", - "groups" : [ "结构模块" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "executionlistenerspackage", "multiinstance_typepackage", "multiinstance_cardinalitypackage", "multiinstance_collectionpackage", "multiinstance_variablepackage", "multiinstance_conditionpackage", "istransactionpackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "Activity", "sequence_start", "sequence_end", "all" ] - }, { - "type" : "node", - "id" : "EventSubProcess", - "title" : "子流程的事件", - "description" : "子流程范围的事件", - "view" : "\n\n \n \n \t\n \t\n \t\n \t\n \t\n \n \n\t\n\t\n \t\n\t\t\n \t\n\t\n\t\n \n", - "icon" : "activity/event.subprocess.png", - "groups" : [ "结构模块" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "executionlistenerspackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "Activity", "all" ] - }, { - "type" : "node", - "id" : "CallActivity", - "title" : "调用活动", - "description" : "调用的活动", - "view" : "\n\n \n \n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \n \n\t\n \n\t\n\t\t\n\t\t\n \n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\n\t\n\t\t\n\t\n \n", - "icon" : "activity/task.png", - "groups" : [ "结构模块" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "executionlistenerspackage", "callactivitycalledelementpackage", "callactivityinparameterspackage", "callactivityoutparameterspackage", "multiinstance_typepackage", "multiinstance_cardinalitypackage", "multiinstance_collectionpackage", "multiinstance_variablepackage", "multiinstance_conditionpackage", "isforcompensationpackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "Activity", "sequence_start", "sequence_end", "all" ] - }, { + },{ "type" : "node", "id" : "ExclusiveGateway", "title" : "单一网关", @@ -912,160 +463,6 @@ "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "sequencefloworderpackage" ], "hiddenPropertyPackages" : [ ], "roles" : [ "sequence_start", "GatewaysMorph", "sequence_end", "all" ] - }, { - "type" : "node", - "id" : "ParallelGateway", - "title" : "并行网关", - "description" : "并行执行的网关", - "view" : "\n\n \n \n \n \n \n \n \n \n\t\n\t\n \n\n", - "icon" : "gateway/parallel.png", - "groups" : [ "网关" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "sequencefloworderpackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "sequence_start", "GatewaysMorph", "sequence_end", "all" ] - }, { - "type" : "node", - "id" : "InclusiveGateway", - "title" : "包含网关", - "description" : "满足条件的包含性的网关", - "view" : "\n\n \n \n \n \n\n \n \n \n\t\n\t\n \n\n", - "icon" : "gateway/inclusive.png", - "groups" : [ "网关" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "sequencefloworderpackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "sequence_start", "GatewaysMorph", "sequence_end", "all" ] - }, { - "type" : "node", - "id" : "EventGateway", - "title" : "事件网关", - "description" : "事件网关", - "view" : "\n\n \n \n \n \n \n \t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\t\n\t\t\n\t\t\n\t\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\n\t\n\t\n\t\n\t\n \t\n\t\n\n", - "icon" : "gateway/eventbased.png", - "groups" : [ "网关" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "sequencefloworderpackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "sequence_start", "GatewaysMorph", "sequence_end", "all" ] - }, { - "type" : "node", - "id" : "BoundaryErrorEvent", - "title" : "边界出错事件", - "description" : "捕获BPMN的错误的边界事件", - "view" : "\n\n \n \n \t\n \n \n \n \n \n \n \n\t\n \n", - "icon" : "catching/error.png", - "groups" : [ "边界事件" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "errorrefpackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "sequence_start", "BoundaryEventsMorph", "IntermediateEventOnActivityBoundary" ] - }, { - "type" : "node", - "id" : "BoundaryTimerEvent", - "title" : "边界的定时事件", - "description" : "A boundary event with a timer trigger", - "view" : "\n\n \n \n \t\n \n \n \n \n \t\n \n \n \n \n \n \n \t\n\t\n \n", - "icon" : "catching/timer.png", - "groups" : [ "边界事件" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "timercycledefinitionpackage", "timerdatedefinitionpackage", "timerdurationdefinitionpackage", "timerenddatedefinitionpackage", "cancelactivitypackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "sequence_start", "BoundaryEventsMorph", "IntermediateEventOnActivityBoundary" ] - }, { - "type" : "node", - "id" : "BoundarySignalEvent", - "title" : "边界信号事件", - "description" : "带有事件触发器的边界事件", - "view" : "\n\n \n \n \t\n \n \n \n \n \t\n \n \n \n \n\t\n\t\n \n", - "icon" : "catching/signal.png", - "groups" : [ "边界事件" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "signalrefpackage", "cancelactivitypackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "sequence_start", "BoundaryEventsMorph", "IntermediateEventOnActivityBoundary" ] - }, { - "type" : "node", - "id" : "BoundaryMessageEvent", - "title" : "边界消息事件", - "description" : "带有消息触发器的边界事件", - "view" : "\n\n \n \n \t\n \n \n \n \n \t\n \n \t\n \n \n \n\t\n\t\t\n\t\n\t\n\t\n \n", - "icon" : "catching/message.png", - "groups" : [ "边界事件" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "messagerefpackage", "cancelactivitypackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "sequence_start", "BoundaryEventsMorph", "IntermediateEventOnActivityBoundary" ] - }, { - "type" : "node", - "id" : "BoundaryCancelEvent", - "title" : "边界取消事件", - "description" : "边界取消事件", - "view" : "\n\n \n \n \t\n \n \n \n \n \n \n \n \n\t\n \n", - "icon" : "catching/cancel.png", - "groups" : [ "边界事件" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "sequence_start", "BoundaryEventsMorph", "IntermediateEventOnActivityBoundary" ] - }, { - "type" : "node", - "id" : "BoundaryCompensationEvent", - "title" : "边界修正事件", - "description" : "边界修正事件", - "view" : "\n\n \n \n \t\n \n \n \n\t\n \n \n \n \n \n\t\n \n", - "icon" : "catching/compensation.png", - "groups" : [ "边界事件" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "BoundaryEventsMorph", "IntermediateEventOnActivityBoundary", "all" ] - }, { - "type" : "node", - "id" : "CatchTimerEvent", - "title" : "捕捉中间定时器的事件", - "description" : "带有捕捉定时器触发的事件", - "view" : "\n\n \n \n \t\n \n \n \n \n \t\n \n \n \n \n \n \n \t\n\t\n \n", - "icon" : "catching/timer.png", - "groups" : [ "中间捕获事件" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "executionlistenerspackage", "timercycledefinitionpackage", "timerdatedefinitionpackage", "timerdurationdefinitionpackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "sequence_start", "sequence_end", "CatchEventsMorph", "all" ] - }, { - "type" : "node", - "id" : "CatchSignalEvent", - "title" : "中间信号捕获事件", - "description" : "信号触发的中间捕获事件", - "view" : "\n\n \n \n \t\n \n \n \n \n \t\n \n \n \n \n\t\n\t\n \n", - "icon" : "catching/signal.png", - "groups" : [ "中间捕获事件" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "executionlistenerspackage", "signalrefpackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "sequence_start", "sequence_end", "CatchEventsMorph", "all" ] - }, { - "type" : "node", - "id" : "CatchMessageEvent", - "title" : "中间消息捕获事件", - "description" : "消息触发的中间捕获事件", - "view" : "\n\n \n \n \t\n \n \n \n \n \t\n \n \t\n \n \n \n\t\n\t\t\n\t\n\t\n\t\n \n", - "icon" : "catching/message.png", - "groups" : [ "中间捕获事件" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "executionlistenerspackage", "messagerefpackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "sequence_start", "sequence_end", "CatchEventsMorph", "all" ] - }, { - "type" : "node", - "id" : "ThrowNoneEvent", - "title" : "无触发的中间事件", - "description" : "无特定触发器的中间事件", - "view" : "\n\n \n \n \t\n \n \n \n \n \n \n\t\n \n", - "icon" : "throwing/none.png", - "groups" : [ "中间捕获事件" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "executionlistenerspackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "ThrowEventsMorph", "sequence_start", "sequence_end", "all" ] - }, { - "type" : "node", - "id" : "ThrowSignalEvent", - "title" : "抛出信号的中间事件", - "description" : "通过信号触发器的中间事件", - "view" : "\n\n \n \n \t\n \n \n \n \n \n \n\t\n \n", - "icon" : "throwing/signal.png", - "groups" : [ "中间捕获事件" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "executionlistenerspackage", "signalrefpackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "ThrowEventsMorph", "sequence_start", "sequence_end", "all" ] }, { "type" : "node", "id" : "EndNoneEvent", @@ -1077,65 +474,7 @@ "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "executionlistenerspackage" ], "hiddenPropertyPackages" : [ ], "roles" : [ "EndEventsMorph", "sequence_end", "all" ] - }, { - "type" : "node", - "id" : "EndErrorEvent", - "title" : "结束事件(出错)", - "description" : "抛出错误的结束事件", - "view" : "\n\n \n \n \t\n \n \n \n \n \n \n\t\n \n", - "icon" : "endevent/error.png", - "groups" : [ "结束事件" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "executionlistenerspackage", "errorrefpackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "EndEventsMorph", "sequence_end", "all" ] - }, { - "type" : "node", - "id" : "EndCancelEvent", - "title" : "结束事件(取消)", - "description" : "取消的结束事件", - "view" : "\n\n \n \n \t\n \n \n \n \n \n\t\n \n", - "icon" : "endevent/cancel.png", - "groups" : [ "结束事件" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "executionlistenerspackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "EndEventsMorph", "sequence_end", "all" ] - }, { - "type" : "node", - "id" : "EndTerminateEvent", - "title" : "结束事件(终止)", - "description" : "终止类型的结束事件", - "view" : "\n\n \n \n \t\n \n \n \n \n \n\t\n \n", - "icon" : "endevent/terminate.png", - "groups" : [ "结束事件" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "executionlistenerspackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "EndEventsMorph", "sequence_end", "all" ] - }, { - "type" : "node", - "id" : "Pool", - "title" : "泳道", - "description" : "用来结构化流程定义的泳道", - "view" : "\n\n \n \n \t\n \t\n \t\n \t\n \t\n \n \n \n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\n\t \t\n \t\n \n \n\t\n\t\n\t\n\t\n \n \n \n", - "icon" : "swimlane/pool.png", - "groups" : [ "泳道" ], - "layout" : [ { - "type" : "layout.bpmn2_0.pool" - } ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "process_idpackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "canContainArtifacts", "all" ] - }, { - "type" : "node", - "id" : "Lane", - "title" : "区域", - "description" : "结构化流程定义的区域", - "view" : "\n\n \n \n \n \n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\n\t\n \t\t\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n \n\t\n \n", - "icon" : "swimlane/lane.png", - "groups" : [ "泳道" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "PoolChild", "canContainArtifacts", "all" ] - }, { + }, { "type" : "edge", "id" : "SequenceFlow", "title" : "顺序跳转线", @@ -1191,18 +530,7 @@ "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage" ], "hiddenPropertyPackages" : [ ], "roles" : [ "ConnectingObjectsMorph", "all" ] - }, { - "type" : "node", - "id" : "TextAnnotation", - "title" : "文本关联", - "description" : "关联一组元素进行文本描述", - "view" : "\n\n \n \n \t\n \n \n \n \n \n \n\t\n \n", - "icon" : "artifact/text.annotation.png", - "groups" : [ "文档注释" ], - "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "textpackage" ], - "hiddenPropertyPackages" : [ ], - "roles" : [ "all" ] - }, { + }, { "type" : "node", "id" : "DataStore", "title" : "数据存储", diff --git a/src/main/resources/templates/admin/act_model_list.ftl b/src/main/resources/templates/admin/act_model_list.ftl index 94f834f..34d0d1d 100644 --- a/src/main/resources/templates/admin/act_model_list.ftl +++ b/src/main/resources/templates/admin/act_model_list.ftl @@ -74,7 +74,9 @@
- <#if userName! == 'admin'> + <#if list.procDefKey == 'saleContract' + || list.procDefKey == 'businessPurchase' + >