From 8407adff59ebc259596bc39a29a70968237390b2 Mon Sep 17 00:00:00 2001 From: zhangzhiguo <17621308561@163.com> Date: Wed, 27 Nov 2024 14:01:31 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=B1=E4=BA=AB=E5=AE=A1=E6=89=B9=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=88=86=E9=85=8D=20=E6=8A=A5=E9=94=80=E5=8D=95?= =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fs/plugin/form/DailyreimbursPlugin.java | 1 - .../ReimbursementCheckAttachmentPlugin.java | 1 - .../fs/plugin/form/UserHomeConfPlugin.java | 2 - .../zcdev/zcdev/fs/plugin/task/WorkTask.java | 83 +++++++ .../zcdev/fs/plugin/workflow/WorkLoadExt.java | 218 ++++++++++++++++++ 5 files changed, 301 insertions(+), 4 deletions(-) create mode 100644 code/zcdev/zcgj-zcdev-zcdev-fs/src/main/java/zcgj/zcdev/zcdev/fs/plugin/task/WorkTask.java create mode 100644 code/zcdev/zcgj-zcdev-zcdev-fs/src/main/java/zcgj/zcdev/zcdev/fs/plugin/workflow/WorkLoadExt.java diff --git a/code/zcdev/zcgj-zcdev-zcdev-fs/src/main/java/zcgj/zcdev/zcdev/fs/plugin/form/DailyreimbursPlugin.java b/code/zcdev/zcgj-zcdev-zcdev-fs/src/main/java/zcgj/zcdev/zcdev/fs/plugin/form/DailyreimbursPlugin.java index e83ffcf..c8d57f1 100644 --- a/code/zcdev/zcgj-zcdev-zcdev-fs/src/main/java/zcgj/zcdev/zcdev/fs/plugin/form/DailyreimbursPlugin.java +++ b/code/zcdev/zcgj-zcdev-zcdev-fs/src/main/java/zcgj/zcdev/zcdev/fs/plugin/form/DailyreimbursPlugin.java @@ -13,7 +13,6 @@ import kd.bos.orm.query.QCP; import kd.bos.orm.query.QFilter; import kd.bos.servicehelper.QueryServiceHelper; import kd.sdk.plugin.Plugin; -import zcgj.zcdev.zcdev.fs.plugin.task.WorkTask; import java.text.SimpleDateFormat; import java.time.LocalDate; diff --git a/code/zcdev/zcgj-zcdev-zcdev-fs/src/main/java/zcgj/zcdev/zcdev/fs/plugin/form/ReimbursementCheckAttachmentPlugin.java b/code/zcdev/zcgj-zcdev-zcdev-fs/src/main/java/zcgj/zcdev/zcdev/fs/plugin/form/ReimbursementCheckAttachmentPlugin.java index 1c8e929..6787d28 100644 --- a/code/zcdev/zcgj-zcdev-zcdev-fs/src/main/java/zcgj/zcdev/zcdev/fs/plugin/form/ReimbursementCheckAttachmentPlugin.java +++ b/code/zcdev/zcgj-zcdev-zcdev-fs/src/main/java/zcgj/zcdev/zcdev/fs/plugin/form/ReimbursementCheckAttachmentPlugin.java @@ -6,7 +6,6 @@ import kd.bos.entity.operate.Submit; import kd.bos.form.events.BeforeDoOperationEventArgs; import kd.sdk.plugin.Plugin; -import java.text.SimpleDateFormat; /** * 报销单附件控制插件 diff --git a/code/zcdev/zcgj-zcdev-zcdev-fs/src/main/java/zcgj/zcdev/zcdev/fs/plugin/form/UserHomeConfPlugin.java b/code/zcdev/zcgj-zcdev-zcdev-fs/src/main/java/zcgj/zcdev/zcdev/fs/plugin/form/UserHomeConfPlugin.java index f01dd6e..283d23a 100644 --- a/code/zcdev/zcgj-zcdev-zcdev-fs/src/main/java/zcgj/zcdev/zcdev/fs/plugin/form/UserHomeConfPlugin.java +++ b/code/zcdev/zcgj-zcdev-zcdev-fs/src/main/java/zcgj/zcdev/zcdev/fs/plugin/form/UserHomeConfPlugin.java @@ -13,8 +13,6 @@ import kd.bos.orm.query.QFilter; import kd.bos.servicehelper.BusinessDataServiceHelper; import kd.sdk.plugin.Plugin; -import java.text.SimpleDateFormat; - /** * 来往家居地配置界面插件 */ diff --git a/code/zcdev/zcgj-zcdev-zcdev-fs/src/main/java/zcgj/zcdev/zcdev/fs/plugin/task/WorkTask.java b/code/zcdev/zcgj-zcdev-zcdev-fs/src/main/java/zcgj/zcdev/zcdev/fs/plugin/task/WorkTask.java new file mode 100644 index 0000000..7a72585 --- /dev/null +++ b/code/zcdev/zcgj-zcdev-zcdev-fs/src/main/java/zcgj/zcdev/zcdev/fs/plugin/task/WorkTask.java @@ -0,0 +1,83 @@ +package zcgj.zcdev.zcdev.fs.plugin.task; + +import kd.bos.context.RequestContext; +import kd.bos.dataentity.entity.DynamicObject; +import kd.bos.exception.KDException; +import kd.bos.logging.Log; +import kd.bos.logging.LogFactory; +import kd.bos.orm.query.QCP; +import kd.bos.orm.query.QFilter; +import kd.bos.schedule.executor.AbstractTask; +import kd.bos.servicehelper.BusinessDataServiceHelper; +import kd.bos.servicehelper.operation.SaveServiceHelper; +import kd.bos.servicehelper.workflow.WorkflowServiceHelper; +import kd.ssc.task.disRebuild.engine.Distribution; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * 记录自动审批的调度任务 + */ +public class WorkTask extends AbstractTask { + + private static final Log log = LogFactory.getLog(WorkTask.class); + + //发送物料库存至消息平台 + @Override + public void execute(RequestContext requestContext, Map map) throws KDException { + long currUserId = requestContext.getCurrUserId(); + log.info("用户id " + currUserId + " 执行调度任务"); + //开发商标识 + String prefix ="zcgj"; + //查询审批记录表(二开基础资料) + String approvalsLogsEntityName = prefix+"_auto_approvals_logs"; + QFilter approvalFilter = new QFilter(prefix+"_isapprovals", QCP.equals, "A"); + DynamicObject[] logsToApprove = BusinessDataServiceHelper.load(approvalsLogsEntityName, "id,zcgj_billid,zcgj_bill_number,zcgj_bill_entityname,zcgj_isapprovals,zcgj_bill_sscid", new QFilter[]{approvalFilter}); + + for (DynamicObject log : logsToApprove) { + String billId = log.getString(prefix+"_billid"); + String billNumber = log.getString(prefix+"_bill_number"); + String billEntityName = log.getString(prefix+"_bill_entityname"); + String billSscid = log.getString(prefix+"_bill_sscid"); + + // 获取当前任务节点的审批人 + List approvers = WorkflowServiceHelper.getApproverByBusinessKey(billId); + + if (!approvers.isEmpty()) { + Long firstApproverId = approvers.get(0); + + //获取共享任务中心任务数据,作为传入机器人审批的task数据 + QFilter nameQFilter = new QFilter("billid",QCP.equals,billId); + DynamicObject[] taskTasks = BusinessDataServiceHelper.load("task_task", "billnumber,billid,billno,apprevalmessage", new QFilter[]{nameQFilter}); + + //机器审批组审批的task集合 + List taskList = new ArrayList<>(Arrays.asList(taskTasks)); + + //自动审核制定机器人组逻辑 + //1.获取共享中心id billSscid + + //2.通过单据获得的共享中心ID查询当前共享中心下的机器人组 + //获取共享组织下的机器人组 + QFilter nameQFilterEntity = new QFilter("createorg",QCP.equals,Long.valueOf(billSscid)) + .and(new QFilter("number",QCP.equals,"robots")) + .and(new QFilter("isrobots",QCP.equals,"1")); + DynamicObject[] userGroupObject = BusinessDataServiceHelper.load("task_usergroup", "id", new QFilter[]{nameQFilterEntity}); + if(userGroupObject!=null && userGroupObject.length>0){ + DynamicObject doj = userGroupObject[0]; + long userGroupBotsId = doj.getLong("id"); + //分配到机器人组进行自动审批 + //manualDisTaskDeal4Batch(机器人用户组,审批人员id,task集合) + //审批人可以指定实际人,也可以创建一个机器人用户进行审批。用户组的人员id可以不在机器人用户组中,这个审批人是显示在流程中的人 + //机器人审批 + List longs = Distribution.manualDisTaskDeal4Batch(userGroupBotsId, firstApproverId, taskList); + // 更改任务状态为已审批 + log.set(prefix+"_isapprovals", "B"); + SaveServiceHelper.update(log); + } + } + } + } +} diff --git a/code/zcdev/zcgj-zcdev-zcdev-fs/src/main/java/zcgj/zcdev/zcdev/fs/plugin/workflow/WorkLoadExt.java b/code/zcdev/zcgj-zcdev-zcdev-fs/src/main/java/zcgj/zcdev/zcdev/fs/plugin/workflow/WorkLoadExt.java new file mode 100644 index 0000000..0bd342a --- /dev/null +++ b/code/zcdev/zcgj-zcdev-zcdev-fs/src/main/java/zcgj/zcdev/zcdev/fs/plugin/workflow/WorkLoadExt.java @@ -0,0 +1,218 @@ +package zcgj.zcdev.zcdev.fs.plugin.workflow; + +import kd.bos.dataentity.entity.DynamicObject; +import kd.bos.orm.query.QCP; +import kd.bos.orm.query.QFilter; +import kd.bos.servicehelper.BusinessDataServiceHelper; +import kd.bos.servicehelper.operation.SaveServiceHelper; +import kd.bos.servicehelper.workflow.WorkflowServiceHelper; +import kd.bos.workflow.component.approvalrecord.IApprovalRecordGroup; +import kd.bos.workflow.engine.dynprocess.freeflow.WFAuditTask; +import kd.bos.workflow.engine.dynprocess.freeflow.WFCustomParam; +import kd.bos.workflow.engine.dynprocess.freeflow.WFFlowElement; +import kd.ssc.task.dis.WorkLoad; +import kd.ssc.task.dis.WorkerStatusPojo; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * 共享任务人员重分配 + */ +public class WorkLoadExt extends WorkLoad { + + + @Override + public Set deletePerson4Return(Long groupId, DynamicObject task) { + Set longs = super.deletePerson4Return(groupId, task); + //开发商标识 + String prefix ="zcgj"; + //是否自动审批通过 + boolean isAutoPass = false; + boolean isVoucher = false; + // 组->人映射,<组ID,组中人员工作状态信息> + //获取所有的共享审批组 + Map> groupPersonMap = getGroupPersonMap(); + // 记录删除的处理人 + //((DynamicObject)task.get("tasktypeid")).get("number") + List delPersonsList = getDeletedPersonsList(); + //获取当前共享审批组 + List workLoadList = groupPersonMap.get(groupId); + if (workLoadList == null) { + workLoadList = new ArrayList<>(10); + groupPersonMap.put(groupId, workLoadList); + } + //迭代共享审批组 + Iterator it = workLoadList.iterator(); + //获取单据的创建人 + /*DynamicObject creator = (DynamicObject)task.get("creator"); + long crtUserId = creator.getLong("id");*/ + //当前单据的id + String billid = task.getString("billid"); + //单据编码 + String billnumber = task.getString("billnumber"); + //单据实体 + String entityName = String.valueOf(((DynamicObject) ((DynamicObject) task.get("billtype")).get("bindBill")).get("number")); + //共享中心id + String sscid = ((DynamicObject) task.get("sscid")).getString("id"); + //审批节点名称 + String string = task.getString("subject"); + //流程实例id + //Long processInstanceIdByBusinessKey = WorkflowServiceHelper.getProcessInstanceIdByBusinessKey(billid); + List approvalUserIds = new ArrayList<>(); + //所有审批记录,从审批记录中获取已经审批过的人 + List allApprovalRecords = WorkflowServiceHelper.getApprovalRecords(entityName, billid, true); + for (IApprovalRecordGroup allApprovalRecord : allApprovalRecords) { + String groupDecisionType = allApprovalRecord.getGroupDecisionType(); + //过滤提交的和待分配的任务 + if(!"submit".equals(groupDecisionType) && !"wait".equals(groupDecisionType)){ //获取每个节点的审批类型 提交:submit + Long userId = allApprovalRecord.getChildren().get(0).getUserId();//获取每个节点的审批人 + approvalUserIds.add(userId); + } + } + + //通过billid获取流程实例id + Long processInstanceIdByBusinessKey = WorkflowServiceHelper.getProcessInstanceIdByBusinessKey(billid); + //通过流程实例id获取wf_task数据,用于获取和过滤共享节点的配置参数 + QFilter taskFilter1 = new QFilter("processinstanceid", QCP.equals, processInstanceIdByBusinessKey); + DynamicObject[] taskDynamicObjects = BusinessDataServiceHelper.load("wf_task", "taskdefinitionkey", new QFilter[]{taskFilter1}); + //构建单据对象,用于查询单据的工作流流程元素数据 + DynamicObject billDynamicObject = BusinessDataServiceHelper.newDynamicObject(entityName); + billDynamicObject.set("id",billid); + List processElements = WorkflowServiceHelper.getProcessElements(billDynamicObject, null); + //查询流程元素数据 + List sscApprove = processElements.stream().filter(e -> e.getId().equals(taskDynamicObjects[0].get("taskdefinitionkey"))).collect(Collectors.toList()); + WFFlowElement wfFlowElement = sscApprove.get(0); + //获取流程配置参数 + List customParams = ((WFAuditTask) wfFlowElement).getCustomParams(); + //遍历流程配置的参数,获取isVoucher用来判断当前节点是否要生成凭证 + for (WFCustomParam customParam : customParams) { + String number = customParam.getNumber(); + String value = customParam.getValue(); + //如果当前节点需要生成凭证 + if(number.equals("isVoucher") && value.equals("true")){ + isVoucher= true; + } + } + //当前共享组所有审批人员ID集合 + List sharedApprovers = workLoadList.stream().map(WorkerStatusPojo::getUserId).collect(Collectors.toList()); + //当前流程已经审批过的所有人员ID集合 + List localApprovers = approvalUserIds.stream().sorted().collect(Collectors.toList()); + + //localApprovers.add(crtUserId);//测试 + + //获取需要移除的审批人和是否自动审批 + Map stringObjectMap = handleApproval(localApprovers, sharedApprovers); + + //是否自动审批 + isAutoPass = (boolean)stringObjectMap.get("isAutoPass"); + //需要移除的人员id集合 + Set userIdSet = (Set)stringObjectMap.get("removedApprovers"); + + //记录审批日期,如果需要自动审批则isapprovals设置为A + String approvalsLogsEntityName = "zcgj_auto_approvals_logs"; + DynamicObject dynamicObject = BusinessDataServiceHelper.newDynamicObject(approvalsLogsEntityName); + //日志编码 + dynamicObject.set("number",System.currentTimeMillis()); + //审批节点名称 + dynamicObject.set("name", string); + //业务单据名称 + //dynamicObject.set(prefix+"_bill_name", billname); + //业务单据id + dynamicObject.set(prefix+"_billid", billid); + //业务单据编码 + dynamicObject.set(prefix+"_bill_number", billnumber); + //业务单据标识 + dynamicObject.set(prefix+"_bill_entityname", entityName); + //业务单据共享中心id + dynamicObject.set(prefix+"_bill_sscid",sscid); + + //自动审批且不需要生成凭证则可以执行自动审批 + if(isAutoPass && !isVoucher){ + dynamicObject.set(prefix+"_isapprovals","A");//自动审批 + dynamicObject.set(prefix+"_remark","机器人自动审批且不需要生成凭证"); + }else{ + dynamicObject.set(prefix+"_isapprovals","B");//不自动审批 + dynamicObject.set(prefix+"_remark","需要审核人手动审批或需要生成凭证"); + } + + Object[] save = SaveServiceHelper.save(new DynamicObject[]{dynamicObject}); + + //循环判断当前单据的共享审批节点是否有本地已经审批过的人,如果有则进行移除 + //如果本地没有审批人,则不移除审批人 + if(userIdSet == null || userIdSet.isEmpty()||localApprovers.isEmpty()){ + return longs; + } + //迭代审批人集合 + while (it.hasNext()) { + WorkerStatusPojo person = it.next(); + Long userId = person.getUserId(); + if (userIdSet.contains(userId)) { + // 记录删除的处理人 + longs.add(userId); + //记录需要删除的审批人,返回后系统会自动移除该共享组的审批人 + delPersonsList.add(person); + //迭代移除操作 + it.remove(); + } + //移除全部-测试用 + //it.remove(); + } + return longs; + } + + /** + * 处理审批逻辑 + * @param localApprovers 本地审批人列表 + * @param sharedApprovers 共享审批人列表 + */ + public static Map handleApproval(List localApprovers, List sharedApprovers) { + Map map = new HashMap<>(); + Set localSet = new HashSet<>(localApprovers); + Set sharedSet = new HashSet<>(sharedApprovers); + Set removedApprovers = new HashSet<>(sharedSet); + //是否自动审批通过 + boolean isAutoPass = false; + if(localApprovers.isEmpty()){ + System.out.println("本地无人审批,跳过移除审批人,不自动审批通过。"); + map.put("isAutoPass", isAutoPass); + map.put("removedApprovers", removedApprovers); + return map; + } + // 判断共享节点是否被完全覆盖 + if (localSet.containsAll(sharedSet)) { + // 完全覆盖:随机选择一个共享审批人,自动审批通过 + Long approver = getRandomApprover(sharedApprovers); + removedApprovers.remove(approver); + System.out.println("共享审批节点完全被覆盖,审批人:" + approver + ",自动审批通过。"); + System.out.println("被移除掉的审批人:" + removedApprovers); + isAutoPass =true; + } else { + // 未完全覆盖:选择不在本地节点中的共享审批人,不自动审批通过 + sharedSet.removeAll(localSet); + if (!sharedSet.isEmpty()) { + Long approver = sharedSet.iterator().next(); + removedApprovers.remove(approver); + System.out.println("共享审批节点未被完全覆盖,审批人:" + approver + ",不自动审批通过。"); + System.out.println("被移除掉的审批人:" + removedApprovers); + isAutoPass = false; + } else { + System.out.println("未找到合适的审批人。"); + } + } + map.put("isAutoPass", isAutoPass); + map.put("removedApprovers", removedApprovers); + return map; + } + + /** + * 随机选择一个审批人 + * @param approvers 审批人列表 + * @return 随机选择的审批人 + */ + public static Long getRandomApprover(List approvers) { + Random random = new Random(); + int index = random.nextInt(approvers.size()); + return approvers.get(index); + } +}