activiti工作流委托功能的设计和实现
最近公司开发一个项目,客户提出了一个需求,用户在出差的时候,可以将自己的工作进行委托。可以指定委托时间、委托工作内容、指定委托人等等内容。
然后我就上网查询资料,发现activiti工作流本身并不支持这种委托功能,于是就自己参考一些资料,进行开发,基本实现客户所需的功能。
1.用户需求分析:
(1)不同任务流程委托给不同人
(2)全盘委托
(3)委托给多个人共同决策(一票否决,一票通过)
(4)委托时间
(5)本项目功能在SSM框架下开发,前端采用VUE框架
2.设计数据表
ACT_RU_DELEGATE //委托配置数据表
CREATE TABLE `act_ru_delegate` (
`ID` bigint(20) NOT NULL AUTO_INCREMENT,
`ASSIGNEE` varchar(200) DEFAULT NULL,
`ATTORNEY` varchar(200) DEFAULT NULL,
`START_TIME` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`END_TIME` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`PROCESS_DEFINITION_ID` varchar(100) DEFAULT NULL,
`STATUS` int(11) DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=utf8;
ACT_HI_DELEGATE //委托配置数据表
CREATE TABLE `act_hi_delegate` (
`ID` bigint(20) NOT NULL AUTO_INCREMENT,
`ASSIGNEE` varchar(200) DEFAULT NULL,
`ATTORNEY` varchar(200) DEFAULT NULL,
`DELEGATE_TIME` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`TASK_ID` varchar(100) DEFAULT NULL,
`STATUS` int(11) DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=35 DEFAULT CHARSET=utf8;
3.model模型实现
1.DelegateInfo类
package com.paomo.model;
import java.util.Date;
public class DelegateInfo {
private int id;
private String Assignee;
private String Attorney;
private Date Start_Time;
private Date End_Time;
private String Process_Definition_Id;
private Integer Status;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public DelegateInfo(){
super();
}
public DelegateInfo(int id, String assignee, String attorney, Date start_Time, Date end_Time,
String process_Definition_Id, Integer status) {
super();
this.id = id;
Assignee = assignee;
Attorney = attorney;
Start_Time = start_Time;
End_Time = end_Time;
Process_Definition_Id = process_Definition_Id;
Status = status;
}
public String getAssignee() {
return Assignee;
}
public void setAssignee(String assignee) {
Assignee = assignee;
}
public String getAttorney() {
return Attorney;
}
public void setAttorney(String attorney) {
Attorney = attorney;
}
public Date getStart_Time() {
return Start_Time;
}
public void setStart_Time(Date start_Time) {
Start_Time = start_Time;
}
public Date getEnd_Time() {
return End_Time;
}
public void setEnd_Time(Date end_Time) {
End_Time = end_Time;
}
public String getProcess_Definition_Id() {
return Process_Definition_Id;
}
public void setProcess_Definition_Id(String process_Definition_Id) {
Process_Definition_Id = process_Definition_Id;
}
public Integer getStatus() {
return Status;
}
public void setStatus(Integer status) {
Status = status;
}
}
2.DelegateHistory类
package com.paomo.model;
import java.util.Date;
public class DelegateHistory {
private int id;
private String Assignee;
private String Attorney;
private Date Delegate_Time;
private String TaskId;
private Integer Status;
public DelegateHistory(){
super();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAssignee() {
return Assignee;
}
public void setAssignee(String assignee) {
Assignee = assignee;
}
public String getAttorney() {
return Attorney;
}
public void setAttorney(String attorney) {
Attorney = attorney;
}
public Date getDelegate_Time() {
return Delegate_Time;
}
public void setDelegate_Time(Date delegate_Time) {
Delegate_Time = delegate_Time;
}
public String getTaskId() {
return TaskId;
}
public void setTaskId(String taskId) {
TaskId = taskId;
}
public Integer getStatus() {
return Status;
}
public void setStatus(Integer status) {
Status = status;
}
public DelegateHistory(int id, String assignee, String attorney, Date delegate_Time, String taskId,
Integer status) {
super();
this.id = id;
Assignee = assignee;
Attorney = attorney;
Delegate_Time = delegate_Time;
TaskId = taskId;
Status = status;
}
}
4.DelegateService层接口
package com.paomo.service;
import java.util.List;
import java.util.Map;
import com.paomo.model.DelegateInfo;
public interface DelegateService {
DelegateInfo getDelegateInfo(String targetAssignee,String targetProcessDefinitionId);
void saveRecord(String assignee, String attorney, String taskId);
void removeRecord(Long id);
void removeRecord2(int id);
void addDelegateInfo(String assignee, String attorney,String startTime, String endTime, String processDefinitionId);
List<DelegateInfo> listAll(Map<String, Object> emap);
List<Map<String,Object>> listAllDetail(Map<String, Object> emap);
void update(Map<String,Object> resMap);
List<Map<String, Object>> getProcessList();
int getCount(String userId);
List<Map<String, Object>> listAllDetail2(Map<String, Object> emap);
int getCount2(String userId);
}
5.DelegateServiceImpl实现类
package com.paomo.service.impl;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import com.paomo.dao.DelegateHistoryDao;
import com.paomo.dao.DelegateInfoDao;
import com.paomo.model.DelegateHistory;
import com.paomo.model.DelegateInfo;
import com.paomo.service.DelegateService;
@Service("DelegateService")
public class DelegateServiceImpl implements DelegateService {
@Resource
private DelegateInfoDao delegateInfoDao;
@Resource
private DelegateHistoryDao delegateHistoryDao;
public static DelegateServiceImpl testUtils;
@PostConstruct
public void init() {
testUtils = this;
}
public DelegateInfo getDelegateInfo(String targetAssignee,String targetProcessDefinitionId) {
Map<String,Object> map=new HashMap<String, Object>();
map.put("assignee", targetAssignee);
List<DelegateInfo> list=delegateInfoDao.listAll(map);
for (DelegateInfo delegateInfo : list) {
String processDefinitionId = (String) delegateInfo.getProcess_Definition_Id();
Date startTime = (Date) delegateInfo.getStart_Time();
Date endTime = (Date) delegateInfo.getEnd_Time();
if (timeNotBetweenNow(startTime, endTime)) {
continue;
}
if ((processDefinitionId == null)|| processDefinitionId.equals(targetProcessDefinitionId)) {
return delegateInfo;
}
}
return null;
}
public void saveRecord(String assignee, String attorney, String taskId) {
DelegateHistory delegateHistory=new DelegateHistory();
delegateHistory.setAssignee(assignee);
delegateHistory.setAttorney(attorney);
delegateHistory.setTaskId(taskId);
delegateHistory.setDelegate_Time(new java.sql.Date(System.currentTimeMillis()));
delegateHistory.setStatus(1);
delegateHistoryDao.add(delegateHistory);
}
public void removeRecord(Long id) {
delegateInfoDao.delete(id);
}
public void removeRecord2(int id) {
delegateHistoryDao.delete(id);
}
public void addDelegateInfo(String assignee, String attorney,String startTime, String endTime, String processDefinitionId) {
DelegateInfo delegateInfo=new DelegateInfo();
Map<String,Object> resMap = new HashMap<String,Object>();
resMap.put("assignee", assignee);
resMap.put("attorney", attorney);
resMap.put("endTime", endTime);
resMap.put("startTime", startTime);
resMap.put("processDefinitionId", processDefinitionId);
resMap.put("status", 1);
delegateInfoDao.save(resMap);
}
private boolean timeNotBetweenNow(Date startTime, Date endTime) {
Date now = new Date(System.currentTimeMillis());
if (startTime != null) {
return now.before(startTime);
}
if (endTime != null) {
return now.after(endTime);
}
return false;
}
@Override
public List<DelegateInfo> listAll(Map<String,Object> reMap) {
return delegateInfoDao.listAll(reMap);
}
@Override
public void update(Map<String, Object> resMap) {
delegateInfoDao.update(resMap);
}
@Override
public List<Map<String, Object>> getProcessList() {
return delegateInfoDao.getProcessList();
}
@Override
public int getCount(String userId) {
return delegateInfoDao.getCount(userId);
}
@Override
public List<Map<String, Object>> listAllDetail(Map<String, Object> emap) {
return delegateInfoDao.listAllDetail(emap);
}
@Override
public List<Map<String, Object>> listAllDetail2(Map<String, Object> emap) {
return delegateHistoryDao.listAllDetail(emap);
}
@Override
public int getCount2(String userId) {
return delegateHistoryDao.getCount(userId);
}
}
6.DelegateInfoDao
package com.paomo.dao;
import java.util.Date;
import java.util.List;
import java.util.Map;
import com.paomo.model.DelegateInfo;
public interface DelegateInfoDao {
DelegateInfo getDelegateInfo(String targetAssignee,String targetProcessDefinitionId);
void saveRecord(String assignee, String attorney, String taskId);
void removeRecord(Long id);
void addDelegateInfo(String assignee, String attorney,Date startTime, Date endTime, String processDefinitionId);
List<DelegateInfo> listAll(Map<String, Object> reMap);
void delete(Long id);
DelegateInfo getById(Long id);
void save(Map<String, Object> resMap);
void update(Map<String, Object> resMap);
List<Map<String, Object>> getProcessList();
int getCount(String userId);
List<Map<String,Object>> listAllDetail(Map<String, Object> emap);
}
7.DelegateHistoryDao
package com.paomo.dao;
import java.util.List;
import java.util.Map;
import com.paomo.model.DelegateHistory;
public interface DelegateHistoryDao {
void update(DelegateHistory delegateHistory);
void add(DelegateHistory delegateHistory);
List<Map<String, Object>> listAllDetail(Map<String, Object> emap);
int getCount(String assignee);
void delete(int id);
}
8.DelegateMapper
<?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.paomo.dao.DelegateInfoDao">
<insert id="save" parameterType="Map">
insert into act_ru_delegate(ASSIGNEE,ATTORNEY,START_TIME,END_TIME,PROCESS_DEFINITION_ID,STATUS) values(#{assignee},#{attorney},#{startTime},#{endTime},#{processDefinitionId},1)
</insert>
<delete id="delete" parameterType="Long">
delete from act_ru_delegate where ID=#{id}
</delete>
<select id="listAll" parameterType="Map" resultType="DelegateInfo">
select * from act_ru_delegate where STATUS=1 and ASSIGNEE=#{assignee}
</select>
<select id="listAllDetail" parameterType="Map" resultType="Map">
select a.ID, a.START_TIME startTime,a.END_TIME endTime,b.NAME_ processName,c.`name` assignee,d.`name` attorney,a.ATTORNEY attorneyId,a.ASSIGNEE assigneeId from act_ru_delegate a
LEFT JOIN act_re_procdef b ON a.PROCESS_DEFINITION_ID=b.ID_
LEFT JOIN act_id_user c ON a.ASSIGNEE=c.id
LEFT JOIN act_id_user d ON a.ATTORNEY=d.id
where a.STATUS=1 and a.ASSIGNEE=#{assignee}
<if test="currentPage!=-1">
limit #{currentPage},#{pageSize}
</if>
</select>
<select id="getCount" parameterType="String" resultType="Integer">
select count(*) from act_ru_delegate where STATUS=1 and ASSIGNEE=#{assignee} order by ID desc
</select>
<select id="getProcessList" resultType="Map">
SELECT ID_,NAME_ FROM act_re_procdef GROUP BY NAME_ ORDER BY VERSION_ desc
</select>
<update id="update" parameterType="Map">
update act_ru_delegate
<set>
<if test="assigneeId!=null and assigneeId!=''">
ASSIGNEE=#{assigneeId},
</if>
<if test="attorney!=null and attorney!=''">
ATTORNEY=#{attorney},
</if>
<if test="startTime!=null and startTime!='NaN-aN-aN aN:aN:aN'">
Start_Time=#{startTime},
</if>
<if test="endTime!=null and endTime!='NaN-aN-aN aN:aN:aN'">
End_Time=#{endTime},
</if>
<if test="processDefinitionId!=null and processDefinitionId!=''">
Process_Definition_Id=#{processDefinitionId},
</if>
</set>
where ID =#{ID}
</update>
</mapper>
9.DelegateHistoryMapper
<?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.qajt.paomo.DelegateHistoryDao">
<insert id="add" parameterType="DelegateInfo">
insert into act_hi_delegate(ASSIGNEE,ATTORNEY,DELEGATE_TIME,TASK_ID,STATUS) values(
#{Assignee},#{Attorney},#{Delegate_Time},#{TaskId},#{Status})
</insert>
<select id="listAllDetail" parameterType="Map" resultType="Map">
select a.ID,a.TASK_ID taskId, a.DELEGATE_TIME delegateTime,c.`name` assignee,d.`name` attorney,a.ATTORNEY attorneyId,a.ASSIGNEE assigneeId from act_hi_delegate a
LEFT JOIN act_id_user c ON a.ASSIGNEE=c.id
LEFT JOIN act_id_user d ON a.ATTORNEY=d.id
where a.STATUS=1 and a.ASSIGNEE=#{assignee}
<if test="currentPage!=-1">
limit #{currentPage},#{pageSize}
</if>
</select>
<select id="getCount" parameterType="Map" resultType="Integer">
select count(*) from act_hi_delegate a
where a.STATUS=1 and a.ASSIGNEE=#{assignee}
</select>
<delete id="delete" parameterType="Integer">
delete from act_hi_delegate where ID=#{id}
</delete>
</mapper>
10.TaskAsigneeListenerImpl监听类的实现 对单一指派人 assignee
package com.paomo.service.impl;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import com.paomo.dao.DelegateInfoDao;
import com.paomo.model.DelegateInfo;
import com.paomo.service.DelegateService;
@Component("TaskAsigneeListenerImpl")
public class TaskAsigneeListenerImpl implements TaskListener {
@Resource
private DelegateService delegateService;
@Override
public void notify(DelegateTask delegateTask) {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); //ssm框架下直接注入service出错,所以这块要用XML的方式对service进行注入
DelegateService dsService = (DelegateService) ac.getBean("DelegateService");
//如果有委托,设置委托人
String assignee = delegateTask.getAssignee();
String processDefinitionId = delegateTask.getProcessDefinitionId();
DelegateInfo delegateInfo = dsService.getDelegateInfo(assignee,
processDefinitionId);
if (delegateInfo == null) {
return;
}
String attorney = delegateInfo.getAttorney();
delegateTask.setAssignee(attorney);
dsService.saveRecord(assignee, attorney, delegateTask.getId());
}
}
11.在工作流流程图中配置监听类
12.新建委托,新建流程进行测试。
启动一个新流程,测试可得发给张刚的流程,最终发到了周星驰那里。