|
|
@@ -0,0 +1,2172 @@
|
|
|
+package kd.cosmic.jkjt.msg.feishu;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSONArray;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import kd.bos.dataentity.entity.DynamicObject;
|
|
|
+import kd.bos.dataentity.metadata.IDataEntityProperty;
|
|
|
+import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
|
|
|
+import kd.bos.dataentity.metadata.dynamicobject.DynamicObjectType;
|
|
|
+import kd.bos.dataentity.utils.ObjectUtils;
|
|
|
+import kd.bos.entity.BasedataEntityType;
|
|
|
+import kd.bos.orm.query.QCP;
|
|
|
+import kd.bos.orm.query.QFilter;
|
|
|
+import kd.bos.servicehelper.BusinessDataServiceHelper;
|
|
|
+import kd.bos.servicehelper.QueryServiceHelper;
|
|
|
+import kd.bos.servicehelper.operation.SaveServiceHelper;
|
|
|
+import kd.bos.servicehelper.workflow.WorkflowServiceHelper;
|
|
|
+import kd.bos.util.StringUtils;
|
|
|
+import kd.bos.workflow.component.approvalrecord.IApprovalRecordItem;
|
|
|
+import kd.bos.workflow.engine.WfUtils;
|
|
|
+import kd.bos.workflow.engine.impl.persistence.entity.task.component.ApprovalRecordGroup;
|
|
|
+import kd.bos.workflow.engine.msg.AbstractMessageServiceHandler;
|
|
|
+import kd.bos.workflow.engine.msg.ctx.MessageContext;
|
|
|
+import kd.bos.workflow.engine.msg.info.LinkMessageInfo;
|
|
|
+import kd.bos.workflow.engine.msg.info.MessageInfo;
|
|
|
+import kd.bos.workflow.engine.msg.info.ToDoInfo;
|
|
|
+import kd.cosmic.jkjt.tmc.util.ParamsUtil;
|
|
|
+import org.apache.commons.collections.CollectionUtils;
|
|
|
+import org.apache.commons.lang.time.DateFormatUtils;
|
|
|
+import org.apache.http.HttpResponse;
|
|
|
+import org.apache.http.client.methods.HttpPost;
|
|
|
+import org.apache.http.entity.StringEntity;
|
|
|
+import org.apache.http.impl.client.DefaultHttpClient;
|
|
|
+import org.apache.http.message.BasicHeader;
|
|
|
+import org.apache.http.util.EntityUtils;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+import java.io.UnsupportedEncodingException;
|
|
|
+import java.net.URLEncoder;
|
|
|
+import java.rmi.ConnectException;
|
|
|
+import java.sql.Timestamp;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 测试环境类
|
|
|
+ * 插件说明:飞书待办类,
|
|
|
+ */
|
|
|
+public class TestFeiShuDaiBanServiceHandler extends AbstractMessageServiceHandler {
|
|
|
+
|
|
|
+ public TestFeiShuDaiBanServiceHandler() {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private static final Logger log = LoggerFactory.getLogger(TestFeiShuDaiBanServiceHandler.class);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 人员表标识
|
|
|
+ */
|
|
|
+ private static final String USER_FORM_ID = "bos_user";
|
|
|
+ /**
|
|
|
+ * 用户名
|
|
|
+ */
|
|
|
+ private static final String USERNAME = "username";
|
|
|
+
|
|
|
+ private List<Integer> interErrCodeArr = Arrays.asList(new Integer[]{
|
|
|
+ 65001,90203,90235,90242,91201,95001,95003,95005,95010,95011,
|
|
|
+ 95203,95204,95205,95206,95207,95208,95209,
|
|
|
+ 105001,190003,230020,1050002,1050008,1069301,1069399
|
|
|
+ });
|
|
|
+
|
|
|
+ public static final String createInstanceUrl = "https://www.feishu.cn/approval/openapi/v2/external/instance/create";
|
|
|
+ private static final String TRAGETNAME = "云苍穹移动审批";
|
|
|
+ private static final String SPDYNUMBER = "jxjkxh";//审批定义number
|
|
|
+ private static final String SPDYID = "946F4A46-2D64-4EBF-9C83-5CDBC5FEB9BD";//审批定义id-测试
|
|
|
+ private static final String APP_ID = "cli_a786040738b5d00d";//个人测试
|
|
|
+ private static final String APP_SERCRET = "WCHnL9EIs654PxRtdMFLVeMB30EwUFOJ";
|
|
|
+
|
|
|
+
|
|
|
+ public static String doPostByHttpClient(String url, String data, boolean isBearer,String token, int times) throws ConnectException {
|
|
|
+ System.out.println("url =" + url);
|
|
|
+ System.out.println("data =" + data);
|
|
|
+ try {
|
|
|
+ // System.setProperty("javax.net.debug", "ssl");
|
|
|
+ DefaultHttpClient httpClient = null;
|
|
|
+ if (url.toLowerCase().startsWith("https://")) {
|
|
|
+ System.out.println("use ssl");
|
|
|
+ httpClient = new SSLClient();
|
|
|
+ } else {
|
|
|
+ System.out.println("use nonssl");
|
|
|
+ httpClient = new DefaultHttpClient();
|
|
|
+ }
|
|
|
+
|
|
|
+ HttpPost httpPost = new HttpPost(url);
|
|
|
+ httpPost.addHeader("Content-Type", "application/json; charset=UTF-8");
|
|
|
+ if(isBearer) {
|
|
|
+ httpPost.addHeader("Authorization", "Bearer" + " " + token);
|
|
|
+ }
|
|
|
+
|
|
|
+ StringEntity se = new StringEntity(data, "UTF-8");
|
|
|
+ se.setContentType("text/json");
|
|
|
+ se.setContentEncoding(new BasicHeader("Content-Type", "application/json; charset=UTF-8"));
|
|
|
+ httpPost.setEntity(se);
|
|
|
+ HttpResponse response = httpClient.execute(httpPost);
|
|
|
+ int statusCode = response.getStatusLine().getStatusCode();
|
|
|
+ if (statusCode != 200) {
|
|
|
+ throw new ConnectException("连接服务器发生错误!");
|
|
|
+ }
|
|
|
+ String body = EntityUtils.toString(response.getEntity());
|
|
|
+ System.out.println(body);
|
|
|
+ return body;
|
|
|
+ } catch (Exception e) {
|
|
|
+ String errMsg = e.getMessage() == null ? "未知异常" : e.getMessage();
|
|
|
+ log.error("请求url " + url + " 超时", errMsg);
|
|
|
+ // 执行重试
|
|
|
+ if (times > 0){
|
|
|
+ times--;
|
|
|
+ if (times > 3){
|
|
|
+ times = 3;
|
|
|
+ }
|
|
|
+ return doPostByHttpClient(url, data, isBearer, token, times);
|
|
|
+ }else {
|
|
|
+ throw new ConnectException("请求飞书接口失败:" + errMsg);
|
|
|
+ }
|
|
|
+
|
|
|
+// e.printStackTrace();
|
|
|
+// System.out.println(" ===== doPostByHttpClient() ERROR ===== ");
|
|
|
+// throw new ConnectException(e.getMessage());
|
|
|
+ } finally {
|
|
|
+ System.clearProperty("javax.net.debug");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取飞书token
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static String getToken(){
|
|
|
+ String returnstr = "";
|
|
|
+ String url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal";
|
|
|
+ JSONObject tokenJson = new JSONObject();
|
|
|
+ tokenJson.put("app_id",APP_ID);
|
|
|
+ tokenJson.put("app_secret",APP_SERCRET);
|
|
|
+ try {
|
|
|
+ String returnSt = doPostByHttpClient(url,tokenJson.toJSONString(),false,null, 3);
|
|
|
+ JSONObject returnJson = JSONObject.parseObject(returnSt);
|
|
|
+ if("0".equals(returnJson.getString("code"))){//成功
|
|
|
+ returnstr = returnJson.getString("tenant_access_token");
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (ConnectException e) {
|
|
|
+ log.info(e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return returnstr;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据手机号(暂定)获取userId/openId
|
|
|
+ */
|
|
|
+ public static String getUserId(String cell,String token) {
|
|
|
+ String user_id = "";
|
|
|
+ JSONObject m = new JSONObject();
|
|
|
+ JSONArray mobiles = new JSONArray();
|
|
|
+ mobiles.add(cell);
|
|
|
+ m.put("mobiles", mobiles);
|
|
|
+ String userIdUrl="https://open.feishu.cn/open-apis/contact/v3/users/batch_get_id";
|
|
|
+ try {
|
|
|
+ log.info("获取用户json: " + m.toString());
|
|
|
+ String response = doPostByHttpClient(userIdUrl, m.toJSONString(),true,token, 3);
|
|
|
+ JSONObject userRes = JSONObject.parseObject(response);
|
|
|
+ user_id = userRes.getJSONObject("data").getJSONArray("user_list").getJSONObject(0).getString("user_id");
|
|
|
+ log.info("获取用户结束json: " + userRes.toString());
|
|
|
+ } catch (ConnectException e) {
|
|
|
+ // TODO Auto-generated catch block
|
|
|
+ log.info(e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return user_id;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据手机号(暂定)获取userId/openId
|
|
|
+ */
|
|
|
+ public static String getUserIdTrue(String cell,String token) {
|
|
|
+ String user_id = "";
|
|
|
+ JSONObject m = new JSONObject();
|
|
|
+ JSONArray mobiles = new JSONArray();
|
|
|
+ mobiles.add(cell);
|
|
|
+ m.put("mobiles", mobiles);
|
|
|
+ String userIdUrl="https://open.feishu.cn/open-apis/contact/v3/users/batch_get_id?user_id_type=user_id";
|
|
|
+ try {
|
|
|
+ log.info("获取用户json: " + m.toString());
|
|
|
+
|
|
|
+ String response = doPostByHttpClient(userIdUrl, m.toJSONString(),true,token, 3);
|
|
|
+ JSONObject userRes = JSONObject.parseObject(response);
|
|
|
+ user_id = userRes.getJSONObject("data").getJSONArray("user_list").getJSONObject(0).getString("user_id");
|
|
|
+ log.info("获取用户结束json: " + userRes.toString());
|
|
|
+ } catch (ConnectException e) {
|
|
|
+ // TODO Auto-generated catch block
|
|
|
+ log.info(e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return user_id;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void createToDo(MessageContext messageContext, ToDoInfo toDoInfo) {
|
|
|
+ log.info("财务系统飞书,推送待办开始 ctx: " + messageContext.toString() + ",taskId:" + messageContext.getTaskId());
|
|
|
+
|
|
|
+
|
|
|
+ List<Long> userIds = toDoInfo.getUserIds();
|
|
|
+ if (CollectionUtils.isEmpty(userIds)) {
|
|
|
+ log.info("财务系统飞书,人员为空,推送失败");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ QFilter qFilter = new QFilter("id", QCP.in, userIds);
|
|
|
+ DynamicObject[] load = BusinessDataServiceHelper.load(USER_FORM_ID, USERNAME+",phone", qFilter.toArray());
|
|
|
+ String token = getToken();
|
|
|
+
|
|
|
+
|
|
|
+ DynamicObject taskInfo = BusinessDataServiceHelper.loadSingleFromCache(toDoInfo.getTaskId() ,"wf_task");
|
|
|
+ String status="PENDING";
|
|
|
+ String fixName= "";
|
|
|
+
|
|
|
+ String pcUrl = toDoInfo.getUrl();
|
|
|
+ String mobUrl = toDoInfo.getUrl();
|
|
|
+
|
|
|
+ //替换PC端域名
|
|
|
+ pcUrl = replacePcUrlDomain(pcUrl);
|
|
|
+ //移动端替换域名
|
|
|
+ mobUrl = replaceMobUrlDomain(mobUrl);
|
|
|
+
|
|
|
+ if("willApproval".equals(taskInfo.getString("handlestate"))){//待审批
|
|
|
+
|
|
|
+ }else if("dismissed".equals(taskInfo.getString("handlestate"))){//驳回
|
|
|
+ status="REJECTED";
|
|
|
+ //驳回新增的待办。不新增。特殊处理
|
|
|
+ List allApprovalRecord = WorkflowServiceHelper.getAllApprovalRecord(messageContext.getBusinessKey());
|
|
|
+ if(allApprovalRecord.size()>2){
|
|
|
+ IApprovalRecordItem item = ((ApprovalRecordGroup) allApprovalRecord.get(allApprovalRecord.size()-2)).getChildren().get(0);
|
|
|
+
|
|
|
+ String taskid = item.getTaskId();
|
|
|
+ String isreject = item.getDecisionType();
|
|
|
+ String submitMsg = item.getMessage();
|
|
|
+
|
|
|
+ if("reject".equals(isreject)){
|
|
|
+ fixName = "(被驳回)";
|
|
|
+ String content =toDoInfo.getContent();
|
|
|
+
|
|
|
+ Map<String, String> logMaps = new HashMap<>();
|
|
|
+
|
|
|
+ logMaps.put("nckd_logtype", "reject");
|
|
|
+ logMaps.put("nckd_apiurl", createInstanceUrl);
|
|
|
+
|
|
|
+ String reveiceUserIds = userIds.stream().map(Object::toString) // 将Long转换为String
|
|
|
+ .collect(Collectors.joining(",")); // 用逗号连接所有String元素
|
|
|
+
|
|
|
+ logMaps.put("nckd_receiveuserids", reveiceUserIds);
|
|
|
+
|
|
|
+ JSONObject m = getBoHuiJson(messageContext,toDoInfo,load,token,true,status,content,taskid, logMaps);
|
|
|
+ try {
|
|
|
+
|
|
|
+ log.info("财务系统飞书驳回待办:"+m.toJSONString());
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ String uuid = saveMsgLogNew(userIds.get(0).toString(), content, "财务系统飞书更新待办[DaJingDaiBanServiceHandler.createToDoreject]", m, logMaps);
|
|
|
+
|
|
|
+ String response = doPostByHttpClient(createInstanceUrl, m.toJSONString(), true,token, 3);
|
|
|
+ log.info("财务系统飞书驳回待办结果:"+response);
|
|
|
+
|
|
|
+ JSONObject res = JSONObject.parseObject(response);
|
|
|
+ if (interErrCodeArr.contains(res.getIntValue("code"))){
|
|
|
+ // 内部错误,可重试
|
|
|
+ Thread.sleep(500L);
|
|
|
+ response = FeishuUtil.doPostByHttpClient(createInstanceUrl, m.toJSONString(), true, token, 3);
|
|
|
+ log.info("财务系统飞书更新待办结果二次:" + response);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!ObjectUtils.isEmpty(uuid)) {
|
|
|
+ // 将发送消息的结果回填到数据库日志记录
|
|
|
+ updateMsgLog(uuid, response);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //发送消息
|
|
|
+ for (int i = 0; i < load.length ; i++) {
|
|
|
+ String userid = getUserIdTrue(load[i].getString("phone"),token);
|
|
|
+ String title = toDoInfo.getTitle();
|
|
|
+ String node = " ";
|
|
|
+ if(messageContext.getEntityName()!=null&&!"".equals(messageContext.getEntityName())){
|
|
|
+ int firstindex = content.indexOf(messageContext.getEntityName());
|
|
|
+ if(firstindex>=0){
|
|
|
+ int subIndex = firstindex+messageContext.getEntityName().length();
|
|
|
+// content =content.substring(0,subIndex)+"\n"+content.substring(subIndex);
|
|
|
+ content =content.substring(subIndex);
|
|
|
+ if("".equals(content)){
|
|
|
+ content =toDoInfo.getContent();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ sendFeishuMessage("1012", submitMsg, toDoInfo.getTaskId(), userid, load[i].getPkValue().toString() ,title,content,node,token,changeDanDianSrc(pcUrl+"&apptype=feishu"),changeDanDianSrc( mobUrl+"&apptype=feishu"));
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (ConnectException e) {
|
|
|
+ log.info("财务系统飞书,推送失败");
|
|
|
+ log.error(e.getMessage(), e);
|
|
|
+ e.printStackTrace();
|
|
|
+ } catch (InterruptedException e1) {
|
|
|
+ log.info("财务系统飞书,推送失败");
|
|
|
+ log.error(e1.getMessage(), e1);
|
|
|
+ throw new RuntimeException(e1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+// return ;
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<String, String> logMaps = new HashMap<>();
|
|
|
+
|
|
|
+ logMaps.put("nckd_logtype", "createToDo");
|
|
|
+ logMaps.put("nckd_apiurl", createInstanceUrl);
|
|
|
+
|
|
|
+ String reveiceUserIds = userIds.stream().map(Object::toString) // 将Long转换为String
|
|
|
+ .collect(Collectors.joining(",")); // 用逗号连接所有String元素
|
|
|
+
|
|
|
+ logMaps.put("nckd_receiveuserids", reveiceUserIds);
|
|
|
+
|
|
|
+ JSONObject m = getToDaiBanJson(messageContext,toDoInfo,load,token,false,"PENDING",null, fixName, logMaps);
|
|
|
+ try {
|
|
|
+
|
|
|
+ log.info("财务系统飞书推送待办:"+m.toJSONString());
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ String title = toDoInfo.getTitle();
|
|
|
+
|
|
|
+ String uuid = saveMsgLogNew(userIds.get(0).toString(), title, "财务系统飞书更新待办[DaJingDaiBanServiceHandler.createToDo]", m, logMaps);
|
|
|
+
|
|
|
+ String response = doPostByHttpClient(createInstanceUrl, m.toJSONString(), true,token, 3);
|
|
|
+ log.info("财务系统飞书推送待办结果:"+response);
|
|
|
+
|
|
|
+ JSONObject res = JSONObject.parseObject(response);
|
|
|
+ if (interErrCodeArr.contains(res.getIntValue("code"))){
|
|
|
+ // 内部错误,可重试
|
|
|
+ Thread.sleep(500L);
|
|
|
+ response = FeishuUtil.doPostByHttpClient(createInstanceUrl, m.toJSONString(), true, token, 3);
|
|
|
+ log.info("财务系统飞书推送待办结果:" + response);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!ObjectUtils.isEmpty(uuid)) {
|
|
|
+ // 将发送消息的结果回填到数据库日志记录
|
|
|
+ updateMsgLog(uuid, response);
|
|
|
+ }
|
|
|
+
|
|
|
+ if("".equals(fixName)) {
|
|
|
+ //发送消息
|
|
|
+ for (int i = 0; i < load.length; i++) {
|
|
|
+ String userid = getUserIdTrue(load[i].getString("phone"), token);
|
|
|
+// String title = "邦财通消息:"+toDoInfo.getTitle();
|
|
|
+
|
|
|
+ String content = toDoInfo.getContent();
|
|
|
+ if (messageContext.getEntityName() != null && !"".equals(messageContext.getEntityName())) {
|
|
|
+ int firstindex = content.indexOf(messageContext.getEntityName());
|
|
|
+ if (firstindex >= 0) {
|
|
|
+ int subIndex = firstindex + messageContext.getEntityName().length();
|
|
|
+// content =content.substring(0,subIndex)+"\n"+content.substring(subIndex);
|
|
|
+ content = content.substring(subIndex);
|
|
|
+ if ("".equals(content)) {
|
|
|
+ content = toDoInfo.getContent();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ String node = " ";
|
|
|
+ title = toDoInfo.getTitle();
|
|
|
+ sendFeishuMessage("1008", "", toDoInfo.getTaskId(), userid, load[i].getPkValue().toString(), title, content, node, token, changeDanDianSrc(pcUrl + "&apptype=feishu"), changeDanDianSrc(mobUrl + "&apptype=feishu"));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (ConnectException e) {
|
|
|
+ log.info("财务系统飞书,推送失败");
|
|
|
+ log.error(e.getMessage(), e);
|
|
|
+ e.printStackTrace();
|
|
|
+ } catch (InterruptedException e1) {
|
|
|
+ log.info("财务系统飞书,推送失败");
|
|
|
+ log.error(e1.getMessage(), e1);
|
|
|
+ throw new RuntimeException(e1);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public String sendDaiBanFeishuMessage(String userid,String title,String content,String node,String token,String pcurl,String phoneurl){
|
|
|
+
|
|
|
+ JSONObject m = new JSONObject();
|
|
|
+
|
|
|
+ m.put("template_id","1008");
|
|
|
+ m.put("user_id",userid);
|
|
|
+ m.put("approval_name","@i18n@1");
|
|
|
+ m.put("note","@i18n@3");
|
|
|
+
|
|
|
+ JSONArray summaries = new JSONArray();
|
|
|
+ JSONObject summarie = new JSONObject();
|
|
|
+ summarie.put("summary","@i18n@2");
|
|
|
+ summaries.add(summarie);
|
|
|
+ JSONObject contentjson = new JSONObject();
|
|
|
+
|
|
|
+ contentjson.put("summaries",summaries);
|
|
|
+ m.put("content",contentjson);
|
|
|
+
|
|
|
+ JSONArray actions = new JSONArray();
|
|
|
+ JSONObject action = new JSONObject();
|
|
|
+ action.put("action_name","DETAIL");
|
|
|
+ action.put("url",pcSrcToFeishu(pcurl));
|
|
|
+ action.put("android_url",phoneurl);
|
|
|
+ action.put("ios_url",phoneurl);
|
|
|
+ action.put("pc_url",pcSrcToFeishu(pcurl));
|
|
|
+ actions.add(action);
|
|
|
+ m.put("actions",actions);
|
|
|
+
|
|
|
+ JSONArray i18n_resources = new JSONArray();
|
|
|
+ JSONObject res = new JSONObject();
|
|
|
+ res.put("locale","en-US");
|
|
|
+ res.put("is_default",true);
|
|
|
+ JSONObject textsjson = new JSONObject();
|
|
|
+
|
|
|
+ String realtitle ="";
|
|
|
+ if(title!=null){
|
|
|
+ int index = title.indexOf("请处理");
|
|
|
+ if(index==0){
|
|
|
+ realtitle = title.substring(3);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ textsjson.put("@i18n@1",realtitle);
|
|
|
+ textsjson.put("@i18n@2",content);
|
|
|
+ textsjson.put("@i18n@3",node);
|
|
|
+ res.put("texts",textsjson);
|
|
|
+ i18n_resources.add(res);
|
|
|
+ m.put("i18n_resources", i18n_resources);
|
|
|
+ String userIdUrl="https://www.feishu.cn/approval/openapi/v1/message/send";
|
|
|
+ try {
|
|
|
+ log.info("门户发送消息:"+m.toString());
|
|
|
+ //飞书推送数据日志
|
|
|
+ log.info("飞书推送数据日志");
|
|
|
+
|
|
|
+ Map<String, String> logMaps = new HashMap<>();
|
|
|
+
|
|
|
+ logMaps.put("nckd_logtype", "other");
|
|
|
+ logMaps.put("nckd_apiurl", userIdUrl);
|
|
|
+
|
|
|
+ logMaps.put("nckd_receiveuserids", userid);
|
|
|
+
|
|
|
+// String uuid = saveMsgLog(userid, title, content, m);
|
|
|
+
|
|
|
+ String uuid = saveMsgLogNew(userid, title, "财务系统飞书其他消息", m, logMaps);
|
|
|
+
|
|
|
+ log.info("飞书推送数据日志保存成功");
|
|
|
+
|
|
|
+ String response = doPostByHttpClient(userIdUrl, m.toString(),true,token, 3);
|
|
|
+ log.info("推送审批bot,url:{}, 结果:{}", userIdUrl, response);
|
|
|
+ if (!ObjectUtils.isEmpty(uuid)) {
|
|
|
+ // 将发送消息的结果回填到数据库日志记录
|
|
|
+ updateMsgLog(uuid, response);
|
|
|
+ }
|
|
|
+ JSONObject userRes = JSONObject.parseObject(response);
|
|
|
+ log.info("门户发送消息结果:"+response);
|
|
|
+ return userRes.toJSONString();
|
|
|
+ } catch (ConnectException e) {
|
|
|
+ log.info(e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public String sendFeishuMessage(String templateid, String submitMsg, Long taskId, String userid, String userpk,String title,String content,String node,String token,String pcurl,String phoneurl){
|
|
|
+
|
|
|
+ JSONObject m = new JSONObject();
|
|
|
+
|
|
|
+ /*************处理消息格式*****************/
|
|
|
+ DynamicObject taskInfo = BusinessDataServiceHelper.loadSingleFromCache(taskId ,"wf_task");
|
|
|
+
|
|
|
+ //add by wnaghaiwu_kd 2024/04/28
|
|
|
+ //如果任务中找不到,就找历史任务
|
|
|
+ if(taskInfo == null){
|
|
|
+ taskInfo = BusinessDataServiceHelper.loadSingleFromCache(taskId ,"wf_hitaskinst");
|
|
|
+ }
|
|
|
+
|
|
|
+ //发起人
|
|
|
+ String startid = "";
|
|
|
+ if(taskInfo != null){
|
|
|
+ Long faqirenid = taskInfo.getLong("starterid");
|
|
|
+ if(faqirenid!=null){
|
|
|
+ DynamicObject faqiren = BusinessDataServiceHelper.loadSingleFromCache(faqirenid,"bos_user");
|
|
|
+ startid = getUserIdTrue(faqiren.getString("phone"),token);
|
|
|
+ }
|
|
|
+ title = taskInfo.getString("entityname");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ m.put("template_id", templateid);
|
|
|
+ m.put("user_id", userid);
|
|
|
+
|
|
|
+ m.put("note","@i18n@3");
|
|
|
+
|
|
|
+ if("1021".equals(templateid)){
|
|
|
+ m.put("custom_title","@i18n@1");
|
|
|
+ m.put("custom_content","@i18n@2");
|
|
|
+
|
|
|
+ JSONArray actions = new JSONArray();
|
|
|
+ JSONObject action = new JSONObject();
|
|
|
+ action.put("action_name","@i18n@4");
|
|
|
+ action.put("url",pcSrcToFeishu(pcurl));
|
|
|
+ action.put("android_url",phoneurl);
|
|
|
+ action.put("ios_url",phoneurl);
|
|
|
+ action.put("pc_url",pcSrcToFeishu(pcurl));
|
|
|
+ actions.add(action);
|
|
|
+ m.put("actions",actions);
|
|
|
+ } else {
|
|
|
+ String kduuid = UUID.randomUUID().toString().replace("-", "");
|
|
|
+ m.put("uuid", kduuid);
|
|
|
+
|
|
|
+ m.put("title_user_id_type", "user_id");
|
|
|
+ m.put("title_user_id", startid);
|
|
|
+ m.put("approval_name", "@i18n@1");
|
|
|
+
|
|
|
+ JSONObject contentobj = new JSONObject();
|
|
|
+ contentobj.put("user_id", startid);
|
|
|
+ contentobj.put("user_id_type", "user_id");
|
|
|
+
|
|
|
+ JSONArray summarys = new JSONArray();
|
|
|
+ JSONObject summary1 = new JSONObject();
|
|
|
+ summary1.put("summary", "@i18n@2");
|
|
|
+
|
|
|
+ summarys.add(summary1);
|
|
|
+//
|
|
|
+// JSONObject summary2 = new JSONObject();
|
|
|
+// summary2.put("summary", "测试内容2");
|
|
|
+// summarys.add(summary2);
|
|
|
+
|
|
|
+ contentobj.put("summaries", summarys);
|
|
|
+ m.put("content", contentobj);
|
|
|
+
|
|
|
+ if("1012".equals(templateid) || "1016".equals(templateid)) {
|
|
|
+ m.put("comment", "@i18n@4");
|
|
|
+ }
|
|
|
+
|
|
|
+ JSONArray actions = new JSONArray();
|
|
|
+ JSONObject action = new JSONObject();
|
|
|
+ action.put("action_name","DETAIL");
|
|
|
+ action.put("url",pcSrcToFeishu(pcurl));
|
|
|
+ action.put("android_url",phoneurl);
|
|
|
+ action.put("ios_url",phoneurl);
|
|
|
+ action.put("pc_url",pcSrcToFeishu(pcurl));
|
|
|
+ actions.add(action);
|
|
|
+ m.put("actions",actions);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ JSONArray i18n_resources = new JSONArray();
|
|
|
+ JSONObject res = new JSONObject();
|
|
|
+ res.put("locale","en-US");
|
|
|
+ res.put("is_default",true);
|
|
|
+ JSONObject textsjson = new JSONObject();
|
|
|
+ textsjson.put("@i18n@1",title);
|
|
|
+ textsjson.put("@i18n@2",content);
|
|
|
+ textsjson.put("@i18n@3", "来自财务系统");
|
|
|
+
|
|
|
+ if("1021".equals(templateid)){
|
|
|
+ textsjson.put("@i18n@4","查看详情");
|
|
|
+ } else if("1012".equals(templateid) || "1016".equals(templateid)) {
|
|
|
+ textsjson.put("@i18n@4", submitMsg);
|
|
|
+ }
|
|
|
+
|
|
|
+ res.put("texts",textsjson);
|
|
|
+ i18n_resources.add(res);
|
|
|
+ m.put("i18n_resources", i18n_resources);
|
|
|
+
|
|
|
+
|
|
|
+// String userIdUrl="https://www.feishu.cn/approval/openapi/v1/message/send";
|
|
|
+ String userIdUrl="https://open.feishu.cn/open-apis/approval/v1/message/send";
|
|
|
+ try {
|
|
|
+ log.info("门户发送消息:"+m.toString());
|
|
|
+
|
|
|
+ Map<String, String> logMaps = new HashMap<>();
|
|
|
+
|
|
|
+ logMaps.put("nckd_logtype", "bot");
|
|
|
+ logMaps.put("nckd_apiurl", userIdUrl);
|
|
|
+ logMaps.put("nckd_receiveuserids", userpk);
|
|
|
+ logMaps.put("nckd_to_useridfeishu", userid);
|
|
|
+
|
|
|
+// String uuid = saveMsgLog(userid, title, content, m);
|
|
|
+ String uuid = saveMsgLogNew(userpk, title, "财务系统飞书发送审批Bot消息", m, logMaps);
|
|
|
+
|
|
|
+ String response = doPostByHttpClient(userIdUrl, m.toString(),true,token, 3);
|
|
|
+ log.info("推送审批bot,url:{}, 结果:{}", userIdUrl, response);
|
|
|
+ if (!ObjectUtils.isEmpty(uuid)) {
|
|
|
+ // 将发送消息的结果回填到数据库日志记录
|
|
|
+ updateMsgLog(uuid, response);
|
|
|
+ }
|
|
|
+ JSONObject userRes = JSONObject.parseObject(response);
|
|
|
+ log.info("门户消息发送成功,发送消息:{}, 结果:{}", m.toJSONString(), response);
|
|
|
+ return userRes.toJSONString();
|
|
|
+ } catch (ConnectException e) {
|
|
|
+ log.info(e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 发送带链接的消息,发送至审批应用
|
|
|
+ * @param ctx
|
|
|
+ * @param message
|
|
|
+ * @param userid
|
|
|
+ * @param token
|
|
|
+ */
|
|
|
+ public void sendLinkMessage(MessageContext ctx, MessageInfo message, String userid, String userpk, String token, String templateid){
|
|
|
+ String node = " ";
|
|
|
+ String pcurl = message.getContentUrl();
|
|
|
+ String moburl = message.getMobContentUrl();
|
|
|
+ if("".equals(pcurl)||pcurl==null){
|
|
|
+ pcurl = System.getProperty("domain.contextUrl")+"/index.html?formId=wf_msg_center";
|
|
|
+ }
|
|
|
+ if("".equals(moburl)||moburl==null){
|
|
|
+ moburl = System.getProperty("domain.contextUrl")+"/mobile.html?form=er_mainpage_daily";
|
|
|
+ moburl = changeDanDianSrc(moburl+"&apptype=feishu");
|
|
|
+ }else{
|
|
|
+ moburl = changeDanDianSrc(moburl+"&apptype=feishu");
|
|
|
+ }
|
|
|
+ pcurl =changeDanDianSrc(pcurl+"&apptype=feishu");
|
|
|
+
|
|
|
+ String content = message.getContent();
|
|
|
+ if("".equals(content)||content==null){
|
|
|
+ content = message.getTitle();
|
|
|
+ }
|
|
|
+
|
|
|
+ //替换PC端域名
|
|
|
+ pcurl = replacePcUrlDomain(pcurl);
|
|
|
+ //移动端替换域名
|
|
|
+ moburl = replaceMobUrlDomain(moburl);
|
|
|
+
|
|
|
+ /*************处理消息格式*****************/
|
|
|
+// String nodename = toDoInfo.getCategory();
|
|
|
+ Long taskId = 0L;
|
|
|
+
|
|
|
+ QFilter qFilter = new QFilter("channel", QCP.equals, "feishu");
|
|
|
+ qFilter.and(new QFilter("id", QCP.equals, Long.valueOf(message.getChannelMsgId())));
|
|
|
+ DynamicObject msgFail = BusinessDataServiceHelper.loadSingle("wf_msg_failmessage", qFilter.toArray());
|
|
|
+
|
|
|
+ if(msgFail != null){
|
|
|
+ qFilter = new QFilter("id", QCP.equals, Long.valueOf(msgFail.getLong("messageid")));
|
|
|
+
|
|
|
+ DynamicObject msg = BusinessDataServiceHelper.loadSingle("wf_msg_message", qFilter.toArray());
|
|
|
+ if(msg != null && StringUtils.isNotEmpty(msg.getString("config"))){
|
|
|
+ JSONObject messateContext = JSONObject.parseObject(msg.getString("config")).getJSONObject("messageContext");
|
|
|
+ if(messateContext != null && messateContext.get("taskId") != null) {
|
|
|
+ taskId = messateContext.getLong("taskId");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("pcurl:"+ pcurl);
|
|
|
+ log.info("mobileurl:" + moburl);
|
|
|
+ sendFeishuMessage(templateid, "", taskId, userid, userpk,message.getTitle(),content,node,token,pcurl,moburl);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void sendLinkMessage(MessageContext ctx, LinkMessageInfo linkMessage) {
|
|
|
+ super.sendLinkMessage(ctx, linkMessage);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 发送传阅消息,发送至抄送页签
|
|
|
+ * @param ctx
|
|
|
+ * @param message
|
|
|
+ * @param userid
|
|
|
+ * @param token
|
|
|
+ */
|
|
|
+ public void sendFlowMessage(MessageContext ctx, MessageInfo message, String userid, String token){
|
|
|
+ try {
|
|
|
+ JSONObject m = new JSONObject(true);
|
|
|
+ JSONObject c = new JSONObject(true);
|
|
|
+
|
|
|
+ String channelMsgId = message.getChannelMsgId() + "";
|
|
|
+
|
|
|
+ c.put("approval_code", SPDYID);
|
|
|
+ c.put("instance_id","cq"+ channelMsgId);
|
|
|
+ c.put("status", "HIDDEN");
|
|
|
+ c.put("display_method", "SIDEBAR");
|
|
|
+ List<Long> userIds = message.getUserIds();
|
|
|
+
|
|
|
+
|
|
|
+ //url连接
|
|
|
+ JSONObject links = new JSONObject();
|
|
|
+
|
|
|
+ String pcUrl = message.getContentUrl() == null ? "" : message.getContentUrl();
|
|
|
+ String mobUrl = message.getMobContentUrl() == null ? pcUrl : message.getMobContentUrl();
|
|
|
+
|
|
|
+ log.info("消息pcurl:" + pcUrl + ", moburl:" + mobUrl);
|
|
|
+
|
|
|
+ //移动端需要走外网,将地址替换成外网地址
|
|
|
+ String curUrl = ParamsUtil.getCommonParamsField("nckd_url");
|
|
|
+ String mobileUrl = ParamsUtil.getCommonParamsField("nckd_mobileurl");
|
|
|
+
|
|
|
+ if(StringUtils.isNotEmpty(pcUrl)){
|
|
|
+ pcUrl = pcUrl.replace(mobileUrl, curUrl);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(StringUtils.isNotEmpty(mobUrl)){
|
|
|
+ mobUrl = mobUrl.replace(curUrl, mobileUrl);
|
|
|
+ }
|
|
|
+
|
|
|
+ if("".equals(pcUrl)||pcUrl==null){
|
|
|
+ pcUrl = System.getProperty("domain.contextUrl")+"/index.html?formId=wf_msg_center";
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ links.put("pc_link",pcSrcToFeishu(changeDanDianSrc(pcUrl+"&apptype=feishu")));
|
|
|
+ links.put("mobile_link", changeDanDianSrc(mobUrl+"&apptype=feishu"));
|
|
|
+ c.put("links", links);
|
|
|
+
|
|
|
+ String content = message.getContent() == null ? message.getTitle() : message.getContent();
|
|
|
+ String title = message.getTitle();
|
|
|
+ //标题
|
|
|
+ c.put("title", title);
|
|
|
+
|
|
|
+ Long createTime = (new Date()).getTime();
|
|
|
+
|
|
|
+ c.put("start_time", createTime);
|
|
|
+ c.put("update_time", createTime);
|
|
|
+ c.put("update_mode", "UPDATE");
|
|
|
+
|
|
|
+
|
|
|
+ /*************处理消息格式*****************/
|
|
|
+// String nodename = toDoInfo.getCategory();
|
|
|
+ String workflowname = "财务系统审批流";
|
|
|
+ String nodename = "";
|
|
|
+ String createDate = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
|
|
|
+
|
|
|
+ QFilter qFilter = new QFilter("channel", QCP.equals, "feishu");
|
|
|
+ qFilter.and(new QFilter("id", QCP.equals, Long.valueOf(message.getChannelMsgId())));
|
|
|
+ DynamicObject msgFail = BusinessDataServiceHelper.loadSingle("wf_msg_failmessage", qFilter.toArray());
|
|
|
+
|
|
|
+ Map<String, String> logMaps = new HashMap<>();
|
|
|
+
|
|
|
+ logMaps.put("nckd_logtype", "flow");
|
|
|
+ logMaps.put("nckd_apiurl", createInstanceUrl);
|
|
|
+
|
|
|
+ String reveiceUserIds = userIds.stream().map(Object::toString) // 将Long转换为String
|
|
|
+ .collect(Collectors.joining(",")); // 用逗号连接所有String元素
|
|
|
+
|
|
|
+ logMaps.put("nckd_receiveuserids", reveiceUserIds);
|
|
|
+
|
|
|
+ if(msgFail != null){
|
|
|
+ qFilter = new QFilter("id", QCP.equals, Long.valueOf(msgFail.getLong("messageid")));
|
|
|
+
|
|
|
+ DynamicObject msg = BusinessDataServiceHelper.loadSingle("wf_msg_message", qFilter.toArray());
|
|
|
+ if(msg != null && StringUtils.isNotEmpty(msg.getString("config"))){
|
|
|
+ JSONObject messateContext = JSONObject.parseObject(msg.getString("config")).getJSONObject("messageContext");
|
|
|
+ Long taskId = messateContext.getLong("taskId");
|
|
|
+ Long faqirenid = messateContext.getLong("startUserId");
|
|
|
+ /*************处理消息格式*****************/
|
|
|
+ DynamicObject taskInfo = BusinessDataServiceHelper.loadSingleFromCache(taskId ,"wf_task");
|
|
|
+
|
|
|
+ //add by wnaghaiwu_kd 2024/04/28
|
|
|
+ //如果任务中找不到,就找历史任务
|
|
|
+ if(taskInfo == null){
|
|
|
+ taskInfo = BusinessDataServiceHelper.loadSingleFromCache(taskId ,"wf_hitaskinst");
|
|
|
+ }
|
|
|
+
|
|
|
+ if(taskInfo != null){
|
|
|
+ nodename = taskInfo.getString("name");
|
|
|
+
|
|
|
+ if(taskInfo.getLong("processdefinitionid") > 0) {
|
|
|
+ qFilter = new QFilter("id", QCP.equals, taskInfo.getLong("processdefinitionid"));
|
|
|
+ DynamicObject processdef = BusinessDataServiceHelper.loadSingle("wf_processdefinition", qFilter.toArray());
|
|
|
+ if (processdef != null) {
|
|
|
+ workflowname = processdef.getString("name");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if("财务系统审批流".equals(workflowname) && taskInfo.getString("entityname") != null){
|
|
|
+ workflowname = taskInfo.getString("entityname") + "审批流程";
|
|
|
+ }
|
|
|
+ if(StringUtils.isNotEmpty(taskInfo.getString("entitynumber"))
|
|
|
+ && StringUtils.isNotEmpty(taskInfo.getString("businesskey"))){
|
|
|
+ qFilter = new QFilter("id", QCP.equals, Long.valueOf(taskInfo.getString("businesskey")));
|
|
|
+ DynamicObject bill = BusinessDataServiceHelper.loadSingle(taskInfo.getString("entitynumber"), qFilter.toArray());
|
|
|
+ if(bill != null){
|
|
|
+ createDate = getCreateTime(bill);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ //发起人
|
|
|
+ faqirenid = taskInfo.getLong("starterid");
|
|
|
+ }
|
|
|
+
|
|
|
+ if(faqirenid != null){
|
|
|
+ DynamicObject faqiren = BusinessDataServiceHelper.loadSingleFromCache(faqirenid,"bos_user");
|
|
|
+ c.put("open_id", getUserId(faqiren.getString("phone"),token));
|
|
|
+
|
|
|
+ //发起人id、发起人飞书id
|
|
|
+ logMaps.put("nckd_creatorid", faqirenid.toString());
|
|
|
+ logMaps.put("nckd_creatoridfeishu", getUserId(faqiren.getString("phone"),token));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ c.put("title", workflowname);
|
|
|
+
|
|
|
+ JSONArray formArr = new JSONArray();
|
|
|
+ JSONObject form1 = new JSONObject();
|
|
|
+ form1.put("name", "流程标题");
|
|
|
+ form1.put("value", StringUtils.isEmpty(msgFail.getString("title")) ? workflowname : msgFail.getString("title"));
|
|
|
+ formArr.add(form1);
|
|
|
+
|
|
|
+ JSONObject form2 = new JSONObject();
|
|
|
+ form2.put("name", "提单时间");
|
|
|
+ form2.put("value", createDate);
|
|
|
+ formArr.add(form2);
|
|
|
+
|
|
|
+ JSONObject form3 = new JSONObject();
|
|
|
+ form3.put("name", "当前节点");
|
|
|
+ form3.put("value", nodename);
|
|
|
+ formArr.add(form3);
|
|
|
+
|
|
|
+ c.put("form", formArr);
|
|
|
+
|
|
|
+ /*************处理消息格式*****************/
|
|
|
+
|
|
|
+ //cc_list 抄送人相关
|
|
|
+ JSONArray ccArr = new JSONArray();
|
|
|
+
|
|
|
+
|
|
|
+ if (CollectionUtils.isEmpty(userIds)) {
|
|
|
+ log.info("财务系统飞书,人员为空,抄送失败");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ qFilter = new QFilter("id", QCP.in, userIds);
|
|
|
+ DynamicObject[] load = BusinessDataServiceHelper.load(USER_FORM_ID, USERNAME+",phone", qFilter.toArray());
|
|
|
+ for (int i = 0; i <load.length ; i++) {
|
|
|
+ JSONObject cc = new JSONObject();
|
|
|
+ cc.put("cc_id", load[i].getPkValue()+"_"+ channelMsgId);
|
|
|
+ cc.put("open_id", getUserId(load[i].getString("phone"),token));
|
|
|
+ cc.put("read_status", "UNREAD");
|
|
|
+ cc.put("title", title);
|
|
|
+ cc.put("create_time", createTime);
|
|
|
+ cc.put("update_time", createTime);
|
|
|
+
|
|
|
+ cc.put("title", workflowname);
|
|
|
+
|
|
|
+// cc.put("display_method", "SIDEBAR");
|
|
|
+
|
|
|
+ JSONObject links1 = new JSONObject();
|
|
|
+ links1.put("pc_link",pcSrcToFeishu(changeDanDianSrc(pcUrl+"&apptype=feishu")));
|
|
|
+ links1.put("mobile_link",changeDanDianSrc(mobUrl+"&apptype=feishu"));
|
|
|
+
|
|
|
+ cc.put("links", links1);
|
|
|
+
|
|
|
+ ccArr.add(cc);
|
|
|
+ }
|
|
|
+ c.put("cc_list", ccArr);
|
|
|
+
|
|
|
+ m.put("content", c);
|
|
|
+
|
|
|
+ log.info("财务系统飞书推送传阅:"+m.toJSONString());
|
|
|
+ if(load.length > 0) {
|
|
|
+ logMaps.put("nckd_to_useridfeishu", getUserId(load[0].getString("phone"), token));
|
|
|
+ }
|
|
|
+
|
|
|
+ String uuid = saveMsgLogNew(userIds.get(0).toString(), title, "财务系统飞书传同步阅消息[DaJingDaiBanServiceHandler.sendMessage]", m, logMaps);
|
|
|
+ String response = doPostByHttpClient(createInstanceUrl, m.toJSONString(), true,token, 3);
|
|
|
+
|
|
|
+ log.info("财务系统飞书推送传阅结果:"+response);
|
|
|
+
|
|
|
+ JSONObject res = JSONObject.parseObject(response);
|
|
|
+ if (interErrCodeArr.contains(res.getIntValue("code"))){
|
|
|
+ // 内部错误,可重试
|
|
|
+ Thread.sleep(500L);
|
|
|
+ response = FeishuUtil.doPostByHttpClient(createInstanceUrl, m.toJSONString(), true, token, 3);
|
|
|
+ log.info("财务系统飞书更新待办结果二次:" + response);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!ObjectUtils.isEmpty(uuid)) {
|
|
|
+ // 将发送消息的结果回填到数据库日志记录
|
|
|
+ updateMsgLog(uuid, response);
|
|
|
+ }
|
|
|
+ } catch (ConnectException e) {
|
|
|
+ log.info("财务系统飞书,推送失败");
|
|
|
+ log.error(e.getMessage(), e);
|
|
|
+ e.printStackTrace();
|
|
|
+ } catch (InterruptedException e1) {
|
|
|
+ log.info("财务系统飞书,推送失败");
|
|
|
+ log.error(e1.getMessage(), e1);
|
|
|
+ throw new RuntimeException(e1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 发送普通消息,发送至自建应用
|
|
|
+ * @param ctx
|
|
|
+ * @param info
|
|
|
+ * @param userid
|
|
|
+ * @param token
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public String sendCustomMessage(MessageContext ctx, MessageInfo info, String userid, String token){
|
|
|
+ JSONObject m = new JSONObject();
|
|
|
+
|
|
|
+ String uuid = "KD-" + UUIDUtil.generateUuid();
|
|
|
+ String title = info.getTitle() == null ? "" : info.getTitle();
|
|
|
+ String contentText = info.getContent() == null ? "" : info.getContent();
|
|
|
+
|
|
|
+ //飞书不支持星瀚的换行标签,替换成飞书兼容的换行标签
|
|
|
+ contentText = contentText.replace("<a></a>", "\r\n");
|
|
|
+ contentText = contentText.replace("</a><a>", "\r\n");
|
|
|
+ contentText = contentText.replace("<a>", "");
|
|
|
+ contentText = contentText.replace("</a>", "");
|
|
|
+
|
|
|
+ m.put("receive_id", userid);
|
|
|
+ m.put("msg_type","text");
|
|
|
+
|
|
|
+ JSONObject content = new JSONObject();
|
|
|
+ content.put("text", contentText);
|
|
|
+ m.put("content", content.toJSONString());
|
|
|
+ m.put("uuid", uuid);
|
|
|
+
|
|
|
+ String linkUrl = info.getContentUrl();
|
|
|
+ String linkMobileUrl = info.getMobContentUrl();
|
|
|
+
|
|
|
+ DynamicObject msgInfo = BusinessDataServiceHelper.loadSingleFromCache(info.getId(), "wf_msg_message");
|
|
|
+ if(msgInfo != null) {
|
|
|
+ if(StringUtils.isNotEmpty(msgInfo.getString("contenturl"))){
|
|
|
+ linkUrl = msgInfo.getString("contenturl");
|
|
|
+ }
|
|
|
+ if(StringUtils.isNotEmpty(msgInfo.getString("contenturl"))){
|
|
|
+ linkMobileUrl = msgInfo.getString("mobcontenturl");
|
|
|
+ }
|
|
|
+ if(StringUtils.isNotEmpty(linkMobileUrl)){
|
|
|
+ linkMobileUrl = linkUrl;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //替换PC端域名
|
|
|
+ linkUrl = replacePcUrlDomain(linkUrl);
|
|
|
+ //移动端替换域名
|
|
|
+ linkMobileUrl = replaceMobUrlDomain(linkMobileUrl);
|
|
|
+
|
|
|
+ String userIdUrl = "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=open_id";
|
|
|
+ try {
|
|
|
+ log.info("门户发送消息:"+m.toString());
|
|
|
+
|
|
|
+// uuid = saveMsgLog(userid, title, content.toJSONString(), m);
|
|
|
+
|
|
|
+ Map<String, String> logMaps = new HashMap<>();
|
|
|
+
|
|
|
+ logMaps.put("nckd_logtype", "message");
|
|
|
+ logMaps.put("nckd_apiurl", userIdUrl);
|
|
|
+
|
|
|
+ logMaps.put("nckd_receiveuserids", userid);
|
|
|
+
|
|
|
+ uuid = saveMsgLogNew(userid, title, "财务系统飞书发送普通消息", m, logMaps);
|
|
|
+
|
|
|
+ String response = doPostByHttpClient(userIdUrl, m.toString(),true,token, 3);
|
|
|
+ log.info("推送审批bot,url:{}, 结果:{}", userIdUrl, response);
|
|
|
+
|
|
|
+ if (!ObjectUtils.isEmpty(uuid)) {
|
|
|
+ // 将发送消息的结果回填到数据库日志记录
|
|
|
+ updateMsgLog(uuid, response);
|
|
|
+ }
|
|
|
+
|
|
|
+ JSONObject userRes = JSONObject.parseObject(response);
|
|
|
+ log.info("门户消息发送成功,发送消息:{}, 结果:{}", m.toJSONString(), response);
|
|
|
+ return userRes.toJSONString();
|
|
|
+ } catch (ConnectException e) {
|
|
|
+ log.info(e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取取消JSON
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public JSONObject getdeleteJson(MessageContext messageContext,ToDoInfo toDoInfo,DynamicObject[] load,String token,boolean isUpdate,String passStatus,String content,String taskId, Map<String, String> logMaps){
|
|
|
+
|
|
|
+ JSONObject m = new JSONObject(true);
|
|
|
+ JSONObject c = new JSONObject(true);
|
|
|
+ c.put("approval_code", SPDYID);
|
|
|
+ c.put("instance_id","cq"+taskId);
|
|
|
+ c.put("status", "CANCELED");
|
|
|
+ c.put("display_method", "SIDEBAR");
|
|
|
+
|
|
|
+ DynamicObject taskInfo = BusinessDataServiceHelper.loadSingleFromCache(toDoInfo.getTaskId() ,"wf_task");
|
|
|
+
|
|
|
+ //add by wnaghaiwu_kd 2024/04/28
|
|
|
+ //如果任务中找不到,就找历史任务
|
|
|
+ if(taskInfo == null){
|
|
|
+ taskInfo = BusinessDataServiceHelper.loadSingleFromCache(toDoInfo.getTaskId() ,"wf_hitaskinst");
|
|
|
+ }
|
|
|
+
|
|
|
+ if(taskInfo != null){
|
|
|
+ String handlestate = taskInfo == null ? "" : taskInfo.getString("handlestate");
|
|
|
+
|
|
|
+ //驳回状态的任务做提交处理时不做待办更新推送。
|
|
|
+ if("willApproval".equals(handlestate)){
|
|
|
+ c.put("status", "APPROVED");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ String pcUrl = toDoInfo.getUrl();
|
|
|
+ String mobUrl = toDoInfo.getUrl();
|
|
|
+
|
|
|
+ //替换PC端域名
|
|
|
+ pcUrl = replacePcUrlDomain(pcUrl);
|
|
|
+ //移动端替换域名
|
|
|
+ mobUrl = replaceMobUrlDomain(mobUrl);
|
|
|
+
|
|
|
+ //url连接
|
|
|
+ JSONObject links = new JSONObject();
|
|
|
+ links.put("pc_link",pcSrcToFeishu(changeDanDianSrc(pcUrl+"&apptype=feishu")));
|
|
|
+ links.put("mobile_link", changeDanDianSrc(mobUrl+"&apptype=feishu"));
|
|
|
+ c.put("links", links);
|
|
|
+
|
|
|
+ //标题
|
|
|
+ c.put("title", toDoInfo.getContent());
|
|
|
+ if(isUpdate){
|
|
|
+ c.put("title", content);
|
|
|
+ }
|
|
|
+
|
|
|
+ //发起人
|
|
|
+ Date d = new Date();
|
|
|
+
|
|
|
+ c.put("start_time", d.getTime());
|
|
|
+ c.put("end_time", d.getTime());
|
|
|
+ c.put("update_time", d.getTime());
|
|
|
+ c.put("update_mode", "UPDATE");
|
|
|
+
|
|
|
+ /*************处理消息格式*****************/
|
|
|
+ String nodename = toDoInfo.getCategory();
|
|
|
+ String workflowname = "财务系统审批流";
|
|
|
+ String createDate = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
|
|
|
+
|
|
|
+ if(taskInfo != null){
|
|
|
+ nodename = taskInfo.getString("name");
|
|
|
+
|
|
|
+ if(taskInfo.getLong("processdefinitionid") > 0) {
|
|
|
+ QFilter qFilter = new QFilter("id", QCP.equals, taskInfo.getLong("processdefinitionid"));
|
|
|
+ DynamicObject processdef = BusinessDataServiceHelper.loadSingle("wf_processdefinition", qFilter.toArray());
|
|
|
+ if (processdef != null) {
|
|
|
+ workflowname = processdef.getString("name");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if("财务系统审批流".equals(workflowname) && taskInfo.getString("entityname") != null){
|
|
|
+ workflowname = taskInfo.getString("entityname") + "审批流程";
|
|
|
+ }
|
|
|
+ if(StringUtils.isNotEmpty(taskInfo.getString("entitynumber"))
|
|
|
+ && StringUtils.isNotEmpty(taskInfo.getString("businesskey"))){
|
|
|
+ QFilter qFilter = new QFilter("id", QCP.equals, Long.valueOf(taskInfo.getString("businesskey")));
|
|
|
+ DynamicObject bill = BusinessDataServiceHelper.loadSingle(taskInfo.getString("entitynumber"), qFilter.toArray());
|
|
|
+ if(bill != null){
|
|
|
+ createDate = getCreateTime(bill);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ c.put("title", workflowname);
|
|
|
+
|
|
|
+ JSONArray formArr = new JSONArray();
|
|
|
+ JSONObject form1 = new JSONObject();
|
|
|
+ form1.put("name", "流程标题");
|
|
|
+ form1.put("value", (StringUtils.isEmpty(toDoInfo.getTitle()) ? workflowname : toDoInfo.getTitle()));
|
|
|
+ formArr.add(form1);
|
|
|
+
|
|
|
+ JSONObject form2 = new JSONObject();
|
|
|
+ form2.put("name", "提单时间");
|
|
|
+ form2.put("value", createDate);
|
|
|
+ formArr.add(form2);
|
|
|
+
|
|
|
+ JSONObject form3 = new JSONObject();
|
|
|
+ form3.put("name", "当前节点");
|
|
|
+ form3.put("value", nodename);
|
|
|
+ formArr.add(form3);
|
|
|
+
|
|
|
+ c.put("form", formArr);
|
|
|
+
|
|
|
+ /*************处理消息格式*****************/
|
|
|
+
|
|
|
+
|
|
|
+ //发起人
|
|
|
+
|
|
|
+ Long faqirenid = taskInfo.getLong("starterid");
|
|
|
+ if(faqirenid!=null){
|
|
|
+ DynamicObject faqiren = BusinessDataServiceHelper.loadSingleFromCache(faqirenid,"bos_user");
|
|
|
+ c.put("open_id", getUserId(faqiren.getString("phone"),token));
|
|
|
+
|
|
|
+ //发起人id、发起人飞书id
|
|
|
+ logMaps.put("nckd_creatorid", faqirenid.toString());
|
|
|
+ logMaps.put("nckd_creatoridfeishu", getUserId(faqiren.getString("phone"),token));
|
|
|
+ }
|
|
|
+
|
|
|
+ //task_list 审批人相关
|
|
|
+ JSONArray taskArr = new JSONArray();
|
|
|
+
|
|
|
+ for (int i = 0; i <load.length ; i++) {
|
|
|
+ JSONObject task = new JSONObject();
|
|
|
+ task.put("task_id",load[i].getPkValue()+"_"+taskId);
|
|
|
+ task.put("open_id", getUserId(load[i].getString("phone"),token));
|
|
|
+
|
|
|
+ JSONObject links1 = new JSONObject();
|
|
|
+
|
|
|
+ links1.put("pc_link",pcSrcToFeishu(changeDanDianSrc(pcUrl+"&apptype=feishu")));
|
|
|
+ links1.put("mobile_link",changeDanDianSrc( changephoneurl(mobUrl,taskId)));
|
|
|
+
|
|
|
+ task.put("links", links1);
|
|
|
+
|
|
|
+ if(isUpdate){
|
|
|
+ task.put("status", passStatus);
|
|
|
+ }else{
|
|
|
+ task.put("status", "DONE");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ task.put("title", toDoInfo.getContent());
|
|
|
+ if(isUpdate){
|
|
|
+ task.put("title", content);
|
|
|
+ }
|
|
|
+
|
|
|
+ task.put("title", workflowname);
|
|
|
+
|
|
|
+ Date d1 = new Date();
|
|
|
+ task.put("create_time", d1.getTime());
|
|
|
+ task.put("end_time", d1.getTime());
|
|
|
+ task.put("update_time", d1.getTime());
|
|
|
+ taskArr.add(task);
|
|
|
+ }
|
|
|
+ c.put("task_list", taskArr);
|
|
|
+
|
|
|
+ m.put("content", c);
|
|
|
+
|
|
|
+
|
|
|
+ return m;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 驳回JSON
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public JSONObject getBoHuiJson(MessageContext messageContext,ToDoInfo toDoInfo,DynamicObject[] load,String token,boolean isUpdate,String passStatus,String content,String taskId, Map<String, String> logMaps){
|
|
|
+
|
|
|
+ boolean isExist = QueryServiceHelper.exists("wf_task",toDoInfo.getTaskId());
|
|
|
+ if(!isExist){
|
|
|
+ return getdeleteJson(messageContext,toDoInfo,load,token,isUpdate,passStatus,content,taskId, logMaps);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ JSONObject m = new JSONObject(true);
|
|
|
+ JSONObject c = new JSONObject(true);
|
|
|
+ c.put("approval_code", SPDYID);
|
|
|
+ c.put("instance_id","cq"+taskId);
|
|
|
+
|
|
|
+ if(isUpdate){
|
|
|
+ if ("DONE".equalsIgnoreCase(passStatus)){
|
|
|
+ passStatus = "APPROVED";
|
|
|
+ }
|
|
|
+ c.put("status", passStatus);
|
|
|
+ }else{
|
|
|
+ c.put("status", "PENDING");
|
|
|
+ }
|
|
|
+
|
|
|
+ c.put("display_method", "SIDEBAR");
|
|
|
+
|
|
|
+ String pcUrl = toDoInfo.getUrl();
|
|
|
+ String mobUrl = toDoInfo.getUrl();
|
|
|
+
|
|
|
+ //替换PC端域名
|
|
|
+ pcUrl = replacePcUrlDomain(pcUrl);
|
|
|
+ //移动端替换域名
|
|
|
+ mobUrl = replaceMobUrlDomain(mobUrl);
|
|
|
+
|
|
|
+ //url连接
|
|
|
+ JSONObject links = new JSONObject();
|
|
|
+ links.put("pc_link",pcSrcToFeishu(changeDanDianSrc(pcUrl+"&apptype=feishu")));
|
|
|
+ links.put("mobile_link",changeDanDianSrc( changephoneurl(mobUrl,taskId)));
|
|
|
+ c.put("links", links);
|
|
|
+
|
|
|
+ //标题
|
|
|
+ if(toDoInfo.getContent()!=null&&!"".equals(toDoInfo.getContent())){
|
|
|
+ c.put("title", toDoInfo.getContent());
|
|
|
+ }
|
|
|
+ if(isUpdate){
|
|
|
+ if(content!=null&&!"".equals(content)) {
|
|
|
+ c.put("title", content);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ String oldcontent="";
|
|
|
+ if(toDoInfo.getContent()==null&&content==null){
|
|
|
+ DynamicObject businessObject = WfUtils.findBusinessObject(messageContext.getBusinessKey(), messageContext.getEntityNumber());
|
|
|
+ oldcontent =getTitle(messageContext,businessObject);
|
|
|
+ c.put("title", oldcontent);
|
|
|
+ }
|
|
|
+ //发起人
|
|
|
+
|
|
|
+ Date d = new Date();
|
|
|
+
|
|
|
+ c.put("start_time", d.getTime());
|
|
|
+ c.put("update_time",d.getTime());
|
|
|
+ c.put("update_mode", "UPDATE");
|
|
|
+
|
|
|
+ /*************处理消息格式*****************/
|
|
|
+ DynamicObject taskInfo = BusinessDataServiceHelper.loadSingleFromCache(toDoInfo.getTaskId() ,"wf_task");
|
|
|
+
|
|
|
+ //add by wnaghaiwu_kd 2024/04/28
|
|
|
+ //如果任务中找不到,就找历史任务
|
|
|
+ if(taskInfo == null){
|
|
|
+ taskInfo = BusinessDataServiceHelper.loadSingleFromCache(toDoInfo.getTaskId() ,"wf_hitaskinst");
|
|
|
+ }
|
|
|
+
|
|
|
+ String nodename = toDoInfo.getCategory();
|
|
|
+ String workflowname = "财务系统审批流";
|
|
|
+ String createDate = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
|
|
|
+
|
|
|
+ if(taskInfo != null){
|
|
|
+ nodename = taskInfo.getString("name");
|
|
|
+
|
|
|
+ if(taskInfo.getLong("processdefinitionid") > 0) {
|
|
|
+ QFilter qFilter = new QFilter("id", QCP.equals, taskInfo.getLong("processdefinitionid"));
|
|
|
+ DynamicObject processdef = BusinessDataServiceHelper.loadSingle("wf_processdefinition", qFilter.toArray());
|
|
|
+ if (processdef != null) {
|
|
|
+ workflowname = processdef.getString("name");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if("财务系统审批流".equals(workflowname) && taskInfo.getString("entityname") != null){
|
|
|
+ workflowname = taskInfo.getString("entityname") + "审批流程";
|
|
|
+ }
|
|
|
+ if(StringUtils.isNotEmpty(taskInfo.getString("entitynumber"))
|
|
|
+ && StringUtils.isNotEmpty(taskInfo.getString("businesskey"))){
|
|
|
+ QFilter qFilter = new QFilter("id", QCP.equals, Long.valueOf(taskInfo.getString("businesskey")));
|
|
|
+ DynamicObject bill = BusinessDataServiceHelper.loadSingle(taskInfo.getString("entitynumber"), qFilter.toArray());
|
|
|
+ if(bill != null){
|
|
|
+ createDate = getCreateTime(bill);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ c.put("title", workflowname);
|
|
|
+
|
|
|
+ JSONArray formArr = new JSONArray();
|
|
|
+ JSONObject form1 = new JSONObject();
|
|
|
+ form1.put("name", "流程标题");
|
|
|
+ form1.put("value", "(被驳回)" + (StringUtils.isEmpty(toDoInfo.getTitle()) ? workflowname : toDoInfo.getTitle()));
|
|
|
+ formArr.add(form1);
|
|
|
+
|
|
|
+ JSONObject form2 = new JSONObject();
|
|
|
+ form2.put("name", "提单时间");
|
|
|
+ form2.put("value", createDate);
|
|
|
+ formArr.add(form2);
|
|
|
+
|
|
|
+ JSONObject form3 = new JSONObject();
|
|
|
+ form3.put("name", "当前节点");
|
|
|
+ form3.put("value", nodename);
|
|
|
+ formArr.add(form3);
|
|
|
+
|
|
|
+ c.put("form", formArr);
|
|
|
+
|
|
|
+ /*************处理消息格式*****************/
|
|
|
+
|
|
|
+ //task_list 审批人相关
|
|
|
+ JSONArray taskArr = new JSONArray();
|
|
|
+
|
|
|
+ for (int i = 0; i <load.length ; i++) {
|
|
|
+ JSONObject task = new JSONObject();
|
|
|
+ task.put("task_id", load[i].getPkValue()+"_"+taskId);
|
|
|
+ task.put("open_id", getUserId(load[i].getString("phone"),token));
|
|
|
+
|
|
|
+ JSONObject links1 = new JSONObject();
|
|
|
+
|
|
|
+ links1.put("pc_link",pcSrcToFeishu(changeDanDianSrc(pcUrl+"&apptype=feishu")));
|
|
|
+ links1.put("mobile_link",changeDanDianSrc(changephoneurl(mobUrl,taskId)) );
|
|
|
+
|
|
|
+ task.put("links", links1);
|
|
|
+
|
|
|
+ if(isUpdate){
|
|
|
+ task.put("status", passStatus);
|
|
|
+ }else{
|
|
|
+ task.put("status", "PENDING");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if(toDoInfo.getContent()!=null&&!"".equals(toDoInfo.getContent())){
|
|
|
+ task.put("title", toDoInfo.getContent());
|
|
|
+ }
|
|
|
+ if(isUpdate){
|
|
|
+ if(content!=null&&!"".equals(content)) {
|
|
|
+ task.put("title", content);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(toDoInfo.getContent()==null&&content==null){
|
|
|
+ task.put("title", oldcontent);
|
|
|
+ }
|
|
|
+
|
|
|
+// task.put("title", workflowname);
|
|
|
+
|
|
|
+ task.put("create_time", d.getTime());
|
|
|
+ task.put("end_time", d.getTime());
|
|
|
+ task.put("update_time", d.getTime());
|
|
|
+ taskArr.add(task);
|
|
|
+ }
|
|
|
+ c.put("task_list", taskArr);
|
|
|
+
|
|
|
+ m.put("content", c);
|
|
|
+ return m;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static String changephoneurl(String url,String taskId){
|
|
|
+ String returnurl="";
|
|
|
+ if(url==null){
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ int firstindex = url.indexOf("&tId=");
|
|
|
+ if(firstindex>0){
|
|
|
+ returnurl = url.substring(0,firstindex)+"&apptype=feishu";
|
|
|
+ }
|
|
|
+ return returnurl;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 待办变已办
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public JSONObject getToYiBanJson(MessageContext messageContext,ToDoInfo toDoInfo,DynamicObject[] load,String token,
|
|
|
+ boolean isUpdate,String passStatus,String content, Map<String, String> logMaps){
|
|
|
+
|
|
|
+ JSONObject m = new JSONObject(true);
|
|
|
+ JSONObject c = new JSONObject(true);
|
|
|
+ c.put("approval_code", SPDYID);
|
|
|
+ c.put("instance_id","cq"+toDoInfo.getTaskId());
|
|
|
+
|
|
|
+ if(isUpdate){
|
|
|
+ if ("DONE".equalsIgnoreCase(passStatus)){
|
|
|
+ passStatus = "APPROVED";
|
|
|
+ }
|
|
|
+ c.put("status", passStatus);
|
|
|
+ }else{
|
|
|
+ c.put("status", "PENDING");
|
|
|
+ }
|
|
|
+
|
|
|
+ c.put("display_method", "SIDEBAR");
|
|
|
+
|
|
|
+ String pcUrl = toDoInfo.getUrl();
|
|
|
+ String mobUrl = toDoInfo.getUrl();
|
|
|
+
|
|
|
+ //替换PC端域名
|
|
|
+ pcUrl = replacePcUrlDomain(pcUrl);
|
|
|
+ //移动端替换域名
|
|
|
+ mobUrl = replaceMobUrlDomain(mobUrl);
|
|
|
+
|
|
|
+
|
|
|
+ //url连接
|
|
|
+ JSONObject links = new JSONObject();
|
|
|
+ links.put("pc_link",pcSrcToFeishu(changeDanDianSrc(pcUrl+"&apptype=feishu")));
|
|
|
+ links.put("mobile_link", changeDanDianSrc(changephoneurl(mobUrl,toDoInfo.getTaskId()+"")));
|
|
|
+ c.put("links", links);
|
|
|
+
|
|
|
+ //标题
|
|
|
+ if(toDoInfo.getContent()!=null&&!"".equals(toDoInfo.getContent())){
|
|
|
+ c.put("title", toDoInfo.getContent());
|
|
|
+ }
|
|
|
+ if(isUpdate){
|
|
|
+ if(content!=null&&!"".equals(content)) {
|
|
|
+ c.put("title", content);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ String oldcontent="";
|
|
|
+ if(toDoInfo.getContent()==null&&content==null){
|
|
|
+ DynamicObject businessObject = WfUtils.findBusinessObject(messageContext.getBusinessKey(), messageContext.getEntityNumber());
|
|
|
+ oldcontent =getTitle(messageContext,businessObject);
|
|
|
+ c.put("title", oldcontent);
|
|
|
+ }
|
|
|
+// Long faqirenid = messageContext.getStartUserId();
|
|
|
+// if(faqirenid!=null){
|
|
|
+// DynamicObject faqiren = BusinessDataServiceHelper.loadSingleFromCache(faqirenid,"bos_user");
|
|
|
+// c.put("open_id", FeishuUtil.getUserId(faqiren.getString("phone"),token));
|
|
|
+// }
|
|
|
+
|
|
|
+ //发起人
|
|
|
+
|
|
|
+
|
|
|
+ /*************处理消息格式*****************/
|
|
|
+ DynamicObject taskInfo = BusinessDataServiceHelper.loadSingleFromCache(toDoInfo.getTaskId() ,"wf_task");
|
|
|
+
|
|
|
+ //add by wnaghaiwu_kd 2024/04/28
|
|
|
+ //如果任务中找不到,就找历史任务
|
|
|
+ if(taskInfo == null){
|
|
|
+ taskInfo = BusinessDataServiceHelper.loadSingleFromCache(toDoInfo.getTaskId() ,"wf_hitaskinst");
|
|
|
+ }
|
|
|
+
|
|
|
+ String nodename = toDoInfo.getCategory();
|
|
|
+ String workflowname = "财务系统审批流";
|
|
|
+ String createDate = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
|
|
|
+
|
|
|
+ if(taskInfo != null){
|
|
|
+ nodename = taskInfo.getString("name");
|
|
|
+
|
|
|
+ if(taskInfo.getLong("processdefinitionid") > 0) {
|
|
|
+ QFilter qFilter = new QFilter("id", QCP.equals, taskInfo.getLong("processdefinitionid"));
|
|
|
+ DynamicObject processdef = BusinessDataServiceHelper.loadSingle("wf_processdefinition", qFilter.toArray());
|
|
|
+ if (processdef != null) {
|
|
|
+ workflowname = processdef.getString("name");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if("财务系统审批流".equals(workflowname) && taskInfo.getString("entityname") != null){
|
|
|
+ workflowname = taskInfo.getString("entityname") + "审批流程";
|
|
|
+ }
|
|
|
+ if(StringUtils.isNotEmpty(taskInfo.getString("entitynumber"))
|
|
|
+ && StringUtils.isNotEmpty(taskInfo.getString("businesskey"))){
|
|
|
+ QFilter qFilter = new QFilter("id", QCP.equals, Long.valueOf(taskInfo.getString("businesskey")));
|
|
|
+ DynamicObject bill = BusinessDataServiceHelper.loadSingle(taskInfo.getString("entitynumber"), qFilter.toArray());
|
|
|
+ if(bill != null){
|
|
|
+ createDate = getCreateTime(bill);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ //发起人
|
|
|
+
|
|
|
+ Long faqirenid = taskInfo.getLong("starterid");
|
|
|
+ if(faqirenid!=null){
|
|
|
+ DynamicObject faqiren = BusinessDataServiceHelper.loadSingleFromCache(faqirenid,"bos_user");
|
|
|
+ c.put("open_id", getUserId(faqiren.getString("phone"),token));
|
|
|
+
|
|
|
+ //发起人id、发起人飞书id
|
|
|
+ logMaps.put("nckd_creatorid", faqirenid.toString());
|
|
|
+ logMaps.put("nckd_creatoridfeishu", getUserId(faqiren.getString("phone"),token));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ c.put("title", workflowname);
|
|
|
+
|
|
|
+ JSONArray formArr = new JSONArray();
|
|
|
+ JSONObject form1 = new JSONObject();
|
|
|
+ form1.put("name", "流程标题");
|
|
|
+ form1.put("value", StringUtils.isEmpty(toDoInfo.getTitle()) ? workflowname : toDoInfo.getTitle());
|
|
|
+ formArr.add(form1);
|
|
|
+
|
|
|
+ JSONObject form2 = new JSONObject();
|
|
|
+ form2.put("name", "提单时间");
|
|
|
+ form2.put("value", createDate);
|
|
|
+ formArr.add(form2);
|
|
|
+
|
|
|
+ JSONObject form3 = new JSONObject();
|
|
|
+ form3.put("name", "当前节点");
|
|
|
+ form3.put("value", nodename);
|
|
|
+ formArr.add(form3);
|
|
|
+
|
|
|
+ c.put("form", formArr);
|
|
|
+
|
|
|
+ /*************处理消息格式*****************/
|
|
|
+
|
|
|
+ Date d = new Date();
|
|
|
+
|
|
|
+ c.put("start_time", d.getTime());
|
|
|
+ c.put("update_time",d.getTime());
|
|
|
+ c.put("update_mode", "UPDATE");
|
|
|
+
|
|
|
+ //task_list 审批人相关
|
|
|
+ JSONArray taskArr = new JSONArray();
|
|
|
+
|
|
|
+ for (int i = 0; i <load.length ; i++) {
|
|
|
+ JSONObject task = new JSONObject();
|
|
|
+ task.put("task_id", load[i].getPkValue()+"_"+toDoInfo.getTaskId());
|
|
|
+ task.put("open_id", getUserId(load[i].getString("phone"),token));
|
|
|
+
|
|
|
+ //接收人飞书id
|
|
|
+ logMaps.put("nckd_to_useridfeishu", getUserId(load[i].getString("phone"),token));
|
|
|
+
|
|
|
+ JSONObject links1 = new JSONObject();
|
|
|
+
|
|
|
+ links1.put("pc_link",pcSrcToFeishu(changeDanDianSrc(pcUrl+"&apptype=feishu")));
|
|
|
+ links1.put("mobile_link",changeDanDianSrc(changephoneurl(mobUrl,toDoInfo.getTaskId()+"")));
|
|
|
+
|
|
|
+ task.put("links", links1);
|
|
|
+
|
|
|
+ if(isUpdate){
|
|
|
+ task.put("status", passStatus);
|
|
|
+ }else{
|
|
|
+ task.put("status", "PENDING");
|
|
|
+ }
|
|
|
+
|
|
|
+ if(toDoInfo.getContent()!=null&&!"".equals(toDoInfo.getContent())){
|
|
|
+ task.put("title", toDoInfo.getContent());
|
|
|
+ }
|
|
|
+ if(isUpdate){
|
|
|
+ if(content!=null&&!"".equals(content)) {
|
|
|
+ task.put("title", content);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(toDoInfo.getContent()==null&&content==null){
|
|
|
+ task.put("title", oldcontent);
|
|
|
+ }
|
|
|
+
|
|
|
+ task.put("title", workflowname);
|
|
|
+
|
|
|
+ task.put("create_time", d.getTime());
|
|
|
+ task.put("end_time", d.getTime());
|
|
|
+ task.put("update_time", d.getTime());
|
|
|
+ taskArr.add(task);
|
|
|
+ }
|
|
|
+ c.put("task_list", taskArr);
|
|
|
+
|
|
|
+ m.put("content", c);
|
|
|
+ return m;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取创建审批实例json
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public JSONObject getToDaiBanJson(MessageContext messageContext,ToDoInfo toDoInfo,DynamicObject[] load,String token,boolean isUpdate,String passStatus,String content, String fixName, Map<String, String> logMaps){
|
|
|
+ boolean isExist = QueryServiceHelper.exists("wf_task",toDoInfo.getTaskId());
|
|
|
+ if(!isExist){
|
|
|
+ return getdeleteJson(messageContext,toDoInfo,load,token,isUpdate,passStatus,content,toDoInfo.getTaskId()+"", logMaps);
|
|
|
+ }
|
|
|
+ DynamicObject taskInfo = BusinessDataServiceHelper.loadSingle(toDoInfo.getTaskId() ,"wf_task");
|
|
|
+
|
|
|
+
|
|
|
+ JSONObject m = new JSONObject(true);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ JSONObject c = new JSONObject(true);
|
|
|
+ c.put("approval_code", SPDYID);
|
|
|
+ c.put("instance_id","cq"+toDoInfo.getTaskId());
|
|
|
+
|
|
|
+ if(isUpdate){
|
|
|
+ if ("DONE".equalsIgnoreCase(passStatus)){
|
|
|
+ passStatus = "APPROVED";
|
|
|
+ }
|
|
|
+ c.put("status", passStatus);
|
|
|
+ }else{
|
|
|
+ c.put("status", "PENDING");
|
|
|
+ }
|
|
|
+
|
|
|
+ c.put("display_method", "SIDEBAR");
|
|
|
+
|
|
|
+ String pcUrl = toDoInfo.getUrl();
|
|
|
+ String mobUrl = toDoInfo.getUrl();
|
|
|
+
|
|
|
+ //替换PC端域名
|
|
|
+ pcUrl = replacePcUrlDomain(pcUrl);
|
|
|
+ //移动端替换域名
|
|
|
+ mobUrl = replaceMobUrlDomain(mobUrl);
|
|
|
+
|
|
|
+ //url连接
|
|
|
+ JSONObject links = new JSONObject();
|
|
|
+ links.put("pc_link",pcSrcToFeishu(changeDanDianSrc(pcUrl+"&apptype=feishu")));
|
|
|
+ links.put("mobile_link", changeDanDianSrc(mobUrl+"&apptype=feishu"));
|
|
|
+ c.put("links", links);
|
|
|
+
|
|
|
+ //标题
|
|
|
+ c.put("title", toDoInfo.getContent());
|
|
|
+ if(isUpdate){
|
|
|
+ c.put("title", content);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*************处理消息格式*****************/
|
|
|
+ String nodename = toDoInfo.getCategory();
|
|
|
+ String workflowname = "财务系统审批流";
|
|
|
+ String createDate = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
|
|
|
+
|
|
|
+ if(taskInfo != null){
|
|
|
+ nodename = taskInfo.getString("name");
|
|
|
+
|
|
|
+ if(taskInfo.getLong("processdefinitionid") > 0) {
|
|
|
+ QFilter qFilter = new QFilter("id", QCP.equals, taskInfo.getLong("processdefinitionid"));
|
|
|
+ DynamicObject processdef = BusinessDataServiceHelper.loadSingle("wf_processdefinition", qFilter.toArray());
|
|
|
+ if (processdef != null) {
|
|
|
+ workflowname = processdef.getString("name");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if("财务系统审批流".equals(workflowname) && taskInfo.getString("entityname") != null){
|
|
|
+ workflowname = taskInfo.getString("entityname") + "审批流程";
|
|
|
+ }
|
|
|
+ if(StringUtils.isNotEmpty(taskInfo.getString("entitynumber"))
|
|
|
+ && StringUtils.isNotEmpty(taskInfo.getString("businesskey"))){
|
|
|
+ QFilter qFilter = new QFilter("id", QCP.equals, Long.valueOf(taskInfo.getString("businesskey")));
|
|
|
+ DynamicObject bill = BusinessDataServiceHelper.loadSingle(taskInfo.getString("entitynumber"), qFilter.toArray());
|
|
|
+ if(bill != null){
|
|
|
+ createDate = getCreateTime(bill);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ c.put("title", workflowname);
|
|
|
+
|
|
|
+ JSONArray formArr = new JSONArray();
|
|
|
+ JSONObject form1 = new JSONObject();
|
|
|
+ form1.put("name", "流程标题");
|
|
|
+ form1.put("value", fixName + (StringUtils.isEmpty(toDoInfo.getTitle()) ? workflowname : toDoInfo.getTitle()));
|
|
|
+ formArr.add(form1);
|
|
|
+
|
|
|
+ JSONObject form2 = new JSONObject();
|
|
|
+ form2.put("name", "提单时间");
|
|
|
+ form2.put("value", createDate);
|
|
|
+ formArr.add(form2);
|
|
|
+
|
|
|
+ JSONObject form3 = new JSONObject();
|
|
|
+ form3.put("name", "当前节点");
|
|
|
+ form3.put("value", nodename);
|
|
|
+ formArr.add(form3);
|
|
|
+
|
|
|
+ c.put("form", formArr);
|
|
|
+
|
|
|
+ /*************处理消息格式*****************/
|
|
|
+
|
|
|
+
|
|
|
+ //发起人
|
|
|
+
|
|
|
+ Long faqirenid = taskInfo.getLong("starterid");
|
|
|
+ if(faqirenid!=null){
|
|
|
+ DynamicObject faqiren = BusinessDataServiceHelper.loadSingleFromCache(faqirenid,"bos_user");
|
|
|
+ c.put("open_id", getUserId(faqiren.getString("phone"),token));
|
|
|
+
|
|
|
+ //发起人id、发起人飞书id
|
|
|
+ logMaps.put("nckd_creatorid", faqirenid.toString());
|
|
|
+ logMaps.put("nckd_creatoridfeishu", getUserId(faqiren.getString("phone"),token));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ c.put("start_time", ((Timestamp)taskInfo.get("createdate")).getTime());
|
|
|
+ c.put("update_time", ((Timestamp)taskInfo.get("createdate")).getTime());
|
|
|
+ c.put("update_mode", "REPLACED");
|
|
|
+
|
|
|
+ //task_list 审批人相关
|
|
|
+ JSONArray taskArr = new JSONArray();
|
|
|
+
|
|
|
+ for (int i = 0; i <load.length ; i++) {
|
|
|
+ JSONObject task = new JSONObject();
|
|
|
+ task.put("task_id", load[i].getPkValue()+"_"+toDoInfo.getTaskId());
|
|
|
+ task.put("open_id", getUserId(load[i].getString("phone"),token));
|
|
|
+
|
|
|
+ JSONObject links1 = new JSONObject();
|
|
|
+
|
|
|
+ links1.put("pc_link",pcSrcToFeishu(changeDanDianSrc(pcUrl+"&apptype=feishu")));
|
|
|
+ links1.put("mobile_link",changeDanDianSrc(mobUrl+"&apptype=feishu"));
|
|
|
+
|
|
|
+ task.put("links", links1);
|
|
|
+
|
|
|
+ if(isUpdate){
|
|
|
+ task.put("status", passStatus);
|
|
|
+ }else{
|
|
|
+ task.put("status", "PENDING");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ task.put("title", toDoInfo.getContent());
|
|
|
+ if(isUpdate){
|
|
|
+ task.put("title", content);
|
|
|
+ }
|
|
|
+ task.put("title", workflowname);
|
|
|
+
|
|
|
+ task.put("create_time", taskInfo.get("createdate"));
|
|
|
+ task.put("end_time", taskInfo.get("createdate"));
|
|
|
+ task.put("update_time", taskInfo.get("createdate"));
|
|
|
+ taskArr.add(task);
|
|
|
+ }
|
|
|
+ c.put("task_list", taskArr);
|
|
|
+
|
|
|
+ m.put("content", c);
|
|
|
+ return m;
|
|
|
+ }
|
|
|
+
|
|
|
+ //pc链接特殊处理
|
|
|
+ public String pcSrcToFeishu(String src){
|
|
|
+ String dandianStr="";
|
|
|
+ if(dandianStr != null) {
|
|
|
+ try {
|
|
|
+ String encodesrc = URLEncoder.encode(src, "utf-8");
|
|
|
+ dandianStr = "https://applink.feishu.cn/client/web_url/open?mode=window&url=" + encodesrc;
|
|
|
+ } catch (UnsupportedEncodingException e) {
|
|
|
+ log.info(e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return dandianStr;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public static String changeDanDianSrc(String src){
|
|
|
+ String dandianStr="";
|
|
|
+ if(src != null) {
|
|
|
+ try {
|
|
|
+ String encodesrc = URLEncoder.encode(src, "utf-8");
|
|
|
+ dandianStr = "https://open.feishu.cn/open-apis/authen/v1/index?redirect_uri=" + encodesrc + "&app_id=" + APP_ID;
|
|
|
+ } catch (UnsupportedEncodingException e) {
|
|
|
+ log.info(e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return dandianStr;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 工作流中将待办变成已办的时候,会调用此接口进行待办变已办的处理
|
|
|
+ * @param messageContext
|
|
|
+ * @param toDoInfo
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public void dealToDo(MessageContext messageContext, ToDoInfo toDoInfo) {
|
|
|
+ log.info("财务系统飞书,更新待办为已办开始 ctx: " + messageContext.toString() + ",taskId:" + messageContext.getTaskId());
|
|
|
+
|
|
|
+ try {
|
|
|
+ List<Long> userIds = toDoInfo.getUserIds();
|
|
|
+ if (CollectionUtils.isEmpty(userIds)) {
|
|
|
+ log.info("财务系统飞书,人员为空,推送失败");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ log.info("获取用户开始");
|
|
|
+
|
|
|
+ QFilter qFilter = new QFilter("id", QCP.in, userIds);
|
|
|
+ DynamicObject[] load = BusinessDataServiceHelper.load(USER_FORM_ID, USERNAME+",phone", qFilter.toArray());
|
|
|
+ log.info("获取用户结束:"+load[0].getPkValue());
|
|
|
+
|
|
|
+ String token = getToken();
|
|
|
+ String status="APPROVED";
|
|
|
+ log.info("获取任务:");
|
|
|
+ boolean isExist = QueryServiceHelper.exists("wf_task",toDoInfo.getTaskId());
|
|
|
+ if(isExist){
|
|
|
+ DynamicObject taskInfo = BusinessDataServiceHelper.loadSingleFromCache(toDoInfo.getTaskId() ,"wf_task");
|
|
|
+ log.info("获取任务结束:"+taskInfo.getPkValue());
|
|
|
+ String taskStatus=taskInfo.getString("handlestate");
|
|
|
+ if("dismissed".equals(taskStatus)){//驳回
|
|
|
+ status="REJECTED";
|
|
|
+ }else if("willApproval".equals(taskStatus)){
|
|
|
+ // status="REJECTED";
|
|
|
+ }
|
|
|
+ }
|
|
|
+// DynamicObject businessObject = WfUtils.findBusinessObject(messageContext.getBusinessKey(), messageContext.getEntityNumber());
|
|
|
+// String content =getTitle(messageContext,businessObject);
|
|
|
+ String content = toDoInfo.getContent();
|
|
|
+ String title = toDoInfo.getTitle();
|
|
|
+
|
|
|
+ log.info("获取json开始:");
|
|
|
+
|
|
|
+ Map<String, String> logMaps = new HashMap<>();
|
|
|
+
|
|
|
+ logMaps.put("nckd_logtype", "dealToDo");
|
|
|
+ logMaps.put("nckd_apiurl", createInstanceUrl);
|
|
|
+
|
|
|
+ String reveiceUserIds = userIds.stream().map(Object::toString) // 将Long转换为String
|
|
|
+ .collect(Collectors.joining(",")); // 用逗号连接所有String元素
|
|
|
+
|
|
|
+ logMaps.put("nckd_receiveuserids", reveiceUserIds);
|
|
|
+
|
|
|
+ JSONObject m = getToYiBanJson(messageContext, toDoInfo, load, token,true, status, content, logMaps);
|
|
|
+
|
|
|
+ log.info("财务系统飞书更新待办:"+m.toJSONString());
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ String uuid = saveMsgLogNew(userIds.get(0).toString(), title, "财务系统飞书更新待办[DaJingDaiBanServiceHandler.dealToDo]", m, logMaps);
|
|
|
+
|
|
|
+ String response = FeishuUtil.doPostByHttpClient(createInstanceUrl, m.toJSONString(), true,token, 3);
|
|
|
+ log.info("财务系统飞书更新待办结果:"+response);
|
|
|
+
|
|
|
+ JSONObject res = JSONObject.parseObject(response);
|
|
|
+ if (interErrCodeArr.contains(res.getIntValue("code"))){
|
|
|
+ // 内部错误,可重试
|
|
|
+ Thread.sleep(500L);
|
|
|
+ response = FeishuUtil.doPostByHttpClient(createInstanceUrl, m.toJSONString(), true, token, 3);
|
|
|
+ log.info("财务系统飞书更新待办结果二次:" + response);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!ObjectUtils.isEmpty(uuid)) {
|
|
|
+ // 将发送消息的结果回填到数据库日志记录
|
|
|
+ updateMsgLog(uuid, response);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.info("财务系统飞书,更新待办失败" + e.getMessage());
|
|
|
+ log.info(e.getMessage());
|
|
|
+// e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 工作流中撤回,或者多人收到任务,其中一人审批,删除其他人的待办时,调用此接口
|
|
|
+ * @param messageContext
|
|
|
+ * @param toDoInfo
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public void deleteToDo(MessageContext messageContext, ToDoInfo toDoInfo) {
|
|
|
+
|
|
|
+ log.info("财务系统飞书,取消待办开始 ctx: " + messageContext.toString() + ",taskId:" + messageContext.getTaskId());
|
|
|
+ List<Long> userIds = toDoInfo.getUserIds();
|
|
|
+ QFilter qFilter = new QFilter("id", QCP.in, userIds);
|
|
|
+ DynamicObject[] load = BusinessDataServiceHelper.load(USER_FORM_ID, USERNAME+",phone", qFilter.toArray());
|
|
|
+ String token = getToken();
|
|
|
+// DynamicObject businessObject = WfUtils.findBusinessObject(messageContext.getBusinessKey(), messageContext.getEntityNumber());
|
|
|
+// String content =getTitle(messageContext,businessObject);
|
|
|
+
|
|
|
+ Map<String, String> logMaps = new HashMap<>();
|
|
|
+
|
|
|
+ logMaps.put("nckd_logtype", "deleteToDo");
|
|
|
+ logMaps.put("nckd_apiurl", createInstanceUrl);
|
|
|
+
|
|
|
+ String reveiceUserIds = userIds.stream().map(Object::toString) // 将Long转换为String
|
|
|
+ .collect(Collectors.joining(",")); // 用逗号连接所有String元素
|
|
|
+
|
|
|
+ logMaps.put("nckd_receiveuserids", reveiceUserIds);
|
|
|
+
|
|
|
+ String content = toDoInfo.getContent();
|
|
|
+ JSONObject m = getToDaiBanJson(messageContext,toDoInfo,load,token,true,"DONE",content, "", logMaps);
|
|
|
+ try {
|
|
|
+ log.info("财务系统飞书取消待办:"+m.toJSONString());
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ String uuid = saveMsgLogNew(userIds.get(0).toString(), content, "财务系统飞书更新待办[DaJingDaiBanServiceHandler.deleteToDo]", m, logMaps);
|
|
|
+ String response = doPostByHttpClient(createInstanceUrl, m.toJSONString(), true,token, 3);
|
|
|
+
|
|
|
+ log.info("财务系统飞书取消待办结果:"+response);
|
|
|
+
|
|
|
+ JSONObject res = JSONObject.parseObject(response);
|
|
|
+ if (interErrCodeArr.contains(res.getIntValue("code"))){
|
|
|
+ // 内部错误,可重试
|
|
|
+ Thread.sleep(500L);
|
|
|
+ response = FeishuUtil.doPostByHttpClient(createInstanceUrl, m.toJSONString(), true, token, 3);
|
|
|
+ log.info("财务系统飞书更新待办结果二次:" + response);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!ObjectUtils.isEmpty(uuid)) {
|
|
|
+ // 将发送消息的结果回填到数据库日志记录
|
|
|
+ updateMsgLog(uuid, response);
|
|
|
+ }
|
|
|
+ } catch (ConnectException e) {
|
|
|
+ log.info("财务系统飞书,取消待办失败");
|
|
|
+ log.error(e.getMessage(), e);
|
|
|
+ e.printStackTrace();
|
|
|
+ } catch (InterruptedException e1) {
|
|
|
+ log.info("财务系统飞书,取消待办失败");
|
|
|
+ log.error(e1.getMessage(), e1);
|
|
|
+ throw new RuntimeException(e1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public String getTitle(MessageContext messageContext,DynamicObject businessObject){
|
|
|
+ String content = "请处理:%s单据编号:%s";
|
|
|
+
|
|
|
+ DynamicObjectType dt = businessObject.getDynamicObjectType();
|
|
|
+ IDataEntityProperty pkProp = dt.getPrimaryKey();
|
|
|
+ DataEntityPropertyCollection properties = dt.getProperties();
|
|
|
+
|
|
|
+ //发现预算的单据虽然是基础资料,但编码字段是billno, 所以改成根据实体属性是否包含number或billno字段
|
|
|
+ if(properties.containsKey("number")){
|
|
|
+ content = String.format(content, messageContext.getEntityName(), businessObject.getString("number"));
|
|
|
+ } else if(properties.containsKey("billno")){
|
|
|
+ content = String.format(content, messageContext.getEntityName(), businessObject.getString("billno"));
|
|
|
+ } else {
|
|
|
+ content = String.format(content, messageContext.getEntityName(), dt.getName());
|
|
|
+ }
|
|
|
+
|
|
|
+// if (dt instanceof BasedataEntityType) {
|
|
|
+// content = String.format(content, messageContext.getEntityName(), businessObject.getString("number"));
|
|
|
+// }else{
|
|
|
+// content = String.format(content, messageContext.getEntityName(), businessObject.getString("billno"));
|
|
|
+// }
|
|
|
+
|
|
|
+ return content;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 普通消息暂时不推送
|
|
|
+ * @param ctx
|
|
|
+ * @param message
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public void sendMessage(MessageContext ctx, MessageInfo message) {
|
|
|
+
|
|
|
+ try {
|
|
|
+ String notifyType = message.getNotifyType();
|
|
|
+ if (ctx != null){
|
|
|
+ log.info("DaiBanServiceHandler.sendMessage 飞书待办消息url:" + message.getContentUrl() + ",mobileurl:" + message.getMobContentUrl()+ ", pk:" + ctx.getBusinessKey());
|
|
|
+ }else {
|
|
|
+ log.info("DaiBanServiceHandler.sendMessage 飞书待办消息url:" + message.getContentUrl() + ",mobileurl:" + message.getMobContentUrl());
|
|
|
+ }
|
|
|
+ if("feishu".equals(notifyType)){
|
|
|
+ log.info("财务系统移动审批,消息发 taskId:" + message.getId());
|
|
|
+ String token = getToken();
|
|
|
+ List<Long> userIds = message.getUserIds();
|
|
|
+
|
|
|
+ String linkUrl = message.getContentUrl();
|
|
|
+ String linkMobileUrl = message.getMobContentUrl();
|
|
|
+
|
|
|
+ //替换PC端域名
|
|
|
+ linkUrl = replacePcUrlDomain(linkUrl);
|
|
|
+ //移动端替换域名
|
|
|
+ linkMobileUrl = replaceMobUrlDomain(linkMobileUrl);
|
|
|
+
|
|
|
+ //发送消息
|
|
|
+ for (int i = 0; i < userIds.size() ; i++) {
|
|
|
+ DynamicObject userInfo = BusinessDataServiceHelper.loadSingle(userIds.get(i),"bos_user");
|
|
|
+ String userid = getUserIdTrue(userInfo.getString("phone"),token);
|
|
|
+
|
|
|
+
|
|
|
+ if("circulation".equals(message.getTplScene())){
|
|
|
+ if(i == 0) {
|
|
|
+ //发送传阅消息,多接收人只需要发一次
|
|
|
+ sendFlowMessage(ctx, message, userid, token);
|
|
|
+ }
|
|
|
+ //发送带链接的消息
|
|
|
+ sendLinkMessage(ctx, message, userid, userIds.get(i).toString(), token, "1016");
|
|
|
+ } else if(StringUtils.isNotEmpty(linkUrl)){
|
|
|
+ //发送带链接的消息
|
|
|
+ sendLinkMessage(ctx, message, userid, userIds.get(i).toString(), token, "1021");
|
|
|
+ } else {
|
|
|
+ //发送普通消息
|
|
|
+ userid = getUserId(userInfo.getString("phone"),token);
|
|
|
+ sendCustomMessage(ctx, message, userid, token);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }catch (Exception e){
|
|
|
+ log.error("DaiBanServiceHandler.sendMessage 发送审批消息异常:" + e.getMessage(), e);
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 替换移动端域名
|
|
|
+ * @param mobUrl
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public String replaceMobUrlDomain(String mobUrl){
|
|
|
+ log.info("替换前移动端地址: moburl:" + mobUrl);
|
|
|
+
|
|
|
+ if(StringUtils.isEmpty(mobUrl)){
|
|
|
+ return mobUrl;
|
|
|
+ }
|
|
|
+
|
|
|
+ //移动端需要走外网,将地址替换成外网地址
|
|
|
+ String curUrl = ParamsUtil.getCommonParamsField("nckd_url");
|
|
|
+ String mobileDomain = ParamsUtil.getCommonParamsField("nckd_mobileurl");
|
|
|
+
|
|
|
+ mobUrl = mobUrl.replace(curUrl, mobileDomain);
|
|
|
+
|
|
|
+ log.info("替换后移动端地址: moburl:" + mobUrl);
|
|
|
+
|
|
|
+ return mobUrl;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 替换PC端域名
|
|
|
+ * @param pcUrl
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public String replacePcUrlDomain(String pcUrl){
|
|
|
+ log.info("替换前PC端地址: pcUrl:" + pcUrl);
|
|
|
+
|
|
|
+ if(StringUtils.isEmpty(pcUrl)){
|
|
|
+ return pcUrl;
|
|
|
+ }
|
|
|
+
|
|
|
+ //移动端需要走外网,将地址替换成外网地址
|
|
|
+ String curUrl = ParamsUtil.getCommonParamsField("nckd_url");
|
|
|
+ String mobileDomain = ParamsUtil.getCommonParamsField("nckd_mobileurl");
|
|
|
+
|
|
|
+ pcUrl = pcUrl.replace(mobileDomain, curUrl);
|
|
|
+
|
|
|
+ log.info("替换后地址: pcUrl:" + pcUrl);
|
|
|
+
|
|
|
+ return pcUrl;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private final String getAppWfName() {
|
|
|
+ return System.getProperty("app.wf.name", TRAGETNAME);
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getCreateTime(DynamicObject bill){
|
|
|
+ String createDate = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
|
|
|
+ if(bill.getDynamicObjectType().getProperties().contains("createtime")) {
|
|
|
+ createDate = DateFormatUtils.format(bill.getDate("createtime"), "yyyy-MM-dd HH:mm:ss");
|
|
|
+ } else if(bill.getDynamicObjectType().getProperties().contains("createdate")) {
|
|
|
+ createDate = DateFormatUtils.format(bill.getDate("createdate"), "yyyy-MM-dd HH:mm:ss");
|
|
|
+ }
|
|
|
+
|
|
|
+ return createDate;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 保存飞书消息日志
|
|
|
+ *
|
|
|
+ * @param userid 用户id
|
|
|
+ * @param title 标题
|
|
|
+ * @param content 内容
|
|
|
+ * @param m 发送消息体
|
|
|
+ * @return uuid
|
|
|
+ */
|
|
|
+ private String saveMsgLog(String userid, String title, String content, JSONObject m) {
|
|
|
+ try {
|
|
|
+ log.info("记录新增飞书推送数据日志");
|
|
|
+ String uuid = UUID.randomUUID().toString().replace("-", "");
|
|
|
+ DynamicObject dynamicObject = BusinessDataServiceHelper.newDynamicObject("nckd_log_feishumsg");
|
|
|
+
|
|
|
+ dynamicObject.set("billno", uuid);
|
|
|
+ dynamicObject.set("billstatus", "C");
|
|
|
+ dynamicObject.set("nckd_to_userid", userid);
|
|
|
+ dynamicObject.set("nckd_msg_title", title);
|
|
|
+ String msgContent = m.toString();
|
|
|
+ if (msgContent.length() < 200){
|
|
|
+ dynamicObject.set("nckd_msg_content_l", msgContent);
|
|
|
+ }else {
|
|
|
+ dynamicObject.set("nckd_msg_content_l", msgContent.substring(0,200) + "...");
|
|
|
+ }
|
|
|
+ dynamicObject.set("nckd_msg_content_l_tag", msgContent);
|
|
|
+ if (content.length() < 200){
|
|
|
+ dynamicObject.set("nckd_msg_content", content);
|
|
|
+ }else {
|
|
|
+ dynamicObject.set("nckd_msg_content", content.substring(0,200) + "...");
|
|
|
+ }
|
|
|
+ dynamicObject.set("nckd_msg_content_tag", content);
|
|
|
+ dynamicObject.set("nckd_send_time", new Date());
|
|
|
+ SaveServiceHelper.save(new DynamicObject[]{dynamicObject});
|
|
|
+ log.info("记录新增飞书推送数据日志成功:{}", uuid);
|
|
|
+ return uuid;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.info("记录新增飞书推送数据日志异常:" + e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 保存飞书消息日志
|
|
|
+ *
|
|
|
+ * @param userid 用户id
|
|
|
+ * @param title 标题
|
|
|
+ * @param content 内容
|
|
|
+ * @param m 发送消息体
|
|
|
+ * @return uuid
|
|
|
+ */
|
|
|
+ private String saveMsgLogNew(String userid, String title, String content, JSONObject m, Map<String, String> logMaps) {
|
|
|
+ try {
|
|
|
+ log.info("记录新增飞书推送数据日志");
|
|
|
+ String uuid = UUID.randomUUID().toString().replace("-", "");
|
|
|
+ DynamicObject dynamicObject = BusinessDataServiceHelper.newDynamicObject("nckd_log_feishumsg");
|
|
|
+
|
|
|
+ dynamicObject.set("billno", uuid);
|
|
|
+ dynamicObject.set("billstatus", "C");
|
|
|
+ dynamicObject.set("nckd_to_userid", userid);
|
|
|
+ dynamicObject.set("nckd_msg_title", title);
|
|
|
+ String msgContent = m.toString();
|
|
|
+ if (msgContent.length() < 200){
|
|
|
+ dynamicObject.set("nckd_msg_content_l", msgContent);
|
|
|
+ }else {
|
|
|
+ dynamicObject.set("nckd_msg_content_l", msgContent.substring(0,200) + "...");
|
|
|
+ }
|
|
|
+ dynamicObject.set("nckd_msg_content_l_tag", msgContent);
|
|
|
+ if (content.length() < 200){
|
|
|
+ dynamicObject.set("nckd_msg_content", content);
|
|
|
+ }else {
|
|
|
+ dynamicObject.set("nckd_msg_content", content.substring(0,200) + "...");
|
|
|
+ }
|
|
|
+ dynamicObject.set("nckd_msg_content_tag", content);
|
|
|
+ dynamicObject.set("nckd_send_time", new Date());
|
|
|
+ dynamicObject.set("nckd_sysstatus", "fail");
|
|
|
+
|
|
|
+ if(logMaps != null){
|
|
|
+ dynamicObject.set("nckd_logtype", logMaps.get("nckd_logtype"));
|
|
|
+ dynamicObject.set("nckd_apiurl", logMaps.get("nckd_apiurl"));
|
|
|
+ dynamicObject.set("nckd_to_useridfeishu", logMaps.get("nckd_to_useridfeishu"));
|
|
|
+ dynamicObject.set("nckd_creatorid", logMaps.get("nckd_creatorid"));
|
|
|
+ dynamicObject.set("nckd_creatoridfeishu", logMaps.get("nckd_creatoridfeishu"));
|
|
|
+ dynamicObject.set("nckd_receiveuserids", logMaps.get("nckd_receiveuserids"));
|
|
|
+ }
|
|
|
+
|
|
|
+ SaveServiceHelper.save(new DynamicObject[]{dynamicObject});
|
|
|
+ log.info("记录新增飞书推送数据日志成功:{}", uuid);
|
|
|
+ return uuid;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.info("记录新增飞书推送数据日志异常:" + e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新消息响应到对应日志记录
|
|
|
+ * @param uuid uuid
|
|
|
+ * @param response 消息响应
|
|
|
+ */
|
|
|
+ private void updateMsgLog(String uuid, String response) {
|
|
|
+ try {
|
|
|
+ log.info("记录更新飞书推送结果数据日志");
|
|
|
+ QFilter qFilterCas = new QFilter("billno", QCP.equals, uuid);
|
|
|
+ DynamicObject[] dynamicObjects = BusinessDataServiceHelper.load("nckd_log_feishumsg", "id", new QFilter[]{qFilterCas});
|
|
|
+ if (dynamicObjects != null && dynamicObjects.length > 0) {
|
|
|
+ String id = dynamicObjects[0].getPkValue().toString();
|
|
|
+ DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle(id, "nckd_log_feishumsg");
|
|
|
+ if (response.length() < 200){
|
|
|
+ dynamicObject.set("nckd_send_result_l", response);
|
|
|
+ }else {
|
|
|
+ dynamicObject.set("nckd_send_result_l", response.substring(0,200) + "...");
|
|
|
+ }
|
|
|
+ dynamicObject.set("nckd_send_result_l_tag", response);
|
|
|
+
|
|
|
+ if(response != null && isJson(response)) {
|
|
|
+ JSONObject res = JSONObject.parseObject(response);
|
|
|
+ if ("0".equals(res.getString("code"))) {
|
|
|
+ dynamicObject.set("nckd_sysstatus", "success");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ SaveServiceHelper.update(dynamicObject);
|
|
|
+ log.info("记录更新飞书推送结果数据日志成功");
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.info("记录更新飞书推送结果数据日志异常:" + e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void deleteProcessInstance(MessageContext ctx, Long proceInstanceId) {
|
|
|
+ // 打印控制台日志
|
|
|
+ System.out.println(String.format("流程实例:%d 被删除了,messageContext:" + ctx, proceInstanceId));
|
|
|
+ log.info(String.format("流程实例:%d 被删除了,messageContext:" + ctx, proceInstanceId));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void completeProcessInstance(MessageContext ctx, Long proceInstanceId) {
|
|
|
+ // 流程归档
|
|
|
+ System.out.println(String.format("流程实例:%d 结束了,messageContext:" + ctx, proceInstanceId));
|
|
|
+ log.info(String.format("流程实例:%d 结束了,messageContext:" + ctx, proceInstanceId));
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean isJson(String str){
|
|
|
+ try{
|
|
|
+ JSONObject jsonStr = JSONObject.parseObject(str);
|
|
|
+ return true;
|
|
|
+ } catch(Exception e){
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|