1.下面采用的是activiti工作流程的方式,模拟滴滴抢单这样的业务,由申请人发出申请,由抢单人进行抢单,多人员进行抢单,第一个抢单成功后,其他用户抢单就会失败!
1.申请人工作流程图
2.发起人的流程设置
任务监听器对应的代码:
@Controller
@SuppressWarnings("serial")
public class ManagerTaskHandler implements TaskListener {
@Override
public void notify(DelegateTask delegateTask) {
Session session = Jurisdiction.getSession();//shiro中获取session
String processDefinitionId = delegateTask.getProcessDefinitionId();
String processInstanceId=delegateTask.getProcessInstanceId();
//通过上面的两个值组成唯一的key,并在key中存入当前用户
String TASKID = (String)session.getAttribute(processInstanceId+processDefinitionId + "TASKID");
String YAssignee = (String)session.getAttribute(processInstanceId+processDefinitionId + "YAssignee");
if(TASKID!=null&&TASKID!=""){
session.setAttribute(processInstanceId+processDefinitionId + "TASKID", TASKID+","+delegateTask.getId()); //任务ID
}else{
session.setAttribute(processInstanceId+processDefinitionId + "TASKID", delegateTask.getId()); //任务ID
}
if(YAssignee!=null&&YAssignee!=""){
session.setAttribute(processInstanceId+processDefinitionId + "YAssignee", YAssignee+","+delegateTask.getAssignee()); //默认待办人
}else{
session.setAttribute(processInstanceId+processDefinitionId + "YAssignee", delegateTask.getAssignee()); //默认待办人
}
}
}
3. 抢单人流程设置
前端弹出用户选择界面,可设置多个候选人,候选组。可根据需求进行设置页面
4.任务审核页面
5.流程图:
6.后台部分代码
/**办理任务
* @param
* @throws Exception
*/
@RequestMapping(value="/handle")
@RequiresPermissions("rutask:edit")
@ResponseBody
public Object handle() throws Exception{
Map<String,Object> zmap = new HashMap<String,Object>();
String errInfo = "success";
Session session = Jurisdiction.getSession();
PageData pd = new PageData();
pd = this.getPageData();
Task task=taskService.createTaskQuery() // 创建任务查询
.taskId(pd.getString("ID_")) // 根据任务id查询
.singleResult();
if(task==null){
//当前任务已经被其他人办理完成了,
zmap.put("ASSIGNEE_",""); //用于给待办人发送新任务消息
errInfo = "task_end";
zmap.put("result", errInfo); //返回结果
return zmap;
}
String processDefinitionId=task.getProcessDefinitionId(); // 获取流程定义id
String processInstanceId=task.getProcessInstanceId();
String taskId = pd.getString("ID_"); //任务ID
String sfrom = "";
Object ofrom = getVariablesByTaskIdAsMap(taskId,"审批结果");
if(null != ofrom){
sfrom = ofrom.toString();
}
Map<String,Object> map = new LinkedHashMap<String, Object>();
String OPINION = sfrom + Jurisdiction.getName() + ",fh,"+pd.getString("OPINION");//审批人的姓名+审批意见
PageData hivar_nrOf = new PageData();
hivar_nrOf.put("NAME_","nrOfInstances");
hivar_nrOf.put("PROC_INST_ID_",task.getProcessInstanceId());
PageData page_nrOf = hiprocdefService.hivar_Instances(hivar_nrOf); //历史流程实例总数据
PageData hivar_nrOfCompleted = new PageData();
hivar_nrOfCompleted.put("NAME_","nrOfCompletedInstances");
hivar_nrOfCompleted.put("PROC_INST_ID_",task.getProcessInstanceId());
PageData page_nrOfCompleted = hiprocdefService.hivar_Instances(hivar_nrOfCompleted); //历史流程实例完成数据
String msg = pd.getString("msg");
if("yes".equals(msg)){
Map<String, Object> vMap = new HashMap<String, Object>();//绑定参数
map.put("审批结果", "【批准】" + OPINION); //审批结果
try {
if(page_nrOf!=null&&page_nrOfCompleted!=null){
Integer nrOfInstances=Integer.valueOf(page_nrOf.get("LONG_").toString());
Integer nrOfCompletedInstances=Integer.valueOf(page_nrOfCompleted.get("LONG_").toString());
if(nrOfInstances!=0&&nrOfCompletedInstances!=nrOfInstances){//证明并行网关的任务没有完成
//从数据库中查找任务办理同意次数
PageData pagedata=new PageData();
pagedata.put("ASSIGNEE",processDefinitionId+";"+page_nrOfCompleted.get("EXECUTION_ID_")+";"+"assage");
PageData task_assignee = actRuTaskService.get_task_assignee(pagedata);
if(task_assignee!=null){
vMap.put("assignee",Integer.valueOf(task_assignee.get("TOTALCOUNT")+"")+1);
vMap.put("totalcount",nrOfInstances);
PageData insert_pagedata=new PageData();
insert_pagedata.put("TOTALCOUNT",Integer.valueOf(task_assignee.get("TOTALCOUNT")+"")+1);
insert_pagedata.put("ASSIGNEE",processDefinitionId+";"+page_nrOfCompleted.get("EXECUTION_ID_")+";"+"assage");
actRuTaskService.edit(insert_pagedata);
}else{
vMap.put("assignee",1);
vMap.put("totalcount",nrOfInstances);
PageData insert_pagedata=new PageData();
insert_pagedata.put("TOTALCOUNT",1);
insert_pagedata.put("ASSIGNEE",processDefinitionId+";"+page_nrOfCompleted.get("EXECUTION_ID_")+";"+"assage");
insert_pagedata.put("ID", UUID.randomUUID().toString());
actRuTaskService.save(insert_pagedata);
}
}
}
setVariablesByTaskIdAsMap(taskId,map); //设置流程变量
}catch (Exception e){
if(e.getMessage().indexOf("Cannot find task with")!=-1){
//当前任务已经被其他人办理完成了,
zmap.put("ASSIGNEE_",""); //用于给待办人发送新任务消息
errInfo = "task_end";
zmap.put("result", errInfo); //返回结果
return zmap;
}
}
setVariablesByTaskId(taskId,"RESULT","批准");
vMap.put("RESULT", "批准");
completeMyPersonalTaskVariable(taskId,vMap);//完成任务,并绑定必要参数
}else{ //驳回
map.put("审批结果", "【驳回】" + OPINION); //审批结果
Map<String, Object> vMap = new HashMap<String, Object>();
try {
if(page_nrOf!=null&&page_nrOfCompleted!=null){
Integer nrOfInstances=Integer.valueOf(page_nrOf.get("LONG_").toString());
Integer nrOfCompletedInstances=Integer.valueOf(page_nrOfCompleted.get("LONG_").toString());
if(nrOfInstances!=0&&nrOfCompletedInstances!=nrOfInstances){//证明并行网关的任务没有完成
//从数据库中查找任务办理同意次数
PageData pagedata=new PageData();
pagedata.put("ASSIGNEE",processDefinitionId+";"+page_nrOfCompleted.get("EXECUTION_ID_")+";"+"assage");
PageData task_assignee = actRuTaskService.get_task_assignee(pagedata);
if(task_assignee!=null){
vMap.put("assignee",Integer.valueOf(task_assignee.get("TOTALCOUNT")+""));
vMap.put("totalcount",nrOfInstances);
}else{
vMap.put("assignee",0);
vMap.put("totalcount",nrOfInstances);
PageData insert_pagedata=new PageData();
insert_pagedata.put("TOTALCOUNT",0);
insert_pagedata.put("ASSIGNEE",processDefinitionId+";"+page_nrOfCompleted.get("EXECUTION_ID_")+";"+"assage");
insert_pagedata.put("ID", UUID.randomUUID().toString());
actRuTaskService.save(insert_pagedata);
}
}
}
setVariablesByTaskIdAsMap(taskId,map); //设置流程变量
}catch (Exception e){
if(e.getMessage().indexOf("ActivitiObjectNotFoundException")!=-1){
//当前任务已经被其他人办理完成了,
zmap.put("ASSIGNEE_",""); //用于给待办人发送新任务消息
errInfo = "task_end";
zmap.put("result", errInfo); //返回结果
return zmap;
}
}
setVariablesByTaskId(taskId,"RESULT","驳回");
vMap.put("RESULT", "驳回");
completeMyPersonalTaskVariable(taskId,vMap);//完成任务,并绑定必要参数
}
try{
removeVariablesByPROC_INST_ID_(pd.getString("PROC_INST_ID_"),"RESULT"); //移除流程变量(从正在运行中)
}catch(Exception e){
/*此流程变量在历史中**/
}
try{
String ASSIGNEE_ = pd.getString("ASSIGNEE_"); //下一待办对象
if(Tools.notEmpty(ASSIGNEE_)){
String taskids = (String)session.getAttribute(processInstanceId+processDefinitionId + "TASKID");
if(taskids!=null&&taskids!=""){
String[] split = taskids.split(",");
for(String taskid:split){
setAssignee(taskid,ASSIGNEE_); //指定下一任务待办对象
}
}
}else{
Object os = session.getAttribute(processInstanceId+processDefinitionId +"YAssignee");
if(null != os && !"".equals(os.toString())){
ASSIGNEE_ = os.toString(); //没有指定就是默认流程的待办人
}else{
//ProcessInstance pi = createProcessInstanceQuery().processInstanceId(fiveLevel.getAct().getProcInsId()).singleResult();
ProcessInstance processInstance = singleResult(pd.getString("PROC_INST_ID_"));
if(processInstance==null){
trySendSms(zmap,pd); //没有任务监听时,默认流程结束,发送站内信给任务发起人
}
//trySendSms(zmap,pd); //没有任务监听时,默认流程结束,发送站内信给任务发起人
//此时取消默认流程结束的方式,因为对于投票的业务,审核人需要主要都进行审核才会进入到下一审核
}
}
zmap.put("ASSIGNEE_",ASSIGNEE_); //用于给待办人发送新任务消息
}catch(Exception e){
zmap.put("ASSIGNEE_","null");
/*手动指定下一待办人,才会触发此异常。
* 任务结束不需要指定下一步办理人了,发送站内信通知任务发起人**/
trySendSms(zmap,pd);
}
if(Tools.notEmpty(pd.getString("COPYTOER"))) {
List<PageData> varList = ruprocdefService.varList(pd); //列出流程变量列表
this.sendSms(pd.getString("COPYTOER"), pd.getString("CREMARKS"), varList, map.get("审批结果").toString()); //发站内信给抄送对象
}
//此时清空TASKID和YAssignee的值
session.removeAttribute(processInstanceId+processDefinitionId + "TASKID");
session.removeAttribute(processInstanceId+processDefinitionId + "YAssignee");
zmap.put("result", errInfo); //返回结果
return zmap;
}