Przeglądaj źródła

开发审批流程

release_toaliyun_real
luozukai 7 lat temu
rodzic
commit
6954de8c98
22 zmienionych plików z 970 dodań i 261 usunięć
  1. +0
    -255
      mallinkAdmin/src/main/java/com/iformall/controller/FlowAbleController.java
  2. +95
    -0
      mallinkAdmin/src/main/java/com/iformall/controller/WxFlowAbleController.java
  3. +3
    -0
      mallinkAdmin/src/main/java/com/iformall/flowable/ContractTaskFinishHandler.java
  4. +2
    -0
      mallinkAdmin/src/main/resources/application-dev.yml
  5. +3
    -1
      mallinkAdmin/src/main/resources/application-prod.yml
  6. +3
    -1
      mallinkAdmin/src/main/resources/application-test.yml
  7. +3
    -1
      mallinkAdmin/src/main/resources/application.yml
  8. +126
    -0
      mallinkService/src/main/java/com/iformall/domain/po/WxFlowRecord.java
  9. +2
    -2
      mallinkService/src/main/java/com/iformall/domain/po/WxMsgValidationcode.java
  10. +1
    -0
      mallinkService/src/main/java/com/iformall/domain/po/WxRentContract.java
  11. +40
    -0
      mallinkService/src/main/java/com/iformall/enums/EnumFlowRecordStatus.java
  12. +37
    -0
      mallinkService/src/main/java/com/iformall/enums/EnumMsgModelType.java
  13. +12
    -0
      mallinkService/src/main/java/com/iformall/mapper/WxFlowRecordMapper.java
  14. +26
    -0
      mallinkService/src/main/java/com/iformall/service/WxFlowRecordService.java
  15. +58
    -0
      mallinkService/src/main/java/com/iformall/service/WxFlowService.java
  16. +10
    -0
      mallinkService/src/main/java/com/iformall/service/WxMsgValidationcodeService.java
  17. +35
    -0
      mallinkService/src/main/java/com/iformall/service/impl/WxFlowRecordServiceImpl.java
  18. +410
    -0
      mallinkService/src/main/java/com/iformall/service/impl/WxFlowServiceImpl.java
  19. +53
    -0
      mallinkService/src/main/java/com/iformall/service/impl/WxMsgValidationcodeServiceImpl.java
  20. +2
    -0
      mallinkService/src/main/java/com/iformall/service/impl/WxRentContractServiceImpl.java
  21. +48
    -0
      mallinkService/src/main/resources/mapper/WxFlowRecordMapper.xml
  22. +1
    -1
      mallinkService/src/main/resources/mapper/WxRentContractMapper.xml

+ 0
- 255
mallinkAdmin/src/main/java/com/iformall/controller/FlowAbleController.java Wyświetl plik

@@ -1,255 +0,0 @@
package com.iformall.controller;

import com.iformall.common.ResultData;
import com.iformall.domain.po.WxRentContract;
import com.iformall.enums.EnumFlowKey;
import com.iformall.enums.EnumRentContractAppStatus;
import com.iformall.service.WxRentContractService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections.map.HashedMap;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.engine.*;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.task.Comment;
import org.flowable.image.ProcessDiagramGenerator;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;

@RestController
@Api(description = "工作流相关接口")
@RequestMapping(value = "workflow")
public class FlowAbleController extends BaseController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());

@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
@Autowired
private RepositoryService repositoryService;
@Autowired
private ProcessEngine processEngine;
@Autowired
private WxRentContractService wxRentContractService;

/**
* 1合同 2账单
* @param flowType
* @return
*/
public String getFlowKeyByType(int flowType){
if(1 == flowType){
return EnumFlowKey.CONTRACT.getCode();
}else if(2 == flowType){
return EnumFlowKey.BILL.getCode();
}
return null;
}

@ApiOperation("启动流程")
@PostMapping("/start")
public ResultData start(@RequestBody Map<String, String> params) {
logger.debug("[" + getIpAddr() + "] FlowAbleController::start");

try{
//设置发起人
Authentication.setAuthenticatedUserId(super.getUser().getId().toString());
String firstTaskUserId = params.get("firstTaskUserId");
String secondTaskUserId = params.get("secondTaskUserId");
String remark = params.get("remark");
Long businessId = Long.parseLong(params.get("businessId"));
Integer flowType = Integer.parseInt(params.get("flowType"));
HashMap<String, Object> map = new HashMap<>();

// 设置节点处理人
map.put("firstTaskUser", firstTaskUserId);
map.put("secondTaskUser", secondTaskUserId);
// map info
map.put("starterId", super.getUser().getId());
map.put("starter", super.getUser().getName());
map.put("startTime",new Date().getTime());
map.put("remark",remark);
map.put("businessId",businessId);

ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(getFlowKeyByType(flowType), map);
logger.debug("流程启动,流程id:{}",processInstance.getId());

// 合同审核状态改为审核中
WxRentContract wxRentContract = new WxRentContract();
wxRentContract.setId(businessId);
wxRentContract.setApplyStatus(EnumRentContractAppStatus.APPLYING.getCode());
wxRentContractService.updateApplyStatus(wxRentContract);
return new ResultData();
}catch (Exception e){
logger.error("启动流程发生错误",e);
throw new RuntimeException(e);
}finally {
Authentication.setAuthenticatedUserId(null);
}
}

/**
* 用户代办列表
*/
@ApiOperation("用户代办列表")
@PostMapping(value = "/list")
@ResponseBody
public Object list(@RequestBody Map<String, Object> params) {
String userId = (String)params.get("userId");
Integer flowType = (Integer)params.get("flowType");
String flowKey = getFlowKeyByType(flowType);

List<Task> tasks = taskService.createTaskQuery().processDefinitionKey(flowKey).taskCandidateUser(userId).orderByTaskCreateTime().desc().list();
List<Map<String,Object>> result = new ArrayList<>();

for (Task task : tasks) {
Map<String,Object> taskInfoMap = new HashedMap();
taskInfoMap.put("starter",taskService.getVariable(task.getId(),"starter"));
taskInfoMap.put("startTime",taskService.getVariable(task.getId(),"startTime"));
taskInfoMap.put("processInstanceId",task.getProcessInstanceId());
taskInfoMap.put("taskId",task.getId());
result.add(taskInfoMap);
}
return new ResultData(result);
}

