赞
踩
1、说明
某天接到领导的一个需求,让某个用户拥有超级审批权限,当该用户执行超级审批时,同一节点的其它审批人将默认通过。例如某会签节点中,张三、李四、王五均是审批人,若此时李四和王五尚未审批通过,且张三有超级审批的权限,则可以直接让李四和王五默认通过,从而达到快速通过审批节省时间的目的。
2、编写service
总体思路:①获取所需审批节点的所有有权限审批的人员id列表 ②调用ekp自带的审批接口逐一对节点进行审批
- package com.landray.kmss.xp.lbpm.workflow.service;
-
- import java.util.List;
-
- /**
- * @author liquid
- */
- public interface IXpLbpmService {
- /**
- * 当前节点审批通过(针对当前登录人)
- * @author liquid
- * @date 2022年6月28日
- * @param fdModelId 流程实例id(km_review_main.fd_id)
- * @param factNodeId 流程id(N2\N3\N4...)
- */
- void passProcess(String fdModelId, String factNodeId);
-
- /**
- * 获取节点实际处理人(有权限处理)id列表
- * @param fdModelId 流程实例id(km_review_main.fd_id)
- * @param factNodeId 流程id(N2\N3\N4...)
- */
- List<String> getActualHandlesByFactNodeId(String fdModelId, String factNodeId) throws Exception;
-
- /**
- * 超级审批
- * @author liquid
- * @date 2022年6月28日
- * @param fdModelId 流程实例id(km_review_main.fd_id)
- * @param factNodeId 流程id(N2\N3\N4...)
- * @return 审批结果(fail、success)
- */
- String superPassProcess(String fdModelId, String factNodeId, String handleId, String approveContent, String nextFactNodeId) throws Exception;
- }
- package com.landray.kmss.xp.lbpm.workflow.service.spring;
-
- import com.alibaba.fastjson.JSONObject;
- import com.landray.kmss.km.review.model.KmReviewMain;
- import com.landray.kmss.km.review.webservice.IKmReviewWebserviceService;
- import com.landray.kmss.km.review.webservice.KmReviewParamterForm;
- import com.landray.kmss.sys.lbpm.engine.api.NodeInstanceHolder;
- import com.landray.kmss.sys.lbpm.engine.api.ProcessHolder;
- import com.landray.kmss.sys.lbpm.engine.api.WorkitemHolder;
- import com.landray.kmss.sys.lbpm.engine.integrate.expecterlog.ILbpmExpecterLogService;
- import com.landray.kmss.sys.lbpm.engine.persistence.model.LbpmProcess;
- import com.landray.kmss.sys.lbpmservice.api.ApproveParameter;
- import com.landray.kmss.sys.lbpmservice.api.LbpmService;
- import com.landray.kmss.sys.lbpmservice.operation.handler.HandlerPassData;
- import com.landray.kmss.sys.lbpmservice.support.service.ILbpmProcessService;
- import com.landray.kmss.sys.lbpmservice.support.service.spring.LbpmAPIService;
- import com.landray.kmss.sys.lbpmservice.support.service.spring.LbpmProcessServiceImp;
- import com.landray.kmss.sys.organization.model.SysOrgElement;
- import com.landray.kmss.util.SpringBeanUtil;
- import com.landray.kmss.util.UserUtil;
- import com.landray.kmss.xp.app.km.review.util.XpReviewUtil;
- import com.landray.kmss.xp.lbpm.workflow.service.IXpLbpmService;
- import com.landray.kmss.xp.org.organizational.constant.XpSysOrgElementConstant;
- import com.landray.kmss.xp.org.organizational.util.XpOrgUtil;
-
- import java.util.List;
- import java.util.Map;
-
- /**
- * @author liquid
- */
- public class XpLbpmServiceImp implements IXpLbpmService {
- private ILbpmProcessService lbpmProcessService;
- private ILbpmExpecterLogService lbpmExpecterLogService;
- private LbpmService lbpmApiService;
- private IKmReviewWebserviceService kmReviewWebserviceService;
-
- public ILbpmProcessService getLbpmProcessService() {
- if (lbpmProcessService == null) {
- lbpmProcessService = (LbpmProcessServiceImp)SpringBeanUtil.getBean("lbpmProcessServiceTarget");
- }
- return lbpmProcessService;
- }
-
- public ILbpmExpecterLogService getLbpmExpecterLogService() {
- if (lbpmExpecterLogService == null) {
- lbpmExpecterLogService = (ILbpmExpecterLogService)SpringBeanUtil.getBean("lbpmExpecterLogService");
- }
- return lbpmExpecterLogService;
- }
-
- public LbpmService getLbpmApiService() {
- if (lbpmApiService == null) {
- lbpmApiService = (LbpmAPIService)SpringBeanUtil.getBean("lbpmServiceTarget");
- }
- return lbpmApiService;
- }
-
- public IKmReviewWebserviceService getKmReviewWebserviceService() {
- if (kmReviewWebserviceService == null) {
- kmReviewWebserviceService = (IKmReviewWebserviceService)SpringBeanUtil.getBean("kmReviewWebserviceServiceTarget");
- }
- return kmReviewWebserviceService;
- }
-
- /**
- * 当前节点审批通过(针对当前登录人)
- * @author liquid
- * @date 2022年6月28日
- * @param fdModelId 流程实例id(km_review_main.fd_id)
- * @param factNodeId 流程id(N2\N3\N4...)
- */
- @Override
- public void passProcess(String fdModelId, String factNodeId) {
- // 获取【主文档实例】
- KmReviewMain mainModel = (KmReviewMain) XpReviewUtil.getReviewMainModelById(fdModelId);
-
- // 获取【主文档实例对应的流程信息】
- LbpmService lbpmApiService = getLbpmApiService();
- ProcessHolder processHolder = lbpmApiService.load(mainModel);
-
- // 流程当前节点信息列表
- List<? extends NodeInstanceHolder> nodeInstHolders = processHolder.getCurrentNodeInfos();
- for (NodeInstanceHolder nodeInstHolder : nodeInstHolders) {
- // 非目标节点 → 跳过
- String thisFactNodeId = nodeInstHolder.getNodeInstance().getFdFactNodeId();
- if (!thisFactNodeId.equalsIgnoreCase(factNodeId)) {
- continue;
- }
-
- // 当前登录人此节点的全部事项
- List<? extends WorkitemHolder> workitemHolders = nodeInstHolder.getHandlerWrokitemInfos();
- for (WorkitemHolder workitemHolder : workitemHolders) {
- // 创建[通过]操作数据,此处就需要去参考[通过]操作的扩展描述
- HandlerPassData data = new HandlerPassData();
-
- // 驱动流程的操作参数,此处第二个参数参考[通过]操作的扩展描述
- ApproveParameter parameter = new ApproveParameter(workitemHolder, "handler_pass");
- parameter.setData(data);
- // 设置后续处理人的通知方式
- parameter.setNotifyType("todo;email");
- // 设置流程结束时通知当前处理人
- parameter.setNotifyOnFinish(true);
- // 设置审批意见
- parameter.setAuditNote(UserUtil.getUser().getFdName() + ": 执行超级审批");
-
- // 驱动流程...
- lbpmApiService.approveProcess(mainModel, parameter);
- }
- }
- }
-
- /**
- * 获取节点实际处理人(有权限处理)id列表
- * @param fdModelId 流程实例id(km_review_main.fd_id)
- * @param factNodeId 流程id(N2\N3\N4...)
- * @throws Exception 异常
- */
- @Override
- public List<String> getActualHandlesByFactNodeId(String fdModelId, String factNodeId) throws Exception {
- /* 获取实际处理人列表 */
- ILbpmExpecterLogService lbpmExpecterLogService = getLbpmExpecterLogService();
- Map<String, List<String>> nodeHandlersMap = lbpmExpecterLogService.findCurrentNodeIdHandlerIds(fdModelId);
- return nodeHandlersMap.get(factNodeId);
- }
-
- /**
- * 超级审批
- * @author liquid
- * @date 2022年6月28日
- * @param fdModelId 流程实例id(km_review_main.fd_id)
- * @param factNodeId 流程id(N2\N3\N4...)
- * @return 审批结果(fail、success)
- * @throws Exception 异常
- */
- @Override
- public String superPassProcess(String fdModelId, String factNodeId, String handleId, String approveContent, String nextFactNodeId) throws Exception {
- ILbpmProcessService lbpmProcessService = getLbpmProcessService();
- IKmReviewWebserviceService kmReviewWebserviceService = getKmReviewWebserviceService();
-
- /* 获取主文档实例 */
- KmReviewMain mainModel = (KmReviewMain) XpReviewUtil.getReviewMainModelById(fdModelId);
-
- /* 获取流程实例 */
- LbpmProcess process = (LbpmProcess) lbpmProcessService.findByPrimaryKey(fdModelId);
-
- /* 设置审批参数 */
- KmReviewParamterForm kmParamForm = new KmReviewParamterForm();
- // 流程模板id
- kmParamForm.setFdTemplateId(mainModel.getFdTemplate().getFdId());
- // 流程起草人
- JSONObject docCreator = new JSONObject();
- docCreator.put("Id", process.getFdCreator().getFdId());
- kmParamForm.setDocCreator(docCreator.toJSONString());
- // 流程实例id
- kmParamForm.setFdId(fdModelId);
- // 流程主题
- kmParamForm.setDocSubject(mainModel.getDocSubject());
- // 富文本(如果流程存在富文本内容,则不允许为空)
- kmParamForm.setDocContent("");
- JSONObject flowParam = new JSONObject();
- // 设置处理人
- SysOrgElement actualHandler = XpOrgUtil.getSysOrgElementById(handleId, SysOrgElement.class);
- // 如处理人是非人员类型(如岗位), 需获取岗位人员(多个取第一个)
- if (!actualHandler.getFdOrgType().equals(XpSysOrgElementConstant.ORG_TYPE_PERSON)) {
- handleId = ((SysOrgElement)actualHandler.getFdPersons().get(0)).getFdId();
- }
- JSONObject handler = new JSONObject();
- handler.put("Id", handleId);
- flowParam.put("handler", handler.toJSONString());
- // 操作类型(审批)
- flowParam.put("operationType", "handler_pass");
- // 审批意见
- flowParam.put("auditNote", approveContent);
- // 流向下一节点的ID,需要人工决策时设置此参数
- flowParam.put("futureNodeId", nextFactNodeId);
- kmParamForm.setFlowParam(flowParam.toJSONString());
-
- /* 执行超级审批 */
- try {
- // 多个处理人操作同一份文档时采用锁机制,必须等上一个处理人操作完成后才能操作下一个
- System.out.println("超级审批(参数): " + JSONObject.toJSONString(kmParamForm));
- kmReviewWebserviceService.approveProcess(kmParamForm);
- } catch (Exception e) {
- e.printStackTrace();
- return "fail";
- }
-
- return "success";
- }
- }
相关xml:
- <?xml version="1.0" encoding="UTF-8"?>
- <beans
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
- xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <bean
- id="xpLbpmTarget"
- class="com.landray.kmss.xp.lbpm.workflow.service.spring.XpLbpmServiceImp">
- </bean>
- </beans>
3、编写action
- package com.landray.kmss.xp.app.km.review.actions;
-
- import com.alibaba.fastjson.JSONObject;
- import com.landray.kmss.common.actions.ExtendAction;
- import com.landray.kmss.common.service.IBaseService;
- import com.landray.kmss.sys.formula.provider.function.OrgFunction;
- import com.landray.kmss.util.SpringBeanUtil;
- import com.landray.kmss.util.StringUtil;
- import com.landray.kmss.util.UserUtil;
- import com.landray.kmss.web.action.ActionForm;
- import com.landray.kmss.web.action.ActionForward;
- import com.landray.kmss.web.action.ActionMapping;
- import com.landray.kmss.xp.lbpm.workflow.service.IXpLbpmService;
- import com.landray.kmss.xp.util.XpRequestUtil;
-
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.util.ArrayList;
- import java.util.List;
-
- import static com.landray.kmss.tic.core.common.actions.TicCoreInvokeFuncAction.ReadAsChars;
-
- /**
- * @author liquid
- */
- public class XpReviewMainAction extends ExtendAction {
- private IXpLbpmService xpLbpmService;
-
- @Override
- protected IBaseService getServiceImp(HttpServletRequest request) {
- return null;
- }
-
- public IXpLbpmService getXpLbpmService() {
- if (xpLbpmService == null) {
- xpLbpmService = (IXpLbpmService)SpringBeanUtil.getBean("xpLbpmTarget");
- }
- return xpLbpmService;
- }
-
- /**
- * @apiNote 当前节点实际审批人(有审批权限)列表
- * @author liquid
- * @date 2022年6月28日
- * 传入参数-
- * modelId 流程模板实例id(km_review_main.fd_id,前端lbpm.modelId)
- * factNodeId 流程节点id(N1\N2\N3...)
- * 返回参数-
- * handles 审批人id列表
- */
- public ActionForward getActualHandlesByFactNodeId(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
- JSONObject result = new JSONObject();
- response.setHeader("Content-Type", "application/json;charset=utf-8");
- String bodyStr = ReadAsChars(request);
- JSONObject o = JSONObject.parseObject(bodyStr);
-
- /* 获取body参数 */
- String fdModelId = o.getString("modelId");
- String factNodeId = o.getString("factNodeId");
- // 参数校验
- if (StringUtil.isNull(fdModelId) || StringUtil.isNull(factNodeId)) {
- XpRequestUtil.setFailure(response, "调用失败:请检查参数[名]和[值]");
- return null;
- }
-
- /* 业务逻辑 */
- IXpLbpmService xpLbpmService = getXpLbpmService();
- List<String> handles = xpLbpmService.getActualHandlesByFactNodeId(fdModelId, factNodeId);
-
- /* 响应数据 */
- result.put("status", XpRequestUtil.STATUS_SUCCESS);
- result.put("code", XpRequestUtil.CODE_SUCCESS);
- result.put("msg", "调用成功");
- result.put("handles", handles == null ? new ArrayList<>() : handles);
- XpRequestUtil.setResponseResult(response, result);
-
- return null;
- }
-
- /**
- * @apiNote 当前节点审批通过(针对当前登录人)
- * @author liquid
- * @date 2022年6月28日
- * 传入参数-
- * modelId 流程模板实例id(km_review_main.fd_id,前端lbpm.modelId)
- * factNodeId 流程节点id(N1\N2\N3...)
- * 返回参数-
- * approveInfo 审批通过信息
- */
- public ActionForward approveProcessByFactNodeId(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
- JSONObject result = new JSONObject();
- response.setHeader("Content-Type", "application/json;charset=utf-8");
- String bodyStr = ReadAsChars(request);
- JSONObject o = JSONObject.parseObject(bodyStr);
-
- /* 获取body参数 */
- String fdModelId = o.getString("modelId");
- String factNodeId = o.getString("factNodeId");
-
- /* 业务逻辑 */
- IXpLbpmService xpLbpmService = getXpLbpmService();
- xpLbpmService.passProcess(fdModelId, factNodeId);
-
- /* 响应数据 */
- result.put("status", XpRequestUtil.STATUS_SUCCESS);
- result.put("code", XpRequestUtil.CODE_SUCCESS);
- result.put("msg", "调用成功");
- result.put("approveInfo", "审批成功");
- XpRequestUtil.setResponseResult(response, result);
-
- return null;
- }
-
- /**
- * @apiNote 超级审批(一次仅审批一个处理人)
- * @author liquid
- * @date 2022年6月29日
- * 传入参数-
- * modelId 流程模板实例id(km_review_main.fd_id,前端lbpm.modelId)
- * factNodeId 流程节点id(N1\N2\N3...)
- * handleId 处理人id
- * approveContent (可选)审批意见,默认值为:(特权人)特权人姓名 : 超级审批
- * nextFactNodeId (可选)当下流为人工决策时,需传入(N1\N2\N3...)
- * 返回参数-
- * approveInfo 审批通过信息
- * approveStatus 审批结果(fail、success、noPermission:无权限)
- */
- public ActionForward superApproveProcessByFactNodeId(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
- JSONObject result = new JSONObject();
- response.setHeader("Content-Type", "application/json;charset=utf-8");
- String bodyStr = ReadAsChars(request);
- JSONObject o = JSONObject.parseObject(bodyStr);
-
- /* 获取body参数 */
- String fdModelId = o.getString("modelId");
- String factNodeId = o.getString("factNodeId");
- String handleId = o.getString("handleId");
- String approveContent = o.getString("approveContent");
- String nextFactNodeId = o.getString("nextFactNodeId");
- // 参数校验
- if (StringUtil.isNull(fdModelId) || StringUtil.isNull(factNodeId) || StringUtil.isNull(handleId)) {
- result.put("status", XpRequestUtil.STATUS_ERROR);
- result.put("code", XpRequestUtil.CODE_ERROR);
- result.put("msg", "调用失败:请检查参数[名]和[值]");
- result.put("approveInfo", "审批失败");
- XpRequestUtil.setResponseResult(response, result);
- return null;
- }
- // 设置可选参数默认值
- approveContent = StringUtil.isNull(approveContent) ? "超级审批" : approveContent;
- approveContent = "(特权人)"+ UserUtil.getUser().getFdName() + " : " + approveContent;
- nextFactNodeId = StringUtil.isNull(approveContent) ? "" : nextFactNodeId;
-
- /* 业务逻辑 */
- // 1、校验调用者权限
- boolean isPrivileged = OrgFunction.chechPersonInGroup(UserUtil.getUser(), "超级审批");
- if (!isPrivileged) {
- /* 响应数据 - 成功 - 无审批权限 */
- result.put("status", XpRequestUtil.STATUS_SUCCESS);
- result.put("code", XpRequestUtil.CODE_SUCCESS);
- result.put("msg", "调用失败:当前登录人没有超级审批权限");
- result.put("approveInfo", "审批失败");
- result.put("approveStatus", "noPermission");
- XpRequestUtil.setResponseResult(response, result);
- return null;
- }
- // 2、执行超级审批
- IXpLbpmService xpLbpmService = getXpLbpmService();
- String approveStatus;
- try{
- approveStatus = xpLbpmService.superPassProcess(fdModelId, factNodeId, handleId, approveContent, nextFactNodeId);
- } catch (Exception e) {
- e.printStackTrace();
- /* 响应数据 - 失败 */
- result.put("status", XpRequestUtil.STATUS_ERROR);
- result.put("code", XpRequestUtil.CODE_ERROR);
- result.put("msg", "调用失败:请检查参数[名]和[值]");
- result.put("approveInfo", "审批失败");
- result.put("approveStatus", "fail");
- XpRequestUtil.setResponseResult(response, result);
- return null;
- }
-
- /* 响应数据 - 成功 */
- result.put("status", XpRequestUtil.STATUS_SUCCESS);
- result.put("code", XpRequestUtil.CODE_SUCCESS);
- result.put("msg", "调用成功");
- result.put("approveInfo", "success".equals(approveStatus) ? "审批成功" : "审批失败");
- result.put("approveStatus", approveStatus);
- XpRequestUtil.setResponseResult(response, result);
-
- return null;
- }
- }
相关xml:
- <?xml version="1.0" encoding="UTF-8"?>
- <beans
- xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
- <bean
- class="com.landray.kmss.xp.app.km.review.actions.XpReviewMainAction"
- name="/xp/app/km/review/actions/XpReviewMainAction.do"
- lazy-init="true"
- parent="KmssBaseAction">
- </bean>
- </beans>
4、前端调用
- /**
- * 超级审批
- * 注意:仅适用于[非编辑状态]的审批节点
- * 审批权限:群组 → 系统类 → 超级审批
- * 2022年7月2日22:21:04 测试通过
- * 2022年7月3日17:37:43 测试通过
- * @author liquid
- * @date 2022年7月2日
- * @param {string}[factNodeId=当前节点] 节点id(N1\N2\N3...)
- * @param {string}[approveContent] 审批意见
- * @param {string}[nextFactNodeId] 当下流为人工决策时,需传入(N1\N2\N3...)
- */
- let superApprovalCountLimit = 15;// 审批失败尝试次数上限(避免未知错误导致不断循环执行审批调用)
- let superApprovalCount = 0;
- function superApprove(factNodeId, approveContent, nextFactNodeId) {
- factNodeId = factNodeId || lbpm.nowNodeId;
- lui_loading(true, "<div style='text-align:center;width:100%;color:#6584ed'>正在执行超级审批...</div>");
- // 延迟执行超级审批,避免同步执行导致阻塞loading的显示
- setTimeout(()=>{
- __superApprove();
- }, 200);
-
- function __superApprove() {
- superApprovalCount ++;
- // (同步)获取节点实际审批人id
- let handlers;
- const _path_1 = "xp/app/km/review/actions/XpReviewMainAction.do?method=getActualHandlesByFactNodeId";
- const _data_1 = {
- modelId: lbpm.modelId,
- factNodeId: factNodeId,
- }
- ajaxAction(_path_1, _data_1, false, {
- success:(res)=>{
- if (res.status !== "success") { errorHandler(res); return; }
- handlers = res.handles;
- }
- })
- // 可能在点击超级审批的前一刻,最后一个审批人刚好审批完
- if (handlers.length === 0) {
- lui_loading(false);
- lui_fail("当前节点无审批人!");
- setTimeout(()=>{
- location.reload();
- }, 200)
- return;
- }
-
- // (同步)执行超级审批
- let isReturn = false;
- for (const handlerId of handlers) {
- if (isReturn) return;
- const _path_2 = "xp/app/km/review/actions/XpReviewMainAction.do?method=superApproveProcessByFactNodeId";
- const _data_2 = {
- modelId: lbpm.modelId,
- factNodeId: factNodeId,
- handleId: handlerId,
- approveContent: approveContent,
- nextFactNodeId: nextFactNodeId
- }
- ajaxAction(_path_2, _data_2, false, {
- success:(res)=>{
- if (res.status !== "success") {
- errorHandler(res, false);
- lui_loading(false);
- return;
- }
- // 成功回调
- console.log("超级审批返回:", res);
- // 无权限
- if (res.approveStatus === 'noPermission'){
- lui_loading(false);
- lui_fail("抱歉,您尚无超级审批权限!");
- isReturn = true;
- }
- // 有权限,审批失败(同时操作同一个文档导致)
- else if (res.approveStatus === "fail" && superApprovalCount <= superApprovalCountLimit) {
- console.log("审批失败,重新调用superApproval(),已调用次数:" + superApprovalCount);
- // 失败递归调用
- __superApprove(factNodeId);
- isReturn = true;
- }
- else if (superApprovalCount > superApprovalCountLimit) {
- console.log("审批失败,重新调用superApproval(),已达调用次数上限:" + superApprovalCount);
- lui_loading(false);
- lui_fail("超级审批:未知错误,请联系管理员");
- isReturn = true;
- }
- }
- })
- }
-
- lui_loading(false);
- lui_success("超级审批:执行完毕!");
- // 延迟刷新页面(以保证获取到最的流程状态信息)
- setTimeout(()=>{
- location.reload();
- }, 500)
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。