package com.kingdee.eas.custom.integration.weaveroa.utils; import com.kingdee.bos.BOSException; import com.kingdee.bos.Context; import com.kingdee.bos.dao.ormapping.ObjectUuidPK; import com.kingdee.bos.dao.ormapping.SQLAccessException; import com.kingdee.bos.metadata.entity.*; import com.kingdee.bos.util.BOSObjectType; import com.kingdee.bos.util.BOSUuid; import com.kingdee.eas.base.message.AssignReadFactory; import com.kingdee.eas.base.message.AssignReadInfo; import com.kingdee.eas.base.message.IAssignRead; import com.kingdee.eas.base.message.MsgStatus; import com.kingdee.eas.base.message.webservice.WSMessage; import com.kingdee.eas.base.message.webservice.WfrAssignMessage; import com.kingdee.eas.base.message.webservice.WfrProcMessage; import com.kingdee.eas.base.permission.IUser; import com.kingdee.eas.base.permission.UserFactory; import com.kingdee.eas.base.permission.UserInfo; import com.kingdee.eas.basedata.org.HROrgUnitInfo; import com.kingdee.eas.common.EASBizException; import com.kingdee.eas.custom.integration.base.util.EncryptUtil; import com.kingdee.eas.custom.integration.base.util.SHRApiUtils; import com.kingdee.eas.custom.integration.weaveroa.*; import com.kingdee.eas.custom.integration.weaveroa.bizEnum.InstanceStatusEnum; import com.kingdee.eas.custom.integration.weaveroa.bizEnum.IsRemarkEnum; import com.kingdee.eas.custom.integration.weaveroa.bizEnum.ViewTypeEnum; import com.kingdee.eas.hr.base.AbstractHRBillBaseInfo; import com.kingdee.eas.hr.base.HRBillStateEnum; import com.kingdee.shr.base.syssetting.util.BaseMetaDataUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.util.UriComponentsBuilder; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.sql.Time; /** * @Description 泛微OA消息工具类 * @Date 2026/3/10 16:08 * @Created by HeYuan */ public class WeaverOAMessageUtils { private static Logger logger = LoggerFactory.getLogger(WeaverOAMessageUtils.class); //HR组织 private static final HROrgUnitInfo HRORGUNITINFO = new HROrgUnitInfo(); static { HRORGUNITINFO.setId(BOSUuid.read("00000000-0000-0000-0000-000000000000CCE7AED4")); } /** * 流程任务完成 * * @param wfrMmessage * @return */ public static boolean completedApproveMessage(WfrProcMessage wfrMmessage) { logger.error("completedApproveMessage 开始"); try { Context ctx = SHRApiUtils.getContext(wfrMmessage.getCtx()); // String billID = wfrMmessage.getBillID(); BOSObjectType bosType = BOSUuid.read(billID).getType(); AbstractHRBillBaseInfo billInfo = (AbstractHRBillBaseInfo) BaseMetaDataUtil.getBizInterface(ctx, bosType).getValue(new ObjectUuidPK(billID)); //单据状态 HRBillStateEnum billState = billInfo.getBillState(); IWeaverOAApprovalInstance iWeaverOAApprovalInstance = WeaverOAApprovalInstanceFactory.getLocalInstance(ctx); FilterInfo filterInfo = new FilterInfo(); filterInfo.getFilterItems().add(new FilterItemInfo("instanceId", wfrMmessage.getProcInstId())); SelectorItemCollection sic = new SelectorItemCollection(); sic.add("*"); sic.add("taskList.*"); EntityViewInfo viewInfo = EntityViewInfo.getInstance(filterInfo, sic, null); WeaverOAApprovalInstanceCollection instanceCollection = iWeaverOAApprovalInstance.getWeaverOAApprovalInstanceCollection(viewInfo); if (!instanceCollection.isEmpty()) { WeaverOAApprovalInstanceInfo instanceInfo = instanceCollection.get(0); if (HRBillStateEnum.AUDITED.equals(billState)) { //审批通过 instanceInfo.setInstanceStatus(InstanceStatusEnum.APPROVED); } else if (HRBillStateEnum.AUDITEND.equals(billState)) { //审批不通过 instanceInfo.setInstanceStatus(InstanceStatusEnum.REJECTED); } WeaverOAApprovalInstanceTaskListCollection taskList = instanceInfo.getTaskList(); for (int i = 0; i < taskList.size(); i++) { WeaverOAApprovalInstanceTaskListInfo instanceTaskListInfo = taskList.get(i); instanceTaskListInfo.setViewtype(ViewTypeEnum.READ); instanceTaskListInfo.setIsremark(IsRemarkEnum.COMPLETED); //流程结束,需要将所有节点更新为归档 instanceTaskListInfo.setNodename("归档"); } //保存 iWeaverOAApprovalInstance.save(instanceInfo); } } catch (Exception e) { e.printStackTrace(); logger.error("流程任务完成 completedApprovMessage 报错: {}", e.getMessage(), e); return false; } return true; } /** * 更新节点消息查看类型 * * @param ctx * @return */ public static boolean updateNodeMessageViewType(String id, MsgStatus msgStatus, Context ctx) { logger.error("updateNodeMessageViewType 开始, id {} , msgStatus {}", id, msgStatus.getAlias()); ctx = SHRApiUtils.getContext(ctx); String bosType = BOSUuid.read(id).getType().toString(); logger.error("updateNodeMessageViewType bosType {}", bosType); if ("9623EB51".equals(bosType)) { try { //任务阅读表 IAssignRead assignReadIns = AssignReadFactory.getLocalInstance(ctx); AssignReadInfo assignReadInfo = assignReadIns.getAssignReadInfo(new ObjectUuidPK(id)); //节点任务id String assignId = assignReadInfo.getAssignID().toString(); IWeaverOAApprovalInstance iWeaverOAApprovalInstance = WeaverOAApprovalInstanceFactory.getLocalInstance(ctx); IWeaverOAApprovalInstanceTaskList iWeaverOAApprovalInstanceTaskList = WeaverOAApprovalInstanceTaskListFactory.getLocalInstance(ctx); FilterInfo filterInfo = new FilterInfo(); filterInfo.getFilterItems().add(new FilterItemInfo("flowid", assignId)); SelectorItemCollection sic = new SelectorItemCollection(); sic.add("*"); sic.add("parent.instanceStatus"); sic.add("parent.id"); EntityViewInfo viewInfo = EntityViewInfo.getInstance(filterInfo, sic, null); //审批实例任务列表 WeaverOAApprovalInstanceTaskListCollection instanceTaskListCol = iWeaverOAApprovalInstanceTaskList.getWeaverOAApprovalInstanceTaskListCollection(viewInfo); if (!instanceTaskListCol.isEmpty()) { WeaverOAApprovalInstanceTaskListInfo instanceTaskListInfo = instanceTaskListCol.get(0); WeaverOAApprovalInstanceInfo parent = instanceTaskListInfo.getParent(); //流程实例状态 if (InstanceStatusEnum.PENDING.equals(parent.getInstanceStatus())) { if (MsgStatus.READED.equals(msgStatus)) { //已读 instanceTaskListInfo.setViewtype(ViewTypeEnum.READ); } else { //未读 instanceTaskListInfo.setViewtype(ViewTypeEnum.UNREAD); } SelectorItemCollection updateSic = new SelectorItemCollection(); updateSic.add("viewtype"); //更新 iWeaverOAApprovalInstanceTaskList.updatePartial(instanceTaskListInfo, updateSic); //触发同步审批实例 iWeaverOAApprovalInstance.syncApprovalInstance(parent.getId().toString()); } } } catch (Exception e) { e.printStackTrace(); logger.error("updateNodeMessageViewType 报错: {}", e.getMessage(), e); return false; } } return true; } /** * 节点任务取消 * * @param wfrMmessage * @return */ public static boolean nodeCanceledApproveMessage(WfrAssignMessage wfrMmessage) { logger.error("nodeCanceledApproveMessage 开始"); try { Context ctx = SHRApiUtils.getContext(wfrMmessage.getCtx()); // //流程任务id String assignId = wfrMmessage.getAssignId(); IWeaverOAApprovalInstance iWeaverOAApprovalInstance = WeaverOAApprovalInstanceFactory.getLocalInstance(ctx); IWeaverOAApprovalInstanceTaskList iWeaverOAApprovalInstanceTaskList = WeaverOAApprovalInstanceTaskListFactory.getLocalInstance(ctx); FilterInfo filterInfo = new FilterInfo(); filterInfo.getFilterItems().add(new FilterItemInfo("flowid", assignId)); SelectorItemCollection sic = new SelectorItemCollection(); sic.add("*"); sic.add("parent.instanceStatus"); sic.add("parent.id"); EntityViewInfo viewInfo = EntityViewInfo.getInstance(filterInfo, sic, null); //审批实例任务列表 WeaverOAApprovalInstanceTaskListCollection instanceTaskListCol = iWeaverOAApprovalInstanceTaskList.getWeaverOAApprovalInstanceTaskListCollection(viewInfo); if (!instanceTaskListCol.isEmpty()) { WeaverOAApprovalInstanceTaskListInfo instanceTaskListInfo = instanceTaskListCol.get(0); WeaverOAApprovalInstanceInfo parent = instanceTaskListInfo.getParent(); //流程实例状态 if (InstanceStatusEnum.PENDING.equals(parent.getInstanceStatus())) { //已办 instanceTaskListInfo.setIsremark(IsRemarkEnum.PROCESSED); //已读 instanceTaskListInfo.setViewtype(ViewTypeEnum.READ); //保存 iWeaverOAApprovalInstanceTaskList.save(instanceTaskListInfo); //触发同步审批实例 iWeaverOAApprovalInstance.syncApprovalInstance(parent.getId().toString()); } } } catch (Exception e) { e.printStackTrace(); logger.error("节点任务转交 nodeCanceledApproveMessage 报错: {}", e.getMessage(), e); return false; } return true; } /** * 节点任务完成 * * @param wfrMmessage * @return */ public static boolean nodeCompletedApproveMessage(WfrAssignMessage wfrMmessage) { logger.error("nodeCompletedApproveMessage 开始"); try { Context ctx = SHRApiUtils.getContext(wfrMmessage.getCtx()); //流程任务id String assignId = wfrMmessage.getAssignId(); IWeaverOAApprovalInstance iWeaverOAApprovalInstance = WeaverOAApprovalInstanceFactory.getLocalInstance(ctx); IWeaverOAApprovalInstanceTaskList iWeaverOAApprovalInstanceTaskList = WeaverOAApprovalInstanceTaskListFactory.getLocalInstance(ctx); FilterInfo filterInfo = new FilterInfo(); filterInfo.getFilterItems().add(new FilterItemInfo("flowid", assignId)); SelectorItemCollection sic = new SelectorItemCollection(); sic.add("*"); sic.add("parent.instanceStatus"); sic.add("parent.id"); EntityViewInfo viewInfo = EntityViewInfo.getInstance(filterInfo, sic, null); //审批实例任务列表 WeaverOAApprovalInstanceTaskListCollection instanceTaskListCol = iWeaverOAApprovalInstanceTaskList.getWeaverOAApprovalInstanceTaskListCollection(viewInfo); if (!instanceTaskListCol.isEmpty()) { WeaverOAApprovalInstanceTaskListInfo instanceTaskListInfo = instanceTaskListCol.get(0); WeaverOAApprovalInstanceInfo parent = instanceTaskListInfo.getParent(); //流程实例状态 if (InstanceStatusEnum.PENDING.equals(parent.getInstanceStatus())) { //已办 instanceTaskListInfo.setIsremark(IsRemarkEnum.PROCESSED); //已读 instanceTaskListInfo.setViewtype(ViewTypeEnum.READ); //保存 iWeaverOAApprovalInstanceTaskList.save(instanceTaskListInfo); //触发同步审批实例 iWeaverOAApprovalInstance.syncApprovalInstance(parent.getId().toString()); } } } catch (Exception e) { e.printStackTrace(); logger.error("节点任务完成 nodeCompletedApprovMessage 报错: {}", e.getMessage(), e); return false; } return true; } /** * 撤销流程 * * @param wfrProcMessage * @return */ public static boolean abortedApproveMessage(WfrProcMessage wfrProcMessage) { logger.error("abortedApproveMessage 开始"); try { Context ctx = SHRApiUtils.getContext(wfrProcMessage.getCtx()); IWeaverOAApprovalInstance iWeaverOAApprovalInstance = WeaverOAApprovalInstanceFactory.getLocalInstance(ctx); //审批实例 FilterInfo filterInfo = new FilterInfo(); filterInfo.getFilterItems().add(new FilterItemInfo("instanceId", wfrProcMessage.getProcInstId())); SelectorItemCollection sic = new SelectorItemCollection(); sic.add("*"); sic.add("taskList.*"); EntityViewInfo viewInfo = EntityViewInfo.getInstance(filterInfo, sic, null); WeaverOAApprovalInstanceCollection instanceCollection = iWeaverOAApprovalInstance.getWeaverOAApprovalInstanceCollection(viewInfo); if (!instanceCollection.isEmpty()) { WeaverOAApprovalInstanceInfo instanceInfo = instanceCollection.get(0); WeaverOAApprovalInstanceTaskListCollection taskList = instanceInfo.getTaskList(); for (int i = 0; i < taskList.size(); i++) { WeaverOAApprovalInstanceTaskListInfo instanceTaskListInfo = taskList.get(i); //流程处理状态 IsRemarkEnum isremark = instanceTaskListInfo.getIsremark(); if (!IsRemarkEnum.COMPLETED.equals(isremark)) { //流程任务处理状态设置为办结 instanceTaskListInfo.setIsremark(IsRemarkEnum.COMPLETED); //流程查看状态 设置为已读 instanceTaskListInfo.setViewtype(ViewTypeEnum.READ); } //流程结束,需要将所有节点更新为归档 instanceTaskListInfo.setNodename("归档"); } //流程状态更新为 审批人撤销 instanceInfo.setInstanceStatus(InstanceStatusEnum.CANCELED); //保存 iWeaverOAApprovalInstance.save(instanceInfo); } } catch (Exception e) { e.printStackTrace(); logger.error("撤销流程 abortedApprovMessage 报错: {}", e.getMessage(), e); return false; } return true; } /** * 发送审批消息 * * @param message * @return */ public static boolean addApproveMessage(WSMessage message) { logger.error("addApproveMessage 开始"); //流程实例id String procInstId = message.getProcInstId(); try { Context ctx = SHRApiUtils.getContext(message.getContext()); //飞书应用默认配置 WeaverOAConfigInfo defaultConfig = WeaverOAUtil.getDefaultConfig(); //接收人账号 String recieveNumber = message.getRecieveNumber(); logger.info("addApproveMessage 账号加密前: {}", recieveNumber); String encryptRecieveNumber = EncryptUtil.encryptStr(recieveNumber); logger.info("addApproveMessage 账号加密后: {}", encryptRecieveNumber); //PC 端的三方审批实例跳转链接。 String pcLink = getPcLink(defaultConfig, message, encryptRecieveNumber); //移动端的三方审批实例跳转链接。 String mobileLink = getMobileLink(defaultConfig, message, encryptRecieveNumber); //发起人 IUser iUser = UserFactory.getLocalInstance(ctx); UserInfo sender = iUser.getUserInfo("where number='" + message.getSenderNumber() + "'"); IWeaverOAApprovalInstance iWeaverOAApprovalInstance = WeaverOAApprovalInstanceFactory.getLocalInstance(ctx); WeaverOAApprovalInstanceCollection instanceCol = getApprovalInstanceCollection(procInstId, iWeaverOAApprovalInstance); WeaverOAApprovalInstanceInfo instanceInfo = null; //标题 String title = message.getTitle().replace("\r", "\\r").replace("\n", "\\n"); if (instanceCol.isEmpty()) { //没有,新增 instanceInfo = new WeaverOAApprovalInstanceInfo(); instanceInfo.setInstanceId(procInstId); instanceInfo.setHrOrgUnit(HRORGUNITINFO); //审批实例状态 instanceInfo.setInstanceStatus(InstanceStatusEnum.PENDING); //标题 instanceInfo.setTitle(title); //发起人 instanceInfo.setSender(sender); //获取单据对象 EntityObjectInfo entityObjectInfo = BaseMetaDataUtil.getEntityObjectInfo(ctx, BOSUuid.read(message.getBillId()).getType()); //单据类型 instanceInfo.setBillType(entityObjectInfo.getDisplayName()); //异构系统标识 instanceInfo.setSyscode(defaultConfig.getSyscode()); try { //保存 iWeaverOAApprovalInstance.save(instanceInfo); } catch (SQLAccessException e) { logger.error("addApproveMessage 保存审批实例报错: {}", e.getMessage(), e); if (!e.getMessage().contains("IX_CT_WEA_WeaverOAAI")) { throw e; } //并发场景下 实例id重复,说明已经存在实例数据. instanceCol = getApprovalInstanceCollection(procInstId, iWeaverOAApprovalInstance); if (instanceCol.isEmpty()) { throw new RuntimeException("并发情况下未能获取审批实例: " + procInstId); } //审批实例 instanceInfo = instanceCol.get(0); } catch (Exception e) { logger.error("addApproveMessage 保存审批实例报错: {}", e.getMessage(), e); throw e; } } else { //审批实例 instanceInfo = instanceCol.get(0); } //当前节点 String actName = message.getActName(); //保存任务列表 IWeaverOAApprovalInstanceTaskList iWeaverOAApprovalInstanceTaskList = WeaverOAApprovalInstanceTaskListFactory.getLocalInstance(ctx); WeaverOAApprovalInstanceTaskListCollection weaverOAApprovalInstanceTaskList = iWeaverOAApprovalInstanceTaskList.getWeaverOAApprovalInstanceTaskListCollection( "where parent.id='" + instanceInfo.getId() + "' and nodename <> '" + actName + "'" ); if (!weaverOAApprovalInstanceTaskList.isEmpty()) { SelectorItemCollection updateSic = new SelectorItemCollection(); updateSic.add("nodename"); for (int i = 0; i < weaverOAApprovalInstanceTaskList.size(); i++) { WeaverOAApprovalInstanceTaskListInfo weaverOAApprovalInstanceTaskListInfo = weaverOAApprovalInstanceTaskList.get(i); weaverOAApprovalInstanceTaskListInfo.setNodename(actName); //更新现有节点的节点名称 iWeaverOAApprovalInstanceTaskList.updatePartial(weaverOAApprovalInstanceTaskListInfo, updateSic); } } WeaverOAApprovalInstanceTaskListInfo task = createTask(ctx, message, pcLink, mobileLink); task.setParent(instanceInfo); iWeaverOAApprovalInstanceTaskList.save(task); //同步 iWeaverOAApprovalInstance.syncApprovalInstance(instanceInfo.getId().toString()); } catch (Exception e) { e.printStackTrace(); return false; } return true; } /** * 根据实例id获取审批实例 * * @param procInstId * @param iWeaverOAApprovalInstance * @return * @throws BOSException */ private static WeaverOAApprovalInstanceCollection getApprovalInstanceCollection( String procInstId, IWeaverOAApprovalInstance iWeaverOAApprovalInstance ) throws BOSException { FilterInfo filterInfo = new FilterInfo(); filterInfo.getFilterItems().add(new FilterItemInfo("instanceId", procInstId)); EntityViewInfo viewInfo = EntityViewInfo.getInstance(filterInfo, null, null); WeaverOAApprovalInstanceCollection instanceCol = iWeaverOAApprovalInstance.getWeaverOAApprovalInstanceCollection(viewInfo); return instanceCol; } /** * 创建任务数据 * * @param ctx * @param message * @param pcLink * @param mobileLink * @return * @throws BOSException * @throws EASBizException */ private static WeaverOAApprovalInstanceTaskListInfo createTask( Context ctx, WSMessage message, String pcLink, String mobileLink ) throws BOSException, EASBizException { IUser iUser = UserFactory.getLocalInstance(ctx); //标题 String title = message.getTitle().replace("\r", "\\r").replace("\n", "\\n"); //发送时间 Time sendTime = new Time(message.getSendTime().getTime()); //审批人 UserInfo reciever = iUser.getUserByID(new ObjectUuidPK(message.getRecieverID())); //发送人 UserInfo sender = iUser.getUserInfo("where number='" + message.getSenderNumber() + "'"); //接收时间 Time receiveTime = new Time(message.getReceiveTime().getTime()); WeaverOAApprovalInstanceTaskListInfo taskListInfo = new WeaverOAApprovalInstanceTaskListInfo(); //任务id taskListInfo.setFlowid(message.getSourceID()); //标题 taskListInfo.setRequestname(title); //获取单据对象 EntityObjectInfo entityObjectInfo = BaseMetaDataUtil.getEntityObjectInfo(ctx, BOSUuid.read(message.getBillId()).getType()); //流程类型名称 taskListInfo.setWorkflowname(entityObjectInfo.getDisplayName()); //步骤名称(节点名称) taskListInfo.setNodename(message.getActName()); //PC端链接 taskListInfo.setPcurl(pcLink); //移动端链接 taskListInfo.setAppurl(mobileLink); //流程处理状态 待办 taskListInfo.setIsremark(IsRemarkEnum.TODO); //流程查看状态 taskListInfo.setViewtype(ViewTypeEnum.UNREAD); //创建人 taskListInfo.setCreator(sender); //创建日期时间 taskListInfo.setCreatedatetime(sendTime); //接收人 taskListInfo.setReceiver(reciever); //接收日期时间 taskListInfo.setReceivedatetime(receiveTime); return taskListInfo; } /** * 获取pc待办地址 * * @param message * @return * @throws UnsupportedEncodingException * @throws BOSException * @throws EASBizException */ private static String getPcLink( WeaverOAConfigInfo defaultConfig, WSMessage message, String encryptRecieveNumber ) throws BOSException { try { String shrServerName = defaultConfig.getSHRServerName(); String utf8String = StandardCharsets.UTF_8.toString(); //构建重定向地址 String redirectUrl = UriComponentsBuilder.fromUriString(shrServerName + "/easweb/webviews/workflow/transferApprove.jsp") .queryParam("AssignmentId", URLEncoder.encode(message.getSourceID(), utf8String))//任务id .queryParam("billID", URLEncoder.encode(message.getBillId(), utf8String))//单据id .build(true) .toUriString(); //构建pc端链接 String targetUrl = UriComponentsBuilder.fromUriString(shrServerName + "/qy/weaverOA/V9/ssoSHRByNumber/") .queryParam("number", URLEncoder.encode(encryptRecieveNumber, utf8String)) .queryParam("redirectUrl", URLEncoder.encode(redirectUrl, utf8String)) .queryParam("platform", "pc")//平台 .build(true) .toUriString(); logger.error("getPcLink targetUrl: {}", targetUrl); return targetUrl; } catch (Exception e) { e.printStackTrace(); throw new BOSException(e.getMessage()); } } /** * 获取移动端待办地址 * * @param message * @return * @throws BOSException * @throws EASBizException * @throws UnsupportedEncodingException */ private static String getMobileLink( WeaverOAConfigInfo defaultConfig, WSMessage message, String encryptRecieveNumber ) throws BOSException { try { String shrServerName = defaultConfig.getSHRServerName(); String utf8String = StandardCharsets.UTF_8.toString(); //构建重定向地址 String redirectUrl = UriComponentsBuilder.fromUriString("https://mbos.kdeascloud.com/mbos/mbosw/getWorkflowUrl") .queryParam("assignId", URLEncoder.encode(message.getSourceID(), utf8String))//任务id .queryParam("eid", URLEncoder.encode(defaultConfig.getMEid(), utf8String))//mbos企业id .queryParam("storeEid", "21231") .queryParam("name", URLEncoder.encode("approveui.navui", utf8String)) .queryParam("billID", URLEncoder.encode(message.getBillId(), utf8String)) .build(true) .toUriString(); //构建移动端链接 String targetUrl = UriComponentsBuilder.fromUriString(shrServerName + "/qy/weaverOA/V9/ssoSHRByNumber/") .queryParam("number", URLEncoder.encode(encryptRecieveNumber, utf8String)) .queryParam("redirectUrl", URLEncoder.encode(redirectUrl, utf8String)) .queryParam("platform", "mobile")//平台 .build(true) .toUriString(); logger.error("getMobileLink targetUrl : {}", targetUrl); return targetUrl; } catch (Exception e) { e.printStackTrace(); throw new BOSException(e.getMessage()); } } }