/**
* 审批
*/
@ApiOperation("审批")
@PostMapping(value = "apply")
public ResultData apply(@RequestBody Map<String, String> params) {
String taskId = params.get("taskId");
String processInstanceId = params.get("processInstanceId");
String remark = params.get("remark");
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
if (task == null) {
throw new RuntimeException("流程不存在");
}
taskService.addComment(taskId,processInstanceId,remark);
taskService.complete(taskId);

return new ResultData();
}

/**
* 驳回
*/
@ApiOperation("驳回")
@PostMapping(value = "reject")
public ResultData reject(@RequestBody Map<String, String> params) {
String taskId = params.get("taskId");
String processInstanceId = params.get("processInstanceId");
String remark = params.get("remark");
String businessId = params.get("businessId");

taskService.addComment(taskId,processInstanceId,remark);
runtimeService.deleteProcessInstance(processInstanceId, "驳回");

// 修改合同审核状态为驳回
WxRentContract wxRentContract = new WxRentContract();
wxRentContract.setId(Long.parseLong(businessId));
wxRentContract.setApplyStatus(EnumRentContractAppStatus.REJECT.getCode());
wxRentContractService.updateApplyStatus(wxRentContract);

return new ResultData();
}

/**
* 审批记录
*
* @param processInstanceId 流程实例ID
*/
@ApiOperation("审批记录")
@GetMapping(value = "applyHistory")
@ResponseBody
public String applyHistory(String processInstanceId) {
List<HistoricTaskInstance> list = processEngine.getHistoryService()
.createHistoricTaskInstanceQuery()
.processInstanceId(processInstanceId)
.list();
if (list != null && list.size() > 0) {
for (HistoricTaskInstance hti : list) {
System.out.print("taskId:" + hti.getId()+",");
System.out.print("name:" + hti.getName()+",");
System.out.print("pdId:" + hti.getProcessDefinitionId()+",");
System.out.print("assignee:" + hti.getAssignee()+",");
List<Comment> commentList = taskService.getTaskComments(hti.getId());
for (Comment c:commentList) {
System.out.println("备注:"+c.getFullMessage());
}
System.out.println("====================================");
}
}

return "ok!";
}



/**
* 生成流程图
*
* @param processId 任务ID
*/
@GetMapping(value = "processDiagram")
public void genProcessDiagram(HttpServletResponse httpServletResponse, String processId) throws Exception {
ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult();

//流程走完的不显示图
if (pi == null) {
return;
}
Task task = taskService.createTaskQuery().processInstanceId(pi.getId()).singleResult();
//使用流程实例ID,查询正在执行的执行对象表,返回流程实例对象
String InstanceId = task.getProcessInstanceId();
List<Execution> executions = runtimeService
.createExecutionQuery()
.processInstanceId(InstanceId)
.list();

//得到正在执行的Activity的Id
List<String> activityIds = new ArrayList<>();
List<String> flows = new ArrayList<>();
for (Execution exe : executions) {
List<String> ids = runtimeService.getActiveActivityIds(exe.getId());
activityIds.addAll(ids);
}

//获取流程图
BpmnModel bpmnModel = repositoryService.getBpmnModel(pi.getProcessDefinitionId());
ProcessEngineConfiguration engconf = processEngine.getProcessEngineConfiguration();
ProcessDiagramGenerator diagramGenerator = engconf.getProcessDiagramGenerator();
InputStream in = diagramGenerator.generateDiagram(bpmnModel, "png", activityIds, flows, engconf.getActivityFontName(), engconf.getLabelFontName(), engconf.getAnnotationFontName(), engconf.getClassLoader(), 1.0,true);
OutputStream out = null;
byte[] buf = new byte[1024];
int legth = 0;
try {
out = httpServletResponse.getOutputStream();
while ((legth = in.read(buf)) != -1) {
out.write(buf, 0, legth);
}
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}


}

+ 95
- 0
mallinkAdmin/src/main/java/com/iformall/controller/WxFlowAbleController.java Wyświetl plik

@@ -0,0 +1,95 @@
package com.iformall.controller;

import com.iformall.common.ResultData;
import com.iformall.service.WxFlowService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

@RestController
@Api(description = "工作流相关接口")
@RequestMapping(value = "workflow")
public class WxFlowAbleController extends BaseController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());

@Autowired
private WxFlowService wxFlowService;


@ApiOperation(value = "启动流程",notes = "{\"businessId\":\"215315084967149568\",\"businessType\":1,\"remark\":\"意见意见。\",\"taskAssignee\":[{\"taskKey\":\"firstTaskUser\",\"assignee\":204398756307664896},{\"taskKey\":\"secondTaskUser\",\"assignee\":204398756307664896}]}")
@PostMapping("/start")
public ResultData start(@RequestBody Map<String, Object> params) {
logger.debug("[" + getIpAddr() + "] FlowAbleController::start");
return wxFlowService.start(params,super.getUser().getId(),super.getUser().getName(),super.getTenantId());
}

/**
* 用户代办列表
*/
@ApiOperation("用户代办列表")
@GetMapping(value = "/list")
@ApiImplicitParams({
@ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true),
@ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true),
@ApiImplicitParam(name = "flowType", value = "流程类型,1合同流程 2账单流程", dataType = "int", paramType = "query", required = true)
})
public ResultData list(Integer flowType,Integer pageNum, Integer pageSize) {
logger.debug("[" + getIpAddr() + "] FlowAbleController::list");
return wxFlowService.list(flowType,pageNum,pageSize,super.getUser().getId());
}

