diff --git a/main/java/shjh/jhzj7/fi/fi/plugin/workflow/closeTaskPagePlugin.java b/main/java/shjh/jhzj7/fi/fi/plugin/workflow/closeTaskPagePlugin.java new file mode 100644 index 0000000..69b41f7 --- /dev/null +++ b/main/java/shjh/jhzj7/fi/fi/plugin/workflow/closeTaskPagePlugin.java @@ -0,0 +1,51 @@ +package shjh.jhzj7.fi.fi.plugin.workflow; + +import com.alibaba.fastjson.JSON; +import kd.bos.form.FormShowParameter; +import kd.bos.logging.Log; +import kd.bos.logging.LogFactory; +import kd.bos.mvc.form.FormView; +import kd.bos.workflow.taskcenter.plugin.validate.IApprovalSubPlugin; + +import java.util.HashMap; +import java.util.Map; + +/** + * 待办提交关闭页面 + */ +public class closeTaskPagePlugin implements IApprovalSubPlugin { + private static final Log logger = LogFactory.getLog(closeTaskPagePlugin.class); + + @Override + public boolean executeClosePageAfterSubmitTask(boolean isPCShow, Map customParams) { + logger.info("进入页面关闭方法"); + boolean flag = false; + FormView view = (FormView) customParams.get("formView"); + FormShowParameter parameter = view.getFormShowParameter(); + logger.info("获取view对象成功"); + if (parameter.getCustomParams().containsKey("apptype")) { + String apptype = parameter.getCustomParam("apptype"); + if ("fanwei".equals(apptype)) { + if (isPCShow) { + try { + view.close(); + } catch (Exception e) { + logger.info("发送指令时异常" + e.getMessage()); + throw new RuntimeException(e); + } + flag = true; + } else { + HashMap map = new HashMap<>(); + map.put("method", "closeWebView"); + String mapString = JSON.toJSONString(map); + view.executeClientCommand("callAPPApi", map); + logger.info("准备发送指令" + mapString); + logger.info("准备关闭移动页面"); + flag = true; + } + } + } + return flag; + } + +} diff --git a/main/java/shjh/jhzj7/fi/fi/plugin/workflow/todoZyTaskServiceHandler.java b/main/java/shjh/jhzj7/fi/fi/plugin/workflow/todoZyTaskServiceHandler.java new file mode 100644 index 0000000..7e433ad --- /dev/null +++ b/main/java/shjh/jhzj7/fi/fi/plugin/workflow/todoZyTaskServiceHandler.java @@ -0,0 +1,151 @@ +package shjh.jhzj7.fi.fi.plugin.workflow; + +import com.alibaba.fastjson.JSONObject; +import kd.bos.dataentity.entity.DynamicObject; +import kd.bos.logging.Log; +import kd.bos.logging.LogFactory; +import kd.bos.servicehelper.BusinessDataServiceHelper; +import kd.bos.workflow.engine.msg.AbstractMessageServiceHandler; +import kd.bos.workflow.engine.msg.ctx.MessageContext; +import kd.bos.workflow.engine.msg.info.MessageInfo; +import kd.bos.workflow.engine.msg.info.ToDoInfo; + +import java.text.SimpleDateFormat; +import java.util.*; + +import static kd.bd.assistant.plugin.basedata.WorkCalendarEditPlugin.SDF; +import static shjh.jhzj7.fi.fi.utils.OAUtils.thirdParty; + + +public class todoZyTaskServiceHandler extends AbstractMessageServiceHandler { + + private static final Log logger = LogFactory.getLog(todoZyTaskServiceHandler.class); + + @Override + public void createToDo(MessageContext messageContext, ToDoInfo toDoInfo) { + System.out.println("createToDo"); + // 构建第三方数据映射 + Map thirdPartyMap = buildThirdPartyMap(messageContext, toDoInfo, "0", "0"); + //推送OA待办接口 + thirdParty(thirdPartyMap); + System.out.println("createToDo"); + } + + @Override + public void dealToDo(MessageContext messageContext, ToDoInfo toDoInfo) { + //select * from t_wf_operationlog where fbillno = '测试:待办推送致远(1106-1915)' + //todo 待办推送第三方,节点审批通过或者驳回到某节点时都会进入(dealToDo)方法,代码如何判断该节点是驳回还是审批通过 + System.out.println("dealToDo"); + // 构建第三方数据映射 流程处理状态;0:待办,2:已办,4:办结 流程查看状态;0:未读,1:已读 + Map thirdPartyMap = buildThirdPartyMap(messageContext, toDoInfo, "2", "1"); + // 推送 OA 待办接口 + thirdParty(thirdPartyMap); + System.out.println("dealToDo"); + } + + @Override + public void deleteToDo(MessageContext messageContext, ToDoInfo toDoInfo) { + System.out.println("deleteToDo"); + // 构建第三方数据映射 + Map thirdPartyMap = buildThirdPartyMap(messageContext, toDoInfo, "4", "1"); + // 推送 OA 待办接口 + thirdParty(thirdPartyMap); + System.out.println("deleteToDo"); + } + + @Override + public void sendMessage(MessageContext messageContext, MessageInfo message) { + System.out.println("sendMessage"); + System.out.println("sendMessage"); + } + + /** + * 构建第三方数据映射 + * + * @param messageContext 消息上下文 + * @param toDoInfo 待办信息 + * @param isRemark 流程处理状态 + * @param viewType 流程查看状态 + * @return 第三方数据映射 + */ + private Map buildThirdPartyMap(MessageContext messageContext, ToDoInfo toDoInfo, String isRemark, String viewType) { + // 获取流程实例ID + Long processInstanceId = messageContext.getProcessInstanceId(); + // 获取任务步骤 + Long executionId = messageContext.getExecutionId(); // 节点ID + // 获取当前任务ID + Long taskId = messageContext.getTaskId(); + // 获取单据编码 + String billNo = messageContext.getBillNo(); + // 获取审批人集合 + List approvers = new ArrayList<>(); + List userIds = toDoInfo.getUserIds(); // 审批人ID集合 + List approversLists = getApprovers(userIds, approvers); + // 获取任务标题 + Map params = toDoInfo.getParams(); + String subjectJson = (String) params.get("subject"); + JSONObject subjectObj = JSONObject.parseObject(subjectJson); + String title = subjectObj.getString("zh_CN"); + // 节点名称 + String executionName = ""; + DynamicObject execution = BusinessDataServiceHelper.loadSingle(executionId, "wf_execution"); + if (execution != null) { + executionName = execution.getString("activityname");// 节点名称 + } + // 获取Url + String url = toDoInfo.getUrl(); // 链接 + String appurl = url + "&device=mob&ado=view"; + // 获取任务创建人 + Long startUserId = messageContext.getStartUserId(); // 审批实例发起人id + DynamicObject startUser = BusinessDataServiceHelper.loadSingle(startUserId, "bos_user"); + String startNumber = ""; + String startName = ""; + if (null != startUser) { + startNumber = startUser.getString("number"); + startName = startUser.getString("name"); + } + // 待办创建时间(格式:yyyy-MM-dd HH:mm:ss) + Date createDate = messageContext.getCreateDate(); + String createDateStr = SDF.format(createDate); + + Map thirdPartyMap = new HashMap<>(); + thirdPartyMap.put("syscode", "Kingdee");// 异构系统标识 + thirdPartyMap.put("flowid", taskId);// 流程任务ID,流程数据的标识,可自定义 + thirdPartyMap.put("requestname", title);// 标题 + thirdPartyMap.put("approversLists", approversLists);// 审批人集合 + thirdPartyMap.put("workflowname", "流程类型名称");// todo:流程类型名称 + thirdPartyMap.put("nodename", executionName);// 步骤名称(节点名称) + thirdPartyMap.put("pcurl", url);// PC地址,第三方系统中流程处理界面的PC端地址 + thirdPartyMap.put("appurl", appurl);// APP地址,第三方系统中流程处理界面的移动端地址 + thirdPartyMap.put("isremark", isRemark);// 流程处理状态;0:待办 ,2:已办 ,4:办结。 + thirdPartyMap.put("viewtype", viewType);// 流程查看状态;0:未读,1:已读。 + thirdPartyMap.put("creator", startNumber);// 发起人 + thirdPartyMap.put("createDateStr", createDateStr);// 创建日期时间,格式:yyyy-MM-dd HH:mm:ss + thirdPartyMap.put("receivedatetime", createDateStr);// 接收日期时间,格式:yyyy-MM-dd HH:mm:ss + thirdPartyMap.put("billNo", billNo);// 单据编号 + + return thirdPartyMap; + } + + /** + * 通过人员id获取人员信息 + * + * @param userIds 人员id集合 + * @param approvers 人员信息集合 + */ + private List getApprovers(List userIds, List approvers) { + + List distinctUserIds = new ArrayList<>(); + for (Long userId : userIds) { + if (!distinctUserIds.contains(userId)) { + distinctUserIds.add(userId); + } + } + + for (Long userId : distinctUserIds) { + DynamicObject user = BusinessDataServiceHelper.loadSingle(userId, "bos_user"); + approvers.add(user); + } + return approvers; + } +} diff --git a/main/java/shjh/jhzj7/fi/fi/utils/OAUtils.java b/main/java/shjh/jhzj7/fi/fi/utils/OAUtils.java new file mode 100644 index 0000000..26d4e1b --- /dev/null +++ b/main/java/shjh/jhzj7/fi/fi/utils/OAUtils.java @@ -0,0 +1,180 @@ +package shjh.jhzj7.fi.fi.utils; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import kd.bos.dataentity.entity.DynamicObject; +import kd.bos.logging.Log; +import kd.bos.logging.LogFactory; +import kd.bos.util.HttpClientUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * 待办集成工具类-->泛微 + */ +public class OAUtils { + + public static final String oaUrl = "https://hipint-stg.jahwa.com.cn:6443/gateway/HIP_ReceiveToOA/1.0/receiveToOA";//测试环境 + public static final String oaAPIKey = "207b5296-9866-4b4b-8146-1fea58b3c8c9";//测试环境APIKey + private static final Log logger = LogFactory.getLog(OAUtils.class); + private static final String Apimenthod = "OA待办接口"; + +// public static final String oaUrl = "https://hipint.jahwa.com.cn:6443/gateway/HIP_ReceiveToOA/1.0/receiveToOA";//正式环境 +// public static final String oaAPIKey = "8281da80-b39b-48c4-83bd-f8e480740c6a";//测试环境APIKey + + /** + * 金蝶系统推送OA待办新增 + * @param thirdPartyMap 流程参数 + * 接收流程数据:可接收待办、已办、归档的流程数据 + * x-Gateway-APIKey: 207b5296-9866-4b4b-8146-1fea58b3c8c9(测试) + * 8281da80-b39b-48c4-83bd-f8e480740c6a(生产) + */ + public static void thirdParty(Map thirdPartyMap) { + // 构建请求头 + Map customerHeader = buildCustomerHeader(thirdPartyMap); + // 组装请求体 + JSONObject pendingsBody = buildPendingsBody(thirdPartyMap); + // 发送请求并处理响应 + processRequest(customerHeader, pendingsBody, thirdPartyMap); + } + + /** + * 构建请求头 + * @param thirdPartyMap 第三方数据映射 + * @return 请求头映射 + */ + private static Map buildCustomerHeader(Map thirdPartyMap) { + Map customerHeader = new HashMap<>(); + customerHeader.put("Content-Type", "application/json;charset=UTF-8");//请求报文类型 + customerHeader.put("x-Gateway-APIKey",oaAPIKey);//apiKey,由ESB提供 + customerHeader.put("interfaceID", "TodoFlow");//todo:识别被调接口并进行路由 + customerHeader.put("senderID", String.valueOf(thirdPartyMap.get("creator")));//定义的发送者.暂定工号 + return customerHeader; + } + + /** + * 组装请求体 + * @param thirdPartyMap 第三方数据映射 + * @return 请求体的 JSON 对象 + */ + private static JSONObject buildPendingsBody(Map thirdPartyMap) { + //组装请求体 + JSONObject pendingsBody = new JSONObject(); + pendingsBody.put("rootContextID", "qqqqqq");//todo:唯一事务ID,采用UUID或其他强唯一性ID + pendingsBody.put("requestTime", String.valueOf(thirdPartyMap.get("createdatetime")));//请求时间,格式为yyyy-MM-dd HH:mm:ss.SSS + + JSONArray data = new JSONArray(); + //接收人信息 + List approversLists = (List) thirdPartyMap.get("approversLists"); + for (DynamicObject approver : approversLists) { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("syscode", String.valueOf(thirdPartyMap.get("syscode")));//异构系统标识 + jsonObject.put("flowid", String.valueOf(thirdPartyMap.get("flowid")) + approver.getString("number"));//流程任务ID,流程数据的标识,可自定义 + jsonObject.put("requestname", String.valueOf(thirdPartyMap.get("requestname")));//标题 + jsonObject.put("workflowname", String.valueOf(thirdPartyMap.get("workflowname")));//todo:流程类型名称 + jsonObject.put("nodename", String.valueOf(thirdPartyMap.get("nodename")));//步骤名称(节点名称) + jsonObject.put("pcurl", String.valueOf(thirdPartyMap.get("pcurl")));//PC地址,第三方系统中流程处理界面的PC端地址 + jsonObject.put("appurl", String.valueOf(thirdPartyMap.get("appurl")));//APP地址,第三方系统中流程处理界面的移动端地址 + jsonObject.put("isremark", String.valueOf(thirdPartyMap.get("isremark")));//流程处理状态;0:待办 ,2:已办 ,4:办结。 + jsonObject.put("viewtype", String.valueOf(thirdPartyMap.get("viewtype")));//流程查看状态;0:未读,1:已读。 + jsonObject.put("creator", String.valueOf(thirdPartyMap.get("creator")));//创建人,工号 + jsonObject.put("createdatetime", String.valueOf(thirdPartyMap.get("createdatetime")));//创建日期时间,格式:yyyy-MM-dd HH:mm:ss + jsonObject.put("receiver", approver.getString("number"));//接收人,工号 + jsonObject.put("receivedatetime", String.valueOf(thirdPartyMap.get("receivedatetime")));//接收日期时间,格式:yyyy-MM-dd HH:mm:ss + data.add(jsonObject); + } + pendingsBody.put("data", data); + return pendingsBody; + } + + /** + * 发送请求并处理响应 + * + * @param customerHeader 请求头 + * @param pendingsBody 请求体 + * @param thirdPartyMap 第三方数据映射 + */ + private static void processRequest(Map customerHeader, JSONObject pendingsBody, Map thirdPartyMap) { + String pendingPostjson = null; + JSONObject jsonObject = null; + try { + // 发送POST请求并获取响应 + pendingPostjson = HttpClientUtils.postjson(OAUtils.oaUrl, customerHeader, pendingsBody.toJSONString()); + jsonObject = parseResponse(pendingPostjson); + + // 检查JSON对象是否为空 + if (jsonObject != null && !jsonObject.isEmpty()) { + handleResponse(jsonObject, pendingsBody, thirdPartyMap); + } + } catch (Exception e) { + handleException(e, pendingsBody, thirdPartyMap, jsonObject); + } + } + + /** + * 解析响应 JSON 字符串 + * @param response 响应的 JSON 字符串 + * @return 解析后的 JSON 对象 + */ + private static JSONObject parseResponse(String response) { + try { + return JSONObject.parseObject(response); + } catch (Exception e) { + logger.error("解析响应 JSON 时出错: {}", e.getMessage()); + return null; + } + } + + /** + * 处理响应结果 + * @param jsonObject 响应的 JSON 对象 + * @param pendingsBody 请求体 + * @param thirdPartyMap 第三方数据映射 + */ + private static void handleResponse(JSONObject jsonObject, JSONObject pendingsBody, Map thirdPartyMap) { + JSONArray data1 = jsonObject.getJSONArray("data"); + if (data1 == null || data1.isEmpty()) { + logger.info("推送OA消息失败!"); + saveLog("待办:" + String.valueOf(thirdPartyMap.get("billno")), pendingsBody, jsonObject, false); + return; + } + JSONObject jsonobject = data1.getJSONObject(0); + String operResult = jsonobject.getString("operResult"); + String logMessage = Objects.equals(operResult, "1") ? "金蝶系统推送OA消息成功!" : "金蝶系统推送OA消息失败!"; + + // 记录日志 + logger.info(logMessage); + saveLog("待办:" + String.valueOf(thirdPartyMap.get("billno")), pendingsBody, jsonObject, true); + } + + /** + * 处理异常情况 + * @param e 捕获的异常 + * @param pendingsBody 请求体 + * @param thirdPartyMap 第三方数据映射 + * @param jsonObject 响应的 JSON 对象 + */ + private static void handleException(Exception e, JSONObject pendingsBody, Map thirdPartyMap, JSONObject jsonObject) { + // 记录异常信息 + String errorMessage = String.format("待办接口异常:%s", e.getMessage()); + logger.error(errorMessage); + saveLog("待办:" + String.valueOf(thirdPartyMap.get("billno")), pendingsBody, jsonObject, false); + throw new RuntimeException(e); + } + + /** + * 保存日志 + * + * @param billNo 账单号 + * @param pendingsBody 请求体 + * @param jsonObject 响应的 JSON 对象 + * @param isSuccess 是否成功 + */ + private static void saveLog(String billNo, JSONObject pendingsBody, JSONObject jsonObject, boolean isSuccess) { + JhzjUtils.saveLog(billNo, OAUtils.Apimenthod, pendingsBody.toJSONString(), + jsonObject != null ? jsonObject.toJSONString() : "{}", isSuccess, "API"); + } +} diff --git a/main/java/shjh/jhzj7/fi/fi/webapi/ApplyAdjustBillControler.java b/main/java/shjh/jhzj7/fi/fi/webapi/ApplyAdjustBillControler.java index 6d23ae9..be318de 100644 --- a/main/java/shjh/jhzj7/fi/fi/webapi/ApplyAdjustBillControler.java +++ b/main/java/shjh/jhzj7/fi/fi/webapi/ApplyAdjustBillControler.java @@ -24,6 +24,7 @@ import kd.bos.orm.query.QCP; import kd.bos.orm.query.QFilter; import kd.bos.servicehelper.BusinessDataServiceHelper; import kd.bos.servicehelper.operation.OperationServiceHelper; +import kd.bos.servicehelper.operation.SaveServiceHelper; import shjh.jhzj7.fi.fi.utils.JhzjUtils; import shjh.jhzj7.fi.fi.webapi.model.ApplyAdjustBillModel; @@ -50,6 +51,7 @@ public class ApplyAdjustBillControler { @ApiPostMapping(value = apimenthod, desc = "应付付款调整单接口") public CustomApiResult applybill_adjust(@NotNull @Valid @ApiRequestBody(value = "入参json格式数据") ApplyAdjustBillModel applyAdjustbill) { + JSONObject json_body; String jsonBodyString = null; try { @@ -179,6 +181,9 @@ public class ApplyAdjustBillControler { log.error("审核成功,费控调整单号:" + fkBillNum); JhzjUtils.saveLog(fkBillNum, Apimenthod, jsonBodyString, null, true, "API"); return CustomApiResult.success(null); + }else { + // 调整金额大于分录未调整过的申请金额,反馈无法处理 + return handleErrorAndReturn("同步失败, 调整单号:" + fkBillNum + "的调整金额大于分录未调整过的申请金额", fkBillNum, jsonBodyString); } } else {