diff --git a/slife-activiti/src/main/java/com.slife/controller/ProcessController.java b/slife-activiti/src/main/java/com.slife/controller/ProcessController.java new file mode 100644 index 0000000..77e2179 --- /dev/null +++ b/slife-activiti/src/main/java/com.slife/controller/ProcessController.java @@ -0,0 +1,77 @@ +package com.slife.controller; + +import com.slife.base.entity.ReturnDTO; +import com.slife.base.vo.DataTable; +import com.slife.enums.HttpCodeEnum; +import com.slife.exception.SlifeException; +import com.slife.service.ProcessService; +import com.slife.util.ReturnDTOUtil; +import com.slife.vo.ProcessVO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.InputStream; + +/** + * @author: felix. + * @createTime: 2017/12/11. + */ +@Controller +@RequestMapping("/process") +@Api(description = "流程实例的前端控制器") +public class ProcessController { + + @Autowired + ProcessService processService; + + @ApiOperation(value = "进入流程管理页面", notes = "进入流程管理页面") + @GetMapping(value = "") + public String list(org.springframework.ui.Model model, HttpServletRequest request) { + model.addAttribute("url", request.getContextPath()+"/process/"); + return "process/list"; + } + + @ApiOperation(value = "获取流程列表数据", notes = "获取流程列表数据:使用约定的DataTable") + @PostMapping(value = "/list") + @ResponseBody + public DataTable list(@RequestBody DataTable dt) { + if (null == dt) { + return null; + } + return processService.getProcessByPage(dt); + } + + @ApiOperation(value = "读取xml/image资源", notes = "resType为xml或者image") + @GetMapping(value = "/resource") + public void resourceRead(String procDefId, String proInsId, String resType, HttpServletResponse response) { + if ("xml".equals(resType)) { + response.setContentType("application/xml"); + } else { + response.setContentType("image/png"); + } + + try { + InputStream resourceAsStream = processService.resourceRead(procDefId, proInsId, resType); + byte[] b = new byte[1024]; + int len = -1; + while ((len = resourceAsStream.read(b, 0, 1024)) != -1) { + response.getOutputStream().write(b, 0, len); + } + } catch (Exception e) { + throw new SlifeException(HttpCodeEnum.FAIL); + } + } + + @ApiOperation(value = "激活/挂起", notes = "active为激活,suspend为挂起") + @PostMapping("/status") + @ResponseBody + public ReturnDTO updateState(@RequestParam String status, @RequestParam String procDefId) { + processService.updateStatus(status, procDefId); + return ReturnDTOUtil.success(); + } +} diff --git a/slife-activiti/src/main/java/com.slife/service/ModelService.java b/slife-activiti/src/main/java/com.slife/service/ModelService.java index 7a2a398..0762f9e 100644 --- a/slife-activiti/src/main/java/com.slife/service/ModelService.java +++ b/slife-activiti/src/main/java/com.slife/service/ModelService.java @@ -24,7 +24,7 @@ import java.io.UnsupportedEncodingException; import java.util.List; /** - * @author: felixu. + * @author: felix. * @createTime: 2017/11/26. */ @Service diff --git a/slife-activiti/src/main/java/com.slife/service/ProcessService.java b/slife-activiti/src/main/java/com.slife/service/ProcessService.java new file mode 100644 index 0000000..b68d47c --- /dev/null +++ b/slife-activiti/src/main/java/com.slife/service/ProcessService.java @@ -0,0 +1,84 @@ +package com.slife.service; + +import com.slife.base.vo.DataTable; +import com.slife.utils.ActivitiUtils; +import com.slife.vo.ProcessVO; +import org.activiti.engine.HistoryService; +import org.activiti.engine.RepositoryService; +import org.activiti.engine.RuntimeService; +import org.activiti.engine.repository.Deployment; +import org.activiti.engine.repository.ProcessDefinition; +import org.activiti.engine.repository.ProcessDefinitionQuery; +import org.activiti.engine.runtime.ProcessInstance; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.InputStream; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author: felix. + * @createTime: 2017/12/11. + */ +@Service +public class ProcessService { + + @Autowired + private RepositoryService repositoryService; + + @Autowired + private RuntimeService runtimeService; + + public DataTable getProcessByPage(DataTable dt) { + ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery().latestVersion(); + String category = (String) dt.getSearchParams().get("category"); + if (StringUtils.isNotBlank(category)){ + query.processDefinitionCategory(category); + } + dt.setTotal(((Long)query.count()).intValue()); + query.listPage((dt.getPageNumber() - 1) * dt.getPageSize(), dt.getPageSize()) + .stream() + .forEach(processDefinition -> { + Deployment deployment = repositoryService.createDeploymentQuery() + .deploymentId(processDefinition.getDeploymentId()).singleResult(); + dt.getRows().add(ActivitiUtils.toProcessVO(processDefinition, deployment)); + }); + dt.setRows((List) dt.getRows() + .stream() + .sorted(Comparator.comparing(ProcessVO::getDeploymentTime).reversed()) + .collect(Collectors.toList())); + return dt; + } + + public InputStream resourceRead(String procDefId, String proInsId, String resType) throws Exception { + + if (StringUtils.isBlank(procDefId)){ + ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(proInsId).singleResult(); + procDefId = processInstance.getProcessDefinitionId(); + } + ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(procDefId).singleResult(); + + String resourceName = ""; + if (resType.equals("image")) { + resourceName = processDefinition.getDiagramResourceName(); + } else if (resType.equals("xml")) { + resourceName = processDefinition.getResourceName(); + } + + InputStream resourceAsStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), resourceName); + return resourceAsStream; + } + + @Transactional(readOnly = false) + public String updateStatus(String status, String procDefId) { + if (status.equals("active")) { + repositoryService.activateProcessDefinitionById(procDefId, true, null); + } else if (status.equals("suspend")) { + repositoryService.suspendProcessDefinitionById(procDefId, true, null); + } + return status; + } +} diff --git a/slife-activiti/src/main/java/com.slife/utils/ActivitiUtils.java b/slife-activiti/src/main/java/com.slife/utils/ActivitiUtils.java new file mode 100644 index 0000000..f642f2d --- /dev/null +++ b/slife-activiti/src/main/java/com.slife/utils/ActivitiUtils.java @@ -0,0 +1,161 @@ +package com.slife.utils; + +import com.slife.enums.HttpCodeEnum; +import com.slife.exception.SlifeException; +import com.slife.vo.ProcessVO; +import org.activiti.engine.repository.Deployment; +import org.activiti.engine.repository.ProcessDefinition; +import java.util.HashMap; +import java.util.Map; +/** + * @author: xufei. + * @createTime: 2017/8/11. + */ +public class ActivitiUtils { + +// static UserDetailDao userDetailDao = Application.getBean(UserDetailDao.class); +// +// static UserServiceClient userServiceClient = Application.getBean(UserServiceClient.class); +// +// static HistoryService historyService = Application.getBean(HistoryService.class); + + /** + * 获取用户信息 + * @param userId + * @return + */ +// public static UserInfo getUserInfo(String userId) { +// if (userDetailDao.has(userId)) { +// return parseUserInfo(userDetailDao.get(userId)); +// } +// RespDTO resp = userServiceClient.getUser(userId); +// return Optional.ofNullable(resp.data) +// .map(data -> { +// userDetailDao.set(JSON.toJSONString(data), userId); +// return parseUserInfo(JSON.toJSONString(data)); +// }) +// .orElseThrow(() ->new TaiChiException(ErrorCode.FAIL, "get user from user service error")); +// } + +// private static UserInfo parseUserInfo(String json) { +// return JSON.parseObject(json, UserInfo.class); +// } + +// /** +// * 删除缓存 +// * @param userId +// */ +// public static void delUserCache(String userId) { +// if (userDetailDao.has(userId)) { +// userDetailDao.del(userId); +// } +// } + + /** + * 节点对应的中文名称 + * @param type + * @return + */ + public static String parseToZhType(String type) { + Map types = new HashMap(); + types.put("userTask", "用户任务"); + types.put("serviceTask", "系统任务"); + types.put("startEvent", "开始节点"); + types.put("endEvent", "结束节点"); + types.put("exclusiveGateway", "条件判断节点(系统自动根据条件处理)"); + types.put("inclusiveGateway", "并行处理任务"); + types.put("callActivity", "子流程"); + return types.get(type) == null ? type : types.get(type); + } + + /** + * 将dto转为activiti的entity + * @param role + * @return + */ +// public static GroupEntity toActivitiGroup(SysRoleDTO role){ +// GroupEntity groupEntity = new GroupEntity(); +// groupEntity.setId(role.getRoleId()); +// groupEntity.setName(role.getName()); +// groupEntity.setType(role.getType() + ""); +// groupEntity.setRevision(1); +// return groupEntity; +// } + + /** + * 将dto转为activiti的entity + * @param user + * @return + */ +// public static UserEntity toActivitiUser(SysUserDTO user){ +// UserEntity userEntity = new UserEntity(); +// userEntity.setId(user.getUserId()); +// userEntity.setFirstName(user.getRealname()); +// userEntity.setLastName(StringUtils.EMPTY); +// userEntity.setPassword(user.getPassword()); +// userEntity.setEmail(user.getEmail()); +// userEntity.setRevision(1); +// return userEntity; +// } + + /** + * 抽取流程实例需要返回的内容 + * @param processDefinition + * @param deployment + * @return + */ + public static ProcessVO toProcessVO(ProcessDefinition processDefinition, Deployment deployment) { + if (null == processDefinition || null == deployment) { + throw new SlifeException(HttpCodeEnum.INVALID_REQUEST); + } + ProcessVO dto = new ProcessVO(); + dto.category = processDefinition.getCategory(); + dto.processonDefinitionId = processDefinition.getId(); + dto.key = processDefinition.getKey(); + dto.name = deployment.getName(); + dto.revision = processDefinition.getVersion(); + dto.deploymentTime = deployment.getDeploymentTime().getTime(); + dto.xmlName = processDefinition.getResourceName(); + dto.picName = processDefinition.getDiagramResourceName(); + dto.deploymentId = deployment.getId(); + dto.suspend = processDefinition.isSuspended(); + dto.description = processDefinition.getDescription(); + return dto; + } + +// public static TaskDTO toTaskDTO(TaskInfo task, String status, ProcessDefinition processDefinition, Deployment deployment) { +// TaskDTO dto = new TaskDTO(); +// dto.setTaskId(task.getId()); +// dto.setTaskName(task.getName()); +//// dto.setTime(historyService.createHistoricProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult().getStartTime().getTime()); +// dto.setVariable(task.getTaskLocalVariables()); +// dto.setPdName(deployment.getName()); +// dto.setVersion("V:" + processDefinition.getVersion()); +// dto.setProcessInstanceId(task.getProcessInstanceId()); +// dto.setStatus(status); +// dto.setTitle((String) task.getProcessVariables().get("title")); +// dto.setNodeKey(task.getTaskDefinitionKey()); +// dto.setProcessDefKey(processDefinition.getKey()); +// return dto; +// } + +// public static TaskListDTO toTaskListDTO(PageResultsDTO dto, String category) { +// TaskListDTO taskList = new TaskListDTO(); +// taskList.setCategory(category); +// taskList.setPage(dto.page); +// taskList.setPageSize(dto.pageSize); +// taskList.setTotalCount((int) dto.totalCount); +// taskList.setTasks(dto.getList()); +// return taskList; +// } +// +// public static TaskListDTO toTaskListDTO(List tasks, String category, int page, int pageSize, long totalCount) { +// TaskListDTO taskList = new TaskListDTO(); +// taskList.setCategory(category); +// taskList.setPage(page); +// taskList.setPageSize(pageSize); +// taskList.setTotalCount((int) totalCount); +// taskList.setTasks(tasks); +// return taskList; +// } +} \ No newline at end of file diff --git a/slife-activiti/src/main/java/com.slife/vo/ProcessVO.java b/slife-activiti/src/main/java/com.slife/vo/ProcessVO.java new file mode 100644 index 0000000..9d6e5b4 --- /dev/null +++ b/slife-activiti/src/main/java/com.slife/vo/ProcessVO.java @@ -0,0 +1,108 @@ +package com.slife.vo; + +/** + * @author: felix. + * @createTime: 2017/12/11. + */ +public class ProcessVO { + + public String category; + public String processonDefinitionId; + public String key; + public String name; + public Integer revision; + public Long deploymentTime; + public String xmlName; + public String picName; + public String deploymentId; + public Boolean suspend; + public String description; + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Boolean getSuspend() { + return suspend; + } + + public void setSuspend(Boolean suspend) { + this.suspend = suspend; + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + public String getProcessonDefinitionId() { + return processonDefinitionId; + } + + public void setProcessonDefinitionId(String processonDefinitionId) { + this.processonDefinitionId = processonDefinitionId; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getRevision() { + return revision; + } + + public void setRevision(Integer revision) { + this.revision = revision; + } + + public Long getDeploymentTime() { + return deploymentTime; + } + + public void setDeploymentTime(Long deploymentTime) { + this.deploymentTime = deploymentTime; + } + + public String getXmlName() { + return xmlName; + } + + public void setXmlName(String xmlName) { + this.xmlName = xmlName; + } + + public String getPicName() { + return picName; + } + + public void setPicName(String picName) { + this.picName = picName; + } + + public String getDeploymentId() { + return deploymentId; + } + + public void setDeploymentId(String deploymentId) { + this.deploymentId = deploymentId; + } +} diff --git a/slife-activiti/src/main/resources/static/editor-app/configuration/toolbar-default-actions.js b/slife-activiti/src/main/resources/static/editor-app/configuration/toolbar-default-actions.js index 1279527..80626fb 100644 --- a/slife-activiti/src/main/resources/static/editor-app/configuration/toolbar-default-actions.js +++ b/slife-activiti/src/main/resources/static/editor-app/configuration/toolbar-default-actions.js @@ -261,7 +261,7 @@ KISBPM.TOOLBAR = { }, closeEditor: function(services) { - window.location.href = "/model-list.html"; + window.location.href = "/model"; }, /** @@ -326,7 +326,7 @@ var SaveModelCtrl = [ '$rootScope', '$scope', '$http', '$route', '$location', $scope.saveAndClose = function () { $scope.save(function() { - window.location.href = "/model-list.html"; + window.location.href = "/model"; }); }; $scope.save = function (successCallback) { diff --git a/slife-activiti/src/main/resources/templates/model/list.ftl b/slife-activiti/src/main/resources/templates/model/list.ftl index 078ffa0..653206d 100644 --- a/slife-activiti/src/main/resources/templates/model/list.ftl +++ b/slife-activiti/src/main/resources/templates/model/list.ftl @@ -108,6 +108,12 @@ } load_data( getcolumns(), {"createDate": "desc"}); + function dt_edit_model_button(row) { + var uri = url.substring(0, url.length - 1); + var editO = ' '; + return editO; + } + function dt_doploy_button(row) { var editO = ' '; diff --git a/slife-activiti/src/main/resources/templates/process/list.ftl b/slife-activiti/src/main/resources/templates/process/list.ftl new file mode 100644 index 0000000..9a9a87b --- /dev/null +++ b/slife-activiti/src/main/resources/templates/process/list.ftl @@ -0,0 +1,140 @@ + + + + 模型管理 + + + + + + + + +
+
+
+
+ +
+ + + + +
+ + +
+ +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/slife-common/src/main/java/com/slife/base/vo/DataTable.java b/slife-common/src/main/java/com/slife/base/vo/DataTable.java index 91145e9..01b5036 100644 --- a/slife-common/src/main/java/com/slife/base/vo/DataTable.java +++ b/slife-common/src/main/java/com/slife/base/vo/DataTable.java @@ -22,7 +22,7 @@ public class DataTable implements Serializable { /** * 返回列表 */ - private List rows; + private List rows = new ArrayList<>(); /** * 排序 条件 diff --git a/slife-web/src/main/java/com/slife/config/sitemesh/WebSiteMeshFilter.java b/slife-web/src/main/java/com/slife/config/sitemesh/WebSiteMeshFilter.java index c10bbbf..954427c 100644 --- a/slife-web/src/main/java/com/slife/config/sitemesh/WebSiteMeshFilter.java +++ b/slife-web/src/main/java/com/slife/config/sitemesh/WebSiteMeshFilter.java @@ -15,7 +15,7 @@ public class WebSiteMeshFilter extends ConfigurableSiteMeshFilter { /** 需要装饰的访问路径 */ private String contentPath="/sys/user,/sys/menu,/sys/dict,/sys/role,/sys/office,/sys/,/index,/monitor/*," + - "/blog/content**,/404,/model"; + "/blog/content**,/404,/model,/process"; /** 装饰器页面路径 */ diff --git a/slife-web/src/main/resources/static/js/slife/datatable.js b/slife-web/src/main/resources/static/js/slife/datatable.js index f6b9ece..6ccf5b3 100644 --- a/slife-web/src/main/resources/static/js/slife/datatable.js +++ b/slife-web/src/main/resources/static/js/slife/datatable.js @@ -209,16 +209,6 @@ function dt_edit_button(row) { return editO; } -/** - * 编辑 按钮 - * @returns {string} - */ -function dt_edit_model_button(row) { - var uri = url.substring(0, url.length - 1); - var editO = ' '; - return editO; -} - /** * 详情按钮 * @returns {*}