feat: 企标立项/变更流程

This commit is contained in:
2023-10-11 13:47:36 +08:00
parent 745f7d4a1f
commit 3e10e06618
12 changed files with 937 additions and 2 deletions
@@ -0,0 +1,131 @@
package com.jero.modules.activiti.process.common.service;
import com.jero.common.exception.JeroBootException;
import com.jero.common.system.api.ISysBaseAPI;
import com.jero.modules.activiti.util.SpringContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@Service
@Transactional
public class ActFlowCommonService {
@Resource
private RepositoryService repositoryService;
@Resource
private RuntimeService runtimeService;
@Resource
private TaskService taskService;
@Resource
private HistoryService historyService;
@Resource
private ISysBaseAPI sysBaseApi;
/**
* 启动流程实例
*/
public ProcessInstance startProcess(String formKey, String beanName, String businessKey, String id) {
IActFlowCustomService customService = (IActFlowCustomService) SpringContextUtil.getBean(beanName);
// 修改业务的状态
customService.startRunTask(id);
Map<String, Object> variables = customService.setVariables(id);
variables.put("businessKey", businessKey);
// 启动流程
log.info("【启动流程】,formKey {},businessKey:{}", formKey, businessKey);
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(formKey, businessKey, variables);
// 流程实例ID
String processDefinitionId = processInstance.getProcessDefinitionId();
log.info("【启动流程】- 成功,processDefinitionId{}", processDefinitionId);
return processInstance;
}
/**
* 完成提交任务
*/
public void completeTask(String remark, String taskId, String userId) {
//任务Id 查询任务对象
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
if (task == null) {
log.error("completeProcess - task is null!!");
throw new JeroBootException("找不到对应任务");
}
//任务对象 获取流程实例Id
String processInstanceId = task.getProcessInstanceId();
//设置审批人的userId
Authentication.setAuthenticatedUserId(userId);
//添加记录
taskService.addComment(taskId, processInstanceId, remark);
log.info("-----------完成任务操作 开始----------");
log.info("任务Id=" + taskId);
log.info("负责人id=" + userId);
log.info("流程实例id=" + processInstanceId);
//完成办理
taskService.complete(taskId);
log.info("-----------完成任务操作 结束----------");
}
/**
* 查看个人任务列表
*/
public List<Map<String, Object>> myTaskList(String userid) {
TaskQuery taskQuery = taskService.createTaskQuery().taskAssignee(userid);
List<Task> list = taskQuery.orderByTaskCreateTime().desc().list();
List<Map<String, Object>> listMap = new ArrayList<>();
for (Task task : list) {
Map<String, Object> map = new HashMap<>();
map.put("taskId", task.getId());
map.put("taskName", task.getName());
map.put("description", task.getDescription());
map.put("priority", task.getPriority());
map.put("owner", task.getOwner());
map.put("assignee", task.getAssignee());
map.put("delegationState", task.getDelegationState());
map.put("processInstanceId", task.getProcessInstanceId());
map.put("executionId", task.getExecutionId());
map.put("processDefinitionId", task.getProcessDefinitionId());
map.put("createTime", task.getCreateTime());
map.put("taskDefinitionKey", task.getTaskDefinitionKey());
map.put("dueDate", task.getDueDate());
map.put("category", task.getCategory());
map.put("parentTaskId", task.getParentTaskId());
map.put("tenantId", task.getTenantId());
listMap.add(map);
}
return listMap;
}
/**
* 转办
*/
public void transfer(String taskId, String userId) {
taskService.setAssignee(taskId, userId);
log.info("转办 任务Id:{} 转办用户Id{}", taskId, userId);
}
}
@@ -0,0 +1,31 @@
package com.jero.modules.activiti.process.common.service;
import java.util.Map;
/**
* 业务service 的接口 必须实现接口 实现其方法
*/
public interface IActFlowCustomService {
/**
* 设置流程变量
* @param id
* @return
*/
Map<String, Object> setVariables(String id);
/**
* 整个流程开始时需要执行的任务
* @param id
*/
void startRunTask(String id);
/**
* 整个流程结束需要执行的任务
* @param id
*/
void endRunTask(String id);
}
@@ -0,0 +1,120 @@
package com.jero.modules.activiti.process.esInitChange.controller;
import com.jero.common.api.vo.Result;
import com.jero.common.aspect.annotation.AutoLog;
import com.jero.modules.activiti.process.esInitChange.entity.ProcessEsInitChange;
import com.jero.modules.activiti.process.esInitChange.service.ProcessEsInitChangeService;
import com.jero.modules.laws.common.constant.FieldCommon;
import com.jero.modules.laws.enterprise.util.EnterpriseStandardUtil;
import com.jero.modules.tag.enums.TableNameEnum;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
/**
* @author: Mzaxd
* @Date: 2023/10/10 14:14
*/
@Slf4j
@RestController
@Api(tags = "企标立项变更流程")
@RequestMapping("/process/es/initChange")
public class ProcessESInitChangeController {
@Resource
private ProcessEsInitChangeService initChangeService;
@Resource
private EnterpriseStandardUtil esUtil;
/**
* 生成企标编号并返回
* @param esInitChange
*/
@AutoLog(value = "企标立项变更流程-生成企标编号并返回")
@ApiOperation(value="企标立项变更流程-生成企标编号并返回", notes="企标立项变更流程-生成企标编号并返回")
@PostMapping("/getStandardNo")
public Result<?> getStandardNo(@Valid @RequestBody ProcessEsInitChange esInitChange) {
// 生成企标编号并返回
Map<String, Object> map = new HashMap<>();
map.put(FieldCommon.ENTERPRISE_STANDARD_CODE, esInitChange.getEnStandardCode());
map.put(FieldCommon.ENTERPRISE_NAME_CODE, esInitChange.getEnNameCode());
map.put(FieldCommon.STANDARD_CATEGORY_CODE, esInitChange.getStandardCategoryCode());
return Result.OK(esUtil.generateStandardNumber(map));
}
/**
* 保存到待办
* @param taskId
* @param esInitChange
*/
@AutoLog(value = "企标立项变更流程-保存到待办")
@ApiOperation(value="企标立项变更流程-保存到待办", notes="企标立项变更流程-保存到待办")
@PostMapping("/saveToWait")
public Result<?> saveToWait(@RequestParam("taskId") String taskId,
@RequestBody ProcessEsInitChange esInitChange) {
initChangeService.saveToWait(taskId, esInitChange);
return Result.OK();
}
/**
* 保存到草稿
* @param esInitChange
*/
@AutoLog(value = "企标立项变更流程-保存到草稿")
@ApiOperation(value="企标立项变更流程-保存到草稿", notes="企标立项变更流程-保存到草稿")
@PostMapping("/saveToDraft")
public Result<?> saveToWait(@RequestBody ProcessEsInitChange esInitChange) {
// TODO 保存到草稿
initChangeService.saveToDraft(esInitChange);
return Result.OK();
}
/**
* 新增立项变更申请
*
* @param esInitChange
*/
@AutoLog(value = "企标立项变更流程-新增立项变更申请")
@ApiOperation(value="企标立项变更流程-新增立项变更申请", notes="企标立项变更流程-新增立项变更申请")
@PostMapping("/add")
public Result<?> addInitChange(@RequestBody ProcessEsInitChange esInitChange) {
initChangeService.addInitChange(esInitChange);
return Result.OK();
}
/**
* 审批(同意/驳回)
*
* @param taskId
* @param esInitChange
*/
@AutoLog(value = "企标立项变更流程-审批(同意/驳回)")
@ApiOperation(value="企标立项变更流程-审批(同意/驳回)", notes="企标立项变更流程-审批(同意/驳回)")
@PostMapping("/approval")
public Result<?> approval(@RequestParam("taskId") String taskId, @RequestBody ProcessEsInitChange esInitChange) {
//审批
initChangeService.approvalInitChange(taskId, esInitChange);
return Result.OK();
}
/**
* 转办
*
* @param taskId
* @param userId
*/
@AutoLog(value = "企标立项变更流程-转办")
@ApiOperation(value="企标立项变更流程-转办", notes="企标立项变更流程-转办")
@PostMapping(value = "/transfer")
public Result<?> transfer(@RequestParam("taskId") String taskId, @RequestParam("userId") String userId) {
initChangeService.transfer(taskId, userId);
return Result.OK();
}
}
@@ -0,0 +1,349 @@
package com.jero.modules.activiti.process.esInitChange.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 企标计划
* @TableName process_es_init_change
*/
@Data
@TableName(value ="process_es_init_change")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@ApiModel(value="process_es_init_change对象", description="企标立项变更对象")
public class ProcessEsInitChange implements Serializable {
/** 主键ID */
@TableId(type = IdType.ASSIGN_ID)
@ApiModelProperty(value = "主键ID")
private String id;
/**
* 创建人
*/
private String createBy;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新人
*/
private String updateBy;
/**
* 更新时间
*/
private Date updateTime;
/**
* 所属部门
*/
private String orgCode;
/**
* 0表示未删除,1表示删除
*/
private Integer delFlag;
/**
* 流程名称
*/
private String processName;
/**
* 流程实例Id
*/
private String processInstanceId;
/**
* 截止日期
*/
private Date deadlineDate;
/**
* 流程说明
*/
private String processDescription;
/**
* 申请类别
*/
private String applicationCategory;
/**
* 项目类型
*/
private String projectType;
/**
* 原企标编号
*/
private String originEnStandardNo;
/**
* 新企标编号
*/
private String newEnStandardNo;
/**
* 原企标名称
*/
private String originEnStandardName;
/**
* 新企标名称
*/
private String newEnStandardName;
/**
* 企标英文名称
*/
private String enStandardEnglishName;
/**
* 企标体系
*/
private String enStandardSystem;
/**
* 企业标准代号
*/
private String enStandardCode;
/**
* 企业名称代号
*/
private String enNameCode;
/**
* 标准类别代号
*/
private String standardCategoryCode;
/**
* 年代号
*/
private String decadeCode;
/**
* 标准类型
*/
private String standardType;
/**
* 企标等级分类
*/
private String enStandardClassification;
/**
* 草稿计划完成日期
*/
private Date draftPlannedCompleteDate;
/**
* 征求意见稿计划完成日期
*/
private Date solicitationDraftPlanCompleteDate;
/**
* 计划报批日期
*/
private Date planApprovalDate;
/**
* 项目状态
*/
private String projectStatus;
/**
* 编制说明
*/
private String compilationDescription;
/**
* 零部件名称
*/
private String componentName;
/**
* 适用专业
*/
private String applicableProfession;
/**
* 主起草人
*/
private String mainDraftingUser;
/**
* 主起草单位
*/
private String mainDraftingUnit;
/**
* 主起草单位责任人
*/
private String mainDraftingUnitResponsiblePerson;
/**
* 标准推进人
*/
private String standardPromoter;
/**
* 草稿完成日期
*/
private Date draftCompletionDate;
/**
* 提交草稿日期
*/
private Date draftSubmissionDate;
/**
* 是否征求意见
*/
private String solicitationOpinionEnabled;
/**
* 征求意见稿完成日期
*/
private Date solicitationDraftCompletionDate;
/**
* 评审日期
*/
private Date reviewDate;
/**
* 报批日期
*/
private Date approvalDate;
/**
* 发布日期
*/
private Date releaseDate;
/**
* 变更状态
*/
private String changeStatus;
/**
* 立项背景、立项依据
*/
private String projectBackground;
/**
* 国际、国家及行业同类标准分析
*/
private String similarNaStandardsAnalysis;
/**
* 企业同类标准对比分析
*/
private String similarEnStandardsAnalysis;
/**
* 立项标准的领先性与必要性
*/
private String standardLeadingNecessity;
/**
* 立项目的及预期效果等
*/
private String projectExpectedEffects;
/**
* 备注
*/
private String remarks;
/**
* 附件
*/
private String attachment;
/**
* 是否为优质标准
*/
private String qualityFlag;
/**
* 变更原因
*/
private String changeReason;
/**
* 新主起草人
*/
private String newMainDraftingUser;
/**
* 新主起草单位
*/
private String newMainDraftingUnit;
/**
* 部所联络人
*/
private String contactUser;
/**
* 标准专家
*/
private String standardExpert;
/**
* 主起草人主管级领导
*/
private String mainDraftUserLeader;
/**
* 主起草人主管级领导上级领导
*/
private String mainDraftUserLeaderLeader;
/**
* 标准化审批人
*/
private String standardizationApprovalUser;
/**
* 新主起草部门领导的领导
*/
private String newMainDraftUserLeaderLeader;
/**
* 新主起草部门领导
*/
private String newMainDraftUserLeader;
/**
* 相关人员
*/
private String relatedUser;
/**
* 抄送人
*/
private String copyUser;
@TableField(exist = false)
private static final long serialVersionUID = 1781238971297838971L;
}
@@ -0,0 +1,30 @@
package com.jero.modules.activiti.process.esInitChange.entity.enums;
/**
* @author: Mzaxd
* @Date: 2023/10/9 16:28
*/
public enum ESApplicationCategoryEnum {
INITIATION("立项", "1"),
CHANGE("变更", "2")
;
private final String name;
private final String value;
public String getName() {
return name;
}
public String getValue() {
return value;
}
ESApplicationCategoryEnum(String name, String value) {
this.name = name;
this.value = value;
}
}
@@ -0,0 +1,36 @@
package com.jero.modules.activiti.process.esInitChange.entity.enums;
/**
* @author: Mzaxd
* @Date: 2023/10/9 16:28
*/
public enum ESProjectType {
/** 变更 **/
COMPLETE_TIME_CHANGE("完成时间变更", "1"),
WORK_TERMINATE("工作中止", "2"),
RESPONSIBLE_DEPT_CHANGE("责任部门变更", "3"),
MERGE("合并", "4"),
/** 立项 **/
ENACT("制定", "5"),
MODIFY("修订", "6"),
;
private final String name;
private final String value;
public String getName() {
return name;
}
public String getValue() {
return value;
}
ESProjectType(String name, String value) {
this.name = name;
this.value = value;
}
}
@@ -1,4 +1,4 @@
package com.jero.modules.activiti.entity;
package com.jero.modules.activiti.process.esInitChange.entity.vo;
import lombok.Data;
@@ -7,7 +7,7 @@ import lombok.Data;
* @Date: 2023/10/9 16:57
*/
@Data
public class FlowUserInfo {
public class FlowUserInfoVO {
// 主起草人
private String mainDraftUser;
@@ -0,0 +1,18 @@
package com.jero.modules.activiti.process.esInitChange.mapper;
import com.jero.modules.activiti.process.esInitChange.entity.ProcessEsInitChange;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author ThinkBook
* @description 针对表【process_es_init_change(企标计划)】的数据库操作Mapper
* @createDate 2023-10-10 13:48:56
* @Entity com.jero.modules.activiti.process.esInitChange.entity.ProcessEsInitChange
*/
public interface ProcessEsInitChangeMapper extends BaseMapper<ProcessEsInitChange> {
}
@@ -0,0 +1,46 @@
package com.jero.modules.activiti.process.esInitChange.service;
import com.jero.modules.activiti.process.esInitChange.entity.ProcessEsInitChange;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author ThinkBook
* @description 针对表【process_es_init_change(企标计划)】的数据库操作Service
* @createDate 2023-10-10 13:48:56
*/
public interface ProcessEsInitChangeService extends IService<ProcessEsInitChange> {
/**
* 新增记录
* @param esInitChange
* @return
*/
void addInitChange(ProcessEsInitChange esInitChange);
/**
* 转办
* @param taskId
* @param userId
*/
void transfer(String taskId, String userId);
/**
* 审批
* @param taskId
* @param esInitChange
*/
void approvalInitChange(String taskId, ProcessEsInitChange esInitChange);
/**
* 保存到待办
* @param taskId
* @param esInitChange
*/
void saveToWait(String taskId, ProcessEsInitChange esInitChange);
/**
* 保存到草稿
* @param esInitChange
*/
void saveToDraft(ProcessEsInitChange esInitChange);
}
@@ -0,0 +1,123 @@
package com.jero.modules.activiti.process.esInitChange.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jero.common.exception.JeroBootException;
import com.jero.modules.activiti.process.common.service.ActFlowCommonService;
import com.jero.modules.activiti.process.common.service.IActFlowCustomService;
import com.jero.modules.activiti.process.esInitChange.entity.ProcessEsInitChange;
import com.jero.modules.activiti.process.esInitChange.service.ProcessEsInitChangeService;
import com.jero.modules.activiti.process.esInitChange.mapper.ProcessEsInitChangeMapper;
import com.jero.modules.sys.utils.UserUtils;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.*;
/**
* @author ThinkBook
* @description 针对表【process_es_init_change(企标计划)】的数据库操作Service实现
* @createDate 2023-10-10 13:48:56
*/
@Service
@Transactional(rollbackFor = JeroBootException.class)
@Slf4j
public class ProcessEsInitChangeServiceImpl extends ServiceImpl<ProcessEsInitChangeMapper, ProcessEsInitChange>
implements ProcessEsInitChangeService, IActFlowCustomService {
@Resource
private ActFlowCommonService actFlowCommonService;
@Override
public Map<String, Object> setVariables(String id) {
Map<String, Object> map = new HashMap<>();
ProcessEsInitChange initChange = getById(id);
// 设置流程中各个节点的人
map.put("createUser", initChange.getCreateBy());
map.put("contactUser", initChange.getContactUser());
map.put("standardExpertList", Optional.ofNullable(initChange.getStandardExpert()).map(s -> Arrays.asList(s.split(","))).orElse(Collections.emptyList()));
map.put("mainDraftUserLeader", initChange.getMainDraftUserLeader());
map.put("mainDraftUserLeaderLeader", initChange.getMainDraftUserLeaderLeader());
map.put("standardizationApprovalUser", initChange.getStandardizationApprovalUser());
map.put("newMainDraftUserLeaderLeader", initChange.getNewMainDraftUserLeaderLeader());
map.put("newMainDraftUserLeader", initChange.getNewMainDraftUserLeader());
map.put("relatedUserList", Optional.ofNullable(initChange.getRelatedUser()).map(s -> Arrays.asList(s.split(","))).orElse(Collections.emptyList()));
map.put("copyUser", initChange.getCreateBy());
return map;
}
@Override
public void startRunTask(String id) {
}
@Override
public void endRunTask(String id) {
}
@Override
public void addInitChange(ProcessEsInitChange esInitChange) {
String userId = UserUtils.getUserId();
// TODO 根据业务需求设置流程状态
// 对数据进行其他操作
// 保存到业务流程表
save(esInitChange);
String id = esInitChange.getId();
String formKey = "initChange";
String beanName = formKey + "Service";
// 使用流程变量设置字符串(格式 : XXX:id 的形式)
String businessKey = formKey + ":" + id;
ProcessInstance processInstance = actFlowCommonService.startProcess(formKey, beanName, businessKey, id);
// 获取流程实例ID
String processDefinitionId = processInstance.getProcessDefinitionId();
log.info("启动流程实例成功,流程定义ID为:{}", processDefinitionId);
List<Map<String, Object>> taskList = actFlowCommonService.myTaskList(userId);
if (!CollectionUtils.isEmpty(taskList)) {
for (Map<String, Object> map : taskList) {
if (map.get("assignee").toString().equals(userId) &&
map.get("processDefinitionId").toString().equals(processDefinitionId)) {
log.info("当前用户ID:{},相关联的流程定义ID:{}", userId, map.get("processDefinitionId").toString());
log.info("匹配到的任务ID{}", map.get("taskId").toString());
actFlowCommonService.completeTask("同意", map.get("taskId").toString(), userId);
}
}
}
}
@Override
public void transfer(String taskId, String userId) {
actFlowCommonService.transfer(taskId, userId);
}
@Override
public void approvalInitChange(String taskId, ProcessEsInitChange esInitChange) {
String userId = UserUtils.getUserId();
actFlowCommonService.completeTask(esInitChange.getRemarks(), taskId, userId);
}
@Override
public void saveToWait(String taskId, ProcessEsInitChange esInitChange) {
// TODO 检查任务是否存在
saveOrUpdate(esInitChange);
}
@Override
public void saveToDraft(ProcessEsInitChange esInitChange) {
// TODO 保存到草稿
}
}
@@ -0,0 +1,48 @@
package com.jero.modules.activiti.util;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* Spring 上下文工具, 可用于获取spring 容器中的Bean
*/
@Component
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextUtil.applicationContext = applicationContext;
}
/**
* 获取spring容器中的bean,通过bean名称获取
* @param beanName bean名称
* @return: Object 返回Object,需要做强制类型转换
*/
public static Object getBean(String beanName){
return applicationContext.getBean(beanName);
}
/**
* 获取spring容器中的bean, 通过bean类型获取
* @param beanClass bean 类型
* @return: T 返回指定类型的bean实例
*/
public static <T> T getBean(Class<T> beanClass) {
return applicationContext.getBean(beanClass);
}
/**
* 获取spring容器中的bean, 通过bean名称和bean类型精确获取
* @param beanName bean 名称
* @param beanClass bean 类型
* @return: T 返回指定类型的bean实例
*/
public static <T> T getBean(String beanName, Class<T> beanClass){
return applicationContext.getBean(beanName,beanClass);
}
}
@@ -41,6 +41,7 @@ public class EnterpriseStandardUtil {
public String generateNewSequenceNumber(String esCodeDictValue, String esNameCodeDictValue, String categoryCodeDictValue) {
String sequenceNumber = "0001";
// 根据 标准代号/名称代号/标准类别 的相关性生成顺序号
// 已经存在的标准
LambdaQueryWrapper<LawsEnterpriseStandard> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(LawsEnterpriseStandard::getStandardCode, esCodeDictValue);
lambdaQueryWrapper.eq(LawsEnterpriseStandard::getNameCode, esNameCodeDictValue);
@@ -50,6 +51,8 @@ public class EnterpriseStandardUtil {
List<String> dbSequenceNumberList = esList.stream().map(LawsEnterpriseStandard::getStandardNumber)
.map(EnterpriseStandardUtil::getSequenceNoFromStandardNo).collect(Collectors.toList());
// TODO 流程中的标准
// 获取最大的序列号
Optional<String> maxSequence = dbSequenceNumberList.stream().max(Comparator.naturalOrder());