完善OA流程
This commit is contained in:
parent
3533ae4c32
commit
3f4a8b287a
@ -4,10 +4,12 @@ import com.alibaba.fastjson.JSONObject;
|
||||
import ink.wgink.common.base.DefaultBaseController;
|
||||
import ink.wgink.exceptions.ParamsException;
|
||||
import ink.wgink.interfaces.consts.ISystemConstant;
|
||||
import ink.wgink.module.activiti.pojo.dtos.ActivitiFlowNodeDTO;
|
||||
import ink.wgink.module.activiti.pojo.vos.ActivitiModelVO;
|
||||
import ink.wgink.module.activiti.service.activiti.IActivitiModelService;
|
||||
import ink.wgink.pojo.result.ErrorResult;
|
||||
import ink.wgink.pojo.result.SuccessResult;
|
||||
import ink.wgink.pojo.result.SuccessResultData;
|
||||
import ink.wgink.util.RegexUtil;
|
||||
import io.swagger.annotations.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -16,6 +18,7 @@ import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.List;
|
||||
|
||||
;
|
||||
|
||||
@ -54,6 +57,16 @@ public class ActivitiModelController extends DefaultBaseController {
|
||||
return new SuccessResult();
|
||||
}
|
||||
|
||||
@ApiOperation(value = "通过部署ID获取节点列表", notes = "通过部署ID获取节点列表接口")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "deploymentId", value = "部署ID", paramType = "path"),
|
||||
})
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
@GetMapping("list-flow-node/deployment-id/{deploymentId}")
|
||||
public List<ActivitiFlowNodeDTO> listFlowNodeByDefineId(@PathVariable("deploymentId") String deploymentId) {
|
||||
return activitiModelService.listFlowNodeByDeploymentId(deploymentId);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "模型json数据", notes = "模型json数据接口")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "modelId", value = "模型ID", paramType = "path")
|
||||
@ -71,4 +84,15 @@ public class ActivitiModelController extends DefaultBaseController {
|
||||
return activitiModelService.getStencilset();
|
||||
}
|
||||
|
||||
@ApiOperation(value = "流程XML数据", notes = "流程XML数据接口")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "processDefinitionId", value = "流程定义ID", paramType = "path")
|
||||
})
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
@GetMapping("get-process-xml/{processDefinitionId}")
|
||||
public SuccessResultData<String> getProcessXml(@PathVariable("processDefinitionId") String processDefinitionId) {
|
||||
String processXml = activitiModelService.getProcessXml(processDefinitionId);
|
||||
return new SuccessResultData<>(processXml);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package ink.wgink.module.activiti.controller.api;
|
||||
|
||||
import ink.wgink.common.base.DefaultBaseController;
|
||||
import ink.wgink.interfaces.consts.ISystemConstant;
|
||||
import ink.wgink.module.activiti.pojo.dtos.ActivitiFlowNodeDTO;
|
||||
import ink.wgink.module.activiti.pojo.dtos.ActivitiProcdefDTO;
|
||||
import ink.wgink.module.activiti.service.activiti.IActivitiProcdefService;
|
||||
import ink.wgink.pojo.ListPage;
|
||||
@ -52,14 +51,4 @@ public class ActivitiProcdefController extends DefaultBaseController {
|
||||
return activitiProcdefService.listPage(page.getPage(), page.getRows());
|
||||
}
|
||||
|
||||
@ApiOperation(value = "通过部署ID获取任务列表", notes = "通过部署ID获取任务列表接口")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "deploymentId", value = "部署ID", paramType = "path"),
|
||||
})
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
@GetMapping("list-flow-node/deployment-id/{deploymentId}")
|
||||
public List<ActivitiFlowNodeDTO> listFlowNodeByDefineId(@PathVariable("deploymentId") String deploymentId) {
|
||||
return activitiProcdefService.listFlowNodeByDeploymentId(deploymentId);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,40 @@
|
||||
package ink.wgink.module.activiti.controller.api;
|
||||
|
||||
import ink.wgink.common.base.DefaultBaseController;
|
||||
import ink.wgink.interfaces.consts.ISystemConstant;
|
||||
import ink.wgink.module.activiti.service.activiti.IActivitiUserTaskService;
|
||||
import ink.wgink.pojo.result.SuccessResult;
|
||||
import io.swagger.annotations.Api;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: ActivitiUserTaskController
|
||||
* @Description: 流程用户任务
|
||||
* @Author: WangGeng
|
||||
* @Date: 2021/7/12 21:56
|
||||
* @Version: 1.0
|
||||
**/
|
||||
@Api(tags = ISystemConstant.API_TAGS_SYSTEM_PREFIX + "流程用户任务接口")
|
||||
@RestController
|
||||
@RequestMapping(ISystemConstant.API_PREFIX + "/activiti/user-task")
|
||||
public class ActivitiUserTaskController extends DefaultBaseController {
|
||||
|
||||
@Autowired
|
||||
private IActivitiUserTaskService activitiUserTaskService;
|
||||
|
||||
@GetMapping("get-next-user-task/{userTaskId}")
|
||||
public SuccessResult getNextUserTask(@PathVariable("userTaskId") String userTaskId) {
|
||||
activitiUserTaskService.getNextUserTask(userTaskId);
|
||||
return new SuccessResult();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package ink.wgink.module.activiti.controller.route;
|
||||
|
||||
import ink.wgink.interfaces.consts.ISystemConstant;
|
||||
import ink.wgink.module.activiti.service.activiti.IActivitiModelService;
|
||||
import ink.wgink.pojo.result.ErrorResult;
|
||||
import io.swagger.annotations.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* @ClassName: ActivitiModelRouteController
|
||||
* @Description: 流程模型
|
||||
* @Author: wanggeng
|
||||
* @Date: 2022/3/28 15:57
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Api(tags = ISystemConstant.ROUTE_TAGS_PREFIX + "activiti模型")
|
||||
@Controller
|
||||
@RequestMapping(ISystemConstant.ROUTE_PREFIX + "/activiti/model")
|
||||
public class ActivitiModelRouteController {
|
||||
|
||||
@Autowired
|
||||
private IActivitiModelService activitiModelService;
|
||||
|
||||
@GetMapping("get-process-xml")
|
||||
public ModelAndView getProcessImage() {
|
||||
ModelAndView mv = new ModelAndView("activiti/model/get-process-xml");
|
||||
return mv;
|
||||
}
|
||||
|
||||
@ApiOperation(value = "查看流程图", notes = "查看流程图接口")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "deploymentId", value = "流程部署ID", paramType = "path")
|
||||
})
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
@GetMapping("get-process-image/{deploymentId}")
|
||||
public void getProcessImage(HttpServletResponse response, @PathVariable("deploymentId") String deploymentId) {
|
||||
activitiModelService.getProcessImage(response, deploymentId);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "查看运行流程图", notes = "查看运行流程图接口")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "processInstanceId", value = "流程实例ID", paramType = "path")
|
||||
})
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
@GetMapping("get-runtime-process-image/{processInstanceId}")
|
||||
public void getRuntimeProcessImage(HttpServletResponse response, @PathVariable("processInstanceId") String processInstanceId) {
|
||||
activitiModelService.getRuntimeProcessImage(response, processInstanceId);
|
||||
}
|
||||
|
||||
}
|
@ -2,17 +2,13 @@ package ink.wgink.module.activiti.controller.route;
|
||||
|
||||
import ink.wgink.interfaces.consts.ISystemConstant;
|
||||
import ink.wgink.module.activiti.service.activiti.IActivitiModelService;
|
||||
import ink.wgink.pojo.result.ErrorResult;
|
||||
import io.swagger.annotations.*;
|
||||
import io.swagger.annotations.Api;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* @ClassName: ActivitiRouteController
|
||||
* @Description: activiti路由
|
||||
@ -25,10 +21,6 @@ import javax.servlet.http.HttpServletResponse;
|
||||
@RequestMapping(ISystemConstant.ROUTE_PREFIX + "/activiti")
|
||||
public class ActivitiRouteController {
|
||||
|
||||
@Autowired
|
||||
private IActivitiModelService activitiModelService;
|
||||
|
||||
|
||||
@GetMapping("list")
|
||||
public ModelAndView list() {
|
||||
ModelAndView mv = new ModelAndView("activiti/list");
|
||||
@ -47,24 +39,4 @@ public class ActivitiRouteController {
|
||||
return mv;
|
||||
}
|
||||
|
||||
@ApiOperation(value = "查看流程图", notes = "查看流程图接口")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "deploymentId", value = "流程部署ID", paramType = "path")
|
||||
})
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
@GetMapping("get-process-image/{deploymentId}")
|
||||
public void getProcessImage(HttpServletResponse response, @PathVariable("deploymentId") String deploymentId) {
|
||||
activitiModelService.getProcessImage(response, deploymentId);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "查看运行流程图", notes = "查看运行流程图接口")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "processInstanceId", value = "流程实例ID", paramType = "path")
|
||||
})
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
@GetMapping("get-runtime-process-image/{processInstanceId}")
|
||||
public void getRuntimeProcessImage(HttpServletResponse response, @PathVariable("processInstanceId") String processInstanceId) {
|
||||
activitiModelService.getRuntimeProcessImage(response, processInstanceId);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,32 @@
|
||||
package ink.wgink.module.activiti.listener.task;
|
||||
|
||||
import org.activiti.engine.delegate.DelegateExecution;
|
||||
import org.activiti.engine.delegate.DelegateTask;
|
||||
import org.activiti.engine.delegate.JavaDelegate;
|
||||
import org.activiti.engine.delegate.TaskListener;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @ClassName: OaUserTaskAssignmentListener
|
||||
* @Description: OA用户任务节点分配处理人监听器
|
||||
* @Author: wanggeng
|
||||
* @Date: 2022/3/28 10:31
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Component
|
||||
public class OaUserTaskAssignmentListener implements TaskListener, JavaDelegate {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(OaUserTaskAssignmentListener.class);
|
||||
|
||||
@Override
|
||||
public void notify(DelegateTask delegateTask) {
|
||||
LOG.debug("userTask assignment");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(DelegateExecution execution) {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package ink.wgink.module.activiti.listener.task;
|
||||
|
||||
import ink.wgink.module.activiti.service.activiti.IActivitiModelService;
|
||||
import ink.wgink.module.activiti.service.oa.IOaFormReportService;
|
||||
import org.activiti.bpmn.model.UserTask;
|
||||
import org.activiti.engine.RuntimeService;
|
||||
import org.activiti.engine.delegate.DelegateExecution;
|
||||
import org.activiti.engine.delegate.DelegateTask;
|
||||
import org.activiti.engine.delegate.JavaDelegate;
|
||||
import org.activiti.engine.delegate.TaskListener;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @ClassName: OaUserTaskCompleteListener
|
||||
* @Description: OA用户任务节点完成监听器
|
||||
* @Author: wanggeng
|
||||
* @Date: 2022/3/28 10:31
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Component
|
||||
public class OaUserTaskCompleteListener implements TaskListener, JavaDelegate {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(OaUserTaskCompleteListener.class);
|
||||
|
||||
@Autowired
|
||||
private RuntimeService runtimeService;
|
||||
@Autowired
|
||||
private IActivitiModelService activitiModelService;
|
||||
@Autowired
|
||||
private IOaFormReportService oaFormReportService;
|
||||
|
||||
@Override
|
||||
public void notify(DelegateTask delegateTask) {
|
||||
LOG.debug(">>>> userTask complete");
|
||||
Map<String, Object> variables = runtimeService.getVariables(delegateTask.getProcessInstanceId());
|
||||
String reportUid = variables.get(IOaFormReportService.KEY_REPORT_UID).toString();
|
||||
String formCode = variables.get(IOaFormReportService.KEY_FORM_CODE).toString();
|
||||
Integer formVersion = Integer.parseInt(variables.get(IOaFormReportService.KEY_FORM_VERSION).toString());
|
||||
LOG.debug("查询表单数据:formCode: {}, formVersion: {}, reportUid: {}", formCode, formVersion, reportUid);
|
||||
Map<String, Object> reportForm = oaFormReportService.get(formCode, formVersion, reportUid);
|
||||
UserTask nextUserTask = activitiModelService.getNextUserTaskByTaskDefinitionKeyAndProcessDefinitionIdAndReportForm(delegateTask.getTaskDefinitionKey(), delegateTask.getProcessDefinitionId(), reportForm);
|
||||
if (nextUserTask != null) {
|
||||
nextUserTask.setAssignee("1");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(DelegateExecution execution) {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package ink.wgink.module.activiti.listener.task;
|
||||
|
||||
import org.activiti.engine.delegate.DelegateExecution;
|
||||
import org.activiti.engine.delegate.DelegateTask;
|
||||
import org.activiti.engine.delegate.JavaDelegate;
|
||||
import org.activiti.engine.delegate.TaskListener;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @ClassName: OaUserTaskCreateListener
|
||||
* @Description: OA用户任务节点创建监听器
|
||||
* @Author: wanggeng
|
||||
* @Date: 2022/3/28 10:31
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Component
|
||||
public class OaUserTaskCreateListener implements TaskListener, JavaDelegate {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(OaUserTaskCreateListener.class);
|
||||
|
||||
@Override
|
||||
public void notify(DelegateTask delegateTask) {
|
||||
LOG.debug("userTask create");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(DelegateExecution execution) {
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package ink.wgink.module.activiti.listener.task;
|
||||
|
||||
import org.activiti.engine.delegate.DelegateExecution;
|
||||
import org.activiti.engine.delegate.DelegateTask;
|
||||
import org.activiti.engine.delegate.JavaDelegate;
|
||||
import org.activiti.engine.delegate.TaskListener;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @ClassName: OaUserTaskDeleteListener
|
||||
* @Description: OA用户任务节点删除监听器
|
||||
* @Author: wanggeng
|
||||
* @Date: 2022/3/28 10:31
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Component
|
||||
public class OaUserTaskDeleteListener implements TaskListener, JavaDelegate {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(OaUserTaskDeleteListener.class);
|
||||
|
||||
@Override
|
||||
public void notify(DelegateTask delegateTask) {
|
||||
LOG.debug("userTask delete");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(DelegateExecution execution) {
|
||||
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package ink.wgink.module.activiti.pojo.dtos.oa;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
/**
|
||||
* @ClassName: OaTaskDTO
|
||||
@ -12,14 +13,28 @@ import io.swagger.annotations.ApiModel;
|
||||
@ApiModel
|
||||
public class OaTaskDTO {
|
||||
|
||||
@ApiModelProperty(name = "taskId", value = "任务ID")
|
||||
private String taskId;
|
||||
@ApiModelProperty(name = "taskName", value = "任务名称")
|
||||
private String taskName;
|
||||
@ApiModelProperty(name = "taskDescription", value = "任务描述")
|
||||
private String taskDescription;
|
||||
@ApiModelProperty(name = "formCode", value = "表单编码")
|
||||
private String formCode;
|
||||
@ApiModelProperty(name = "formVersion", value = "表单版本")
|
||||
private Integer formVersion;
|
||||
@ApiModelProperty(name = "getFormKey", value = "动态表单ID")
|
||||
private String getFormKey;
|
||||
@ApiModelProperty(name = "reportUid", value = "上报表单UID")
|
||||
private String reportUid;
|
||||
@ApiModelProperty(name = "reportTitle", value = "上报表单标题")
|
||||
private String reportTitle;
|
||||
@ApiModelProperty(name = "owner", value = "所有者")
|
||||
private String owner;
|
||||
@ApiModelProperty(name = "taskDefinitionKey", value = "任务定义Key")
|
||||
private String taskDefinitionKey;
|
||||
@ApiModelProperty(name = "processDefinitionId", value = "流程定义ID")
|
||||
private String processDefinitionId;
|
||||
|
||||
public String getTaskId() {
|
||||
return taskId == null ? "" : taskId.trim();
|
||||
@ -77,6 +92,14 @@ public class OaTaskDTO {
|
||||
this.reportUid = reportUid;
|
||||
}
|
||||
|
||||
public String getReportTitle() {
|
||||
return reportTitle == null ? "" : reportTitle.trim();
|
||||
}
|
||||
|
||||
public void setReportTitle(String reportTitle) {
|
||||
this.reportTitle = reportTitle;
|
||||
}
|
||||
|
||||
public String getOwner() {
|
||||
return owner == null ? "" : owner.trim();
|
||||
}
|
||||
@ -84,4 +107,20 @@ public class OaTaskDTO {
|
||||
public void setOwner(String owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public String getTaskDefinitionKey() {
|
||||
return taskDefinitionKey == null ? "" : taskDefinitionKey.trim();
|
||||
}
|
||||
|
||||
public void setTaskDefinitionKey(String taskDefinitionKey) {
|
||||
this.taskDefinitionKey = taskDefinitionKey;
|
||||
}
|
||||
|
||||
public String getProcessDefinitionId() {
|
||||
return processDefinitionId == null ? "" : processDefinitionId.trim();
|
||||
}
|
||||
|
||||
public void setProcessDefinitionId(String processDefinitionId) {
|
||||
this.processDefinitionId = processDefinitionId;
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,14 @@
|
||||
package ink.wgink.module.activiti.service.activiti;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import ink.wgink.module.activiti.pojo.dtos.ActivitiFlowNodeDTO;
|
||||
import org.activiti.bpmn.model.*;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
@ -18,10 +22,111 @@ import java.io.UnsupportedEncodingException;
|
||||
**/
|
||||
public interface IActivitiModelService {
|
||||
|
||||
/**
|
||||
* 排他网关条件关键字
|
||||
*/
|
||||
String EXCLUSIVE_GATEWAY_CONDITION_KEY = "exc";
|
||||
|
||||
/**
|
||||
* 并行网关条件关键字
|
||||
*/
|
||||
String PARALLEL_GATEWAY_CONDITION_KEY = "par";
|
||||
|
||||
/**
|
||||
* 保存模型
|
||||
*
|
||||
* @param modelId
|
||||
* @param name
|
||||
* @param description
|
||||
* @param json_xml
|
||||
* @param svg_xml
|
||||
* @throws Exception
|
||||
*/
|
||||
void saveModel(String modelId, String name, String description, String json_xml, String svg_xml) throws Exception;
|
||||
|
||||
/**
|
||||
* 获取原生流程节点列表
|
||||
*
|
||||
* @param bpmnModel
|
||||
* @return
|
||||
*/
|
||||
List<FlowNode> listFlowNode(BpmnModel bpmnModel);
|
||||
|
||||
/**
|
||||
* 获取当前流程节点
|
||||
*
|
||||
* @param currentTaskDefinitionKey
|
||||
* @param processDefinitionId
|
||||
* @return
|
||||
*/
|
||||
FlowNode getCurrentFlowNode(String currentTaskDefinitionKey, String processDefinitionId);
|
||||
|
||||
/**
|
||||
* 获取下一个用户任务
|
||||
*
|
||||
* @param currentUserTask 当前用户任务
|
||||
* @return
|
||||
*/
|
||||
UserTask getNextUserTaskByCurrentUserTask(UserTask currentUserTask);
|
||||
|
||||
/**
|
||||
* 获取下一个用户任务
|
||||
*
|
||||
* @param exclusiveGateway 排他网关
|
||||
* @param reportForm 上报表单
|
||||
* @return
|
||||
*/
|
||||
UserTask getNextUserTaskByExclusiveGatewayAndReportForm(ExclusiveGateway exclusiveGateway, Map<String, Object> reportForm);
|
||||
|
||||
/**
|
||||
* 获取下一个用户任务
|
||||
*
|
||||
* @param currentTaskDefinitionKey 当前任务定义Key
|
||||
* @param processDefinitionId 流程定义ID
|
||||
* @param reportForm 上报表单
|
||||
* @return
|
||||
*/
|
||||
UserTask getNextUserTaskByTaskDefinitionKeyAndProcessDefinitionIdAndReportForm(String currentTaskDefinitionKey, String processDefinitionId, Map<String, Object> reportForm);
|
||||
|
||||
/**
|
||||
* 获得开始节点
|
||||
*
|
||||
* @param flowNodes
|
||||
* @return
|
||||
*/
|
||||
StartEvent getStartEvent(List<FlowNode> flowNodes);
|
||||
|
||||
/**
|
||||
* 获取自定义的流程节点列表
|
||||
*
|
||||
* @param flowNodes
|
||||
* @return
|
||||
*/
|
||||
List<ActivitiFlowNodeDTO> listActivitiFlowNodeByModel(List<FlowNode> flowNodes);
|
||||
|
||||
/**
|
||||
* 获取流程节点列表
|
||||
*
|
||||
* @param deploymentId 部署ID
|
||||
* @return
|
||||
*/
|
||||
List<ActivitiFlowNodeDTO> listFlowNodeByDeploymentId(String deploymentId);
|
||||
|
||||
/**
|
||||
* 获取编辑的json数据
|
||||
*
|
||||
* @param modelId
|
||||
* @return
|
||||
* @throws UnsupportedEncodingException
|
||||
*/
|
||||
JSONObject getEditorJson(String modelId) throws UnsupportedEncodingException;
|
||||
|
||||
/**
|
||||
* 获取模板套件
|
||||
*
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
JSONObject getStencilset() throws IOException;
|
||||
|
||||
/**
|
||||
@ -39,4 +144,12 @@ public interface IActivitiModelService {
|
||||
* @param processInstanceId
|
||||
*/
|
||||
void getRuntimeProcessImage(HttpServletResponse response, String processInstanceId);
|
||||
|
||||
/**
|
||||
* 获取流程xml
|
||||
*
|
||||
* @param processDefinitionId 流程定义ID
|
||||
*/
|
||||
String getProcessXml(String processDefinitionId);
|
||||
|
||||
}
|
||||
|
@ -1,9 +1,7 @@
|
||||
package ink.wgink.module.activiti.service.activiti;
|
||||
|
||||
import ink.wgink.module.activiti.pojo.dtos.ActivitiFlowNodeDTO;
|
||||
import ink.wgink.module.activiti.pojo.dtos.ActivitiProcdefDTO;
|
||||
import ink.wgink.pojo.result.SuccessResultList;
|
||||
import org.activiti.bpmn.model.BpmnModel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -20,7 +18,4 @@ public interface IActivitiProcdefService {
|
||||
|
||||
SuccessResultList<List<ActivitiProcdefDTO>> listPage(int page, int rows);
|
||||
|
||||
List<ActivitiFlowNodeDTO> listFlowNodeByDeploymentId(String deploymentId);
|
||||
|
||||
List<ActivitiFlowNodeDTO> listFlowNodeByModel(BpmnModel bpmnModel);
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
package ink.wgink.module.activiti.service.activiti;
|
||||
|
||||
/**
|
||||
* @ClassName: IActivitiUserTaskService
|
||||
* @Description: 流程用户任务
|
||||
* @Author: wanggeng
|
||||
* @Date: 2022/3/29 17:43
|
||||
* @Version: 1.0
|
||||
*/
|
||||
public interface IActivitiUserTaskService {
|
||||
|
||||
void getNextUserTask(String userTaskId);
|
||||
|
||||
}
|
@ -6,11 +6,11 @@ import ink.wgink.common.base.DefaultBaseService;
|
||||
import ink.wgink.exceptions.SearchException;
|
||||
import ink.wgink.exceptions.base.SystemException;
|
||||
import ink.wgink.interfaces.consts.ISystemConstant;
|
||||
import ink.wgink.module.activiti.pojo.dtos.ActivitiFlowNodeDTO;
|
||||
import ink.wgink.module.activiti.service.activiti.IActivitiModelService;
|
||||
import ink.wgink.util.ResourceUtil;
|
||||
import org.activiti.bpmn.model.BpmnModel;
|
||||
import org.activiti.bpmn.model.FlowNode;
|
||||
import org.activiti.bpmn.model.SequenceFlow;
|
||||
import ink.wgink.util.xml.XMLUtil;
|
||||
import org.activiti.bpmn.model.*;
|
||||
import org.activiti.editor.constants.ModelDataJsonConstants;
|
||||
import org.activiti.engine.HistoryService;
|
||||
import org.activiti.engine.RepositoryService;
|
||||
@ -29,10 +29,7 @@ import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -87,6 +84,115 @@ public class ActivitiModelServiceImpl extends DefaultBaseService implements IAct
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FlowNode> listFlowNode(BpmnModel bpmnModel) {
|
||||
return bpmnModel.getMainProcess().findFlowElementsOfType(FlowNode.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlowNode getCurrentFlowNode(String currentTaskDefinitionKey, String processDefinitionId) {
|
||||
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
|
||||
return (FlowNode) bpmnModel.getFlowElement(currentTaskDefinitionKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserTask getNextUserTaskByCurrentUserTask(UserTask currentUserTask) {
|
||||
List<SequenceFlow> outgoingFlows = currentUserTask.getOutgoingFlows();
|
||||
if (outgoingFlows.size() > 1 || outgoingFlows.size() == 0) {
|
||||
throw new SystemException("流程错误,下个用户任务节点数只能有1个");
|
||||
}
|
||||
FlowElement targetFlowElement = outgoingFlows.get(0).getTargetFlowElement();
|
||||
if (!(targetFlowElement instanceof UserTask)) {
|
||||
throw new SystemException("下个节点不是用户任务");
|
||||
}
|
||||
return (UserTask) targetFlowElement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserTask getNextUserTaskByExclusiveGatewayAndReportForm(ExclusiveGateway exclusiveGateway, Map<String, Object> reportForm) {
|
||||
List<SequenceFlow> outgoingFlows = exclusiveGateway.getOutgoingFlows();
|
||||
for (SequenceFlow sequenceFlow : outgoingFlows) {
|
||||
FlowElement targetFlowElement = sequenceFlow.getTargetFlowElement();
|
||||
if (targetFlowElement instanceof UserTask) {
|
||||
if (isExclusiveConditionPass(sequenceFlow.getConditionExpression(), reportForm)) {
|
||||
return (UserTask) targetFlowElement;
|
||||
}
|
||||
} else if (targetFlowElement instanceof ExclusiveGateway) {
|
||||
return getNextUserTaskByExclusiveGatewayAndReportForm(exclusiveGateway, reportForm);
|
||||
}
|
||||
}
|
||||
throw new SystemException("未找到下一节点用户任务");
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserTask getNextUserTaskByTaskDefinitionKeyAndProcessDefinitionIdAndReportForm(String currentTaskDefinitionKey, String processDefinitionId, Map<String, Object> reportForm) {
|
||||
FlowNode currentFlowNode = getCurrentFlowNode(currentTaskDefinitionKey, processDefinitionId);
|
||||
List<SequenceFlow> outgoingFlows = currentFlowNode.getOutgoingFlows();
|
||||
for (SequenceFlow sequenceFlow : outgoingFlows) {
|
||||
FlowElement targetFlowElement = sequenceFlow.getTargetFlowElement();
|
||||
if (targetFlowElement instanceof UserTask) {
|
||||
return (UserTask) targetFlowElement;
|
||||
} else if (targetFlowElement instanceof ExclusiveGateway) {
|
||||
LOG.debug("排他网关节点,继续查找");
|
||||
ExclusiveGateway exclusiveGateway = (ExclusiveGateway) targetFlowElement;
|
||||
return getNextUserTaskByExclusiveGatewayAndReportForm(exclusiveGateway, reportForm);
|
||||
} else if (targetFlowElement instanceof EndEvent) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
throw new SystemException("未找到下一节点用户任务");
|
||||
}
|
||||
|
||||
@Override
|
||||
public StartEvent getStartEvent(List<FlowNode> flowNodes) {
|
||||
if (flowNodes == null || flowNodes.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
for (FlowNode flowNode : flowNodes) {
|
||||
if (flowNode instanceof StartEvent) {
|
||||
return (StartEvent) flowNode;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ActivitiFlowNodeDTO> listActivitiFlowNodeByModel(List<FlowNode> flowNodes) {
|
||||
List<ActivitiFlowNodeDTO> activitiFlowNodeDTOs = new ArrayList<>();
|
||||
for (FlowNode flowNode : flowNodes) {
|
||||
ActivitiFlowNodeDTO activitiFlowNodeDTO = new ActivitiFlowNodeDTO();
|
||||
activitiFlowNodeDTO.setId(flowNode.getId());
|
||||
activitiFlowNodeDTO.setName(flowNode.getName());
|
||||
activitiFlowNodeDTO.setSummary(flowNode.getDocumentation());
|
||||
if (flowNode instanceof StartEvent) {
|
||||
StartEvent startEvent = (StartEvent) flowNode;
|
||||
activitiFlowNodeDTO.setFormKey(startEvent.getFormKey());
|
||||
activitiFlowNodeDTO.setType(StartEvent.class.getSimpleName());
|
||||
} else if (flowNode instanceof EndEvent) {
|
||||
activitiFlowNodeDTO.setType(EndEvent.class.getSimpleName());
|
||||
} else if (flowNode instanceof UserTask) {
|
||||
UserTask userTask = (UserTask) flowNode;
|
||||
activitiFlowNodeDTO.setFormKey(userTask.getFormKey());
|
||||
activitiFlowNodeDTO.setType(UserTask.class.getSimpleName());
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
activitiFlowNodeDTOs.add(activitiFlowNodeDTO);
|
||||
}
|
||||
return activitiFlowNodeDTOs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ActivitiFlowNodeDTO> listFlowNodeByDeploymentId(String deploymentId) {
|
||||
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult();
|
||||
if (processDefinition == null) {
|
||||
throw new SearchException("流程定义不存在,请检查流程部署情况");
|
||||
}
|
||||
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());
|
||||
List<FlowNode> flowNodes = listFlowNode(bpmnModel);
|
||||
return listActivitiFlowNodeByModel(flowNodes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject getEditorJson(String modelId) throws UnsupportedEncodingException {
|
||||
Model model = repositoryService.getModel(modelId);
|
||||
@ -166,6 +272,27 @@ public class ActivitiModelServiceImpl extends DefaultBaseService implements IAct
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProcessXml(String processDefinitionId) {
|
||||
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
|
||||
if (processDefinition == null) {
|
||||
throw new SearchException("流程定义不存在");
|
||||
}
|
||||
String result;
|
||||
try (InputStream inputStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getResourceName());
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
) {
|
||||
StringBuilder xmlSB = new StringBuilder();
|
||||
for (String line; (line = bufferedReader.readLine()) != null; ) {
|
||||
xmlSB.append(line);
|
||||
}
|
||||
result = XMLUtil.formatXmlString(xmlSB.toString());
|
||||
} catch (IOException e) {
|
||||
throw new SystemException(e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取运行流程图输入流
|
||||
*
|
||||
@ -291,5 +418,48 @@ public class ActivitiModelServiceImpl extends DefaultBaseService implements IAct
|
||||
return new ArrayList<>(flowSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* 排他条件判断通过
|
||||
*
|
||||
* @param conditionExpression 条件表达式
|
||||
* @param reportFormMap 表单变量
|
||||
* @return
|
||||
*/
|
||||
private static boolean isExclusiveConditionPass(String conditionExpression, Map<String, Object> reportFormMap) {
|
||||
if (StringUtils.isBlank(conditionExpression)) {
|
||||
LOG.debug("排他网关条件表达式为空");
|
||||
return false;
|
||||
}
|
||||
if (reportFormMap.isEmpty()) {
|
||||
LOG.debug("上报表单为空");
|
||||
return false;
|
||||
}
|
||||
//分割表达式
|
||||
String[] expressionArray = conditionExpression.split("[{}$&]");
|
||||
for (String expression : expressionArray) {
|
||||
// 是否包含条件字段
|
||||
if (!expression.contains(IActivitiModelService.EXCLUSIVE_GATEWAY_CONDITION_KEY)) {
|
||||
continue;
|
||||
}
|
||||
// 表单中是否包含条件字段
|
||||
if (!reportFormMap.containsKey(IActivitiModelService.EXCLUSIVE_GATEWAY_CONDITION_KEY)) {
|
||||
continue;
|
||||
}
|
||||
if (expression.contains("==")) {
|
||||
String[] primes = expression.split("==");
|
||||
String valExpr = primes[1].trim();
|
||||
if (valExpr.startsWith("'")) {
|
||||
valExpr = valExpr.substring(1);
|
||||
}
|
||||
if (valExpr.endsWith("'")) {
|
||||
valExpr = valExpr.substring(0, valExpr.length() - 1);
|
||||
}
|
||||
if (primes.length == 2 && valExpr.equals(reportFormMap.get(IActivitiModelService.EXCLUSIVE_GATEWAY_CONDITION_KEY))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,14 +1,10 @@
|
||||
package ink.wgink.module.activiti.service.activiti.impl;
|
||||
|
||||
import ink.wgink.common.base.DefaultBaseService;
|
||||
import ink.wgink.exceptions.SearchException;
|
||||
import ink.wgink.exceptions.base.SystemException;
|
||||
import ink.wgink.module.activiti.pojo.dtos.ActivitiFlowNodeDTO;
|
||||
import ink.wgink.module.activiti.pojo.dtos.ActivitiProcdefDTO;
|
||||
import ink.wgink.module.activiti.service.activiti.IActivitiModelService;
|
||||
import ink.wgink.module.activiti.service.activiti.IActivitiProcdefService;
|
||||
import ink.wgink.pojo.result.SuccessResultList;
|
||||
import org.activiti.bpmn.model.Process;
|
||||
import org.activiti.bpmn.model.*;
|
||||
import org.activiti.engine.RepositoryService;
|
||||
import org.activiti.engine.RuntimeService;
|
||||
import org.activiti.engine.repository.ProcessDefinition;
|
||||
@ -34,6 +30,8 @@ public class ActivitiProcdefServiceImpl extends DefaultBaseService implements IA
|
||||
private RepositoryService repositoryService;
|
||||
@Autowired
|
||||
private RuntimeService runtimeService;
|
||||
@Autowired
|
||||
private IActivitiModelService activitiModelService;
|
||||
|
||||
@Override
|
||||
public void delete(String deploymentId) {
|
||||
@ -55,46 +53,4 @@ public class ActivitiProcdefServiceImpl extends DefaultBaseService implements IA
|
||||
return new SuccessResultList<>(activitiProcdefDTOs, page, processDefinitionQuery.count());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ActivitiFlowNodeDTO> listFlowNodeByDeploymentId(String deploymentId) {
|
||||
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult();
|
||||
if (processDefinition == null) {
|
||||
throw new SearchException("流程定义不存在,请检查流程部署情况");
|
||||
}
|
||||
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());
|
||||
return listFlowNodeByModel(bpmnModel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ActivitiFlowNodeDTO> listFlowNodeByModel(BpmnModel bpmnModel) {
|
||||
List<Process> processes = bpmnModel.getProcesses();
|
||||
if (processes.size() > 1) {
|
||||
throw new SystemException("流程不能有多条");
|
||||
}
|
||||
List<FlowNode> flowNodes = processes.get(0).findFlowElementsOfType(FlowNode.class);
|
||||
List<ActivitiFlowNodeDTO> activitiFlowNodeDTOs = new ArrayList<>();
|
||||
for (FlowNode flowNode : flowNodes) {
|
||||
ActivitiFlowNodeDTO activitiFlowNodeDTO = new ActivitiFlowNodeDTO();
|
||||
activitiFlowNodeDTO.setId(flowNode.getId());
|
||||
activitiFlowNodeDTO.setName(flowNode.getName());
|
||||
activitiFlowNodeDTO.setSummary(flowNode.getDocumentation());
|
||||
if (flowNode instanceof StartEvent) {
|
||||
StartEvent startEvent = (StartEvent) flowNode;
|
||||
activitiFlowNodeDTO.setFormKey(startEvent.getFormKey());
|
||||
activitiFlowNodeDTO.setType(StartEvent.class.getSimpleName());
|
||||
} else if (flowNode instanceof EndEvent) {
|
||||
activitiFlowNodeDTO.setType(EndEvent.class.getSimpleName());
|
||||
} else if (flowNode instanceof UserTask) {
|
||||
UserTask userTask = (UserTask) flowNode;
|
||||
activitiFlowNodeDTO.setFormKey(userTask.getFormKey());
|
||||
activitiFlowNodeDTO.setType(UserTask.class.getSimpleName());
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
activitiFlowNodeDTOs.add(activitiFlowNodeDTO);
|
||||
}
|
||||
return activitiFlowNodeDTOs;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import ink.wgink.module.activiti.pojo.dtos.ActivitiFlowNodeDTO;
|
||||
import ink.wgink.module.activiti.pojo.vos.ActivitiVO;
|
||||
import ink.wgink.module.activiti.pojo.vos.oa.NodeFieldUpdateVO;
|
||||
import ink.wgink.module.activiti.pojo.vos.oa.NodeFieldVO;
|
||||
import ink.wgink.module.activiti.service.activiti.IActivitiModelService;
|
||||
import ink.wgink.module.activiti.service.activiti.IActivitiProcdefService;
|
||||
import ink.wgink.module.activiti.service.activiti.IActivitiService;
|
||||
import ink.wgink.module.activiti.service.oa.INodeFieldService;
|
||||
@ -20,9 +21,7 @@ import ink.wgink.module.form.pojo.pos.design.FormPO;
|
||||
import ink.wgink.module.form.service.design.IFormFieldService;
|
||||
import ink.wgink.module.form.service.design.IFormService;
|
||||
import ink.wgink.pojo.result.SuccessResultList;
|
||||
import org.activiti.bpmn.model.BpmnModel;
|
||||
import org.activiti.bpmn.model.EndEvent;
|
||||
import org.activiti.bpmn.model.StartEvent;
|
||||
import org.activiti.bpmn.model.*;
|
||||
import org.activiti.editor.constants.ModelDataJsonConstants;
|
||||
import org.activiti.editor.language.json.converter.BpmnJsonConverter;
|
||||
import org.activiti.engine.HistoryService;
|
||||
@ -60,6 +59,8 @@ public class ActivitiServiceImpl extends DefaultBaseService implements IActiviti
|
||||
@Autowired
|
||||
private RuntimeService runtimeService;
|
||||
@Autowired
|
||||
private IActivitiModelService activitiModelService;
|
||||
@Autowired
|
||||
private IActivitiProcdefService activitiProcdefService;
|
||||
@Autowired
|
||||
private INodeFieldService nodeFieldService;
|
||||
@ -110,15 +111,46 @@ public class ActivitiServiceImpl extends DefaultBaseService implements IActiviti
|
||||
LOG.debug("部署流程");
|
||||
JsonNode modelNode = new ObjectMapper().readTree(modelEditorSource);
|
||||
BpmnModel bpmnModel = new BpmnJsonConverter().convertToBpmnModel(modelNode);
|
||||
|
||||
|
||||
LOG.debug("获取流程节点列表");
|
||||
List<FlowNode> flowNodes = activitiModelService.listFlowNode(bpmnModel);
|
||||
LOG.debug("获得开始节点");
|
||||
StartEvent startEvent = activitiModelService.getStartEvent(flowNodes);
|
||||
// 判断是否存在表单,如果存在表单,说明是OA流程,进行初始化再部署,如果不是OA流程则正常部署
|
||||
String formKey = startEvent.getFormKey();
|
||||
String deploymentId;
|
||||
if (!StringUtils.isBlank(formKey)) {
|
||||
LOG.debug("存在自定义表单,是OA流程,执行初始化操作");
|
||||
LOG.debug("1.初始化");
|
||||
LOG.debug("2.部署流程");
|
||||
deploymentId = deployProcess(model, bpmnModel);
|
||||
LOG.debug("3.绑定节点设置");
|
||||
LOG.debug("4.绑定流程节点与表单关系");
|
||||
saveNodeField(deploymentId, flowNodes);
|
||||
} else {
|
||||
LOG.debug("不存在自定义表单,不是OA流程,直接部署");
|
||||
deploymentId = deployProcess(model, bpmnModel);
|
||||
}
|
||||
model.setDeploymentId(deploymentId);
|
||||
LOG.debug("保存模型");
|
||||
repositoryService.saveModel(model);
|
||||
}
|
||||
|
||||
/**
|
||||
* 部署流程
|
||||
*
|
||||
* @param model
|
||||
* @param bpmnModel
|
||||
* @return
|
||||
*/
|
||||
private String deployProcess(Model model, BpmnModel bpmnModel) {
|
||||
Deployment deployment = repositoryService.createDeployment()
|
||||
.name(model.getName())
|
||||
.key(model.getKey())
|
||||
.addBpmnModel(model.getKey() + "." + model.getVersion() + ".bpmn20.xml", bpmnModel)
|
||||
.deploy();
|
||||
model.setDeploymentId(deployment.getId());
|
||||
repositoryService.saveModel(model);
|
||||
LOG.debug("节点关联表单");
|
||||
saveNodeField(deployment.getId(), bpmnModel);
|
||||
return deployment.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -126,8 +158,8 @@ public class ActivitiServiceImpl extends DefaultBaseService implements IActiviti
|
||||
*
|
||||
* @param deploymentId
|
||||
*/
|
||||
private void saveNodeField(String deploymentId, BpmnModel bpmnModel) {
|
||||
List<ActivitiFlowNodeDTO> activitiFlowNodeDTOs = activitiProcdefService.listFlowNodeByModel(bpmnModel);
|
||||
private void saveNodeField(String deploymentId, List<FlowNode> flowNodes) {
|
||||
List<ActivitiFlowNodeDTO> activitiFlowNodeDTOs = activitiModelService.listActivitiFlowNodeByModel(flowNodes);
|
||||
if (activitiFlowNodeDTOs.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
@ -0,0 +1,115 @@
|
||||
package ink.wgink.module.activiti.service.activiti.impl;
|
||||
|
||||
import ink.wgink.common.base.DefaultBaseService;
|
||||
import ink.wgink.module.activiti.service.activiti.IActivitiUserTaskService;
|
||||
import org.activiti.bpmn.model.*;
|
||||
import org.activiti.engine.RepositoryService;
|
||||
import org.activiti.engine.RuntimeService;
|
||||
import org.activiti.engine.TaskService;
|
||||
import org.activiti.engine.task.Task;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @ClassName: ActivitiUserTaskServiceImpl
|
||||
* @Description: 流程用户任务
|
||||
* @Author: wanggeng
|
||||
* @Date: 2022/3/29 17:44
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Service
|
||||
public class ActivitiUserTaskServiceImpl extends DefaultBaseService implements IActivitiUserTaskService {
|
||||
|
||||
@Autowired
|
||||
private TaskService taskService;
|
||||
@Autowired
|
||||
private RuntimeService runtimeService;
|
||||
@Autowired
|
||||
private RepositoryService repositoryService;
|
||||
|
||||
@Override
|
||||
public void getNextUserTask(String userTaskId) {
|
||||
Task task = taskService.createTaskQuery().taskId(userTaskId).singleResult();
|
||||
String taskDefinitionKey = task.getTaskDefinitionKey();
|
||||
String processInstanceId = task.getProcessInstanceId();
|
||||
String processDefinitionId = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult().getProcessDefinitionId();
|
||||
|
||||
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
|
||||
|
||||
FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(taskDefinitionKey);
|
||||
|
||||
// 流入线
|
||||
List<SequenceFlow> incomingFlows = flowNode.getIncomingFlows();
|
||||
|
||||
// 流出线
|
||||
List<SequenceFlow> outgoingFlows = flowNode.getOutgoingFlows();
|
||||
HashMap<String, Object> vars = new HashMap<>();
|
||||
vars.put("message", "");
|
||||
for (SequenceFlow outgoingFlow : outgoingFlows) {
|
||||
//获取输出节点元素
|
||||
FlowElement targetFlowElement = outgoingFlow.getTargetFlowElement();
|
||||
//排除非用户任务接点
|
||||
if (targetFlowElement instanceof UserTask) {
|
||||
LOG.debug("UserTask");
|
||||
UserTask userTask = (UserTask) targetFlowElement;
|
||||
System.out.println(userTask);
|
||||
//判断输出节点的el表达式
|
||||
// if (isCondition(outgoingFlow.getConditionExpression(), vars)) {
|
||||
// //true 获取输出节点名称
|
||||
// // nameList.add(outgoingFlow.getTargetFlowElement().getName());
|
||||
// }
|
||||
} else if (targetFlowElement instanceof ExclusiveGateway) {
|
||||
LOG.debug("排他网关");
|
||||
|
||||
} else if (targetFlowElement instanceof ParallelGateway) {
|
||||
LOG.debug("并行网关");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println(flowNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* el表达式判断
|
||||
*
|
||||
* @param expression
|
||||
* @param vars
|
||||
* @return
|
||||
*/
|
||||
private static boolean isCondition(String expression, Map<String, Object> vars) {
|
||||
if (expression == null || expression == "") {
|
||||
return false;
|
||||
}
|
||||
|
||||
//分割表达式
|
||||
String[] exprArr = expression.split("[{}$&]");
|
||||
for (String expr : exprArr) {
|
||||
//是否包含键message
|
||||
if (expr.contains("message")) {
|
||||
if (!vars.containsKey("message")) {
|
||||
continue;
|
||||
}
|
||||
if (expr.contains("==")) {
|
||||
String[] primes = expr.split("==");
|
||||
String valExpr = primes[1].trim();
|
||||
if (valExpr.startsWith("'")) {
|
||||
valExpr = valExpr.substring(1);
|
||||
}
|
||||
if (valExpr.endsWith("'")) {
|
||||
valExpr = valExpr.substring(0, valExpr.length() - 1);
|
||||
}
|
||||
if (primes.length == 2 && valExpr.equals(vars.get("message"))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -27,6 +27,7 @@ public interface IOaFormReportService {
|
||||
|
||||
/**
|
||||
* 更新表单
|
||||
*
|
||||
* @param taskId
|
||||
* @param formCode
|
||||
* @param formVersion
|
||||
@ -35,4 +36,13 @@ public interface IOaFormReportService {
|
||||
*/
|
||||
void update(String taskId, String formCode, Integer formVersion, String uid, Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 表单详情
|
||||
*
|
||||
* @param formCode
|
||||
* @param formVersion
|
||||
* @param uid
|
||||
*/
|
||||
Map<String, Object> get(String formCode, Integer formVersion, String uid);
|
||||
|
||||
}
|
||||
|
@ -47,4 +47,9 @@ public class OaFormReportServiceImpl extends DefaultBaseService implements IOaFo
|
||||
taskService.complete(taskId, params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> get(String formCode, Integer formVersion, String uid) {
|
||||
return formReportService.get(formCode, formVersion, uid);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -134,6 +134,8 @@ public class OaServiceImpl extends DefaultBaseService implements IOaService {
|
||||
oaTaskDTO.setTaskName(task.getName());
|
||||
oaTaskDTO.setTaskDescription(task.getDescription());
|
||||
oaTaskDTO.setOwner(task.getOwner());
|
||||
oaTaskDTO.setTaskDefinitionKey(task.getTaskDefinitionKey());
|
||||
oaTaskDTO.setProcessDefinitionId(task.getProcessDefinitionId());
|
||||
|
||||
Map<String, Object> variables = runtimeService.getVariables(task.getProcessInstanceId());
|
||||
if (variables.isEmpty()) {
|
||||
|
@ -33,7 +33,7 @@ var KisBpmTaskListenersCtrl = [ '$scope', '$modal', '$timeout', '$translate', fu
|
||||
$modal(opts);
|
||||
}];
|
||||
|
||||
var KisBpmTaskListenersPopupCtrl = [ '$scope', '$q', '$translate', function($scope, $q, $translate) {
|
||||
var KisBpmTaskListenersPopupCtrl = [ '$scope', '$timeout', '$q', '$translate', function($scope, $timeout, $q, $translate) {
|
||||
|
||||
// Put json representing form properties on scope
|
||||
if ($scope.property.value !== undefined && $scope.property.value !== null
|
||||
@ -158,15 +158,89 @@ var KisBpmTaskListenersPopupCtrl = [ '$scope', '$q', '$translate', function($sco
|
||||
}
|
||||
};
|
||||
|
||||
function addListener(event, className, expression, delegateExpression) {
|
||||
var implementation = '';
|
||||
if(className) {
|
||||
implementation = className;
|
||||
} else if(expression) {
|
||||
implementation = expression;
|
||||
} else if(delegateExpression) {
|
||||
implementation = delegateExpression;
|
||||
}
|
||||
$scope.taskListeners.push({
|
||||
event : event,
|
||||
implementation : implementation,
|
||||
className : className ? className : '',
|
||||
expression: expression ? expression : '',
|
||||
delegateExpression: delegateExpression ? delegateExpression : ''
|
||||
});
|
||||
}
|
||||
|
||||
// Click handler for add button
|
||||
$scope.addNewListener = function() {
|
||||
$scope.taskListeners.push({ event : 'create',
|
||||
implementation : '',
|
||||
className : '',
|
||||
expression: '',
|
||||
delegateExpression: ''});
|
||||
addListener('create');
|
||||
};
|
||||
|
||||
/**
|
||||
* 判断监听器是否存在
|
||||
* @param event
|
||||
* @param className
|
||||
*/
|
||||
function isListenerExist(event, className) {
|
||||
for(var i = 0, item; item = $scope.taskListeners[i++]; ) {
|
||||
if(item.event == event && item.className == className) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// quick add listener
|
||||
$scope.addOaUserTaskCreateListener = function() {
|
||||
var event = 'create',
|
||||
className = '',
|
||||
expression = '',
|
||||
delegateExpression = '${oaUserTaskCreateListener}';
|
||||
if(isListenerExist(event, className)) {
|
||||
top.dialog.msg('监听器已经存在');
|
||||
return;
|
||||
}
|
||||
addListener(event, className, expression, delegateExpression);
|
||||
}
|
||||
$scope.addOaUserTaskCompleteListener = function() {
|
||||
var event = 'complete',
|
||||
className = '',
|
||||
expression = '',
|
||||
delegateExpression = '${oaUserTaskCompleteListener}';
|
||||
if(isListenerExist(event, className)) {
|
||||
top.dialog.msg('监听器已经存在');
|
||||
return;
|
||||
}
|
||||
addListener(event, className, expression, delegateExpression);
|
||||
}
|
||||
$scope.addOaUserTaskAssignmentListener = function() {
|
||||
var event = 'assignment',
|
||||
className = '',
|
||||
expression = '',
|
||||
delegateExpression = '${oaUserTaskAssignmentListener}';
|
||||
if(isListenerExist(event, className)) {
|
||||
top.dialog.msg('监听器已经存在');
|
||||
return;
|
||||
}
|
||||
addListener(event, className, expression, delegateExpression);
|
||||
}
|
||||
$scope.addOaUserTaskDeleteListener = function() {
|
||||
var event = 'delete',
|
||||
className = '',
|
||||
expression = '',
|
||||
delegateExpression = '${oaUserTaskDeleteListener}';
|
||||
if(isListenerExist(event, className)) {
|
||||
top.dialog.msg('监听器已经存在');
|
||||
return;
|
||||
}
|
||||
addListener(event, className, expression, delegateExpression);
|
||||
}
|
||||
|
||||
// Click handler for remove button
|
||||
$scope.removeListener = function() {
|
||||
if ($scope.selectedListeners.length > 0) {
|
||||
@ -189,12 +263,12 @@ var KisBpmTaskListenersPopupCtrl = [ '$scope', '$q', '$translate', function($sco
|
||||
var index = $scope.taskListeners.indexOf($scope.selectedListeners[0]);
|
||||
if (index != 0) { // If it's the first, no moving up of course
|
||||
// Reason for funny way of swapping, see https://github.com/angular-ui/ng-grid/issues/272
|
||||
var prevIndex = index - 1;
|
||||
var temp = $scope.taskListeners[index];
|
||||
$scope.taskListeners.splice(index, 1);
|
||||
$timeout(function(){
|
||||
$scope.taskListeners.splice(index + -1, 0, temp);
|
||||
$timeout(function() {
|
||||
$scope.taskListeners.splice(prevIndex, 0, temp);
|
||||
}, 100);
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -205,10 +279,11 @@ var KisBpmTaskListenersPopupCtrl = [ '$scope', '$q', '$translate', function($sco
|
||||
var index = $scope.taskListeners.indexOf($scope.selectedListeners[0]);
|
||||
if (index != $scope.taskListeners.length - 1) { // If it's the last element, no moving down of course
|
||||
// Reason for funny way of swapping, see https://github.com/angular-ui/ng-grid/issues/272
|
||||
var nextIndex = index + 1;
|
||||
var temp = $scope.taskListeners[index];
|
||||
$scope.taskListeners.splice(index, 1);
|
||||
$timeout(function(){
|
||||
$scope.taskListeners.splice(index + 1, 0, temp);
|
||||
$scope.taskListeners.splice(nextIndex, 0, temp);
|
||||
}, 100);
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,102 @@
|
||||
|
||||
<div class="modal" ng-controller="KisBpmTaskListenersPopupCtrl">
|
||||
<div class="modal-dialog modal-wide">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true" ng-click="close()">×</button>
|
||||
<h2>{{'PROPERTY.PROPERTY.EDIT.TITLE' | translate:property}}</h2>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="row row-no-gutter">
|
||||
<div class="col-xs-6">
|
||||
<div ng-if="translationsRetrieved" class="kis-listener-grid" ng-grid="gridOptions"></div>
|
||||
<div class="pull-right">
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-icon btn-lg" rel="tooltip" data-title="{{ACTION.MOVE.UP | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="moveListenerUp()"><i class="glyphicon glyphicon-arrow-up"></i></a>
|
||||
<a class="btn btn-icon btn-lg" rel="tooltip" data-title="{{ACTION.MOVE.DOWN | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="moveListenerDown()"><i class="glyphicon glyphicon-arrow-down"></i></a>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-icon btn-lg" rel="tooltip" data-title="{{ACTION.ADD | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="addNewListener()"><i class="glyphicon glyphicon-plus"></i></a>
|
||||
<a class="btn btn-icon btn-lg" rel="tooltip" data-title="{{ACTION.REMOVE | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="removeListener()"><i class="glyphicon glyphicon-minus"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-6">
|
||||
<div ng-show="selectedListeners.length > 0">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="eventField">{{'PROPERTY.TASKLISTENERS.EVENT' | translate}}</label>
|
||||
<select id="eventField" class="form-control" ng-model="selectedListeners[0].event">
|
||||
<option>create</option>
|
||||
<option>assignment</option>
|
||||
<option>complete</option>
|
||||
<option>delete</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="classField">{{'PROPERTY.TASKLISTENERS.CLASS' | translate}}</label>
|
||||
<input type="text" id="classField" class="form-control" ng-model="selectedListeners[0].className" ng-change="listenerDetailsChanged()" placeholder="{{'PROPERTY.TASKLISTENERS.CLASS.PLACEHOLDER' | translate}}" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="expressionField">{{'PROPERTY.TASKLISTENERS.EXPRESSION' | translate}}</label>
|
||||
<input type="text" id="expressionField" class="form-control" ng-model="selectedListeners[0].expression" ng-change="listenerDetailsChanged()" placeholder="{{'PROPERTY.TASKLISTENERS.EXPRESSION.PLACEHOLDER' | translate}}" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="delegateExpressionField">{{'PROPERTY.TASKLISTENERS.DELEGATEEXPRESSION' | translate}}</label>
|
||||
<input type="text" id="delegateExpressionField" class="form-control" ng-model="selectedListeners[0].delegateExpression" ng-change="listenerDetailsChanged()" placeholder="{{'PROPERTY.TASKLISTENERS.DELEGATEEXPRESSION.PLACEHOLDER' | translate}}" />
|
||||
</div>
|
||||
</div>
|
||||
<div ng-show="selectedListeners.length == 0" class="muted no-property-selected" translate>PROPERTY.TASKLISTENERS.UNSELECTED</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row row-no-gutter">
|
||||
<div class="col-xs-6">
|
||||
<div ng-if="translationsRetrieved" class="kis-field-grid" ng-grid="gridFieldOptions"></div>
|
||||
<div class="pull-right">
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-icon btn-lg" rel="tooltip" data-title="{{ACTION.MOVE.UP | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="moveFieldUp()"><i class="glyphicon glyphicon-arrow-up"></i></a>
|
||||
<a class="btn btn-icon btn-lg" rel="tooltip" data-title="{{ACTION.MOVE.DOWN | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="moveFieldDown()"><i class="glyphicon glyphicon-arrow-down"></i></a>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-icon btn-lg" rel="tooltip" data-title="{{ACTION.ADD | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="addNewField()"><i class="glyphicon glyphicon-plus"></i></a>
|
||||
<a class="btn btn-icon btn-lg" rel="tooltip" data-title="{{ACTION.REMOVE | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="removeField()"><i class="glyphicon glyphicon-minus"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-6">
|
||||
<div ng-show="selectedFields.length > 0">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="nameField">{{'PROPERTY.TASKLISTENERS.FIELDS.NAME' | translate}}</label>
|
||||
<input type="text" id="nameField" class="form-control" ng-model="selectedFields[0].name" placeholder="{{'PROPERTY.TASKLISTENERS.FIELDS.NAME.PLACEHOLDER' | translate}}" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="stringValueField">{{'PROPERTY.TASKLISTENERS.FIELDS.STRINGVALUE' | translate}}</label>
|
||||
<input type="text" id="stringValueField" class="form-control" ng-model="selectedFields[0].stringValue" ng-change="fieldDetailsChanged()" placeholder="{{'PROPERTY.TASKLISTENERS.FIELDS.STRINGVALUE.PLACEHOLDER' | translate}}" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="expressionField">{{'PROPERTY.TASKLISTENERS.FIELDS.EXPRESSION' | translate}}</label>
|
||||
<input type="text" id="expressionField" class="form-control" ng-model="selectedFields[0].expression" ng-change="fieldDetailsChanged()" placeholder="{{'PROPERTY.TASKLISTENERS.FIELDS.EXPRESSION.PLACEHOLDER' | translate}}" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="stringField">{{'PROPERTY.TASKLISTENERS.FIELDS.STRING' | translate}}</label>
|
||||
<textarea id="stringField" class="form-control" ng-model="selectedFields[0].string" ng-change="fieldDetailsChanged()" placeholder="{{'PROPERTY.TASKLISTENERS.FIELDS.STRING.PLACEHOLDER' | translate}}"></textarea>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div ng-show="selectedFields.length == 0" class="muted no-property-selected"translate>PROPERTY.TASKLISTENERS.FIELDS.EMPTY</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button ng-click="cancel()" class="btn btn-primary" translate>ACTION.CANCEL</button>
|
||||
<button ng-click="save()" class="btn btn-primary" translate>ACTION.SAVE</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -11,18 +11,26 @@
|
||||
<div class="row row-no-gutter">
|
||||
<div class="col-xs-6">
|
||||
<div ng-if="translationsRetrieved" class="kis-listener-grid" ng-grid="gridOptions"></div>
|
||||
<div class="pull-right">
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-icon btn-lg" rel="tooltip" data-title="{{ACTION.MOVE.UP | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="moveListenerUp()"><i class="glyphicon glyphicon-arrow-up"></i></a>
|
||||
<a class="btn btn-icon btn-lg" rel="tooltip" data-title="{{ACTION.MOVE.DOWN | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="moveListenerDown()"><i class="glyphicon glyphicon-arrow-down"></i></a>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-icon btn-lg" rel="tooltip" data-title="{{ACTION.ADD | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="addNewListener()"><i class="glyphicon glyphicon-plus"></i></a>
|
||||
<a class="btn btn-icon btn-lg" rel="tooltip" data-title="{{ACTION.REMOVE | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="removeListener()"><i class="glyphicon glyphicon-minus"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin: 10px 0;">
|
||||
快速设置
|
||||
<div class="btn-group">
|
||||
<button type="button" ng-click="addOaUserTaskCreateListener()">任务创建(OA)</button>
|
||||
<button type="button" ng-click="addOaUserTaskAssignmentListener()">任务代理人设置(OA)</button>
|
||||
<button type="button" ng-click="addOaUserTaskCompleteListener()">任务完成(OA)</button>
|
||||
<button type="button" ng-click="addOaUserTaskDeleteListener()">任务删除(OA)</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pull-right" style="margin-bottom: 15px;">
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-icon btn-xs" rel="tooltip" data-title="{{ACTION.MOVE.UP | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="moveListenerUp()"><i class="glyphicon glyphicon-arrow-up"></i></a>
|
||||
<a class="btn btn-icon btn-xs" rel="tooltip" data-title="{{ACTION.MOVE.DOWN | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="moveListenerDown()"><i class="glyphicon glyphicon-arrow-down"></i></a>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-icon btn-xs" rel="tooltip" data-title="{{ACTION.ADD | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="addNewListener()"><i class="glyphicon glyphicon-plus"></i></a>
|
||||
<a class="btn btn-icon btn-xs" rel="tooltip" data-title="{{ACTION.REMOVE | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="removeListener()"><i class="glyphicon glyphicon-minus"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-6">
|
||||
<div ng-show="selectedListeners.length > 0">
|
||||
|
||||
@ -57,12 +65,12 @@
|
||||
<div ng-if="translationsRetrieved" class="kis-field-grid" ng-grid="gridFieldOptions"></div>
|
||||
<div class="pull-right">
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-icon btn-lg" rel="tooltip" data-title="{{ACTION.MOVE.UP | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="moveFieldUp()"><i class="glyphicon glyphicon-arrow-up"></i></a>
|
||||
<a class="btn btn-icon btn-lg" rel="tooltip" data-title="{{ACTION.MOVE.DOWN | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="moveFieldDown()"><i class="glyphicon glyphicon-arrow-down"></i></a>
|
||||
<a class="btn btn-icon btn-xs" rel="tooltip" data-title="{{ACTION.MOVE.UP | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="moveFieldUp()"><i class="glyphicon glyphicon-arrow-up"></i></a>
|
||||
<a class="btn btn-icon btn-xs" rel="tooltip" data-title="{{ACTION.MOVE.DOWN | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="moveFieldDown()"><i class="glyphicon glyphicon-arrow-down"></i></a>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-icon btn-lg" rel="tooltip" data-title="{{ACTION.ADD | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="addNewField()"><i class="glyphicon glyphicon-plus"></i></a>
|
||||
<a class="btn btn-icon btn-lg" rel="tooltip" data-title="{{ACTION.REMOVE | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="removeField()"><i class="glyphicon glyphicon-minus"></i></a>
|
||||
<a class="btn btn-icon btn-xs" rel="tooltip" data-title="{{ACTION.ADD | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="addNewField()"><i class="glyphicon glyphicon-plus"></i></a>
|
||||
<a class="btn btn-icon btn-xs" rel="tooltip" data-title="{{ACTION.REMOVE | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="removeField()"><i class="glyphicon glyphicon-minus"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -116,7 +116,7 @@
|
||||
if(!row.deploymentId) {
|
||||
return '-';
|
||||
}
|
||||
var flowChatImg = '<img id="flowChat'+ row.id +'" src="route/activiti/get-process-image/'+ row.deploymentId +'" style="width: 30px; height: 30px;"/>'
|
||||
var flowChatImg = '<img id="flowChat'+ row.id +'" src="route/activiti/model/get-process-image/'+ row.deploymentId +'" style="width: 30px; height: 30px;"/>'
|
||||
setTimeout(function() {
|
||||
new Viewer(document.getElementById('flowChat'+ row.id));
|
||||
}, 50);
|
||||
|
@ -0,0 +1,104 @@
|
||||
<!doctype html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<base th:href="${#request.getContextPath() + '/'}">
|
||||
<meta charset="utf-8">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||
<link rel="stylesheet" href="assets/fonts/font-awesome/css/font-awesome.css"/>
|
||||
<link rel="stylesheet" href="assets/layuiadmin/layui/css/layui.css" media="all">
|
||||
<link rel="stylesheet" href="assets/layuiadmin/style/admin.css" media="all">
|
||||
<link rel="stylesheet" href="assets/js/vendor/codemirror/codemirror.css">
|
||||
<link rel="stylesheet" href="assets/js/vendor/codemirror/theme/dracula.css">
|
||||
<style>
|
||||
.resource-img, .resource-img-path {text-align: center}
|
||||
.layui-btn-container .layui-btn {margin-bottom: 0px}
|
||||
.layui-table {width: auto;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="layui-anim layui-anim-fadein">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body" style="padding: 15px;">
|
||||
<form class="layui-form layui-form-pane" lay-filter="dataForm">
|
||||
<textarea id="formXml" name="formXml" style="display: none;"></textarea>
|
||||
<div class="layui-form-item layui-layout-admin">
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-footer" style="left: 0;">
|
||||
<button type="button" class="layui-btn layui-btn-primary close">返回上级</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="assets/js/vendor/viewer/viewer.min.js"></script>
|
||||
<script src="assets/js/vendor/codemirror/codemirror.js"></script>
|
||||
<script src="assets/js/vendor/codemirror/mode/xml/xml.js"></script>
|
||||
<script src="assets/layuiadmin/layui/layui.js"></script>
|
||||
<script>
|
||||
layui.config({
|
||||
base: 'assets/layuiadmin/' //静态资源所在路径
|
||||
}).extend({
|
||||
index: 'lib/index' //主入口模块
|
||||
}).use(['index', 'form', 'laydate'], function(){
|
||||
var $ = layui.$;
|
||||
var win = $(window)
|
||||
var laytpl = layui.laytpl;
|
||||
var processDefinitionId = top.restAjax.params(window.location.href).processDefinitionId;
|
||||
var codeMirrorConfig = {
|
||||
lineNumbers: true,
|
||||
theme: 'dracula',
|
||||
matchBrackets: true,
|
||||
indentUnit : 4,
|
||||
tabSize : 4,
|
||||
extraKeys: {
|
||||
'Shift-Tab': function (cm) {
|
||||
if (cm.somethingSelected()) {
|
||||
cm.indentSelection('subtract');
|
||||
} else {
|
||||
cm.indentLine(cm.getCursor().line, "subtract");
|
||||
}
|
||||
return;
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
function closeBox() {
|
||||
parent.layer.close(parent.layer.getFrameIndex(window.name));
|
||||
}
|
||||
|
||||
function initFormXml(value) {
|
||||
codeMirrorConfig.mode = 'application/xml';
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById('formXml'), codeMirrorConfig);
|
||||
editor.setValue(value);
|
||||
editor.setSize('100%', win.height() - 90);
|
||||
editor.on('change', function(self, changeValue) {
|
||||
$('#formXml').val(self.getValue());
|
||||
});
|
||||
}
|
||||
|
||||
// 初始化
|
||||
function initData() {
|
||||
var loadLayerIndex;
|
||||
top.restAjax.get(top.restAjax.path('api/activiti/model/get-process-xml/{processDefinitionId}', [processDefinitionId]), {}, null, function(code, data) {
|
||||
initFormXml(data.data);
|
||||
}, function(code, data) {
|
||||
top.dialog.msg(data.msg);
|
||||
}, function() {
|
||||
loadLayerIndex = top.dialog.msg(top.dataMessage.loading, {icon: 16, time: 0, shade: 0.3});
|
||||
}, function() {
|
||||
top.dialog.close(loadLayerIndex);
|
||||
});
|
||||
}
|
||||
initData();
|
||||
|
||||
$('.close').on('click', function() {
|
||||
closeBox();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -57,7 +57,7 @@
|
||||
cols: [
|
||||
[
|
||||
{field:'rowNum', width:80, title: '序号', fixed: 'left', align:'center', templet: '<span>{{d.LAY_INDEX}}</span>'},
|
||||
{field:'id', width:150, title: '主键', align:'center',
|
||||
{field:'id', width:220, title: '流程定义ID', align:'center',
|
||||
templet: function(row) {
|
||||
var rowData = row[this.field];
|
||||
if(typeof(rowData) === 'undefined' || rowData == null || rowData == '') {
|
||||
@ -66,7 +66,7 @@
|
||||
return rowData;
|
||||
}
|
||||
},
|
||||
{field:'key', width:150, title: '流程定义ID', align:'center',
|
||||
{field:'key', width:150, title: '流程key', align:'center',
|
||||
templet: function(row) {
|
||||
var rowData = row[this.field];
|
||||
if(typeof(rowData) === 'undefined' || rowData == null || rowData == '') {
|
||||
@ -84,7 +84,7 @@
|
||||
return rowData;
|
||||
}
|
||||
},
|
||||
{field:'name', width:150, title: '名称', align:'center',
|
||||
{field:'name', width:200, title: '名称', align:'center',
|
||||
templet: function(row) {
|
||||
var rowData = row[this.field];
|
||||
if(typeof(rowData) === 'undefined' || rowData == null || rowData == '') {
|
||||
@ -93,7 +93,7 @@
|
||||
return rowData;
|
||||
}
|
||||
},
|
||||
{field:'description', width:150, title: '描述', align:'center',
|
||||
{field:'description', width:200, title: '描述', align:'center',
|
||||
templet: function(row) {
|
||||
var rowData = row[this.field];
|
||||
if(typeof(rowData) === 'undefined' || rowData == null || rowData == '') {
|
||||
@ -111,13 +111,13 @@
|
||||
return rowData;
|
||||
}
|
||||
},
|
||||
{field:'resourceName', width:200, title: '流程资源名称', align:'center',
|
||||
{field:'resourceName', width:300, title: '流程资源名称', align:'center',
|
||||
templet: function(row) {
|
||||
var rowData = row[this.field];
|
||||
if(typeof(rowData) === 'undefined' || rowData == null || rowData == '') {
|
||||
return '-';
|
||||
}
|
||||
return rowData;
|
||||
return '<a href="javascript:void(0);" lay-event="showXml">'+ rowData +'</a>';
|
||||
}
|
||||
},
|
||||
{field: 'diagramResourceName', width: 80, title: '流程图', align:'center',
|
||||
@ -125,7 +125,7 @@
|
||||
if(!row.deploymentId) {
|
||||
return '-';
|
||||
}
|
||||
var flowChatImg = '<img id="flowChat'+ row.id +'" src="route/activiti/get-process-image/'+ row.deploymentId +'" style="width: 30px; height: 30px;"/>'
|
||||
var flowChatImg = '<img id="flowChat'+ row.id +'" src="route/activiti/model/get-process-image/'+ row.deploymentId +'" style="width: 30px; height: 30px;"/>'
|
||||
setTimeout(function() {
|
||||
new Viewer(document.getElementById('flowChat'+ row.id));
|
||||
}, 50);
|
||||
@ -181,7 +181,15 @@
|
||||
table.on('tool(dataTable)', function(obj) {
|
||||
var data = obj.data;
|
||||
var layEvent = obj.event;
|
||||
if(layEvent === 'nodeEvent') {
|
||||
if(layEvent === 'showXml') {
|
||||
top.dialog.open({
|
||||
url: top.restAjax.path('route/activiti/model/get-process-xml?processDefinitionId={processDefinitionId}', [data.id]),
|
||||
title: '流程XML',
|
||||
width: '80%',
|
||||
height: '95%',
|
||||
onClose: function() {}
|
||||
});
|
||||
} else if(layEvent === 'nodeEvent') {
|
||||
top.dialog.open({
|
||||
url: top.restAjax.path('route/oa/node-field/list-node?deploymentId={deploymentId}', [data.deploymentId]),
|
||||
title: '节点字段管理',
|
||||
|
@ -57,7 +57,7 @@
|
||||
cols: [
|
||||
[
|
||||
{field:'rowNum', width:80, title: '序号', fixed: 'left', align:'center', templet: '<span>{{d.LAY_INDEX}}</span>'},
|
||||
{field:'id', width:150, title: '主键', align:'center',
|
||||
{field:'id', width:300, title: '流程定义ID', align:'center',
|
||||
templet: function(row) {
|
||||
var rowData = row[this.field];
|
||||
if(typeof(rowData) === 'undefined' || rowData == null || rowData == '') {
|
||||
@ -75,7 +75,7 @@
|
||||
return rowData;
|
||||
}
|
||||
},
|
||||
{field:'name', width:150, title: '名称', align:'center',
|
||||
{field:'name', width:200, title: '名称', align:'center',
|
||||
templet: function(row) {
|
||||
var rowData = row[this.field];
|
||||
if(typeof(rowData) === 'undefined' || rowData == null || rowData == '') {
|
||||
@ -84,7 +84,7 @@
|
||||
return rowData;
|
||||
}
|
||||
},
|
||||
{field:'description', width:150, title: '描述', align:'center',
|
||||
{field:'description', width:200, title: '描述', align:'center',
|
||||
templet: function(row) {
|
||||
var rowData = row[this.field];
|
||||
if(typeof(rowData) === 'undefined' || rowData == null || rowData == '') {
|
||||
@ -98,7 +98,7 @@
|
||||
if(!row.deploymentId) {
|
||||
return '-';
|
||||
}
|
||||
var flowChatImg = '<img id="flowChat'+ row.id +'" src="route/activiti/get-process-image/'+ row.deploymentId +'" style="width: 30px; height: 30px;"/>'
|
||||
var flowChatImg = '<img id="flowChat'+ row.id +'" src="route/activiti/model/get-process-image/'+ row.deploymentId +'" style="width: 30px; height: 30px;"/>'
|
||||
setTimeout(function() {
|
||||
new Viewer(document.getElementById('flowChat'+ row.id));
|
||||
}, 50);
|
||||
|
Loading…
Reference in New Issue
Block a user