用activiti工作流实现申请主播审核功能
<dependency><!-- 00 --> <groupId>org.activiti</groupId> <artifactId>activiti-engine</artifactId> <version>5.17.0</version> </dependency>
首先引入一个工作流的jar包
下面是主播申请表的entity
/** * Copyright © 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved. */ package com.jeeplus.modules.zdcj.entity; import java.util.Map; import org.activiti.engine.history.HistoricProcessInstance; import org.activiti.engine.repository.ProcessDefinition; import org.activiti.engine.runtime.ProcessInstance; import org.activiti.engine.task.Task; import com.jeeplus.common.persistence.DataEntity; import com.jeeplus.common.utils.excel.annotation.ExcelField; /** * 申请主播Entity * @author ywj * @version 2016-12-22 */ public class ZdcjApply extends DataEntity<ZdcjApply> { private static final long serialVersionUID = 1L; private String userId; // 用户ID private String name; // 真实姓名 private String mobile; // 手机号 private String qq; // QQ private String email; // 邮箱 private String applystatus; // 状态 private String processInstanceId;//流程定义id //-- 临时属性 --// // 流程任务 private Task task; private Map<String, Object> variables; // 运行中的流程实例 private ProcessInstance processInstance; // 历史的流程实例 private HistoricProcessInstance historicProcessInstance; // 流程定义 private ProcessDefinition processDefinition; @ExcelField(title="流程实例id", align=2, sort=13) public String getProcessInstanceId() { return processInstanceId; } public void setProcessInstanceId(String processInstanceId) { this.processInstanceId = processInstanceId; } public Task getTask() { return task; } public void setTask(Task task) { this.task = task; } public Map<String, Object> getVariables() { return variables; } public void setVariables(Map<String, Object> variables) { this.variables = variables; } public ProcessInstance getProcessInstance() { return processInstance; } public void setProcessInstance(ProcessInstance processInstance) { this.processInstance = processInstance; } public HistoricProcessInstance getHistoricProcessInstance() { return historicProcessInstance; } public void setHistoricProcessInstance( HistoricProcessInstance historicProcessInstance) { this.historicProcessInstance = historicProcessInstance; } public ProcessDefinition getProcessDefinition() { return processDefinition; } public void setProcessDefinition(ProcessDefinition processDefinition) { this.processDefinition = processDefinition; } public ZdcjApply() { super(); } public ZdcjApply(String id){ super(id); } @ExcelField(title="用户ID", align=2, sort=1) public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } @ExcelField(title="真实姓名", align=2, sort=2) public String getName() { return name; } public void setName(String name) { this.name = name; } @ExcelField(title="手机号", align=2, sort=3) public String getMobile() { return mobile; } public void setMobile(String mobile) { this.mobile = mobile; } @ExcelField(title="QQ", align=2, sort=4) public String getQq() { return qq; } public void setQq(String qq) { this.qq = qq; } @ExcelField(title="邮箱", align=2, sort=5) public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @ExcelField(title="状态", dictType="apply_status", align=2, sort=6) public String getApplystatus() { return applystatus; } public void setApplystatus(String applystatus) { this.applystatus = applystatus; } }
下面是工作流的操作
1 /** 2 * Copyright © 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved. 3 */ 4 package com.jeeplus.modules.zdcj.service; 5 6 import java.io.InputStream; 7 import java.util.HashMap; 8 import java.util.List; 9 import java.util.Map; 10 11 import org.activiti.engine.ProcessEngine; 12 import org.activiti.engine.ProcessEngines; 13 import org.activiti.engine.repository.Deployment; 14 import org.activiti.engine.runtime.ProcessInstance; 15 import org.activiti.engine.task.Task; 16 import org.junit.Test; 17 import org.springframework.beans.factory.annotation.Autowired; 18 import org.springframework.stereotype.Service; 19 import org.springframework.transaction.annotation.Transactional; 20 21 import com.jeeplus.common.persistence.Page; 22 import com.jeeplus.common.service.CrudService; 23 import com.jeeplus.modules.zdcj.entity.ZdcjApply; 24 import com.jeeplus.modules.zdcj.dao.ZdcjApplyDao; 25 26 /** 27 * 申请主播Service 28 * @author jzp 29 * @version 2016-12-26 30 */ 31 @Service 32 @Transactional(readOnly = false) 33 public class CactivitiService{ 34 35 @Autowired 36 private ZdcjApplyService zdcjApplyService; 37 38 ProcessEngine processEngine=ProcessEngines.getDefaultProcessEngine(); 39 40 /** 41 * 部署流程定义(从inputStream) 42 */ 43 public String save_inputStream(String nn){ 44 try { 45 InputStream bp = this.getClass().getResourceAsStream("/diagrams/ZdcjApply.bpmn"); 46 InputStream png = this.getClass().getResourceAsStream("/diagrams/ZdcjApply.png"); 47 Deployment deployment = processEngine.getRepositoryService()//与流程定义和部署对象相关的service 48 .createDeployment()//创建一个部署对象 49 .name("申请主播")//添加部署的名称 50 .addInputStream("ZdcjApply.bpmn", bp) 51 .addInputStream("ZdcjApply.png", png) 52 .deploy();//完成部署流程定义 53 return "true"; 54 } catch (Exception e) { 55 e.printStackTrace(); 56 return "false"; 57 } 58 } 59 60 /** 61 * 启动流程实例 62 */ 63 public void startProc(ZdcjApply zdcjApply){ 64 zdcjApplyService.save(zdcjApply);//保存 65 String processKey="ZdcjApply"; 66 String keyid=zdcjApply.getId(); 67 //流程定义的id 68 ProcessInstance processInstance = null; 69 processInstance = processEngine.getRuntimeService()//与正在执行的流程实例和执行对象相关的service 70 .startProcessInstanceByKey(processKey,keyid);//使用流程实例定义的key启动流程实例。key对应helloword.bpmn文件中id的属性值 71 System.out.println("流程实例的id:"+processInstance.getId());//流程实例的id 801 72 System.out.println("流程定义的id:"+processInstance.getProcessDefinitionId());//流程定义的id helloWord:1:704 73 String processInstanceId = processInstance.getId(); 74 zdcjApply.setProcessInstanceId(processInstanceId); 75 zdcjApplyService.save(zdcjApply);//保存 76 } 77 78 /** 79 * 完成我的任务 80 */ 81 public void completeMyPer(String taskid,String key,Boolean message,String name){ 82 //完成任务的同时 设置流程变量 使用流程变量用来指定完成任务后 下一个连线 对应sequenceFlow.bpmn文件中的 ${message=='不重要'} 83 Map map=new HashMap(); 84 map.put(key, message); 85 map.put("applyUserId", name); 86 /*variables = new HashMap<String, Object>(); 87 variables.put("deptLeaderPass", true);*/ 88 processEngine.getTaskService()//与正在执行任务管理相关的service 89 .complete(taskid, map); 90 System.out.println("完成任务,任务id是:"+taskid); 91 /*if("dirPass".equals(key) && true==message){ 92 Map map2=new HashMap(); 93 map2.put(key, message); 94 processEngine.getTaskService()//与正在执行任务管理相关的service 95 .complete(taskid, map2); 96 } 97 System.out.println("完成任务,任务id是:"+taskid);*/ 98 } 99 100 /** 101 * 查询当前人的个人任务 102 */ 103 @Test 104 public List<Task> findMyPer(Map map){ 105 String assignee = (String) map.get("assignee"); 106 if(null!=map.get("instanceId") && !"".equals(map.get("instanceId"))){ 107 List<Task> list = processEngine.getTaskService()//与正在执行任务管理相关的service 108 .createTaskQuery()//创建任务查询对象 109 /**查询条件 where*/ 110 //.taskAssignee(assignee)//指定个人任务查询,指定办理人 111 .processInstanceId(""+map.get("instanceId"))//使用流程实例的id查询 112 /**排序*/ 113 .orderByTaskCreateTime().desc()//创建时间的倒叙排列 114 .list();//返回一个list集合,分装流程定义 115 /*if(list!=null && list.size()>0){ 116 for (Task task : list) { 117 System.out.println("任务id:"+task.getId()); 118 System.out.println("任务名称:"+task.getName()); 119 System.out.println("任务创建时间:"+task.getCreateTime()); 120 System.out.println("任务办理人:"+task.getAssignee()); 121 System.out.println("流程实例id:"+task.getProcessInstanceId()); 122 System.out.println("执行对象id:"+task.getExecutionId()); 123 System.out.println("流程定义id:"+task.getProcessDefinitionId()); 124 System.out.println("#####################################"); 125 } 126 }*/ 127 return list; 128 }else{ 129 return null; 130 } 131 } 132 133 public void claim(String tkid, String userId) { 134 processEngine.getTaskService() 135 .claim(tkid, userId); 136 } 137 138 /** 139 * 删除流程 140 */ 141 public void deleteProcessInstance() { 142 //processEngine.getExecutionService(); 143 //ProcessInstance processInstance = executionService.startProcessInstanceByKey("helloworld"); 144 //executionService.deleteProcessInstanceCascade(processInstance.getId()); 145 } 146 }
下面是审核流程,流程为 用户申请主播→(申请成功)→客服审核→(审核成功)→客服主管审核→(审核成功)→用户成为主播。
如果客服或者客服主管审核未通过,则返回过去,重新调整申请,最后结束流程。
1 /** 2 * Copyright © 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved. 3 */ 4 package com.jeeplus.modules.zdcj.web; 5 6 import java.io.InputStream; 7 import java.util.HashMap; 8 import java.util.List; 9 import java.util.Map; 10 11 import javax.servlet.http.HttpServletRequest; 12 import javax.servlet.http.HttpServletResponse; 13 import javax.servlet.http.HttpSession; 14 import javax.validation.ConstraintViolationException; 15 16 17 import org.apache.shiro.authz.annotation.Logical; 18 import org.apache.shiro.authz.annotation.RequiresPermissions; 19 import org.junit.Test; 20 import org.springframework.beans.factory.annotation.Autowired; 21 import org.springframework.stereotype.Controller; 22 import org.springframework.ui.Model; 23 import org.springframework.web.bind.annotation.ModelAttribute; 24 import org.springframework.web.bind.annotation.PathVariable; 25 import org.springframework.web.bind.annotation.RequestMapping; 26 import org.springframework.web.bind.annotation.RequestMethod; 27 import org.springframework.web.bind.annotation.RequestParam; 28 import org.springframework.web.bind.annotation.ResponseBody; 29 import org.springframework.web.multipart.MultipartFile; 30 import org.springframework.web.servlet.mvc.support.RedirectAttributes; 31 32 import com.google.common.collect.Lists; 33 import com.google.common.collect.Maps; 34 import com.jeeplus.common.utils.DateUtils; 35 import com.jeeplus.common.utils.MyBeanUtils; 36 import com.jeeplus.common.config.Global; 37 import com.jeeplus.common.persistence.Page; 38 import com.jeeplus.common.web.BaseController; 39 import com.jeeplus.common.utils.StringUtils; 40 import com.jeeplus.common.utils.excel.ExportExcel; 41 import com.jeeplus.common.utils.excel.ImportExcel; 42 import com.jeeplus.modules.sys.entity.Role; 43 import com.jeeplus.modules.sys.entity.User; 44 import com.jeeplus.modules.sys.security.SystemAuthorizingRealm.Principal; 45 import com.jeeplus.modules.sys.service.SystemService; 46 import com.jeeplus.modules.sys.utils.UserUtils; 47 import com.jeeplus.modules.zdcj.entity.ZdcjApply; 48 import com.jeeplus.modules.zdcj.service.CactivitiService; 49 import com.jeeplus.modules.zdcj.service.ZdcjApplyService; 50 import com.jeeplus.modules.zdcj.service.ZdcjUserService; 51 52 import org.activiti.engine.ProcessEngine; 53 import org.activiti.engine.ProcessEngines; 54 import org.activiti.engine.repository.Deployment; 55 import org.activiti.engine.repository.ProcessDefinition; 56 import org.activiti.engine.runtime.ProcessInstance; 57 import org.activiti.engine.task.Task; 58 59 /** 60 * 申请主播Controller 61 * @author ywj 62 * @version 2016-12-22 63 */ 64 @Controller 65 @RequestMapping(value = "${adminPath}/zdcj/zdcjApply") 66 public class ZdcjApplyController extends BaseController { 67 68 @Autowired 69 private ZdcjApplyService zdcjApplyService; 70 71 @Autowired 72 private CactivitiService cactivitiService; 73 74 @Autowired 75 private SystemService systemService; 76 77 ProcessEngine processEngine=ProcessEngines.getDefaultProcessEngine(); 78 79 @ModelAttribute 80 public ZdcjApply get(@RequestParam(required=false) String id) { 81 ZdcjApply entity = null; 82 if (StringUtils.isNotBlank(id)){ 83 entity = zdcjApplyService.get(id); 84 } 85 if (entity == null){ 86 entity = new ZdcjApply(); 87 } 88 return entity; 89 } 90 91 /** 92 * 申请信息列表页面 93 */ 94 @RequiresPermissions("zdcj:zdcjApply:list") 95 @RequestMapping(value = {"list", ""}) 96 public String list(ZdcjApply zdcjApply, HttpServletRequest request, HttpServletResponse response, Model model) { 97 Page<ZdcjApply> page = zdcjApplyService.findPage(new Page<ZdcjApply>(request, response), zdcjApply); 98 List<ZdcjApply> aj=page.getList(); 99 for (ZdcjApply aa : aj) { 100 Map map=new HashMap(); 101 map.put("instanceId", aa.getProcessInstanceId()); 102 List<Task> tk=cactivitiService.findMyPer(map); 103 if(tk!=null && tk.size()>0){ 104 aa.setTask(tk.get(0)); 105 } 106 } 107 model.addAttribute("page", page); 108 return "modules/zdcj/zdcjApplyList"; 109 } 110 111 /** 112 * 查看,增加,编辑申请信息表单页面 113 */ 114 @RequiresPermissions(value={"zdcj:zdcjApply:view","zdcj:zdcjApply:add","zdcj:zdcjApply:edit"},logical=Logical.OR) 115 @RequestMapping(value = "form") 116 public String form(ZdcjApply zdcjApply, Model model) { 117 model.addAttribute("zdcjApply", zdcjApply); 118 return "modules/zdcj/zdcjApplyForm"; 119 } 120 121 /** 122 * 保存申请信息 123 */ 124 @RequiresPermissions(value={"zdcj:zdcjApply:add","zdcj:zdcjApply:edit"},logical=Logical.OR) 125 @RequestMapping(value = "save") 126 public String save(ZdcjApply zdcjApply, Model model, RedirectAttributes redirectAttributes, 127 HttpServletRequest request, HttpServletResponse response) throws Exception{ 128 Principal principal = UserUtils.getPrincipal(); 129 String tongyi=request.getParameter("tongyi"); 130 tongyi=tongyi+""; 131 //是否同意 true 同意, FALSE 不同意 132 Boolean message=false; 133 if(tongyi.equals("同意")){ 134 message=true; 135 }else if(tongyi.equals("不同意")){ 136 message=false; 137 } 138 if (!beanValidator(model, zdcjApply)){ 139 return form(zdcjApply, model); 140 } 141 if(!zdcjApply.getIsNewRecord()){//编辑表单保存 142 143 User r=systemService.getUser(principal.getId()); 144 145 String rname=r.getRoleList().get(0).getEnname(); 146 if(null!=rname && !"".equals(rname)){ 147 }else{ 148 addMessage(redirectAttributes, "抱歉 审核失败"); 149 return "redirect:"+Global.getAdminPath()+"/zdcj/zdcjApply/?repage"; 150 } 151 152 if(zdcjApply.getProcessInstanceId()!=null && !"".equals(zdcjApply.getProcessInstanceId())){ 153 Map map=new HashMap(); 154 map.put("instanceId", zdcjApply.getProcessInstanceId()); 155 List<Task> tk=cactivitiService.findMyPer(map); 156 if(tk.get(0).getTaskDefinitionKey().equals("CustomerService")){ 157 User rs=systemService.getUser(zdcjApply.getUserId()); 158 System.out.println("客服审批"); 159 if(rname.equals("kefu")){ 160 cactivitiService.completeMyPer(tk.get(0).getId() ,"deptLeaderPass" , message,rs.getName()); 161 addMessage(redirectAttributes, "审核成功"); 162 }else{ 163 addMessage(redirectAttributes, "抱歉 审核失败"); 164 return "redirect:"+Global.getAdminPath()+"/zdcj/zdcjApply/?repage"; 165 } 166 }else if(tk.size()>0 && tk.get(0).getTaskDefinitionKey().equals("director")){ 167 System.out.println("主管审批"); 168 User rs=systemService.getUser(zdcjApply.getUserId()); 169 if(rname.equals("kfadmin")){ 170 cactivitiService.completeMyPer(tk.get(0).getId() ,"dirPass" , message,rs.getName()); 171 if(message==true){ 172 zdcjApply.setApplystatus("1"); 173 zdcjApplyService.save(zdcjApply);//保存 174 addMessage(redirectAttributes, "审核成功,申请通过"); 175 }else{ 176 addMessage(redirectAttributes, "审核成功,调整申请"); 177 } 178 }else{ 179 addMessage(redirectAttributes, "抱歉 审核失败"); 180 return "redirect:"+Global.getAdminPath()+"/zdcj/zdcjApply/?repage"; 181 } 182 }else if(tk.size()>0 && tk.get(0).getTaskDefinitionKey().equals("modifyApply")){ 183 System.out.println("调整申请"); 184 if(true){ 185 cactivitiService.completeMyPer(tk.get(0).getId() ,"reApply" , message,principal.getName()); 186 if(message==true){ 187 zdcjApplyService.save(zdcjApply);//保存 188 addMessage(redirectAttributes, "重新提交成功"); 189 }else{ 190 zdcjApply.setApplystatus("2"); 191 zdcjApplyService.save(zdcjApply);//保存 192 addMessage(redirectAttributes, "审核结束,申请未通过"); 193 } 194 }/*else{ 195 addMessage(redirectAttributes, "抱歉 审核失败"); 196 return "redirect:"+Global.getAdminPath()+"/zdcj/zdcjApply/?repage"; 197 }*/ 198 }else{ 199 addMessage(redirectAttributes, "抱歉 审核失败"); 200 return "redirect:"+Global.getAdminPath()+"/zdcj/zdcjApply/?repage"; 201 } 202 }else{ 203 addMessage(redirectAttributes, "抱歉 审核失败"); 204 } 205 206 }else{//新增表单保存 207 try { 208 zdcjApply.setUserId(principal.getId()); 209 //流程定义的id 210 if(null==zdcjApply.getApplystatus() || "".equals(zdcjApply.getApplystatus())){ 211 zdcjApply.setApplystatus("0"); 212 } 213 cactivitiService.startProc(zdcjApply); 214 addMessage(redirectAttributes, "提交申请成功"); 215 } catch (Exception e) { 216 addMessage(redirectAttributes, "提交申请失败,您可能没有部署流程定义"); 217 e.printStackTrace(); 218 } 219 } 220 221 return "redirect:"+Global.getAdminPath()+"/zdcj/zdcjApply/?repage"; 222 } 223 224 /** 225 * 部署流程信息 226 */ 227 @RequiresPermissions("zdcj:zdcjApply:add") 228 @RequestMapping(value = "bushu") 229 public String bushu(ZdcjApply zdcjApply, RedirectAttributes redirectAttributes) { 230 try { 231 String name="";//zdcjApply.getName(); 232 String aa=cactivitiService.save_inputStream(name); 233 addMessage(redirectAttributes, "部署成功"); 234 235 } catch (Exception e) { 236 addMessage(redirectAttributes, "部署失败"); 237 e.printStackTrace(); 238 } 239 return "redirect:"+Global.getAdminPath()+"/zdcj/zdcjApply/?repage"; 240 } 241 242 /** 243 * 签收任务 244 */ 245 @RequiresPermissions("zdcj:zdcjApply:edit") 246 @RequestMapping(value = "qianshou") 247 public String qianshou(ZdcjApply zdcjApply, RedirectAttributes redirectAttributes) { 248 Principal principal = UserUtils.getPrincipal(); 249 String userId = principal.getName(); 250 251 //判断角色 252 User r=systemService.getUser(principal.getId()); 253 254 String rname=r.getRoleList().get(0).getEnname(); 255 if(null!=rname && !"".equals(rname)){ 256 }else{ 257 addMessage(redirectAttributes, "您不能该签收任务"); 258 return "redirect:"+Global.getAdminPath()+"/zdcj/zdcjApply/?repage"; 259 } 260 261 262 if(zdcjApply.getProcessInstanceId()!=null && !"".equals(zdcjApply.getProcessInstanceId())){ 263 Map map=new HashMap(); 264 map.put("instanceId", zdcjApply.getProcessInstanceId()); 265 List<Task> tk=cactivitiService.findMyPer(map); 266 if(tk.size()>0 && tk.get(0).getTaskDefinitionKey().equals("CustomerService")){ 267 System.out.println("客服审批"); 268 if(rname.equals("kefu")){ 269 cactivitiService.claim(tk.get(0).getId(), userId); 270 addMessage(redirectAttributes, "任务已签收"); 271 }else{ 272 addMessage(redirectAttributes, "您不能签收该任务"); 273 return "redirect:"+Global.getAdminPath()+"/zdcj/zdcjApply/?repage"; 274 } 275 }else if(tk.size()>0 && tk.get(0).getTaskDefinitionKey().equals("director")){ 276 System.out.println("主管审批"); 277 if(rname.equals("kfadmin")){ 278 cactivitiService.claim(tk.get(0).getId(), userId); 279 addMessage(redirectAttributes, "任务已签收"); 280 }else{ 281 addMessage(redirectAttributes, "您不能该签收任务"); 282 return "redirect:"+Global.getAdminPath()+"/zdcj/zdcjApply/?repage"; 283 } 284 }else{ 285 addMessage(redirectAttributes, "您不能该签收任务"); 286 return "redirect:"+Global.getAdminPath()+"/zdcj/zdcjApply/?repage"; 287 } 288 }else{ 289 addMessage(redirectAttributes, "任务签收失败"); 290 } 291 292 return "redirect:"+Global.getAdminPath()+"/zdcj/zdcjApply/?repage"; 293 } 294 295 /** 296 * APP接口调用 查询流程进度 297 */ 298 @ResponseBody 299 @RequestMapping(value = "app_queryActiviti") 300 public Map<String, Object> app_queryActiviti( @RequestParam(required=false)String id 301 ,HttpServletRequest request, HttpServletResponse response, Model model) { 302 Map<String, Object> map = null; 303 try { 304 map = Maps.newHashMap(); 305 if (null==id || "".equals(id)) { 306 map.put("stauts", "1"); 307 map.put("message", "查询错误 :系统参数异常"); 308 }else{ 309 ZdcjApply zj=zdcjApplyService.get(id); 310 Map map2=new HashMap(); 311 map2.put("instanceId", zj.getProcessInstanceId()); 312 Task task=cactivitiService.findMyPer(map2).get(0); 313 //zj.setTask(tk.get(0)); 314 map.put("stauts", "0"); 315 map.put("message", "查询成功"); 316 Map map3=new HashMap(); 317 map3.put("zdcjApply", zj); 318 map3.put("taskId", task.getId()); 319 map3.put("taskName", task.getName());//任务节点 320 map3.put("taskCreateTime", task.getCreateTime());//任务创建时间 321 map3.put("taskAssignee", task.getAssignee());//任务办理人 322 //map3.put("processInstanceId", task.getProcessInstanceId());//流程实例id 323 map3.put("executionId", task.getExecutionId());//执行对象id 324 map3.put("processDefinitionId", task.getProcessDefinitionId());//流程定义id 325 map.put("data", map3); 326 } 327 } catch (Exception e) { 328 e.printStackTrace(); 329 map.put("stauts", "1"); 330 map.put("message", "查询错误 "); 331 } 332 333 return map; 334 } 335 336 /** 337 * 删除申请信息 338 */ 339 @RequiresPermissions("zdcj:zdcjApply:del") 340 @RequestMapping(value = "delete") 341 public String delete(ZdcjApply zdcjApply, RedirectAttributes redirectAttributes) { 342 /*processEngine.getRepositoryService() 343 .deleteDeployment("45012",true);//删除流程定义*/ 344 zdcjApplyService.delete(zdcjApply); 345 addMessage(redirectAttributes, "删除申请信息成功"); 346 return "redirect:"+Global.getAdminPath()+"/zdcj/zdcjApply/?repage"; 347 } 348 349 /** 350 * 批量删除申请信息 351 */ 352 @RequiresPermissions("zdcj:zdcjApply:del") 353 @RequestMapping(value = "deleteAll") 354 public String deleteAll(String ids, RedirectAttributes redirectAttributes) { 355 String idArray[] =ids.split(","); 356 for(String id : idArray){ 357 zdcjApplyService.delete(zdcjApplyService.get(id)); 358 } 359 addMessage(redirectAttributes, "删除申请信息成功"); 360 return "redirect:"+Global.getAdminPath()+"/zdcj/zdcjApply/?repage"; 361 } 362 363 /** 364 * 导出excel文件 365 */ 366 @RequiresPermissions("zdcj:zdcjApply:export") 367 @RequestMapping(value = "export", method=RequestMethod.POST) 368 public String exportFile(ZdcjApply zdcjApply, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) { 369 try { 370 String fileName = "申请信息"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx"; 371 Page<ZdcjApply> page = zdcjApplyService.findPage(new Page<ZdcjApply>(request, response, -1), zdcjApply); 372 new ExportExcel("申请信息", ZdcjApply.class).setDataList(page.getList()).write(response, fileName).dispose(); 373 return null; 374 } catch (Exception e) { 375 addMessage(redirectAttributes, "导出申请信息记录失败!失败信息:"+e.getMessage()); 376 } 377 return "redirect:"+Global.getAdminPath()+"/zdcj/zdcjApply/?repage"; 378 } 379 380 /** 381 * 导入Excel数据 382 383 */ 384 @RequiresPermissions("zdcj:zdcjApply:import") 385 @RequestMapping(value = "import", method=RequestMethod.POST) 386 public String importFile(MultipartFile file, RedirectAttributes redirectAttributes) { 387 try { 388 int successNum = 0; 389 int failureNum = 0; 390 StringBuilder failureMsg = new StringBuilder(); 391 ImportExcel ei = new ImportExcel(file, 1, 0); 392 List<ZdcjApply> list = ei.getDataList(ZdcjApply.class); 393 for (ZdcjApply zdcjApply : list){ 394 try{ 395 zdcjApplyService.save(zdcjApply); 396 successNum++; 397 }catch(ConstraintViolationException ex){ 398 failureNum++; 399 }catch (Exception ex) { 400 failureNum++; 401 } 402 } 403 if (failureNum>0){ 404 failureMsg.insert(0, ",失败 "+failureNum+" 条申请信息记录。"); 405 } 406 addMessage(redirectAttributes, "已成功导入 "+successNum+" 条申请信息记录"+failureMsg); 407 } catch (Exception e) { 408 addMessage(redirectAttributes, "导入申请信息失败!失败信息:"+e.getMessage()); 409 } 410 return "redirect:"+Global.getAdminPath()+"/zdcj/zdcjApply/?repage"; 411 } 412 413 /** 414 * 下载导入申请信息数据模板 415 */ 416 @RequiresPermissions("zdcj:zdcjApply:import") 417 @RequestMapping(value = "import/template") 418 public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) { 419 try { 420 String fileName = "申请信息数据导入模板.xlsx"; 421 List<ZdcjApply> list = Lists.newArrayList(); 422 new ExportExcel("申请信息数据", ZdcjApply.class, 1).setDataList(list).write(response, fileName).dispose(); 423 return null; 424 } catch (Exception e) { 425 addMessage(redirectAttributes, "导入模板下载失败!失败信息:"+e.getMessage()); 426 } 427 return "redirect:"+Global.getAdminPath()+"/zdcj/zdcjApply/?repage"; 428 } 429 430 431 432 433 }
下面是流程图
1 <?xml version="1.0" encoding="UTF-8"?> 2 <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.kafeitu.me/demo/activiti/leave"> 3 <process id="ZdcjApply" name="申请主播" isExecutable="true"> 4 <documentation>客户申请主播</documentation> 5 <startEvent id="startevent1" name="Start" activiti:initiator="applyUserId"></startEvent> 6 <userTask id="CustomerService" name="客服审批" activiti:candidateGroups="kefu"></userTask> 7 <exclusiveGateway id="exclusivegateway5" name="Exclusive Gateway"></exclusiveGateway> 8 <userTask id="modifyApply" name="调整申请" activiti:assignee="${applyUserId}"></userTask> 9 <userTask id="director" name="主管审批" activiti:candidateGroups="kfadmin"></userTask> 10 <endEvent id="endevent1" name="End"></endEvent> 11 <exclusiveGateway id="exclusivegateway7" name="Exclusive Gateway"></exclusiveGateway> 12 <sequenceFlow id="flow2" sourceRef="startevent1" targetRef="CustomerService"></sequenceFlow> 13 <sequenceFlow id="flow3" sourceRef="CustomerService" targetRef="exclusivegateway5"></sequenceFlow> 14 <sequenceFlow id="flow4" name="不同意" sourceRef="exclusivegateway5" targetRef="modifyApply"> 15 <conditionExpression xsi:type="tFormalExpression"><![CDATA[${!deptLeaderPass}]]></conditionExpression> 16 </sequenceFlow> 17 <sequenceFlow id="flow10" name="重新申请" sourceRef="exclusivegateway7" targetRef="CustomerService"> 18 <conditionExpression xsi:type="tFormalExpression"><![CDATA[${reApply}]]></conditionExpression> 19 </sequenceFlow> 20 <sequenceFlow id="flow11" sourceRef="modifyApply" targetRef="exclusivegateway7"></sequenceFlow> 21 <sequenceFlow id="flow12" name="结束流程" sourceRef="exclusivegateway7" targetRef="endevent1"> 22 <conditionExpression xsi:type="tFormalExpression"><![CDATA[${!reApply}]]></conditionExpression> 23 </sequenceFlow> 24 <exclusiveGateway id="exclusivegateway8" name="Exclusive Gateway"></exclusiveGateway> 25 <sequenceFlow id="flow13" sourceRef="director" targetRef="exclusivegateway8"></sequenceFlow> 26 <sequenceFlow id="flow15" name="不同意" sourceRef="exclusivegateway8" targetRef="modifyApply"> 27 <conditionExpression xsi:type="tFormalExpression"><![CDATA[${!dirPass}]]></conditionExpression> 28 </sequenceFlow> 29 <sequenceFlow id="flow16" name="同意" sourceRef="exclusivegateway8" targetRef="endevent1"> 30 <conditionExpression xsi:type="tFormalExpression"><![CDATA[${dirPass}]]></conditionExpression> 31 </sequenceFlow> 32 <sequenceFlow id="flow17" name="同意" sourceRef="exclusivegateway5" targetRef="director"> 33 <conditionExpression xsi:type="tFormalExpression"><![CDATA[${deptLeaderPass}]]></conditionExpression> 34 </sequenceFlow> 35 </process> 36 <bpmndi:BPMNDiagram id="BPMNDiagram_ZdcjApply"> 37 <bpmndi:BPMNPlane bpmnElement="ZdcjApply" id="BPMNPlane_ZdcjApply"> 38 <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1"> 39 <omgdc:Bounds height="35.0" width="35.0" x="10.0" y="90.0"></omgdc:Bounds> 40 </bpmndi:BPMNShape> 41 <bpmndi:BPMNShape bpmnElement="CustomerService" id="BPMNShape_CustomerService"> 42 <omgdc:Bounds height="55.0" width="105.0" x="90.0" y="80.0"></omgdc:Bounds> 43 </bpmndi:BPMNShape> 44 <bpmndi:BPMNShape bpmnElement="exclusivegateway5" id="BPMNShape_exclusivegateway5"> 45 <omgdc:Bounds height="40.0" width="40.0" x="250.0" y="87.0"></omgdc:Bounds> 46 </bpmndi:BPMNShape> 47 <bpmndi:BPMNShape bpmnElement="modifyApply" id="BPMNShape_modifyApply"> 48 <omgdc:Bounds height="55.0" width="105.0" x="218.0" y="190.0"></omgdc:Bounds> 49 </bpmndi:BPMNShape> 50 <bpmndi:BPMNShape bpmnElement="director" id="BPMNShape_director"> 51 <omgdc:Bounds height="55.0" width="105.0" x="390.0" y="80.0"></omgdc:Bounds> 52 </bpmndi:BPMNShape> 53 <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1"> 54 <omgdc:Bounds height="35.0" width="35.0" x="670.0" y="283.0"></omgdc:Bounds> 55 </bpmndi:BPMNShape> 56 <bpmndi:BPMNShape bpmnElement="exclusivegateway7" id="BPMNShape_exclusivegateway7"> 57 <omgdc:Bounds height="40.0" width="40.0" x="250.0" y="280.0"></omgdc:Bounds> 58 </bpmndi:BPMNShape> 59 <bpmndi:BPMNShape bpmnElement="exclusivegateway8" id="BPMNShape_exclusivegateway8"> 60 <omgdc:Bounds height="40.0" width="40.0" x="600.0" y="87.0"></omgdc:Bounds> 61 </bpmndi:BPMNShape> 62 <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2"> 63 <omgdi:waypoint x="45.0" y="107.0"></omgdi:waypoint> 64 <omgdi:waypoint x="90.0" y="107.0"></omgdi:waypoint> 65 </bpmndi:BPMNEdge> 66 <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3"> 67 <omgdi:waypoint x="195.0" y="107.0"></omgdi:waypoint> 68 <omgdi:waypoint x="250.0" y="107.0"></omgdi:waypoint> 69 </bpmndi:BPMNEdge> 70 <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4"> 71 <omgdi:waypoint x="270.0" y="127.0"></omgdi:waypoint> 72 <omgdi:waypoint x="270.0" y="190.0"></omgdi:waypoint> 73 <bpmndi:BPMNLabel> 74 <omgdc:Bounds height="14.0" width="36.0" x="280.0" y="149.0"></omgdc:Bounds> 75 </bpmndi:BPMNLabel> 76 </bpmndi:BPMNEdge> 77 <bpmndi:BPMNEdge bpmnElement="flow10" id="BPMNEdge_flow10"> 78 <omgdi:waypoint x="250.0" y="300.0"></omgdi:waypoint> 79 <omgdi:waypoint x="142.0" y="299.0"></omgdi:waypoint> 80 <omgdi:waypoint x="142.0" y="135.0"></omgdi:waypoint> 81 <bpmndi:BPMNLabel> 82 <omgdc:Bounds height="14.0" width="48.0" x="160.0" y="300.0"></omgdc:Bounds> 83 </bpmndi:BPMNLabel> 84 </bpmndi:BPMNEdge> 85 <bpmndi:BPMNEdge bpmnElement="flow11" id="BPMNEdge_flow11"> 86 <omgdi:waypoint x="270.0" y="245.0"></omgdi:waypoint> 87 <omgdi:waypoint x="270.0" y="280.0"></omgdi:waypoint> 88 </bpmndi:BPMNEdge> 89 <bpmndi:BPMNEdge bpmnElement="flow12" id="BPMNEdge_flow12"> 90 <omgdi:waypoint x="290.0" y="300.0"></omgdi:waypoint> 91 <omgdi:waypoint x="670.0" y="300.0"></omgdi:waypoint> 92 <bpmndi:BPMNLabel> 93 <omgdc:Bounds height="14.0" width="48.0" x="340.0" y="300.0"></omgdc:Bounds> 94 </bpmndi:BPMNLabel> 95 </bpmndi:BPMNEdge> 96 <bpmndi:BPMNEdge bpmnElement="flow13" id="BPMNEdge_flow13"> 97 <omgdi:waypoint x="495.0" y="107.0"></omgdi:waypoint> 98 <omgdi:waypoint x="600.0" y="107.0"></omgdi:waypoint> 99 </bpmndi:BPMNEdge> 100 <bpmndi:BPMNEdge bpmnElement="flow15" id="BPMNEdge_flow15"> 101 <omgdi:waypoint x="620.0" y="127.0"></omgdi:waypoint> 102 <omgdi:waypoint x="620.0" y="217.0"></omgdi:waypoint> 103 <omgdi:waypoint x="323.0" y="217.0"></omgdi:waypoint> 104 <bpmndi:BPMNLabel> 105 <omgdc:Bounds height="14.0" width="36.0" x="621.0" y="158.0"></omgdc:Bounds> 106 </bpmndi:BPMNLabel> 107 </bpmndi:BPMNEdge> 108 <bpmndi:BPMNEdge bpmnElement="flow16" id="BPMNEdge_flow16"> 109 <omgdi:waypoint x="640.0" y="107.0"></omgdi:waypoint> 110 <omgdi:waypoint x="686.0" y="106.0"></omgdi:waypoint> 111 <omgdi:waypoint x="687.0" y="283.0"></omgdi:waypoint> 112 <bpmndi:BPMNLabel> 113 <omgdc:Bounds height="14.0" width="24.0" x="669.0" y="89.0"></omgdc:Bounds> 114 </bpmndi:BPMNLabel> 115 </bpmndi:BPMNEdge> 116 <bpmndi:BPMNEdge bpmnElement="flow17" id="BPMNEdge_flow17"> 117 <omgdi:waypoint x="290.0" y="107.0"></omgdi:waypoint> 118 <omgdi:waypoint x="390.0" y="107.0"></omgdi:waypoint> 119 <bpmndi:BPMNLabel> 120 <omgdc:Bounds height="14.0" width="24.0" x="300.0" y="107.0"></omgdc:Bounds> 121 </bpmndi:BPMNLabel> 122 </bpmndi:BPMNEdge> 123 </bpmndi:BPMNPlane> 124 </bpmndi:BPMNDiagram> 125 </definitions>
最后sql也贴出来吧
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 3 <mapper namespace="com.jeeplus.modules.zdcj.dao.ZdcjApplyDao"> 4 5 <sql id="zdcjApplyColumns"> 6 a.id AS "id", 7 a.user_id AS "userId", 8 a.name AS "name", 9 a.mobile AS "mobile", 10 a.qq AS "qq", 11 a.email AS "email", 12 a.applystatus AS "applystatus", 13 a.create_by AS "createBy.id", 14 a.create_date AS "createDate", 15 a.update_by AS "updateBy.id", 16 a.update_date AS "updateDate", 17 a.remarks AS "remarks", 18 a.del_flag AS "delFlag", 19 a.process_instance_id AS "processInstanceId" 20 </sql> 21 22 <sql id="zdcjApplyJoins"> 23 </sql> 24 25 26 <select id="get" resultType="ZdcjApply" > 27 SELECT 28 <include refid="zdcjApplyColumns"/> 29 FROM zdcj_apply a 30 <include refid="zdcjApplyJoins"/> 31 WHERE a.id = #{id} 32 </select> 33 34 <select id="findList" resultType="ZdcjApply" > 35 SELECT 36 <include refid="zdcjApplyColumns"/> 37 FROM zdcj_apply a 38 <include refid="zdcjApplyJoins"/> 39 <where> 40 a.del_flag = #{DEL_FLAG_NORMAL} 41 <if test="name != null and name != ''"> 42 AND a.name LIKE 43 <if test="dbName == 'oracle'">'%'||#{name}||'%'</if> 44 <if test="dbName == 'mssql'">'%'+#{name}+'%'</if> 45 <if test="dbName == 'mysql'">concat('%',#{name},'%')</if> 46 </if> 47 <if test="mobile != null and mobile != ''"> 48 AND a.mobile LIKE 49 <if test="dbName == 'oracle'">'%'||#{mobile}||'%'</if> 50 <if test="dbName == 'mssql'">'%'+#{mobile}+'%'</if> 51 <if test="dbName == 'mysql'">concat('%',#{mobile},'%')</if> 52 </if> 53 <if test="qq != null and qq != ''"> 54 AND a.qq LIKE 55 <if test="dbName == 'oracle'">'%'||#{qq}||'%'</if> 56 <if test="dbName == 'mssql'">'%'+#{qq}+'%'</if> 57 <if test="dbName == 'mysql'">concat('%',#{qq},'%')</if> 58 </if> 59 <if test="email != null and email != ''"> 60 AND a.email LIKE 61 <if test="dbName == 'oracle'">'%'||#{email}||'%'</if> 62 <if test="dbName == 'mssql'">'%'+#{email}+'%'</if> 63 <if test="dbName == 'mysql'">concat('%',#{email},'%')</if> 64 </if> 65 <if test="applystatus != null and applystatus != ''"> 66 AND a.applystatus = #{applystatus} 67 </if> 68 <if test="createDate != null and createDate != ''"> 69 AND a.create_date = #{createDate} 70 </if> 71 </where> 72 <choose> 73 <when test="page !=null and page.orderBy != null and page.orderBy != ''"> 74 ORDER BY ${page.orderBy} 75 </when> 76 <otherwise> 77 ORDER BY a.update_date DESC 78 </otherwise> 79 </choose> 80 </select> 81 82 <select id="findAllList" resultType="ZdcjApply" > 83 SELECT 84 <include refid="zdcjApplyColumns"/> 85 FROM zdcj_apply a 86 <include refid="zdcjApplyJoins"/> 87 <where> 88 a.del_flag = #{DEL_FLAG_NORMAL} 89 </where> 90 <choose> 91 <when test="page !=null and page.orderBy != null and page.orderBy != ''"> 92 ORDER BY ${page.orderBy} 93 </when> 94 <otherwise> 95 ORDER BY a.update_date DESC 96 </otherwise> 97 </choose> 98 </select> 99 100 <insert id="insert"> 101 INSERT INTO zdcj_apply( 102 id, 103 user_id, 104 name, 105 mobile, 106 qq, 107 email, 108 applystatus, 109 create_by, 110 create_date, 111 update_by, 112 update_date, 113 remarks, 114 del_flag, 115 process_instance_id 116 ) VALUES ( 117 #{id}, 118 #{userId}, 119 #{name}, 120 #{mobile}, 121 #{qq}, 122 #{email}, 123 #{applystatus}, 124 #{createBy.id}, 125 #{createDate}, 126 #{updateBy.id}, 127 #{updateDate}, 128 #{remarks}, 129 #{delFlag}, 130 #{processInstanceId} 131 ) 132 </insert> 133 134 <update id="update"> 135 UPDATE zdcj_apply SET 136 user_id = #{userId}, 137 name = #{name}, 138 mobile = #{mobile}, 139 qq = #{qq}, 140 email = #{email}, 141 applystatus = #{applystatus}, 142 update_by = #{updateBy.id}, 143 update_date = #{updateDate}, 144 remarks = #{remarks}, 145 process_instance_id = #{processInstanceId} 146 WHERE id = #{id} 147 </update> 148 149 150 <!--物理删除--> 151 <update id="delete"> 152 DELETE FROM zdcj_apply 153 WHERE id = #{id} 154 </update> 155 156 <!--逻辑删除--> 157 <update id="deleteByLogic"> 158 UPDATE zdcj_apply SET 159 del_flag = #{DEL_FLAG_DELETE} 160 WHERE id = #{id} 161 </update> 162 163 164 <!-- 根据实体名称和字段名称和字段值获取唯一记录 --> 165 <select id="findUniqueByProperty" resultType="ZdcjApply" statementType="STATEMENT"> 166 select * FROM zdcj_apply where ${propertyName} = '${value}' 167 </select> 168 169 </mapper>