activiti工作流委托功能的实现
最近公司开发一个项目,客户提出了一个需求,用户在出差的时候,可以将自己的工作进行委托。可以指定委托时间、委托工作内容、指定委托人等等内容。
然后我就上网查询资料,发现activiti工作流本身并不支持这种委托功能,于是就自己参考一些资料,进行开发,基本实现客户所需的功能。
1.用户需求分析:
(1)不同任务流程委托给不同人
(2)全盘委托
(3)委托给多个人共同决策(一票否决,一票通过)
(4)委托时间
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.qajt.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.qajt.dao.DelegateHistoryDao; import com.qajt.dao.DelegateInfoDao; import com.qajt.model.DelegateHistory; import com.qajt.model.DelegateInfo; import com.qajt.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.qajt.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.qajt.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.新建委托,新建流程进行测试。
启动一个新流程,测试可得发给张刚的流程,最终发到了周星驰那里。