/**
* 审批历史
*/
@ApiOperation("审批历史")
@GetMapping(value = "/applyHistory")
@ApiImplicitParams({
@ApiImplicitParam(name = "businessId", value = "业务id", dataType = "long", paramType = "query", required = true),
})
public ResultData applyHistory(Long businessId) {
logger.debug("[" + getIpAddr() + "] FlowAbleController::applyHistory");
return wxFlowService.applyHistory(businessId);
}

/**
* 审批
*/
@ApiOperation(value = "审批",notes = "{\"taskId\":\"\",\"processInstanceId\":\"\",\"remark\":\"\"}")
@PostMapping(value = "apply")
public ResultData apply(@RequestBody Map<String, String> params) {
return wxFlowService.apply(params,super.getUser().getId(),super.getUser().getName(),super.getTenantId());
}

/**
* 驳回
*/
@ApiOperation(value = "驳回",notes = "{\"taskId\":\"\",\"processInstanceId\":\"\",\"remark\":\"\"}")
@PostMapping(value = "reject")
public ResultData reject(@RequestBody Map<String, String> params) {
return wxFlowService.reject(params,super.getUser().getId(),super.getUser().getName(),super.getTenantId());
}

/**
* 生成流程图
*
*/
@GetMapping(value = "processDiagram")
@ApiImplicitParams({
@ApiImplicitParam(name = "processInstanceId", value = "流程id", dataType = "String", paramType = "query", required = true)
})
public void genProcessDiagram(HttpServletResponse httpServletResponse, String processInstanceId) throws Exception {
wxFlowService.genProcessDiagram(httpServletResponse,processInstanceId);
}





}

+ 3
- 0
mallinkAdmin/src/main/java/com/iformall/flowable/ContractTaskFinishHandler.java Wyświetl plik

@@ -1,7 +1,10 @@
package com.iformall.flowable;

import com.iformall.domain.po.WxFlowRecord;
import com.iformall.domain.po.WxRentContract;
import com.iformall.enums.EnumFlowRecordStatus;
import com.iformall.enums.EnumRentContractAppStatus;
import com.iformall.service.WxFlowRecordService;
import com.iformall.service.WxRentContractService;
import org.flowable.engine.delegate.TaskListener;
import org.flowable.task.service.delegate.DelegateTask;


+ 2
- 0
mallinkAdmin/src/main/resources/application-dev.yml Wyświetl plik

@@ -55,3 +55,5 @@ logging:
tk.mybatis: debug
com.iformall: debug
path: ./logs/admin

admin-page: http://admin.malls.iformall.com

+ 3
- 1
mallinkAdmin/src/main/resources/application-prod.yml Wyświetl plik

@@ -49,4 +49,6 @@ logging:
level:
tk.mybatis: debug
com.iformall.mapper: debug
path: ./logs/admin
path: ./logs/admin

admin-page: http://admin.malls.iformall.com

+ 3
- 1
mallinkAdmin/src/main/resources/application-test.yml Wyświetl plik

@@ -49,4 +49,6 @@ logging:
level:
tk.mybatis: debug
com.iformall: debug
path: ./logs/admin
path: ./logs/admin

admin-page: http://admin.malls.iformall.com

+ 3
- 1
mallinkAdmin/src/main/resources/application.yml Wyświetl plik

@@ -94,4 +94,6 @@ jasypt:
encryptor:
password: oRqdnDbK5pj3eMmB

version: @project.version@
version: @project.version@

admin-page: http://admin.malls.iformall.com

+ 126
- 0
mallinkService/src/main/java/com/iformall/domain/po/WxFlowRecord.java Wyświetl plik

@@ -0,0 +1,126 @@
package com.iformall.domain.po;

import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;
import java.util.Date;

