package com.fredo.process.service.impl;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fredo.auth.service.SysUserService;
import com.fredo.custom.LoginUserInfoHelper;
import com.fredo.model.process.Process;
import com.fredo.model.process.ProcessRecord;
import com.fredo.model.process.ProcessTemplate;
import com.fredo.model.system.SysUser;
import com.fredo.process.mapper.ProcessMapper;
import com.fredo.process.service.ProcessRecordService;
import com.fredo.process.service.ProcessService;
import com.fredo.process.service.ProcessTemplateService;
import com.fredo.vo.process.ApprovalVo;
import com.fredo.vo.process.ProcessFormVo;
import com.fredo.vo.process.ProcessQueryVo;
import com.fredo.vo.process.ProcessVo;
import lombok.extern.slf4j.Slf4j;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.EndEvent;
import org.activiti.bpmn.model.FlowNode;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricTaskInstanceQuery;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;
@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class ProcessServiceImpl extends ServiceImpl<ProcessMapper, Process> implements ProcessService {
@Autowired
private ProcessMapper processMapper;
@Autowired
private RepositoryService repositoryService;
@Autowired
private ProcessTemplateService processTemplateService;
@Autowired
private SysUserService sysUserService;
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
@Autowired
private ProcessRecordService processRecordService;
@Autowired
private HistoryService historyService;
@Override
public IPage<ProcessVo> selectPage(Page<ProcessVo> pageParam, ProcessQueryVo processQueryVo) {
// IPage<ProcessVo> page = processMapper.selectPage(pageParam, processQueryVo);
IPage<ProcessVo> page = baseMapper.selectPage(pageParam, processQueryVo);
return page;
}
@Override
public void deployByZip(String deployPath) {
// 定义zip输入流
InputStream inputStream = this
.getClass()
.getClassLoader()
.getResourceAsStream(deployPath);
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
// 流程部署
Deployment deployment = repositoryService.createDeployment()
.addZipInputStream(zipInputStream)
.deploy();
}
public void startUp(ProcessFormVo processFormVo) {
SysUser sysUser = sysUserService.getById(LoginUserInfoHelper.getUserId());
ProcessTemplate processTemplate = processTemplateService.getById(processFormVo.getProcessTemplateId());
Process process = new Process();
BeanUtils.copyProperties(processFormVo, process);
String workNo = System.currentTimeMillis() + "";
process.setProcessCode(workNo);
process.setUserId(LoginUserInfoHelper.getUserId());
process.setFormValues(processFormVo.getFormValues());
process.setTitle(sysUser.getName() + "发起" + processTemplate.getName() + "申请");
process.setStatus(1);
processMapper.insert(process);
//绑定业务id
String businessKey = String.valueOf(process.getId());
//流程参数
Map<String, Object> variables = new HashMap<>();
//将表单数据放入流程实例中
JSONObject jsonObject = JSON.parseObject(process.getFormValues());
JSONObject formData = jsonObject.getJSONObject("formData");
Map<String, Object> map = new HashMap<>();
//循环转换
for (Map.Entry<String, Object> entry : formData.entrySet()) {
map.put(entry.getKey(), entry.getValue());
}
variables.put("data", map);
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(
processTemplate.getProcessDefinitionKey(), businessKey, variables);
//业务表关联当前流程实例id
String processInstanceId = processInstance.getId();
process.setProcessInstanceId(processInstanceId);
//计算下一个审批人,可能有多个(并行审批)
List<Task> taskList = this.getCurrentTaskList(processInstanceId);
if (!CollectionUtils.isEmpty(taskList)) {
List<String> assigneeList = new ArrayList<>();
for (Task task : taskList) {
SysUser user = sysUserService.getByUsername(task.getAssignee());
assigneeList.add(user.getName());
// TODO 推送消息给下一个审批人,后续完善
}
process.setDescription("等待" + StringUtils.join(assigneeList.toArray(), ",") + "审批");
}
processMapper.updateById(process);
//记录操作行为
processRecordService.record(process.getId(), 1, "发起申请");
}
@Override
public IPage<ProcessVo> findPending(Page<Process> pageParam) {
// 根据当前人的ID查询
TaskQuery query = taskService.createTaskQuery()
.taskAssignee(LoginUserInfoHelper.getUsername())
.orderByTaskCreateTime()
.desc();
List<Task> list = query.listPage((int) ((pageParam.getCurrent() - 1) * pageParam.getSize()),
(int) pageParam.getSize());
long totalCount = query.count();
List<ProcessVo> processList = new ArrayList<>();
// 根据流程的业务ID查询实体并关联
for (Task item : list) {
String processInstanceId = item.getProcessInstanceId();
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
.processInstanceId(processInstanceId).singleResult();
if (processInstance == null) {
continue;
}
// 业务key
String businessKey = processInstance.getBusinessKey();
if (businessKey == null) {
continue;
}
Process process = this.getById(Long.parseLong(businessKey));
ProcessVo processVo = new ProcessVo();
BeanUtils.copyProperties(process, processVo);
processVo.setTaskId(item.getId());
processList.add(processVo);
}
IPage<ProcessVo> page = new Page<>(pageParam.getCurrent(), pageParam.getSize(), totalCount);
page.setRecords(processList);
return page;
}
@Override
public Map<String, Object> show(Long id) {
Process process = this.getById(id);
List<ProcessRecord> processRecordList = processRecordService
.list(new LambdaQueryWrapper<ProcessRecord>()
.eq(ProcessRecord::getProcessId, id));
ProcessTemplate processTemplate = processTemplateService
.getById(process.ge