@Table(name = "wx_flow_record")
public class WxFlowRecord implements Serializable {
private static final long serialVersionUID = 1849242743274278L;

@Id
private Long id;
private Long businessId; //业务id
private Integer businessType;//业务类型 1合同审批2账单审批
private Long userId;//用户id
private String userName;//姓名
private String remark;//审批意见
private Integer status;//状态 1新建2审批3驳回4审批通过
private String taskId;//任务id
private String processInstanceId;//流程实例id
private Date createDate;
private Date updateDate;
private String tenantId;

public WxFlowRecord(){}
public WxFlowRecord(Long businessId){
this.businessId = businessId;
}

public String getTenantId() {
return tenantId;
}

public void setTenantId(String tenantId) {
this.tenantId = tenantId;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public Long getBusinessId() {
return businessId;
}

public void setBusinessId(Long businessId) {
this.businessId = businessId;
}

public Integer getBusinessType() {
return businessType;
}

public void setBusinessType(Integer businessType) {
this.businessType = businessType;
}

public Long getUserId() {
return userId;
}

public void setUserId(Long userId) {
this.userId = userId;
}

public String getRemark() {
return remark;
}

public void setRemark(String remark) {
this.remark = remark;
}

public Integer getStatus() {
return status;
}

public void setStatus(Integer status) {
this.status = status;
}

public String getTaskId() {
return taskId;
}

public void setTaskId(String taskId) {
this.taskId = taskId;
}

public String getProcessInstanceId() {
return processInstanceId;
}

public void setProcessInstanceId(String processInstanceId) {
this.processInstanceId = processInstanceId;
}

public Date getCreateDate() {
return createDate;
}

public void setCreateDate(Date createDate) {
this.createDate = createDate;
}

public Date getUpdateDate() {
return updateDate;
}

public void setUpdateDate(Date updateDate) {
this.updateDate = updateDate;
}
}

+ 2
- 2
mallinkService/src/main/java/com/iformall/domain/po/WxMsgValidationcode.java Wyświetl plik

@@ -48,8 +48,8 @@ public class WxMsgValidationcode implements Serializable {
/***/
@io.swagger.annotations.ApiModelProperty(value="",name="createtime")
private Date createtime;
/*场景 1 登录 2买券 3停车**/
@io.swagger.annotations.ApiModelProperty(value="场景 1 登录 2买券 3停车",name="type")
/*场景 1 登录 2买券 3停车 4审批流通知**/
@io.swagger.annotations.ApiModelProperty(value="场景 1 登录 2买券 3停车 4审批流通知",name="type")
private Integer type;
/***/
@io.swagger.annotations.ApiModelProperty(value="",name="tenantId")


+ 1
- 0
mallinkService/src/main/java/com/iformall/domain/po/WxRentContract.java Wyświetl plik

@@ -180,6 +180,7 @@ public class WxRentContract implements Serializable {
@io.swagger.annotations.ApiModelProperty(value = "起租结束时间", name = "rentalEndDate")
private Date endDate;

//审核状态,0未审核 1审核中 2审核通过 3驳回
@io.swagger.annotations.ApiModelProperty(value = "审核状态", name = "applyStatus")
private Integer applyStatus;



+ 40
- 0
mallinkService/src/main/java/com/iformall/enums/EnumFlowRecordStatus.java Wyświetl plik

@@ -0,0 +1,40 @@
package com.iformall.enums;

/**
* Created by luozukai
*/
public enum EnumFlowRecordStatus {

// 1发起申请2审批通过3审批驳回
NEW(1, "发起申请"),
APPLY(2, "审批通过"),
REJECT(3, "审批驳回"),
ASSIGNEE(4, "待审批")
//FINISH(4, "审批通过")
;

public static EnumFlowRecordStatus getEnum(Integer code) {
for (EnumFlowRecordStatus value : values()) {
if (value.getCode().equals(code)) {
return value;
}
}
return null;
}

private Integer code;
private String message;

EnumFlowRecordStatus(Integer code, String message) {
this.code = code;
this.message = message;
}

public Integer getCode() {
return code;
}

public String getMessage() {
return message;
}
}

+ 37
- 0
mallinkService/src/main/java/com/iformall/enums/EnumMsgModelType.java Wyświetl plik

@@ -0,0 +1,37 @@
package com.iformall.enums;

/**
* Created by luozukai
* 消息模板类型 1登录 2工作流通知
*/
public enum EnumMsgModelType {

LOGIN(1, "登录"),
FLOW(2, "工作流通知")
;

public static EnumMsgModelType getEnum(Integer code) {
for (EnumMsgModelType value : values()) {
if (value.getCode().equals(code)) {
return value;
}
}
return null;
}

private Integer code;
private String message;

EnumMsgModelType(Integer code, String message) {
this.code = code;
this.message = message;
}

public Integer getCode() {
return code;
}

public String getMessage() {
return message;
}
}

+ 12
- 0
mallinkService/src/main/java/com/iformall/mapper/WxFlowRecordMapper.java Wyświetl plik

@@ -0,0 +1,12 @@
package com.iformall.mapper;

import com.iformall.common.CommonMapper;
import com.iformall.domain.po.WxFlowRecord;
import java.util.List;

public interface WxFlowRecordMapper extends CommonMapper<WxFlowRecord, Long> {

List<WxFlowRecord> findList(WxFlowRecord flowRecord);

}

+ 26
- 0
mallinkService/src/main/java/com/iformall/service/WxFlowRecordService.java Wyświetl plik

@@ -0,0 +1,26 @@
package com.iformall.service;

import com.iformall.common.IdWorker;
import com.iformall.domain.po.WxFlowRecord;
import com.iformall.domain.po.WxMsgCallback;

import java.util.List;

/**
* @author luozukai
* 流程审批记录
*/
public interface WxFlowRecordService {

/**
* 查询列表
* @param flowRecord
* @return
*/
List<WxFlowRecord> findList(WxFlowRecord flowRecord);
void saveOrUpdate(WxFlowRecord flowRecord);



}

+ 58
- 0
mallinkService/src/main/java/com/iformall/service/WxFlowService.java Wyświetl plik

@@ -0,0 +1,58 @@
package com.iformall.service;

import com.iformall.common.ResultData;
import org.springframework.web.bind.annotation.RequestBody;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
* @author luozukai
* 流程审批服务
*/
public interface WxFlowService {

/**
* 启动流程
* @param params
* @return
*/
ResultData start(Map<String, Object> params,Long userId,String userName,String tenantId);

/**
* 分页代办列表
* @param flowType
* @param pageNum
* @param pageSize
* @return
*/
ResultData list(Integer flowType,Integer pageNum, Integer pageSize,Long userId);

/**
* 审批历史
* @param businessId
* @return
*/
ResultData applyHistory(Long businessId);

/**
* 审批
* @param params
* @return
*/
ResultData apply(@RequestBody Map<String, String> params,Long userId,String userName,String tenantId);

/**
* 驳回
* @param params
* @return
*/
ResultData reject(@RequestBody Map<String, String> params,Long userId,String userName,String tenantId);

/**
* 生成流程图
* @param httpServletResponse
* @param processInstanceId
* @throws Exception
*/
void genProcessDiagram(HttpServletResponse httpServletResponse, String processInstanceId) throws Exception;
}

+ 10
- 0
mallinkService/src/main/java/com/iformall/service/WxMsgValidationcodeService.java Wyświetl plik

@@ -4,8 +4,18 @@ import com.github.pagehelper.PageInfo;
import com.iformall.common.ResultData;
import com.iformall.domain.po.WxMsgValidationcode;

import java.util.Map;

public interface WxMsgValidationcodeService {

/**
* 发送审批流通知短信
* @param wxMsgValidationcode
* @param dynamicContentMap 动态替换的内容
* @return
*/
ResultData sendWorkFlowNodify(WxMsgValidationcode wxMsgValidationcode, Map<String,String> dynamicContentMap);

/**
* 根据实体查询分页列表
*


+ 35
- 0
mallinkService/src/main/java/com/iformall/service/impl/WxFlowRecordServiceImpl.java Wyświetl plik

@@ -0,0 +1,35 @@
package com.iformall.service.impl;

import com.iformall.common.IdWorker;
import com.iformall.domain.po.WxFlowRecord;
import com.iformall.mapper.WxFlowRecordMapper;
import com.iformall.service.WxFlowRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;

/**
* @author luozukai
* @date 2019/1/8 19:09
*/
@Service
public class WxFlowRecordServiceImpl implements WxFlowRecordService {
@Autowired
private WxFlowRecordMapper wxFlowRecordMapper;

@Override
public List<WxFlowRecord> findList(WxFlowRecord flowRecord) {
return wxFlowRecordMapper.findList(flowRecord);
}

@Override
public void saveOrUpdate(WxFlowRecord record) {
if (record.getId() == null) {
final IdWorker idWorker = IdWorker.get();
record.setId(idWorker.nextId());
wxFlowRecordMapper.insertSelective(record);
} else {
wxFlowRecordMapper.updateByPrimaryKeySelective(record);
}
}
}

+ 410
- 0
mallinkService/src/main/java/com/iformall/service/impl/WxFlowServiceImpl.java Wyświetl plik

@@ -0,0 +1,410 @@
package com.iformall.service.impl;

import com.github.pagehelper.PageInfo;
import com.iformall.common.ResultData;
import com.iformall.domain.po.MallUserInfo;
import com.iformall.domain.po.WxFlowRecord;
import com.iformall.domain.po.WxMsgValidationcode;
import com.iformall.domain.po.WxRentContract;
import com.iformall.enums.EnumFlowKey;
import com.iformall.enums.EnumFlowRecordStatus;
import com.iformall.enums.EnumMsgModelType;
import com.iformall.enums.EnumRentContractAppStatus;
import com.iformall.service.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.map.HashedMap;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.*;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.identitylink.api.IdentityLink;
import org.flowable.image.ProcessDiagramGenerator;
import org.flowable.task.api.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;

/**
* @author luozukai
* @date 2019/1/10 14:59
*/
@Service
public class WxFlowServiceImpl implements WxFlowService {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
@Autowired
private RepositoryService repositoryService;
@Autowired
private ProcessEngine processEngine;
@Autowired
private WxRentContractService wxRentContractService;
@Autowired
private WxFlowRecordService wxFlowRecordService;
@Autowired
private MallUserInfoService mallUserInfoService;
@Autowired
private WxMsgValidationcodeService wxMsgValidationcodeService;
@Value("${admin-page}")
private String adminPage;

/**
* 获取流程key,1合同 2账单
* @param flowType
* @return
*/
public String getFlowKeyByType(int flowType){
if(1 == flowType){
return EnumFlowKey.CONTRACT.getCode();
}else if(2 == flowType){
return EnumFlowKey.BILL.getCode();
}
return null;
}

@Override
public ResultData start(Map<String, Object> params,Long userId,String userName,String tenantId) {
String remark = (String)params.get("remark");
Long businessId = Long.parseLong((String)params.get("businessId"));
Integer flowType = (Integer)params.get("businessType");
List<Map<String,String>> taskAssignee = (List)params.get("taskAssignee");

// 设置节点处理人
HashMap<String, Object> map = new HashMap<>();
for (Map<String,String> taskAssigneeMap : taskAssignee) {
map.put(taskAssigneeMap.get("taskKey"), taskAssigneeMap.get("assignee"));
}
// map info,设置发起人等信息
MallUserInfo starterInfo = this.mallUserInfoService.getById(userId);
map.put("starter", starterInfo);
map.put("startTime",new Date().getTime());
map.put("businessId",businessId);
map.put("flowType",flowType);

ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(getFlowKeyByType(flowType), map);
logger.debug("流程启动,流程id:{}",processInstance.getId());

// 合同审核状态改为审核中
WxRentContract wxRentContract = new WxRentContract();
wxRentContract.setId(businessId);
wxRentContract.setApplyStatus(EnumRentContractAppStatus.APPLYING.getCode());
wxRentContractService.updateApplyStatus(wxRentContract);

// 保存wx_flow_record表审批记录
WxFlowRecord wxFlowRecord = new WxFlowRecord();
wxFlowRecord.setBusinessId(businessId);
wxFlowRecord.setBusinessType(flowType);
wxFlowRecord.setProcessInstanceId(processInstance.getId());
wxFlowRecord.setRemark(remark);
wxFlowRecord.setUserId(userId);
wxFlowRecord.setUserName(userName);
wxFlowRecord.setStatus(EnumFlowRecordStatus.NEW.getCode());
wxFlowRecordService.saveOrUpdate(wxFlowRecord);

// 给审批人发送代办通知短信
List<MallUserInfo> mallUserInfoList = getUserByProcessInstanceId(processInstance.getId());
for (MallUserInfo mallUserInfo:mallUserInfoList) {
Map<String,String> content = new HashedMap();
content.put("userName",mallUserInfo.getName());
content.put("page",adminPage);
content.put("modelName","代办通知");

WxMsgValidationcode wxMsgValidationcode = new WxMsgValidationcode();
wxMsgValidationcode.setTenantId(tenantId);
wxMsgValidationcode.setPhone(mallUserInfo.getPhone());
wxMsgValidationcode.setType(EnumMsgModelType.FLOW.getCode());
wxMsgValidationcodeService.sendWorkFlowNodify(wxMsgValidationcode,content);
}

return new ResultData();
}

@Override
public ResultData list(Integer flowType, Integer pageNum, Integer pageSize,Long userId) {
String flowKey = getFlowKeyByType(flowType);

List<Task> tasks = taskService.createTaskQuery().processDefinitionKey(flowKey)
.taskCandidateUser(userId.toString()).orderByTaskCreateTime().desc().listPage((pageNum -1) * pageSize,pageSize);
List<Map<String,Object>> result = new ArrayList<>();

for (Task task : tasks) {
Map<String,Object> taskInfoMap = new HashedMap();
Map<String,Object> mapInfo = taskService.getVariables(task.getId());
taskInfoMap.put("starter",((MallUserInfo)mapInfo.get("starter")).getName());
taskInfoMap.put("startTime",mapInfo.get("startTime"));
taskInfoMap.put("processInstanceId",task.getProcessInstanceId());
taskInfoMap.put("taskId",task.getId());
taskInfoMap.put("businessId",mapInfo.get("businessId"));
result.add(taskInfoMap);
}
PageInfo<Map<String,Object>> pageInfo = new PageInfo<>(result,pageSize);
return new ResultData(pageInfo);
}

@Override
public ResultData applyHistory(Long businessId) {
List<WxFlowRecord> result = wxFlowRecordService.findList(new WxFlowRecord(businessId));
if(CollectionUtils.isNotEmpty(result)){
String processInstanceId = result.get(0).getProcessInstanceId();
List<MallUserInfo> mallUserInfoList = getUserByProcessInstanceId(processInstanceId);

// 如果有代办,加一条待审批
if(CollectionUtils.isNotEmpty(mallUserInfoList)){
String assignee = "";
for (MallUserInfo mallUserInfo:mallUserInfoList) {
assignee += mallUserInfo.getName()+" ";
}

WxFlowRecord wxFlowRecord = new WxFlowRecord();
wxFlowRecord.setUserName(assignee);
wxFlowRecord.setStatus(EnumFlowRecordStatus.ASSIGNEE.getCode());
result.add(wxFlowRecord);
}
}
return new ResultData(result);
}

@Override
public ResultData apply(Map<String, String> params,Long userId,String userName,String tenantId) {
String taskId = params.get("taskId");
String processInstanceId = params.get("processInstanceId");
String remark = params.get("remark");
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
if (task == null) {
throw new RuntimeException("流程不存在");
}
Map<String,Object> mapInfo = taskService.getVariables(task.getId());
Long businessId = (Long)mapInfo.get("businessId");
Integer flowType = (Integer)mapInfo.get("flowType");
MallUserInfo starter = (MallUserInfo)mapInfo.get("starter");

taskService.complete(taskId);

//保存wx_flow_record表审批记录
WxFlowRecord wxFlowRecord = new WxFlowRecord();
wxFlowRecord.setTaskId(taskId);
wxFlowRecord.setProcessInstanceId(processInstanceId);
wxFlowRecord.setRemark(remark);
wxFlowRecord.setUserId(userId);
wxFlowRecord.setStatus(EnumFlowRecordStatus.APPLY.getCode());
wxFlowRecord.setBusinessId(businessId);
wxFlowRecord.setBusinessType(flowType);
wxFlowRecord.setUserName(userName);
wxFlowRecordService.saveOrUpdate(wxFlowRecord);

// 发送短信
Map<String,String> msgReplaceMap = new HashedMap();
WxMsgValidationcode wxMsgValidationcode = new WxMsgValidationcode();
wxMsgValidationcode.setTenantId(tenantId);
wxMsgValidationcode.setType(EnumMsgModelType.FLOW.getCode());
// 判断流程是否结束
if(!isEnded(processInstanceId)){
String assignee = "";
// 给代办人发送通知短信
List<MallUserInfo> mallUserInfoList = getUserByProcessInstanceId(processInstanceId);
for (MallUserInfo mallUserInfo:mallUserInfoList) {
msgReplaceMap.put("userName",mallUserInfo.getName());
msgReplaceMap.put("page",adminPage);
msgReplaceMap.put("modelName","代办通知");

assignee += mallUserInfo.getName()+" ";
wxMsgValidationcode.setPhone(mallUserInfo.getPhone());
wxMsgValidationcodeService.sendWorkFlowNodify(wxMsgValidationcode,msgReplaceMap);
}

// 给发起人发送短信
msgReplaceMap = new HashedMap();
msgReplaceMap.put("userName",userName);
msgReplaceMap.put("page",adminPage);
msgReplaceMap.put("modelName","审批通知");
msgReplaceMap.put("contract",businessId+"");
msgReplaceMap.put("toUserName",assignee.trim());

wxMsgValidationcode = new WxMsgValidationcode();
wxMsgValidationcode.setPhone(starter.getPhone());
wxMsgValidationcodeService.sendWorkFlowNodify(wxMsgValidationcode,msgReplaceMap);
}else{
// 给发起人发送审批通过消息
msgReplaceMap = new HashedMap();
msgReplaceMap.put("modelName","通过审批通知");
msgReplaceMap.put("contract",businessId+"");
msgReplaceMap.put("page",adminPage);

wxMsgValidationcode = new WxMsgValidationcode();
wxMsgValidationcode.setPhone(starter.getPhone());
wxMsgValidationcodeService.sendWorkFlowNodify(wxMsgValidationcode,msgReplaceMap);
}

return new ResultData();
}

@Override
public ResultData reject(Map<String, String> params,Long userId,String userName,String tenantId) {
String taskId = params.get("taskId");
String processInstanceId = params.get("processInstanceId");
String remark = params.get("remark");

Map<String,Object> mapInfo = taskService.getVariables(taskId);
Long businessId = (Long)mapInfo.get("businessId");
Integer flowType = (Integer)mapInfo.get("flowType");
MallUserInfo starter = (MallUserInfo)mapInfo.get("starter");

runtimeService.deleteProcessInstance(processInstanceId, "驳回");

// 修改合同审核状态为驳回
WxRentContract wxRentContract = new WxRentContract();
wxRentContract.setId(businessId);
wxRentContract.setApplyStatus(EnumRentContractAppStatus.REJECT.getCode());
wxRentContractService.updateApplyStatus(wxRentContract);

//保存wx_flow_record表审批记录
WxFlowRecord wxFlowRecord = new WxFlowRecord();
wxFlowRecord.setBusinessId(businessId);
wxFlowRecord.setTaskId(taskId);
wxFlowRecord.setProcessInstanceId(processInstanceId);
wxFlowRecord.setRemark(remark);
wxFlowRecord.setUserId(userId);
wxFlowRecord.setStatus(EnumFlowRecordStatus.REJECT.getCode());
wxFlowRecord.setBusinessType(flowType);
wxFlowRecord.setUserName(userName);
wxFlowRecordService.saveOrUpdate(wxFlowRecord);

// 给发起人发送驳回消息
Map<String,String> msgReplaceMap = new HashedMap();
WxMsgValidationcode wxMsgValidationcode = new WxMsgValidationcode();
wxMsgValidationcode.setTenantId(tenantId);
wxMsgValidationcode.setType(EnumMsgModelType.FLOW.getCode());
msgReplaceMap.put("modelName","驳回通知");
msgReplaceMap.put("contract",businessId+"");
msgReplaceMap.put("page",adminPage);

wxMsgValidationcode = new WxMsgValidationcode();
wxMsgValidationcode.setPhone(starter.getPhone());
wxMsgValidationcodeService.sendWorkFlowNodify(wxMsgValidationcode,msgReplaceMap);
return new ResultData();
}

/**
* 判断流程是否结束
* @param processInstanceId
* @return
*/
public boolean isEnded(String processInstanceId) {
RuntimeService runtimeService = processEngine.getRuntimeService();
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
if(processInstance == null){
return true;
}
return processInstance.isEnded();
}

/**
* 根据流程实例id获取当前节点的代办人信息
* @return
*/
public List<MallUserInfo> getUserByProcessInstanceId(String processInstanceId){
List<MallUserInfo> result = new ArrayList<>();
List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstanceId).orderByTaskCreateTime().desc().list();
if(CollectionUtils.isNotEmpty(tasks)){
for (Task task:tasks) {
List<String> userIdList = getTaskCandidateUserId(task.getId());
for (String userId:userIdList) {
MallUserInfo mallUserInfo = this.mallUserInfoService.getById(Long.parseLong(userId));
result.add(mallUserInfo);
}
}
}
return result;
}

/**
* 获得任务中的候选人
* @param taskId
* @return
*/
private List<String> getTaskCandidateUserId(String taskId) {
List<String> userIdList = new ArrayList<>();
List identityLinkList = taskService.getIdentityLinksForTask(taskId);
if (identityLinkList != null && identityLinkList.size() > 0) {
for (Iterator iterator = identityLinkList.iterator(); iterator.hasNext();) {
IdentityLink identityLink = (IdentityLink) iterator.next();
if (identityLink.getUserId() != null) {
userIdList.add(identityLink.getUserId());
}
// if (identityLink.getGroupId() != null) {
// // 根据组获得对应人员
// List userList = identityService.createUserQuery()
// .memberOfGroup(identityLink.getGroupId()).list();
// if (userList != null && userList.size() > 0)
// users.addAll(userList);
// }
}
}
return userIdList;
}



@Override
public void genProcessDiagram(HttpServletResponse httpServletResponse, String processInstanceId) throws Exception {
ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();

//流程走完的不显示图
if (pi == null) {
return;
}
Task task = taskService.createTaskQuery().processInstanceId(pi.getId()).singleResult();
//使用流程实例ID,查询正在执行的执行对象表,返回流程实例对象
String InstanceId = task.getProcessInstanceId();
List<Execution> executions = runtimeService
.createExecutionQuery()
.processInstanceId(InstanceId)
.list();

//得到正在执行的Activity的Id
List<String> activityIds = new ArrayList<>();
List<String> flows = new ArrayList<>();
for (Execution exe : executions) {
List<String> ids = runtimeService.getActiveActivityIds(exe.getId());
activityIds.addAll(ids);
}

//获取流程图
BpmnModel bpmnModel = repositoryService.getBpmnModel(pi.getProcessDefinitionId());
ProcessEngineConfiguration engconf = processEngine.getProcessEngineConfiguration();
ProcessDiagramGenerator diagramGenerator = engconf.getProcessDiagramGenerator();
InputStream in = diagramGenerator.generateDiagram(bpmnModel, "png", activityIds, flows, engconf.getActivityFontName(), engconf.getLabelFontName(), engconf.getAnnotationFontName(), engconf.getClassLoader(), 1.0,true);
OutputStream out = null;
byte[] buf = new byte[1024];
int legth = 0;
try {
out = httpServletResponse.getOutputStream();
while ((legth = in.read(buf)) != -1) {
out.write(buf, 0, legth);
}
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}

public String getAdminPage() {
return adminPage;
}

public void setAdminPage(String adminPage) {
this.adminPage = adminPage;
}
}

+ 53
- 0
mallinkService/src/main/java/com/iformall/service/impl/WxMsgValidationcodeServiceImpl.java Wyświetl plik

@@ -48,6 +48,59 @@ public class WxMsgValidationcodeServiceImpl implements WxMsgValidationcodeServic
@Autowired
WxMsgCallbackMapper wxMsgCallbackMapper;

@Override
public ResultData sendWorkFlowNodify(WxMsgValidationcode wxMsgValidationcode,Map<String,String> dynamicContentMap) {
//3、从短信配置中查询密钥 bid 等信息
WxMsgConfig wxMsgConfig = new WxMsgConfig();
wxMsgConfig.setTenantId(wxMsgValidationcode.getTenantId());
List<WxMsgConfig> wxMsgConfigs = wxMsgConfigMapper.findList(wxMsgConfig);
if (wxMsgConfigs.size() == 0) new ResultData(ErrorCode.MSG_SEND_ERROR.getCode(),"发送失败");
wxMsgConfig = wxMsgConfigs.get(0);

WxMsgValidationcodeModel wxMsgValidationcodeModel = new WxMsgValidationcodeModel();
wxMsgValidationcodeModel.setTenantId(wxMsgConfig.getTenantId());
wxMsgValidationcodeModel.setType(wxMsgValidationcode.getType());
wxMsgValidationcodeModel.setName(dynamicContentMap.get("modelName"));
wxMsgValidationcodeModel = wxMsgValidationcodeModelMapper.findList(wxMsgValidationcodeModel).get(0);
wxMsgValidationcode.setSignature(wxMsgValidationcodeModel.getSignature());

String secret = wxMsgConfig.getSecret();
String bid = wxMsgConfig.getBid();
String publickey = wxMsgConfig.getPublickey();
// 验证码
String phone = wxMsgValidationcode.getPhone();
String signature = wxMsgValidationcode.getSignature();
//替换内容
String msg = wxMsgValidationcodeModel.getContent();
for (Map.Entry<String, String> entry : dynamicContentMap.entrySet()) {
msg = msg.replace("{"+entry.getKey()+"}", entry.getValue());
}

// wxMsgValidationcode.setCode(String.valueOf(code));
wxMsgValidationcode.setMsg(msg);

String notifyUrl = wxMsgConfig.getNotifyurl();
String result = WiwideUtil.sendMsg(secret, bid, publickey, phone, signature, msg, notifyUrl, EnumVerifyCode.YES.getCode().toString());
JSONObject jsonObjectResult = JSONObject.parseObject(result);
String ret = jsonObjectResult.get("ret").toString();
String batchNo = jsonObjectResult.get("data").toString();
if (ret.equals("1")) {
final IdWorker idWorker = IdWorker.get();
wxMsgValidationcode.setId(idWorker.nextId());
long currentTime = System.currentTimeMillis() ;
Date createtime=new Date(currentTime);
// Integer minutes = wxMsgValidationcodeModel.getMinutes();
// currentTime +=minutes*60*1000;
// Date expiredate=new Date(currentTime);
// wxMsgValidationcode.setExpiretime(expiredate);
wxMsgValidationcode.setCreatetime(createtime);
wxMsgValidationcodeMapper.insertSelective(wxMsgValidationcode);
addMsgCallback(wxMsgValidationcode,batchNo);
return new ResultData(Result.SUCCESS,"发送成功");
}
return new ResultData(ErrorCode.MSG_SEND_ERROR.getCode(),"发送失败");
}

@Override
public PageInfo<WxMsgValidationcode> listAsPage(WxMsgValidationcode record, Integer pageIndex, Integer pageSize) {
return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxMsgValidationcodeMapper.findList(record));


+ 2
- 0
mallinkService/src/main/java/com/iformall/service/impl/WxRentContractServiceImpl.java Wyświetl plik

@@ -111,6 +111,8 @@ public class WxRentContractServiceImpl implements WxRentContractService {
} else {
result.put("wxShops", Collections.EMPTY_LIST);
}
//设置审批流程状态
result.put("applyStatus", wxRentContract.getApplyStatus());
return new ResultData(Result.SUCCESS, "查询成功", result);
}



+ 48
- 0
mallinkService/src/main/resources/mapper/WxFlowRecordMapper.xml Wyświetl plik

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.iformall.mapper.WxFlowRecordMapper">

<resultMap id="BaseResultMap" type="com.iformall.domain.po.WxFlowRecord">
<id column="id" property="id" />
<result column="business_id" property="businessId" />
<result column="business_type" property="businessType" />
<result column="user_id" property="userId" />
<result column="remark" property="remark" />
<result column="status" property="status" />
<result column="task_id" property="taskId" />
<result column="process_instance_id" property="processInstanceId" />
<result column="create_date" property="createDate" />
<result column="update_date" property="updateDate" />
<result column="tenant_id" property="tenantId" />
<result column="user_name" property="userName" />
</resultMap>
<sql id="allColumns">
`id`,`business_id`,`business_type`,`user_id`,`remark`,`status`,`task_id`,`process_instance_id`,`create_date`,`update_date`,`tenant_id`,`user_name`
</sql>

<sql id="dynamicWhereConditions">
where 1 = 1
<if test=" null != id ">
and `id` = #{id}
</if>
<if test=" null != tenantId ">
and `tenant_id` like concat('%', #{tenantId},'%')
</if>
<if test=" null != businessId ">
and `business_id` = #{businessId}
</if>
order by create_date desc
</sql>
<select id="findList" parameterType="com.iformall.domain.po.MallRole" resultMap="BaseResultMap">
select <include refid="allColumns" /> from wx_flow_record
<include refid="dynamicWhereConditions" />
</select>

</mapper>

+ 1
- 1
mallinkService/src/main/resources/mapper/WxRentContractMapper.xml Wyświetl plik

@@ -100,7 +100,7 @@
select rc.id,rc.merchant_name merchantName,rc.rental_start_date rentalStartDate,rc.rental_end_date rentalEndDate,rc.`status`,
rc.price,rc.contract_number contractNumber,s.shop_number shopNumber,f.floor_name floorName,b.building_name buildingName,
rc.lease,rc.filepath,rc.filename,rc.pay_account payAccount,rc.sign_date signDate,rc.merchant_id merchantId,rc.type,
rc.start_date startDate,rc.end_date endDate,br.`name` brandName
rc.start_date startDate,rc.end_date endDate,br.`name` brandName,rc.apply_status applyStatus
from wx_rent_contract rc
left join wx_shop s on rc.shop_id=s.id
left join wx_mall_floor f on s.floor=f.id


Ładowanie…
Anuluj
Zapisz