From 41c0df61041b2e038de7a7528dbad2fee9420859 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=AD=A3=E5=9B=BD?= <438926402@qq.com> Date: Wed, 8 Apr 2026 15:55:54 +0800 Subject: [PATCH] =?UTF-8?q?2025-01-08=E7=A8=BB=E8=8A=B1=E9=A6=99=E4=B8=BB?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E4=BC=81=E4=B8=9A=E5=BE=AE=E4=BF=A1=E5=90=8C?= =?UTF-8?q?=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/qq/weixin/mp/aes/AesException.java | 59 + .../java/com/qq/weixin/mp/aes/ByteGroup.java | 26 + .../java/com/qq/weixin/mp/aes/JsonParse.java | 65 + .../com/qq/weixin/mp/aes/PKCS7Encoder.java | 67 + .../main/java/com/qq/weixin/mp/aes/SHA1.java | 61 + .../qq/weixin/mp/aes/WXBizJsonMsgCrypt.java | 289 ++++ .../apps/src_mainorganization/Sample.java | 127 ++ .../bo/ThirdMemberBo.java | 61 +- .../constans/SyncConstants.java | 7 + .../src_mainorganization/dao/ISyncDdDao.java | 3 - .../dao/ISyncQywxDao.java | 46 + .../dao/impl/ArchiveDaoImpl.java | 1 - .../dao/impl/SyncQywxDaoImpl.java | 387 +++++ .../quartz/OrganizationWorkweixinQuartz.java | 104 ++ .../server/InitializeDingdingSyncServer.java | 5 - .../InitializeWorkweixinSyncServer.java | 211 +++ .../OrganizationOrgDingdingSyncServer.java | 66 +- .../OrganizationOrgWorkweixinSyncServer.java | 1381 +++++++++++++++++ .../servlet/WorkWeixinbindingServlet.java | 70 + .../src_mainorganization/util/ProtUtil.java | 5 +- .../util/WorkweixinProtUtil.java | 179 +++ .../spring/spring-dao.xml | 1 + .../spring/spring-quartz.xml | 1 + .../spring/spring-server.xml | 2 + 24 files changed, 3164 insertions(+), 60 deletions(-) create mode 100644 v5/apps-customize/src/main/java/com/qq/weixin/mp/aes/AesException.java create mode 100644 v5/apps-customize/src/main/java/com/qq/weixin/mp/aes/ByteGroup.java create mode 100644 v5/apps-customize/src/main/java/com/qq/weixin/mp/aes/JsonParse.java create mode 100644 v5/apps-customize/src/main/java/com/qq/weixin/mp/aes/PKCS7Encoder.java create mode 100644 v5/apps-customize/src/main/java/com/qq/weixin/mp/aes/SHA1.java create mode 100644 v5/apps-customize/src/main/java/com/qq/weixin/mp/aes/WXBizJsonMsgCrypt.java create mode 100644 v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/Sample.java create mode 100644 v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/dao/ISyncQywxDao.java create mode 100644 v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/dao/impl/SyncQywxDaoImpl.java create mode 100644 v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/quartz/OrganizationWorkweixinQuartz.java create mode 100644 v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/server/InitializeWorkweixinSyncServer.java create mode 100644 v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/server/OrganizationOrgWorkweixinSyncServer.java create mode 100644 v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/servlet/WorkWeixinbindingServlet.java create mode 100644 v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/util/WorkweixinProtUtil.java diff --git a/v5/apps-customize/src/main/java/com/qq/weixin/mp/aes/AesException.java b/v5/apps-customize/src/main/java/com/qq/weixin/mp/aes/AesException.java new file mode 100644 index 0000000..868637e --- /dev/null +++ b/v5/apps-customize/src/main/java/com/qq/weixin/mp/aes/AesException.java @@ -0,0 +1,59 @@ +package com.qq.weixin.mp.aes; + +@SuppressWarnings("serial") +public class AesException extends Exception { + + public final static int OK = 0; + public final static int ValidateSignatureError = -40001; + public final static int ParseJsonError = -40002; + public final static int ComputeSignatureError = -40003; + public final static int IllegalAesKey = -40004; + public final static int ValidateCorpidError = -40005; + public final static int EncryptAESError = -40006; + public final static int DecryptAESError = -40007; + public final static int IllegalBuffer = -40008; + public final static int EncodeBase64Error = -40009; + public final static int DecodeBase64Error = -40010; + public final static int GenReturnJsonError = -40011; + + private int code; + + private static String getMessage(int code) { + switch (code) { + case ValidateSignatureError: + return "签名验证错误"; + case ParseJsonError: + return "json解析失败"; + case ComputeSignatureError: + return "sha加密生成签名失败"; + case IllegalAesKey: + return "SymmetricKey非法"; + case ValidateCorpidError: + return "corpid校验失败"; + case EncryptAESError: + return "aes加密失败"; + case DecryptAESError: + return "aes解密失败"; + case IllegalBuffer: + return "解密后得到的buffer非法"; + case EncodeBase64Error: + return "base64加密错误"; + case DecodeBase64Error: + return "base64解密错误"; + case GenReturnJsonError: + return "josn生成失败"; + default: + return null; // cannot be + } + } + + public int getCode() { + return code; + } + + AesException(int code) { + super(getMessage(code)); + this.code = code; + } + +} diff --git a/v5/apps-customize/src/main/java/com/qq/weixin/mp/aes/ByteGroup.java b/v5/apps-customize/src/main/java/com/qq/weixin/mp/aes/ByteGroup.java new file mode 100644 index 0000000..6ba4330 --- /dev/null +++ b/v5/apps-customize/src/main/java/com/qq/weixin/mp/aes/ByteGroup.java @@ -0,0 +1,26 @@ +package com.qq.weixin.mp.aes; + +import java.util.ArrayList; + +class ByteGroup { + ArrayList byteContainer = new ArrayList(); + + public byte[] toBytes() { + byte[] bytes = new byte[byteContainer.size()]; + for (int i = 0; i < byteContainer.size(); i++) { + bytes[i] = byteContainer.get(i); + } + return bytes; + } + + public ByteGroup addBytes(byte[] bytes) { + for (byte b : bytes) { + byteContainer.add(b); + } + return this; + } + + public int size() { + return byteContainer.size(); + } +} diff --git a/v5/apps-customize/src/main/java/com/qq/weixin/mp/aes/JsonParse.java b/v5/apps-customize/src/main/java/com/qq/weixin/mp/aes/JsonParse.java new file mode 100644 index 0000000..b03137a --- /dev/null +++ b/v5/apps-customize/src/main/java/com/qq/weixin/mp/aes/JsonParse.java @@ -0,0 +1,65 @@ +/** + * 对企业微信发送给企业后台的消息加解密示例代码. + * + * @copyright Copyright (c) 1998-2020 Tencent Inc. + */ + +// ------------------------------------------------------------------------ + +package com.qq.weixin.mp.aes; + +/** + * 针对 org.json.JSONObject, + * 要编译打包架包json + * 官方源码下载地址 : https://github.com/stleary/JSON-java, jar包下载地址 : https://mvnrepository.com/artifact/org.json/json + */ +import org.json.JSONObject; + + +/** + * JsonParse class + * + * 提供提取消息格式中的密文及生成回复消息格式的接口. + */ +class JsonParse { + + /** + * 提取出 JSON 包中的加密消息 + * @param jsontext 待提取的json字符串 + * @return 提取出的加密消息字符串 + * @throws AesException + */ + public static Object[] extract(String jsontext) throws AesException { + Object[] result = new Object[3]; + try { + + JSONObject json = new JSONObject(jsontext); + String encrypt_msg = json.getString("encrypt"); + String tousername = json.getString("tousername"); + String agentid = json.getString("agentid"); + + result[0] = tousername; + result[1] = encrypt_msg; + result[2] = agentid; + return result; + } catch (Exception e) { + e.printStackTrace(); + throw new AesException(AesException.ParseJsonError); + } + } + + /** + * 生成json消息 + * @param encrypt 加密后的消息密文 + * @param signature 安全签名 + * @param timestamp 时间戳 + * @param nonce 随机字符串 + * @return 生成的json字符串 + */ + public static String generate(String encrypt, String signature, String timestamp, String nonce) { + + String format = "{\"encrypt\":\"%1$s\",\"msgsignature\":\"%2$s\",\"timestamp\":\"%3$s\",\"nonce\":\"%4$s\"}"; + return String.format(format, encrypt, signature, timestamp, nonce); + + } +} diff --git a/v5/apps-customize/src/main/java/com/qq/weixin/mp/aes/PKCS7Encoder.java b/v5/apps-customize/src/main/java/com/qq/weixin/mp/aes/PKCS7Encoder.java new file mode 100644 index 0000000..f1dd021 --- /dev/null +++ b/v5/apps-customize/src/main/java/com/qq/weixin/mp/aes/PKCS7Encoder.java @@ -0,0 +1,67 @@ +/** + * 对企业微信发送给企业后台的消息加解密示例代码. + * + * @copyright Copyright (c) 1998-2014 Tencent Inc. + */ + +// ------------------------------------------------------------------------ + +package com.qq.weixin.mp.aes; + +import java.nio.charset.Charset; +import java.util.Arrays; + +/** + * 提供基于PKCS7算法的加解密接口. + */ +class PKCS7Encoder { + static Charset CHARSET = Charset.forName("utf-8"); + static int BLOCK_SIZE = 32; + + /** + * 获得对明文进行补位填充的字节. + * + * @param count 需要进行填充补位操作的明文字节个数 + * @return 补齐用的字节数组 + */ + static byte[] encode(int count) { + // 计算需要填充的位数 + int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE); + if (amountToPad == 0) { + amountToPad = BLOCK_SIZE; + } + // 获得补位所用的字符 + char padChr = chr(amountToPad); + String tmp = new String(); + for (int index = 0; index < amountToPad; index++) { + tmp += padChr; + } + return tmp.getBytes(CHARSET); + } + + /** + * 删除解密后明文的补位字符 + * + * @param decrypted 解密后的明文 + * @return 删除补位字符后的明文 + */ + static byte[] decode(byte[] decrypted) { + int pad = (int) decrypted[decrypted.length - 1]; + if (pad < 1 || pad > 32) { + pad = 0; + } + return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad); + } + + /** + * 将数字转化成ASCII码对应的字符,用于对明文进行补码 + * + * @param a 需要转化的数字 + * @return 转化得到的字符 + */ + static char chr(int a) { + byte target = (byte) (a & 0xFF); + return (char) target; + } + +} diff --git a/v5/apps-customize/src/main/java/com/qq/weixin/mp/aes/SHA1.java b/v5/apps-customize/src/main/java/com/qq/weixin/mp/aes/SHA1.java new file mode 100644 index 0000000..e460191 --- /dev/null +++ b/v5/apps-customize/src/main/java/com/qq/weixin/mp/aes/SHA1.java @@ -0,0 +1,61 @@ +/** + * 对企业微信发送给企业后台的消息加解密示例代码. + * + * @copyright Copyright (c) 1998-2014 Tencent Inc. + */ + +// ------------------------------------------------------------------------ + +package com.qq.weixin.mp.aes; + +import java.security.MessageDigest; +import java.util.Arrays; + +/** + * SHA1 class + * + * 计算消息签名接口. + */ +class SHA1 { + + /** + * 用SHA1算法生成安全签名 + * @param token 票据 + * @param timestamp 时间戳 + * @param nonce 随机字符串 + * @param encrypt 密文 + * @return 安全签名 + * @throws AesException + */ + public static String getSHA1(String token, String timestamp, String nonce, String encrypt) throws AesException + { + try { + String[] array = new String[] { token, timestamp, nonce, encrypt }; + StringBuffer sb = new StringBuffer(); + // 字符串排序 + Arrays.sort(array); + for (int i = 0; i < 4; i++) { + sb.append(array[i]); + } + String str = sb.toString(); + // SHA1签名生成 + MessageDigest md = MessageDigest.getInstance("SHA-1"); + md.update(str.getBytes()); + byte[] digest = md.digest(); + + StringBuffer hexstr = new StringBuffer(); + String shaHex = ""; + for (int i = 0; i < digest.length; i++) { + shaHex = Integer.toHexString(digest[i] & 0xFF); + if (shaHex.length() < 2) { + hexstr.append(0); + } + hexstr.append(shaHex); + } + return hexstr.toString(); + } catch (Exception e) { + e.printStackTrace(); + throw new AesException(AesException.ComputeSignatureError); + } + } +} diff --git a/v5/apps-customize/src/main/java/com/qq/weixin/mp/aes/WXBizJsonMsgCrypt.java b/v5/apps-customize/src/main/java/com/qq/weixin/mp/aes/WXBizJsonMsgCrypt.java new file mode 100644 index 0000000..2f1074e --- /dev/null +++ b/v5/apps-customize/src/main/java/com/qq/weixin/mp/aes/WXBizJsonMsgCrypt.java @@ -0,0 +1,289 @@ +/** + * 对企业微信发送给企业后台的消息加解密示例代码. + * + * @copyright Copyright (c) 1998-2014 Tencent Inc. + */ + +// ------------------------------------------------------------------------ + +/** + * 针对org.apache.commons.codec.binary.Base64, + * 需要导入架包commons-codec-1.9(或commons-codec-1.8等其他版本) + * 官方下载地址:http://commons.apache.org/proper/commons-codec/download_codec.cgi + */ +package com.qq.weixin.mp.aes; + +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.Random; + +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +import org.apache.commons.codec.binary.Base64; + +/** + * 提供接收和推送给企业微信消息的加解密接口(UTF8编码的字符串). + *
    + *
  1. 第三方回复加密消息给企业微信
  2. + *
  3. 第三方收到企业微信发送的消息,验证消息的安全性,并对消息进行解密。
  4. + *
+ * 说明:异常java.security.InvalidKeyException:illegal Key Size的解决方案 + *
    + *
  1. 在官方网站下载JCE无限制权限策略文件(JDK7的下载地址: + * http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
  2. + *
  3. 下载后解压,可以看到local_policy.jar和US_export_policy.jar以及readme.txt
  4. + *
  5. 如果安装了JRE,将两个jar文件放到%JRE_HOME%\lib\security目录下覆盖原来的文件
  6. + *
  7. 如果安装了JDK,将两个jar文件放到%JDK_HOME%\jre\lib\security目录下覆盖原来文件
  8. + *
+ */ +public class WXBizJsonMsgCrypt { + static Charset CHARSET = Charset.forName("utf-8"); + Base64 base64 = new Base64(); + byte[] aesKey; + String token; + String receiveid; + + /** + * 构造函数 + * @param token 企业微信后台,开发者设置的token + * @param encodingAesKey 企业微信后台,开发者设置的EncodingAESKey + * @param receiveid, 不同场景含义不同,详见文档 + * + * @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息 + */ + public WXBizJsonMsgCrypt(String token, String encodingAesKey, String receiveid) throws AesException { + if (encodingAesKey.length() != 43) { + throw new AesException(AesException.IllegalAesKey); + } + + this.token = token; + this.receiveid = receiveid; + aesKey = Base64.decodeBase64(encodingAesKey + "="); + } + + // 生成4个字节的网络字节序 + byte[] getNetworkBytesOrder(int sourceNumber) { + byte[] orderBytes = new byte[4]; + orderBytes[3] = (byte) (sourceNumber & 0xFF); + orderBytes[2] = (byte) (sourceNumber >> 8 & 0xFF); + orderBytes[1] = (byte) (sourceNumber >> 16 & 0xFF); + orderBytes[0] = (byte) (sourceNumber >> 24 & 0xFF); + return orderBytes; + } + + // 还原4个字节的网络字节序 + int recoverNetworkBytesOrder(byte[] orderBytes) { + int sourceNumber = 0; + for (int i = 0; i < 4; i++) { + sourceNumber <<= 8; + sourceNumber |= orderBytes[i] & 0xff; + } + return sourceNumber; + } + + // 随机生成16位字符串 + String getRandomStr() { + String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + Random random = new Random(); + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < 16; i++) { + int number = random.nextInt(base.length()); + sb.append(base.charAt(number)); + } + return sb.toString(); + } + + /** + * 对明文进行加密. + * + * @param text 需要加密的明文 + * @return 加密后base64编码的字符串 + * @throws AesException aes加密失败 + */ + String encrypt(String randomStr, String text) throws AesException { + ByteGroup byteCollector = new ByteGroup(); + byte[] randomStrBytes = randomStr.getBytes(CHARSET); + byte[] textBytes = text.getBytes(CHARSET); + byte[] networkBytesOrder = getNetworkBytesOrder(textBytes.length); + byte[] receiveidBytes = receiveid.getBytes(CHARSET); + + // randomStr + networkBytesOrder + text + receiveid + byteCollector.addBytes(randomStrBytes); + byteCollector.addBytes(networkBytesOrder); + byteCollector.addBytes(textBytes); + byteCollector.addBytes(receiveidBytes); + + // ... + pad: 使用自定义的填充方式对明文进行补位填充 + byte[] padBytes = PKCS7Encoder.encode(byteCollector.size()); + byteCollector.addBytes(padBytes); + + // 获得最终的字节流, 未加密 + byte[] unencrypted = byteCollector.toBytes(); + + try { + // 设置加密模式为AES的CBC模式 + Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); + SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES"); + IvParameterSpec iv = new IvParameterSpec(aesKey, 0, 16); + cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv); + + // 加密 + byte[] encrypted = cipher.doFinal(unencrypted); + + // 使用BASE64对加密后的字符串进行编码 + String base64Encrypted = base64.encodeToString(encrypted); + + return base64Encrypted; + } catch (Exception e) { + e.printStackTrace(); + throw new AesException(AesException.EncryptAESError); + } + } + + /** + * 对密文进行解密. + * + * @param text 需要解密的密文 + * @return 解密得到的明文 + * @throws AesException aes解密失败 + */ + String decrypt(String text) throws AesException { + byte[] original; + try { + // 设置解密模式为AES的CBC模式 + Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); + SecretKeySpec key_spec = new SecretKeySpec(aesKey, "AES"); + IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16)); + cipher.init(Cipher.DECRYPT_MODE, key_spec, iv); + + // 使用BASE64对密文进行解码 + byte[] encrypted = Base64.decodeBase64(text); + + // 解密 + original = cipher.doFinal(encrypted); + } catch (Exception e) { + e.printStackTrace(); + throw new AesException(AesException.DecryptAESError); + } + + String jsonContent, from_receiveid; + try { + // 去除补位字符 + byte[] bytes = PKCS7Encoder.decode(original); + + // 分离16位随机字符串,网络字节序和receiveid + byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20); + + int jsonLength = recoverNetworkBytesOrder(networkOrder); + + jsonContent = new String(Arrays.copyOfRange(bytes, 20, 20 + jsonLength), CHARSET); + from_receiveid = new String(Arrays.copyOfRange(bytes, 20 + jsonLength, bytes.length), + CHARSET); + } catch (Exception e) { + e.printStackTrace(); + throw new AesException(AesException.IllegalBuffer); + } + + // receiveid不相同的情况 + if (!from_receiveid.equals(receiveid)) { + throw new AesException(AesException.ValidateCorpidError); + } + return jsonContent; + + } + + /** + * 将企业微信回复用户的消息加密打包. + *
    + *
  1. 对要发送的消息进行AES-CBC加密
  2. + *
  3. 生成安全签名
  4. + *
  5. 将消息密文和安全签名打包成json格式
  6. + *
+ * + * @param replyMsg 企业微信待回复用户的消息,json格式的字符串 + * @param timeStamp 时间戳,可以自己生成,也可以用URL参数的timestamp + * @param nonce 随机串,可以自己生成,也可以用URL参数的nonce + * + * @return 加密后的可以直接回复用户的密文,包括msg_signature, timestamp, nonce, encrypt的json格式的字符串 + * @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息 + */ + public String EncryptMsg(String replyMsg, String timeStamp, String nonce) throws AesException { + // 加密 + String encrypt = encrypt(getRandomStr(), replyMsg); + + // 生成安全签名 + if (timeStamp == "") { + timeStamp = Long.toString(System.currentTimeMillis()); + } + + String signature = SHA1.getSHA1(token, timeStamp, nonce, encrypt); + + // System.out.println("发送给平台的签名是: " + signature[1].toString()); + // 生成发送的json + String result = JsonParse.generate(encrypt, signature, timeStamp, nonce); + return result; + } + + /** + * 检验消息的真实性,并且获取解密后的明文. + *
    + *
  1. 利用收到的密文生成安全签名,进行签名验证
  2. + *
  3. 若验证通过,则提取json中的加密消息
  4. + *
  5. 对消息进行解密
  6. + *
+ * + * @param msgSignature 签名串,对应URL参数的msg_signature + * @param timeStamp 时间戳,对应URL参数的timestamp + * @param nonce 随机串,对应URL参数的nonce + * @param postData 密文,对应POST请求的数据 + * + * @return 解密后的原文 + * @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息 + */ + public String DecryptMsg(String msgSignature, String timeStamp, String nonce, String postData) + throws AesException { + + // 密钥,公众账号的app secret + // 提取密文 + Object[] encrypt = JsonParse.extract(postData); + + // 验证安全签名 + String signature = SHA1.getSHA1(token, timeStamp, nonce, encrypt[1].toString()); + + // 和URL中的签名比较是否相等 + // System.out.println("第三方收到URL中的签名:" + msg_sign); + // System.out.println("第三方校验签名:" + signature); + if (!signature.equals(msgSignature)) { + throw new AesException(AesException.ValidateSignatureError); + } + + // 解密 + String result = decrypt(encrypt[1].toString()); + return result; + } + + /** + * 验证URL + * @param msgSignature 签名串,对应URL参数的msg_signature + * @param timeStamp 时间戳,对应URL参数的timestamp + * @param nonce 随机串,对应URL参数的nonce + * @param echoStr 随机串,对应URL参数的echostr + * + * @return 解密之后的echostr + * @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息 + */ + public String VerifyURL(String msgSignature, String timeStamp, String nonce, String echoStr) + throws AesException { + String signature = SHA1.getSHA1(token, timeStamp, nonce, echoStr); + + if (!signature.equals(msgSignature)) { + throw new AesException(AesException.ValidateSignatureError); + } + + String result = decrypt(echoStr); + return result; + } + +} \ No newline at end of file diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/Sample.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/Sample.java new file mode 100644 index 0000000..8d8c09f --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/Sample.java @@ -0,0 +1,127 @@ +package com.seeyon.apps.src_mainorganization; + +import org.json.JSONObject; +import com.qq.weixin.mp.aes.WXBizJsonMsgCrypt; + +public class Sample { + + public static void main(String[] args) throws Exception { + String sToken = "rtfmfptSSM64EEedffcWcnvw6zukb9lG"; + String sCorpID = "ww69c49385cee3746c"; + String sEncodingAESKey = "cuDqCFGORfqjdPx3Yn9D11AAmijNh7Lpq2SdLQcvQkr"; + + WXBizJsonMsgCrypt wxcpt = new WXBizJsonMsgCrypt(sToken, sEncodingAESKey, sCorpID); + /* + ------------使用示例一:验证回调URL--------------- + *企业开启回调模式时,企业微信会向验证url发送一个get请求 + 假设点击验证时,企业收到类似请求: + * GET /cgi-bin/wxpush?msg_signature=5c45ff5e21c57e6ad56bac8758b79b1d9ac89fd3×tamp=1409659589&nonce=263014780&echostr=P9nAzCzyDtyTWESHep1vC5X9xho%2FqYX3Zpb4yKa9SKld1DsH3Iyt3tP3zNdtp%2B4RPcs8TgAE7OaBO%2BFZXvnaqQ%3D%3D + * HTTP/1.1 Host: qy.weixin.qq.com + 接收到该请求时,企业应 1.解析出Get请求的参数,包括消息体签名(msg_signature),时间戳(timestamp),随机数字串(nonce)以及企业微信推送过来的随机加密字符串(echostr), + 这一步注意作URL解码。 + 2.验证消息体签名的正确性 + 3. 解密出echostr原文,将原文当作Get请求的response,返回给企业微信 + 第2,3步可以用企业微信提供的库函数VerifyURL来实现。 + + */ + // 解析出url上的参数值如下: + // String sVerifyMsgSig = HttpUtils.ParseUrl("msg_signature"); + String sVerifyMsgSig = "5c45ff5e21c57e6ad56bac8758b79b1d9ac89fd3"; + // String sVerifyTimeStamp = HttpUtils.ParseUrl("timestamp"); + String sVerifyTimeStamp = "1409659589"; + // String sVerifyNonce = HttpUtils.ParseUrl("nonce"); + String sVerifyNonce = "263014780"; + // String sVerifyEchoStr = HttpUtils.ParseUrl("echostr"); + String sVerifyEchoStr = "P9nAzCzyDtyTWESHep1vC5X9xho/qYX3Zpb4yKa9SKld1DsH3Iyt3tP3zNdtp+4RPcs8TgAE7OaBO+FZXvnaqQ=="; + String sEchoStr; //需要返回的明文 + try { + sEchoStr = wxcpt.VerifyURL(sVerifyMsgSig, sVerifyTimeStamp, + sVerifyNonce, sVerifyEchoStr); + System.out.println("verifyurl echostr: " + sEchoStr); + // 验证URL成功,将sEchoStr返回 + // HttpUtils.SetResponse(sEchoStr); + } catch (Exception e) { + //验证URL失败,错误原因请查看异常 + e.printStackTrace(); + } + + /* + ------------使用示例二:对用户回复的消息解密--------------- + 用户回复消息或者点击事件响应时,企业会收到回调消息,此消息是经过企业微信加密之后的密文以post形式发送给企业,密文格式请参考官方文档 + 假设企业收到企业微信的回调消息如下: + POST /cgi-bin/wxpush? msg_signature=477715d11cdb4164915debcba66cb864d751f3e6×tamp=1409659813&nonce=1372623149 HTTP/1.1 + Host: qy.weixin.qq.com + Content-Length: + Content-Type:text/json + + { + "tousername":"wx5823bf96d3bd56c7", + "encrypt":"RypEvHKD8QQKFhvQ6QleEB4J58tiPdvo+rtK1I9qca6aM/wvqnLSV5zEPeusUiX5L5X/0lWfrf0QADHHhGd3QczcdCUpj911L3vg3W/sYYvuJTs3TUUkSUXxaccAS0qhxchrRYt66wiSpGLYL42aM6A8dTT+6k4aSknmPj48kzJs8qLjvd4Xgpue06DOdnLxAUHzM6+kDZ+HMZfJYuR+LtwGc2hgf5gsijff0ekUNXZiqATP7PF5mZxZ3Izoun1s4zG4LUMnvw2r+KqCKIw+3IQH03v+BCA9nMELNqbSf6tiWSrXJB3LAVGUcallcrw8V2t9EL4EhzJWrQUax5wLVMNS0+rUPA3k22Ncx4XXZS9o0MBH27Bo6BpNelZpS+/uh9KsNlY6bHCmJU9p8g7m3fVKn28H3KDYA5Pl/T8Z1ptDAVe0lXdQ2YoyyH2uyPIGHBZZIs2pDBS8R07+qN+E7Q==", + "agentid":"218" + } + + 企业收到post请求之后应该 1.解析出url上的参数,包括消息体签名(msg_signature),时间戳(timestamp)以及随机数字串(nonce) + 2.验证消息体签名的正确性。 + 3.将post请求的数据进行json解析,并将"encrypt"标签的内容进行解密,解密出来的明文即是用户回复消息的明文,明文格式请参考官方文档 + 第2,3步可以用企业微信提供的库函数DecryptMsg来实现。 + */ + // String sReqMsgSig = HttpUtils.ParseUrl("msg_signature"); + String sReqMsgSig = "0623cbc5a8cbee5bcc137c70de99575366fc2af3"; + // String sReqTimeStamp = HttpUtils.ParseUrl("timestamp"); + String sReqTimeStamp = "1409659813"; + // String sReqNonce = HttpUtils.ParseUrl("nonce"); + String sReqNonce = "1372623149"; + // post请求的密文数据 + // sReqData = HttpUtils.PostData(); + String sReqData = "{\"tousername\":\"wx5823bf96d3bd56c7\",\"encrypt\":\"CZWs4CWRpI4VolQlvn4dlEC1alN2MUEY2VklGehgBVLBrlVF7SyT+SV+Toj43l4ayJ9UMGKphktKKmP7B2j/P1ey67XB8PBgS7Wr5/8+w/yWriZv3Vmoo/MH3/1HsIWZrPQ3N2mJrelStIfI2Y8kLKXA7EhfZgZX4o+ffdkZDM76SEl79Ib9mw7TGjZ9Aw/x/A2VjNbV1E8BtEbRxYYcQippYNw7hr8sFfa3nW1xLdxokt8QkRX83vK3DFP2F6TQFPL2Tu98UwhcUpPvdJBuu1/yiOQIScppV3eOuLWEsko=\",\"agentid\":\"218\"}"; + + try { + String sMsg = wxcpt.DecryptMsg(sReqMsgSig, sReqTimeStamp, sReqNonce, sReqData); + System.out.println("after decrypt msg: " + sMsg); + // TODO: 解析出明文json标签的内容进行处理 + // For example: + JSONObject json = new JSONObject(sMsg); + String Content = json.getString("Content"); + + System.out.println("Content:" + Content); + + } catch (Exception e) { + // TODO + // 解密失败,失败原因请查看异常 + e.printStackTrace(); + } + + /* + ------------使用示例三:企业回复用户消息的加密--------------- + 企业被动回复用户的消息也需要进行加密,并且拼接成密文格式的json串。 + 假设企业需要回复用户的明文如下: + { + "ToUserName": "mycreate", + "FromUserName":"wx5823bf96d3bd56c7", + "CreateTime": 1348831860, + "MsgType": "text", + "Content": "this is a test", + "MsgId": 1234567890123456, + "AgentID": 128 + } + + 为了将此段明文回复给用户,企业应: 1.自己生成时间时间戳(timestamp),随机数字串(nonce)以便生成消息体签名,也可以直接用从企业微信的post url上解析出的对应值。 + 2.将明文加密得到密文。 3.用密文,步骤1生成的timestamp,nonce和企业在企业微信设定的token生成消息体签名。 4.将密文,消息体签名,时间戳,随机数字串拼接成json格式的字符串,发送给企业。 + 以上2,3,4步可以用企业微信提供的库函数EncryptMsg来实现。 + */ + String sRespData = "{\"ToUserName\":\"wx5823bf96d3bd56c7\",\"FromUserName\":\"mycreate\",\"CreateTime\": 1409659813,\"MsgType\":\"text\",\"Content\":\"hello\",\"MsgId\":4561255354251345929,\"AgentID\": 218}"; + try{ + String sEncryptMsg = wxcpt.EncryptMsg(sRespData, sReqTimeStamp, sReqNonce); + System.out.println("after encrypt sEncrytMsg: " + sEncryptMsg); + // 加密成功 + // TODO: + // HttpUtils.SetResponse(sEncryptMsg); + } + catch(Exception e) + { + e.printStackTrace(); + // 加密失败 + } + + } +} diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/bo/ThirdMemberBo.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/bo/ThirdMemberBo.java index 7c21afc..a94b66a 100644 --- a/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/bo/ThirdMemberBo.java +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/bo/ThirdMemberBo.java @@ -574,13 +574,18 @@ public class ThirdMemberBo { } // member.put("isEnabled",fileMember.get("is_enable")); - String memberState = fileMember.get("is_enable").toString(); - CtpEnumItem memberStateEnum = getEnumManagerNew().getEnumItem(Long.parseLong(memberState)); - if("在职,试用,待岗".contains(memberStateEnum.getShowvalue())){ - member.put("isEnabled",true); + if(fileMember.get("is_enable")!=null){ + String memberState = fileMember.get("is_enable").toString(); + CtpEnumItem memberStateEnum = getEnumManagerNew().getEnumItem(Long.parseLong(memberState)); + if("在职,试用,待岗".contains(memberStateEnum.getShowvalue())){ + member.put("isEnabled",true); + }else{ + member.put("isEnabled",false); + } }else{ member.put("isEnabled",false); } + member.put("telNumber",fileMember.get("telnumber")); member.put("loginName",fileMember.get("login_name")); member.put("birthday",""); @@ -594,15 +599,20 @@ public class ThirdMemberBo { if(fileMember.get("gender")==null){ member.put("gender","-1"); }else{ - String genderId = fileMember.get("gender").toString(); - CtpEnumItem genderEnum = getEnumManagerNew().getEnumItem(Long.parseLong(genderId)); - if("0".equals(genderEnum.getEnumvalue())){ - member.put("gender","1"); - }else if("1".equals(genderEnum.getEnumvalue())){ - member.put("gender","2"); + if(fileMember.get("gender")!=null){ + String genderId = fileMember.get("gender").toString(); + CtpEnumItem genderEnum = getEnumManagerNew().getEnumItem(Long.parseLong(genderId)); + if("0".equals(genderEnum.getEnumvalue())){ + member.put("gender","1"); + }else if("1".equals(genderEnum.getEnumvalue())){ + member.put("gender","2"); + }else{ + member.put("gender","-1"); + } }else{ member.put("gender","-1"); } + } // member.put("gender",fileMember.get("gender")); member.put("companyCode",""); @@ -662,15 +672,19 @@ public class ThirdMemberBo { if(serviceAgentMember.get("yd_post_id")!=null){ String ydPostId = serviceAgentMember.get("yd_post_id").toString(); V3xOrgPost ydPost = orgManager.getPostById(Long.parseLong(ydPostId)); - member.put("orgPostId",ydPost.getId().toString()); + member.put("orgPostId",ydPost.getId()); member.put("orgPostName",ydPost.getName()); } member.put("orgLevelId",""); member.put("orgLevelName","业代"); - String memberState = serviceAgentMember.get("is_enabled").toString(); - CtpEnumItem memberStateEnum = getEnumManagerNew().getEnumItem(Long.parseLong(memberState)); - if("在职,试用,待岗".contains(memberStateEnum.getShowvalue())){ - member.put("isEnabled",true); + if(serviceAgentMember.get("is_enabled")!=null){ + String memberState = serviceAgentMember.get("is_enabled").toString(); + CtpEnumItem memberStateEnum = getEnumManagerNew().getEnumItem(Long.parseLong(memberState)); + if("在职,试用,待岗".contains(memberStateEnum.getShowvalue())){ + member.put("isEnabled",true); + }else{ + member.put("isEnabled",false); + } }else{ member.put("isEnabled",false); } @@ -687,15 +701,20 @@ public class ThirdMemberBo { if(serviceAgentMember.get("gender")==null){ member.put("gender","-1"); }else{ - String genderId = serviceAgentMember.get("gender").toString(); - CtpEnumItem genderEnum = getEnumManagerNew().getEnumItem(Long.parseLong(genderId)); - if("0".equals(genderEnum.getEnumvalue())){ - member.put("gender","1"); - }else if("1".equals(genderEnum.getEnumvalue())){ - member.put("gender","2"); + if(serviceAgentMember.get("gender")!=null){ + String genderId = serviceAgentMember.get("gender").toString(); + CtpEnumItem genderEnum = getEnumManagerNew().getEnumItem(Long.parseLong(genderId)); + if("0".equals(genderEnum.getEnumvalue())){ + member.put("gender","1"); + }else if("1".equals(genderEnum.getEnumvalue())){ + member.put("gender","2"); + }else{ + member.put("gender","-1"); + } }else{ member.put("gender","-1"); } + } return member; } diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/constans/SyncConstants.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/constans/SyncConstants.java index a52a6d8..0a73d60 100644 --- a/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/constans/SyncConstants.java +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/constans/SyncConstants.java @@ -12,6 +12,13 @@ public enum SyncConstants { dingdingGetDept("https://oapi.dingtalk.com/topapi/v2/department/get", "查询钉钉部门URL"), dingdingLog("DDTBJL","钉钉同步记录"), dingdingLogloginName("demo","钉钉同步记录创建人"), + + workweixinCorpid("ww69c49385cee3746c", "企业微信corpid"), + workweixinCorpsecret("PGqFDqx5bvMtMwhoR3pfrVF_asaSQOPj92v9A0TnPxY", "企业微信Corpsecret"), + workweixinTxlCorpsecret("mofPHLHcyOpEpfgXn9F0e1XVkuD0sILJCoa9UXqwGEw", "企业微信通讯录Corpsecret"), + workweixinLog("QYWXTBJL","企业微信同步记录"), + workweixinLogloginName("demo","企业微信同步记录创建人"), + qxxLog("QXXTBJL","企学星同步记录"), qxxUrl("http://10.0.1.92:7356","企学星URL"), qxxGetToken("/hklearn/openapi/v1/oauth/getToken?","企学星获取tokenURL"), diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/dao/ISyncDdDao.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/dao/ISyncDdDao.java index 8f432fe..fab3aed 100644 --- a/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/dao/ISyncDdDao.java +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/dao/ISyncDdDao.java @@ -13,9 +13,6 @@ public interface ISyncDdDao { public List getMemberByMobile(String mobile); - - - // 查询钉钉单位绑定信息 public Map getAccountBinding(String orgAccountId); diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/dao/ISyncQywxDao.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/dao/ISyncQywxDao.java new file mode 100644 index 0000000..073810f --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/dao/ISyncQywxDao.java @@ -0,0 +1,46 @@ +package com.seeyon.apps.src_mainorganization.dao; + +import java.util.List; +import java.util.Map; + +public interface ISyncQywxDao { + + // 新增钉钉单位绑定信息 + public int saveAccountBinding(String accountId,String accountName,String ddAccountId ,String ddAccountName); + + public List getAccountsBinding(); + + public Map getAccountBindingByQywxAccount(String qywxAccountId); + + public Map getDepartmentBindingByQywxDepartment(String qywxDepartmentId); + +// 新增钉钉部门绑定信息 + public int saveDepartmentBinding(String departmentId,String departmentName ,String ddDepartmentId ,String ddDepartmentName); + + public List getDepartmentsBinding(); + + public List getDepartmentsOABinding(); + + // 新增钉钉人员绑定信息 + public int saveMemberBinding(String memberId,String membertName ,String ddMemberId ,String ddMemberName,String telnumber); + + public Map getMaxSynchronizationDate(); + + // 查询钉钉单位绑定信息 + public Map getAccountBinding(String orgAccountId); + + // 根据单位ID修改钉钉单位绑定信息 + public int updateAccountBinding(String accountId,String accountName,String ddAccountId ,String ddAccountName); + + // 根据部门ID删除钉钉部门绑定信息 + public int deleteDepartmentBinding(String departmentId); + + // 查询钉钉部门绑定信息 + public Map getDepartmentBinding(String orgDepartmentId); + + // 查询钉钉人员绑定信息 + public Map getMemberBinding(String orgMemberId); + + // 根据人员ID删除钉钉人员绑定信息 + public int deleteMemberBinding(String memberId); +} diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/dao/impl/ArchiveDaoImpl.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/dao/impl/ArchiveDaoImpl.java index fcee849..aaceabd 100644 --- a/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/dao/impl/ArchiveDaoImpl.java +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/dao/impl/ArchiveDaoImpl.java @@ -297,7 +297,6 @@ public class ArchiveDaoImpl implements IArchiveDao { List p = new ArrayList(); agent.execute(sql.toString(), p); List list = agent.resultSetToList(); - for(int i = 0; i < list.size(); ++i) { if (list.size() != 0) { Map map = (Map)list.get(i); diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/dao/impl/SyncQywxDaoImpl.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/dao/impl/SyncQywxDaoImpl.java new file mode 100644 index 0000000..a6ce9a7 --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/dao/impl/SyncQywxDaoImpl.java @@ -0,0 +1,387 @@ +package com.seeyon.apps.src_mainorganization.dao.impl; + +import com.seeyon.apps.src_mainorganization.dao.ISyncQywxDao; +import com.seeyon.ctp.common.exceptions.BusinessException; +import com.seeyon.ctp.util.JDBCAgent; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class SyncQywxDaoImpl implements ISyncQywxDao { + + private String saveAccountBinding = "INSERT INTO src_workweixin_unit (org_account_id, org_account_name, qywx_account_id, qywx_account_name) VALUES (?, ?, ?, ?)"; + @Override + public int saveAccountBinding(String accountId, String accountName, String qywxAccountId, String qywxAccountName) { + int i = 0 ; + JDBCAgent agent = new JDBCAgent(); + try { + StringBuilder sql = new StringBuilder(saveAccountBinding); + List p = new ArrayList(); + p.add(accountId); + p.add(accountName); + p.add(qywxAccountId); + p.add(qywxAccountName); + i=agent.execute(sql.toString(), p); + } catch (BusinessException e) { + e.printStackTrace(); + } catch (SQLException e) { + e.printStackTrace(); + } finally { + if (agent != null) { + agent.close(); + } + } + return i; + } + + private String getAccountsBinding = "select org_account_id,org_account_name,qywx_account_id,qywx_account_name from src_workweixin_unit "; + @Override + public List getAccountsBinding(){ + JDBCAgent agent = new JDBCAgent(); + List res = new ArrayList<>(); + try { + StringBuilder sql = new StringBuilder(getAccountsBinding); + List p = new ArrayList(); + agent.execute(sql.toString(), p); + List list = agent.resultSetToList(); + for(int i = 0 ; i < list.size(); i++){ + res.add(Long.parseLong(list.get(i).get("qywx_account_id").toString())); + } + } catch (BusinessException var13) { + var13.printStackTrace(); + } catch (SQLException var14) { + var14.printStackTrace(); + } finally { + if (agent != null) { + agent.close(); + } + } + return res; + } + + private String getAccountBindingByQywxAccount = "select org_account_id,org_account_name,qywx_account_id,qywx_account_name from src_workweixin_unit where qywx_account_id = ?"; + @Override + public Map getAccountBindingByQywxAccount(String qywxAccountId){ + JDBCAgent agent = new JDBCAgent(); + Map res = new HashMap<>(); + try { + StringBuilder sql = new StringBuilder(getAccountBindingByQywxAccount); + List p = new ArrayList(); + p.add(qywxAccountId); + agent.execute(sql.toString(), p); + List list = agent.resultSetToList(); + if(list.size()>0){ + res = list.get(0); + } + } catch (BusinessException var13) { + var13.printStackTrace(); + } catch (SQLException var14) { + var14.printStackTrace(); + } finally { + if (agent != null) { + agent.close(); + } + } + return res; + } + + private String getDepartmentBindingByQywxDepartment = "select org_department_id,org_department_name,qywx_department_id,qywx_department_name from src_workweixin_dept where qywx_department_id = ?"; + @Override + public Map getDepartmentBindingByQywxDepartment(String qywxDepartmentId){ + JDBCAgent agent = new JDBCAgent(); + Map res = new HashMap<>(); + try { + StringBuilder sql = new StringBuilder(getDepartmentBindingByQywxDepartment); + List p = new ArrayList(); + p.add(qywxDepartmentId); + agent.execute(sql.toString(), p); + List list = agent.resultSetToList(); + if(list.size()>0){ + res = list.get(0); + } + } catch (BusinessException var13) { + var13.printStackTrace(); + } catch (SQLException var14) { + var14.printStackTrace(); + } finally { + if (agent != null) { + agent.close(); + } + } + return res; + } + + private String saveDepartmentBinding = "INSERT INTO src_workweixin_dept (org_department_id, org_department_name, qywx_department_id, qywx_department_name) VALUES (?, ?, ?, ?)"; + @Override + public int saveDepartmentBinding(String departmentId, String departmentName, String qywxDepartmentId, String qywxDepartmentName) { + int i = 0 ; + JDBCAgent agent = new JDBCAgent(); + try { + StringBuilder sql = new StringBuilder(saveDepartmentBinding); + List p = new ArrayList(); + p.add(departmentId); + p.add(departmentName); + p.add(qywxDepartmentId); + p.add(qywxDepartmentName); + i=agent.execute(sql.toString(), p); + } catch (BusinessException e) { + e.printStackTrace(); + } catch (SQLException e) { + e.printStackTrace(); + } finally { + if (agent != null) { + agent.close(); + } + } + return i; + } + + private String getDepartmentsBinding = "select org_department_id,org_department_name,qywx_department_id,qywx_department_name from src_workweixin_dept "; + @Override + public List getDepartmentsBinding(){ + JDBCAgent agent = new JDBCAgent(); + List res = new ArrayList<>(); + try { + StringBuilder sql = new StringBuilder(getDepartmentsBinding); + List p = new ArrayList(); + agent.execute(sql.toString(), p); + List list = agent.resultSetToList(); + for(int i = 0 ; i < list.size(); i++){ + res.add(Long.parseLong(list.get(i).get("qywx_department_id").toString())); + } + } catch (BusinessException var13) { + var13.printStackTrace(); + } catch (SQLException var14) { + var14.printStackTrace(); + } finally { + if (agent != null) { + agent.close(); + } + } + return res; + } + + private String getDepartmentsOABinding = "select org_department_id,org_department_name,qywx_department_id,qywx_department_name from src_workweixin_dept "; + @Override + public List getDepartmentsOABinding(){ + JDBCAgent agent = new JDBCAgent(); + List res = new ArrayList<>(); + try { + StringBuilder sql = new StringBuilder(getDepartmentsOABinding); + List p = new ArrayList(); + agent.execute(sql.toString(), p); + List list = agent.resultSetToList(); + for(int i = 0 ; i < list.size(); i++){ + res.add(Long.parseLong(list.get(i).get("org_department_id").toString())); + } + } catch (BusinessException var13) { + var13.printStackTrace(); + } catch (SQLException var14) { + var14.printStackTrace(); + } finally { + if (agent != null) { + agent.close(); + } + } + return res; + } + + private String saveMemberBinding = "INSERT INTO src_workweixin_member (org_member_id, org_member_name, qywx_member_id, qywx_member_name,qywx_member_telnumber) VALUES (?, ?, ?, ?, ?)"; + @Override + public int saveMemberBinding(String memberId, String membertName, String qywxMemberId, String qywxMemberName,String telnumber) { + int i = 0 ; + JDBCAgent agent = new JDBCAgent(); + try { + StringBuilder sql = new StringBuilder(saveMemberBinding); + List p = new ArrayList(); + p.add(memberId); + p.add(membertName); + p.add(qywxMemberId); + p.add(qywxMemberName); + p.add(telnumber); + i=agent.execute(sql.toString(), p); + } catch (BusinessException e) { + e.printStackTrace(); + } catch (SQLException e) { + e.printStackTrace(); + } finally { + if (agent != null) { + agent.close(); + } + } + return i; + } + + private String getMaxSynchronizationDate = "select max(create_date) as max_create_date from cst_quartz_log where PARENTID = (select id from CST_QUARTZ where bean_id = 'organizationWorkweixinQuartz') and message not like '%任务执行异常%' and message not like '%上次的任务还在运行中%'"; + public Map getMaxSynchronizationDate (){ + JDBCAgent agent = new JDBCAgent(); + Map res = new HashMap<>(); + try { + StringBuilder sql = new StringBuilder(getMaxSynchronizationDate); + List p = new ArrayList(); + agent.execute(sql.toString(), p); + List list = agent.resultSetToList(); + if(list.size()>0){ + res = list.get(0); + } + } catch (BusinessException var13) { + var13.printStackTrace(); + } catch (SQLException var14) { + var14.printStackTrace(); + } finally { + if (agent != null) { + agent.close(); + } + } + return res; + } + + private String getAccountBinding = "select org_account_id,org_account_name,qywx_account_id,qywx_account_name from src_workweixin_unit where org_account_id = ?"; + @Override + public Map getAccountBinding(String orgAccountId) { + JDBCAgent agent = new JDBCAgent(); + Map res = new HashMap<>(); + try { + StringBuilder sql = new StringBuilder(getAccountBinding); + List p = new ArrayList(); + p.add(orgAccountId); + agent.execute(sql.toString(), p); + List list = agent.resultSetToList(); + if(list.size()>0){ + res = list.get(0); + } + } catch (BusinessException var13) { + var13.printStackTrace(); + } catch (SQLException var14) { + var14.printStackTrace(); + } finally { + if (agent != null) { + agent.close(); + } + } + return res; + } + + private String updateAccountBinding = "update src_workweixin_unit set qywx_account_id = ? , qywx_account_name = ? where org_account_id = ?"; + @Override + public int updateAccountBinding(String accountId, String accountName, String qywxAccountId, String qywxAccountName) { + int i = 0 ; + JDBCAgent agent = new JDBCAgent(); + try { + StringBuilder sql = new StringBuilder(updateAccountBinding); + List p = new ArrayList(); + p.add(qywxAccountId); + p.add(qywxAccountName); + p.add(accountId); + i=agent.execute(sql.toString(), p); + } catch (BusinessException e) { + e.printStackTrace(); + } catch (SQLException e) { + e.printStackTrace(); + } finally { + if (agent != null) { + agent.close(); + } + } + return i; + } + + private String deleteDepartmentBinding = "delete from src_workweixin_dept where org_department_id = ?"; + @Override + public int deleteDepartmentBinding(String departmentId){ + int i = 0 ; + JDBCAgent agent = new JDBCAgent(); + try { + StringBuilder sql = new StringBuilder(deleteDepartmentBinding); + List p = new ArrayList(); + p.add(departmentId); + i=agent.execute(sql.toString(), p); + } catch (BusinessException e) { + e.printStackTrace(); + } catch (SQLException e) { + e.printStackTrace(); + } finally { + if (agent != null) { + agent.close(); + } + } + return i; + } + + private String getDepartmentBinding = "select org_department_id,org_department_name,qywx_department_id,qywx_department_name from src_workweixin_dept where org_department_id = ?"; + @Override + public Map getDepartmentBinding(String orgDepartmentId) { + JDBCAgent agent = new JDBCAgent(); + Map res = new HashMap<>(); + try { + StringBuilder sql = new StringBuilder(getDepartmentBinding); + List p = new ArrayList(); + p.add(orgDepartmentId); + agent.execute(sql.toString(), p); + List list = agent.resultSetToList(); + if(list.size()>0){ + res = list.get(0); + } + } catch (BusinessException var13) { + var13.printStackTrace(); + } catch (SQLException var14) { + var14.printStackTrace(); + } finally { + if (agent != null) { + agent.close(); + } + } + return res; + } + + private String getMemberBinding = "select org_member_id,org_member_name,qywx_member_id,qywx_member_name,qywx_member_telnumber from src_workweixin_member where org_member_id = ? "; + @Override + public Map getMemberBinding(String orgMemberId) { + JDBCAgent agent = new JDBCAgent(); + Map res = new HashMap<>(); + try { + StringBuilder sql = new StringBuilder(getMemberBinding); + List p = new ArrayList(); + p.add(orgMemberId); + agent.execute(sql.toString(), p); + List list = agent.resultSetToList(); + if(list.size()>0){ + res = list.get(0); + } + } catch (BusinessException var13) { + var13.printStackTrace(); + } catch (SQLException var14) { + var14.printStackTrace(); + } finally { + if (agent != null) { + agent.close(); + } + } + return res; + } + + private String deleteMemberBinding = "delete from src_workweixin_member where org_member_id = ?"; + @Override + public int deleteMemberBinding(String memberId){ + int i = 0 ; + JDBCAgent agent = new JDBCAgent(); + try { + StringBuilder sql = new StringBuilder(deleteMemberBinding); + List p = new ArrayList(); + p.add(memberId); + i=agent.execute(sql.toString(), p); + } catch (BusinessException e) { + e.printStackTrace(); + } catch (SQLException e) { + e.printStackTrace(); + } finally { + if (agent != null) { + agent.close(); + } + } + return i; + } +} diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/quartz/OrganizationWorkweixinQuartz.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/quartz/OrganizationWorkweixinQuartz.java new file mode 100644 index 0000000..fb8c428 --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/quartz/OrganizationWorkweixinQuartz.java @@ -0,0 +1,104 @@ +package com.seeyon.apps.src_mainorganization.quartz; + +import cn.hutool.log.Log; +import com.seeyon.apps.common.config.ICstConfigApi; +import com.seeyon.apps.common.plugin.vo.ConfigVo; +import com.seeyon.apps.ext.quartz.AbstractQuartzTask; +import com.seeyon.apps.src_mainorganization.constans.SyncConstants; +import com.seeyon.apps.src_mainorganization.dao.ISyncQywxDao; +import com.seeyon.apps.src_mainorganization.server.InitializeWorkweixinSyncServer; +import com.seeyon.apps.src_mainorganization.server.OrganizationOrgWorkweixinSyncServer; +import com.seeyon.ctp.common.AppContext; + +import javax.inject.Inject; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; + +public class OrganizationWorkweixinQuartz extends AbstractQuartzTask { + + private static Log log = Log.get(OrganizationQuartz.class); + + @Override + public String getName() { + return "企业微信通讯录同步定时任务"; + } + + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + @Inject + private ISyncQywxDao syncQywxDao; + @Inject + private OrganizationOrgWorkweixinSyncServer organizationOrgWorkweixinSyncServer; + @Inject + private InitializeWorkweixinSyncServer initializeWorkweixinSyncServer; + + protected ICstConfigApi cstConfigApi = (ICstConfigApi) AppContext.getBean("cstConfigApi"); + public String getPluginId() {return SyncConstants.getPluginId();} + public ConfigVo getOrganizationOrgConfig() {return cstConfigApi.getConfig(getPluginId());} + + @Override + public String taskRun(String s) throws Exception{ + if("initialize".equals(s)){ + log.info("进行企业微信初始化操作"); + Map errorMapAccount = initializeWorkweixinSyncServer.initializeWorkweixinAccount(); + log.info("单位添加完成,部门添加开始"); + Map errorMapDepartment = initializeWorkweixinSyncServer.initializeWorkweixinDepartment(); + log.info("部门添加完成,人员添加开始"); + Map errorMapMember = initializeWorkweixinSyncServer.initializeWorkweixinMember(); + log.info("人员添加完成"); + return "初始化完成"; + } + log.info("进入企业微信通讯录同步定时任务,参数为:"+s); + ConfigVo configVo = this.cstConfigApi.getConfig(this.getPluginId()); + String res = ""; +// 查询上一次同步时间 + Map maxSynchronizationDate = syncQywxDao.getMaxSynchronizationDate(); + Date startDate = (Date) maxSynchronizationDate.get("max_create_date"); +// 如果当前调用定时任务时未进行同步,则直接查询全量数据进行同步 + String isServiceBroker = configVo.getParamVal(SyncConstants.isServiceBroker.name()); + if(startDate==null){ +// 进行企业微信单位同步操作 +// String errorAccountValue = organizationOrgWorkweixinSyncServer.workweixinSyncAllAccounts(); +// 进行企业微信部门同步操作 + String errorDepartmentValue = organizationOrgWorkweixinSyncServer.workweixinSyncAllDepartments(); +// 进行企业微信人员同步操作 + log.info("进行集团人员数据同步"); + String errorMemberValue = organizationOrgWorkweixinSyncServer.workweixinSyncAllMembers(); +// 进行企业微信业代人员同步 + String errorServiceBroker = ""; + if("是".equals(isServiceBroker)||"Y".equals(isServiceBroker)||"y".equals(isServiceBroker)){ + log.info("进行业代人员数据同步"); + errorServiceBroker = organizationOrgWorkweixinSyncServer.workweixinSyncAllServiceBrokers(); + } +// 进行客户单位下人员同步 + log.info("进行客户人员数据同步"); + String errorClientMemberValue = organizationOrgWorkweixinSyncServer.workweixinSyncAllClientMembers(); + res = errorDepartmentValue+","+errorMemberValue+","+errorServiceBroker+","+errorClientMemberValue; + }else{ +// 通过时间查询最新的修改数据并且同步到企业微信。 +// String accountRes = organizationOrgWorkweixinSyncServer.workweixinSyncBatchAccount(simpleDateFormat.format(startDate)); + String departmrntRes = organizationOrgWorkweixinSyncServer.workweixinSyncBatchDepartment(simpleDateFormat.format(startDate)); + log.info("进行增量集团人员数据同步"); + String memberRes = organizationOrgWorkweixinSyncServer.workweixinSyncBatchMember(simpleDateFormat.format(startDate)); + String serviceBrokerRes = ""; + if("是".equals(isServiceBroker)||"Y".equals(isServiceBroker)||"y".equals(isServiceBroker)){ + log.info("进行增量业代人员数据同步"); + serviceBrokerRes = organizationOrgWorkweixinSyncServer.workweixinSyncServiceBroker(simpleDateFormat.format(startDate)); + } + log.info("进行增量客户人员数据同步"); + String clientMemberRes = organizationOrgWorkweixinSyncServer.workweixinSyncBatchClientMember(simpleDateFormat.format(startDate)); + res = departmrntRes+","+memberRes+","+serviceBrokerRes+","+clientMemberRes; + } + int i = 0 ; + for(String str :res.split(",")){ + for(String str1s : str.split(";")){ + log.info(str1s); + i++; + } + } + return "同步完成,失败"+i; + } + + + +} diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/server/InitializeDingdingSyncServer.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/server/InitializeDingdingSyncServer.java index 78e6973..e5da12f 100644 --- a/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/server/InitializeDingdingSyncServer.java +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/server/InitializeDingdingSyncServer.java @@ -216,9 +216,4 @@ public class InitializeDingdingSyncServer { return errorMap; } - - - - - } diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/server/InitializeWorkweixinSyncServer.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/server/InitializeWorkweixinSyncServer.java new file mode 100644 index 0000000..34fb6df --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/server/InitializeWorkweixinSyncServer.java @@ -0,0 +1,211 @@ +package com.seeyon.apps.src_mainorganization.server; + +import cn.hutool.log.Log; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.seeyon.apps.common.config.ICstConfigApi; +import com.seeyon.apps.common.plugin.vo.ConfigVo; +import com.seeyon.apps.src_mainorganization.constans.SyncConstants; +import com.seeyon.apps.src_mainorganization.dao.ISyncQywxDao; +import com.seeyon.apps.src_mainorganization.util.WorkweixinProtUtil; +import com.seeyon.ctp.common.exceptions.BusinessException; +import com.seeyon.ctp.organization.bo.V3xOrgAccount; +import com.seeyon.ctp.organization.bo.V3xOrgDepartment; +import com.seeyon.ctp.organization.bo.V3xOrgMember; +import com.seeyon.ctp.organization.manager.OrgManager; + +import javax.inject.Inject; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class InitializeWorkweixinSyncServer { + + private static Log log = Log.get(InitializeDingdingSyncServer.class); + + @Inject + private ICstConfigApi cstConfigApi; + @Inject + private OrgManager orgManager; + @Inject + private ISyncQywxDao syncQywxDao; + + public String getPluginId() { + return SyncConstants.getPluginId(); + } + + // 进行钉钉单位信息关系绑定初始化 + public Map initializeWorkweixinAccount() throws BusinessException { + Map errorMap = new HashMap<>(); + ConfigVo configVo = this.cstConfigApi.getConfig(this.getPluginId()); + String workweixinCorpid = configVo.getParamVal(SyncConstants.workweixinCorpid.name()); + String workweixinCorpsecret = configVo.getParamVal(SyncConstants.workweixinCorpsecret.name()); +// String accessToken = WorkweixinProtUtil.getAccessToken(workweixinCorpid,workweixinCorpsecret); +// 调用企业微信接口获取企业微信中所有部门信息 + String departmentAllIds = WorkweixinProtUtil.departmentListsubid(workweixinCorpsecret,workweixinCorpid,1l); + JSONObject departmentAllIdsJSON = JSONObject.parseObject(departmentAllIds); + String errcode = departmentAllIdsJSON.getString("errcode"); + JSONArray workweixinDepartments = departmentAllIdsJSON.getJSONArray("department_id"); + if("0".equals(errcode)){ +// 设置跟部门ID + List superDepartments = new ArrayList<>(); + superDepartments.add(1l); +// 通过跟部门ID查询部门下级信息 + while(superDepartments.size()!=0){ + List departmentIds = new ArrayList<>(); + departmentIds.addAll(superDepartments); + superDepartments.clear(); + for (Long superDepartmentId: departmentIds) { +// 调用企业微信接口查询下级部门信息 + List workweixinDepartmentIds = new ArrayList<>(); + for(int i = 0 ; i < workweixinDepartments.size();i++){ + JSONObject workweixinDepartmentId = workweixinDepartments.getJSONObject(i); + String superWorkweixinDepartmentId = workweixinDepartmentId.getString("parentid"); + if(superWorkweixinDepartmentId.equals(superDepartmentId.toString())){ + workweixinDepartmentIds.add(workweixinDepartmentId.getLongValue("id")); + } + } + for(long workweixinDepartmentId : workweixinDepartmentIds){ +// 根据ID查询企业微信中的部门信息 + String departmentData = WorkweixinProtUtil.departmentGet(workweixinCorpsecret,workweixinCorpid,workweixinDepartmentId); + JSONObject departmentDataJSON = JSONObject.parseObject(departmentData); + String departmentDataJSONCode = departmentDataJSON.getString("errcode"); + if("0".equals(departmentDataJSONCode)){ + JSONObject departmentJSON = departmentDataJSON.getJSONObject("department"); + V3xOrgAccount v3xOrgAccount; + if(superDepartmentId==1L && "稻花香集团".equals(departmentJSON.getString("name"))){ +//// 一级部门存在特殊情况,当前是一级部门时名称为稻花香集团绑定主数据平台一级单位 + v3xOrgAccount = orgManager.getAccountByName("主数据平台"); + }else{ +//// 判断当前获取的钉钉部门是否为单位 + v3xOrgAccount = orgManager.getAccountByName(departmentJSON.getString("name")); + } + if(v3xOrgAccount!=null){ +// 添加到临时储存,为下一个循环的请求参数 + superDepartments.add(workweixinDepartmentId); +// 当前查询单位在钉钉中存在,添加绑定关系表 + int saveAccountBindingnum = syncQywxDao.saveAccountBinding(v3xOrgAccount.getId()+"",v3xOrgAccount.getName(),departmentJSON.getString("id"),departmentJSON.getString("name")); + if(saveAccountBindingnum>0){ +// log.info("添加成功"+v3xOrgAccount.getName()); + }else{ + log.info("添加单位失败"+v3xOrgAccount.getId()+v3xOrgAccount.getName()); + } + } + }else{ + log.info("企业微信单位参数查询失败"+workweixinDepartmentId+departmentDataJSON); + } + } + } + } + } + return errorMap; + } + + // 进行钉钉部门信息关系绑定初始化 + public Map initializeWorkweixinDepartment() throws BusinessException { + Map errorMap = new HashMap<>(); + ConfigVo configVo = this.cstConfigApi.getConfig(this.getPluginId()); + String workweixinCorpid = configVo.getParamVal(SyncConstants.workweixinCorpid.name()); + String workweixinCorpsecret = configVo.getParamVal(SyncConstants.workweixinCorpsecret.name()); +// 根据钉钉中的层级信息与OA中的单位信息添加初始化绑定 +// 查询单位列表 + List superDepartments = syncQywxDao.getAccountsBinding(); + while(superDepartments.size()!=0){ +// 创建临时储存列表 + List departmentIds = new ArrayList<>(); +// 临时储存复制 + departmentIds.addAll(superDepartments); +// 清空上级储存内容 + superDepartments.clear(); + for (long superDepartmentId: departmentIds) { +// 调用钉钉接口查询下级部门信息 + String subordinateDepartment = WorkweixinProtUtil.departmentListsubid(workweixinCorpid,workweixinCorpsecret,superDepartmentId); + JSONObject subordinateDepartmentJson = JSONObject.parseObject(subordinateDepartment); + if("0".equals(subordinateDepartmentJson.getString("errcode"))){ + JSONArray subordinateDepartmentIds = subordinateDepartmentJson.getJSONArray("department_id"); + List subordinateDepartmentIdList = new ArrayList<>(); +// 根据上级部门信息,筛选子集部门信息 + for(int i = 0 ; i superAccountMap = syncQywxDao.getAccountBindingByQywxAccount(superDepartmentId+""); + Map superDepartmentMap = syncQywxDao.getDepartmentBindingByQywxDepartment(superDepartmentId+""); +// 判断当前获取的企业微信部门是否为指定部门 + List v3xOrgDepartments = new ArrayList<>(); + if(superAccountMap.size()>0){ + v3xOrgDepartments = orgManager.getChildDeptsByAccountId(Long.parseLong(superAccountMap.get("org_account_id").toString()),true); + }if(superDepartmentMap.size()>0){ + v3xOrgDepartments = orgManager.getChildDepartments(Long.parseLong(superDepartmentMap.get("org_department_id").toString()),true); + } +// 循环匹配子集部门信息 + for(int n = 0 ; n 0){ +// log.info("添加成功"+saveAccountBindingnum); + }else{ + log.info("添加部门失败"+department.getId()+department.getName()); + } + } + } + }else{ + log.info("企业微信部门参数查询失败"+subordinateDepartmentId+departmentGetJson); + } + } + } + } + } + return errorMap; + } + + // 进行钉钉人员信息关系绑定初始化 + public Map initializeWorkweixinMember() throws BusinessException { + Map errorMap = new HashMap<>(); + ConfigVo configVo = this.cstConfigApi.getConfig(this.getPluginId()); + String workweixinCorpid = configVo.getParamVal(SyncConstants.workweixinCorpid.name()); + String workweixinCorpsecret = configVo.getParamVal(SyncConstants.workweixinCorpsecret.name()); +// 根据部门绑定信息查询部门下人员信息,并添加绑定信息 +// 查询绑定关系中的所有的部门 + List superOADepartments = syncQywxDao.getDepartmentsOABinding(); +// 遍历当前部门,在钉钉中查询各部门下的人员 + for (Long superOADepartmentId: superOADepartments) { + V3xOrgDepartment v3xOrgDepartment = orgManager.getDepartmentById(superOADepartmentId); + List v3xOrgMembers = orgManager.getMembersByDepartment(v3xOrgDepartment.getId(),true); + for(V3xOrgMember v3xOrgMember : v3xOrgMembers){ + String memberTelNumber = v3xOrgMember.getTelNumber(); +// 通过手机号查询企业微信人员ID + String workweixinUserIdPost = WorkweixinProtUtil.getUserIdByMobile(workweixinCorpid,workweixinCorpsecret,memberTelNumber); + JSONObject workweixinUserIdJson = JSONObject.parseObject(workweixinUserIdPost); + String workweixinUserIdJsonErrcode = workweixinUserIdJson.getString("errcode"); + if(!"0".equals(workweixinUserIdJsonErrcode)){ + log.info(memberTelNumber+"手机号企业微信中没有查询到具体信息"); + continue; + } + String workweixinUserId = workweixinUserIdJson.getString("userid"); + int saveMemberBindingNum = syncQywxDao.saveMemberBinding(v3xOrgMember.getId().toString(),v3xOrgMember.getName(),workweixinUserId,v3xOrgMember.getName(),memberTelNumber); + if(saveMemberBindingNum>0){ +// log.info(userMobile+userName+"添加成功"+saveMemberBindingNum); + }else{ + log.info(memberTelNumber+v3xOrgMember.getName()+"添加人员绑定关系失败"+saveMemberBindingNum); + } + } + } + return errorMap; + } +} diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/server/OrganizationOrgDingdingSyncServer.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/server/OrganizationOrgDingdingSyncServer.java index 9269264..0e2f4ff 100644 --- a/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/server/OrganizationOrgDingdingSyncServer.java +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/server/OrganizationOrgDingdingSyncServer.java @@ -767,7 +767,7 @@ public class OrganizationOrgDingdingSyncServer { }else{ from.put("是否成功", "失败"); from.put("同步结果",v3xOrgMember.get("name").toString()+memberCreateJson.getString("errmsg")); -// 调用钉钉接口失败 +// 调用钉钉接口失败 errorMap.put(v3xOrgMember.get("id").toString(),"钉钉添加人员失败:"+v3xOrgMember.get("name").toString()+memberCreateJson.getString("errmsg")); } from.put("同步动作","新增"); @@ -915,46 +915,58 @@ public class OrganizationOrgDingdingSyncServer { for(int i = 0 ; i < list.size() ; i++){ // 遍历所有人员信息 Map serviceBroker = list.get(i); - long departmentId; - if(serviceBroker.get("dept_id")!=null){ - departmentId = Long.parseLong(serviceBroker.get("dept_id").toString()); - V3xOrgDepartment orgDepartment = orgManager.getDepartmentById(departmentId); - if(orgDepartment==null){ - log.info(serviceBroker.get("name")+"查询部门为空,跳过处理"); - errorMap.put(serviceBroker.get("id")+"",serviceBroker.get("name")+"查询部门为空,跳过处理"); - continue; + String memberState = serviceBroker.get("state")!=null?serviceBroker.get("state").toString():""; + boolean isenum = false; + if(StringUtil.isNotEmpty(memberState)){ + CtpEnumItem memberStateItem = enumManagerNew.getCtpEnumItem(Long.parseLong(memberState)); + if(memberStateItem.getShowvalue().equals("在职")||memberStateItem.getShowvalue().equals("试用")||memberStateItem.getShowvalue().equals("待岗")){ + isenum = true; } - serviceBroker.put("account_id","-9194677677107822293");//设置固定值营销门户ID + } + if(isenum){ + long departmentId; + if(serviceBroker.get("dept_id")!=null){ + departmentId = Long.parseLong(serviceBroker.get("dept_id").toString()); + V3xOrgDepartment orgDepartment = orgManager.getDepartmentById(departmentId); + if(orgDepartment==null){ + log.info(serviceBroker.get("name")+"查询部门为空,跳过处理"); + errorMap.put(serviceBroker.get("id")+"",serviceBroker.get("name")+"查询部门为空,跳过处理"); + continue; + } + serviceBroker.put("account_id","-9194677677107822293");//设置固定值营销门户ID // 根据部门ID,查询部门主数据对象 - AddressBook departmentAddressBook = addressBookCustomerFieldInfoManager.getByMemberId(orgDepartment.getId()); + AddressBook departmentAddressBook = addressBookCustomerFieldInfoManager.getByMemberId(orgDepartment.getId()); // 根据同步系统枚举字段 - if(departmentAddressBook!=null){ + if(departmentAddressBook!=null){ // 获取部门同步系统自定义参数 - String xt = departmentAddressBook.getExtAttr31(); - if(StringUtil.isNotEmpty(xt) && !"-1".equals(xt)){ + String xt = departmentAddressBook.getExtAttr31(); + if(StringUtil.isNotEmpty(xt) && !"-1".equals(xt)){ // 获取部门同步系统数据值 - CtpEnumItem xtEnum = getEnumManagerNew().getCtpEnumItem(Long.parseLong(xt)); - String xtValue = xtEnum.getEnumvalue(); - if("1".equals(xtValue)||"3".equals(xtValue)||"5".equals(xtValue)||"6".equals(xtValue)){ - // 如果同步则检索岗位信息是否出现在黑名单 - if(postBlackStringList.contains(serviceBroker.get("post_id"))){ - errorMap.putAll(serviceBrokerSynchronization(serviceBroker,false,accessToken)); - }else{ + CtpEnumItem xtEnum = getEnumManagerNew().getCtpEnumItem(Long.parseLong(xt)); + String xtValue = xtEnum.getEnumvalue(); + if("1".equals(xtValue)||"3".equals(xtValue)||"5".equals(xtValue)||"6".equals(xtValue)){ + // 如果同步则检索岗位信息是否出现在黑名单 + if(postBlackStringList.contains(serviceBroker.get("post_id"))){ + errorMap.putAll(serviceBrokerSynchronization(serviceBroker,false,accessToken)); + }else{ // 如果岗位不在黑名单中,设置新增逻辑。 - errorMap.putAll(serviceBrokerSynchronization(serviceBroker,true,accessToken)); + errorMap.putAll(serviceBrokerSynchronization(serviceBroker,true,accessToken)); + } + }else{ +// 如果人员不在白名单中则设置删除逻辑 + errorMap.putAll(serviceBrokerSynchronization(serviceBroker,false,accessToken)); } }else{ -// 如果人员不在白名单中则设置删除逻辑 errorMap.putAll(serviceBrokerSynchronization(serviceBroker,false,accessToken)); } }else{ errorMap.putAll(serviceBrokerSynchronization(serviceBroker,false,accessToken)); } }else{ - errorMap.putAll(serviceBrokerSynchronization(serviceBroker,false,accessToken)); + log.info("当前人员档案中所属部门为空跳过处理"+serviceBroker.get("name")); } }else{ - log.info("当前人员档案中所属部门为空跳过处理"+serviceBroker.get("name")); + errorMap.putAll(serviceBrokerSynchronization(serviceBroker,false,accessToken)); } } @@ -986,7 +998,7 @@ public class OrganizationOrgDingdingSyncServer { Map errorMap = new HashMap<>(); Map memberMap = new HashMap<>(); - if(serviceBroker.get("account_id")!=null){ + if(serviceBroker.get("account_id")!=null){ Map accountBinding = syncDdDao.getAccountBinding(serviceBroker.get("account_id").toString()); if(accountBinding.size()==0){ log.info("当前修改人员所在单位不在钉钉绑定表中跳过处理"); @@ -1206,7 +1218,7 @@ public class OrganizationOrgDingdingSyncServer { List postBlackList = archiveDao.getPostBlackList(); String postBlackString = ""; for (String postBlack:postBlackList) { - postBlackString = postBlackString+ postBlack+ ","; + postBlackString = postBlackString+postBlack+ ","; } List postBlackStringList = Arrays.asList(postBlackString.split(",")); // 查询人员白名单 diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/server/OrganizationOrgWorkweixinSyncServer.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/server/OrganizationOrgWorkweixinSyncServer.java new file mode 100644 index 0000000..0d8bd2a --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/server/OrganizationOrgWorkweixinSyncServer.java @@ -0,0 +1,1381 @@ +package com.seeyon.apps.src_mainorganization.server; + +import cn.hutool.log.Log; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.seeyon.apps.addressbook.manager.AddressBookCustomerFieldInfoManager; +import com.seeyon.apps.addressbook.po.AddressBook; +import com.seeyon.apps.common.config.ICstConfigApi; +import com.seeyon.apps.common.plugin.vo.ConfigVo; +import com.seeyon.apps.src_mainorganization.constans.SyncConstants; +import com.seeyon.apps.src_mainorganization.dao.*; +import com.seeyon.apps.src_mainorganization.util.FormExportUtil; +import com.seeyon.apps.src_mainorganization.util.WorkweixinProtUtil; +import com.seeyon.ctp.common.AppContext; +import com.seeyon.ctp.common.ctpenumnew.manager.EnumManager; +import com.seeyon.ctp.common.exceptions.BusinessException; +import com.seeyon.ctp.common.po.ctpenumnew.CtpEnumItem; +import com.seeyon.ctp.organization.bo.V3xOrgAccount; +import com.seeyon.ctp.organization.bo.V3xOrgDepartment; +import com.seeyon.ctp.organization.bo.V3xOrgPost; +import com.seeyon.ctp.organization.manager.OrgManager; +import com.seeyon.ctp.services.ServiceException; +import com.seeyon.v3x.services.form.FormFactory; +import com.seeyon.v3x.services.form.bean.FormExport; +import com.seeyon.v3x.services.form.bean.ValueExport; +import com.taobao.api.ApiException; +import jodd.util.StringUtil; + +import javax.inject.Inject; +import java.text.SimpleDateFormat; +import java.util.*; + +public class OrganizationOrgWorkweixinSyncServer { + + private static Log log = Log.get(OrganizationOrgDingdingSyncServer.class); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + FormExportUtil formExportUtil = new FormExportUtil(); + @Inject + private ICstConfigApi cstConfigApi; + @Inject + private OrgManager orgManager; + @Inject + private ISyncQywxDao syncQywxDao; + @Inject + private ISrcAccountDao srcAccountDao; + @Inject + private ISrcDepartmentDao srcDepartmentDao; + @Inject + private ISrcMemberDao srcMemberDao; + @Inject + private IArchiveDao archiveDao; + @Inject + private AddressBookCustomerFieldInfoManager addressBookCustomerFieldInfoManager; + @Inject + private FormFactory formFactory; + + private EnumManager enumManagerNew; + public void setEnumManagerNew(EnumManager enumManagerNew) {this.enumManagerNew = enumManagerNew;} + public EnumManager getEnumManagerNew() { + if (enumManagerNew == null) {enumManagerNew = (EnumManager) AppContext.getBean("enumManagerNew");} + return enumManagerNew; + } + + public String getPluginId() { + return SyncConstants.getPluginId(); + } + + public String workweixinSyncAllAccounts() throws BusinessException, ServiceException { + String res = ""; +// 查询所有单位信息 + List> allAccounts = srcAccountDao.getAllAccounts(); + //根据列表查询生成列表部门对象 + Map errorMap = workweixinSyncBatchAccountMap(allAccounts); + log.info("单位异常数"+errorMap.size()); + for (Map.Entry entry : errorMap.entrySet()) { + String value = entry.getValue(); + res= res+value+";"; + } + return res; + } + + // 通过最新修改时间查询变化单位数据,将变化的数据保存到企业微信中 + public String workweixinSyncBatchAccount (String startDate) throws BusinessException, ServiceException { + String res = ""; +// 根据上一次同步时间获取最新修改的单位信息 + List> incrementAccounts = srcAccountDao.getIncrementAccountByUpdateTime(startDate); +// 根据列表查询生成列表部门对象 + Map errorMap = workweixinSyncBatchAccountMap(incrementAccounts); + log.info("单位异常数"+errorMap.size()); + for (Map.Entry entry : errorMap.entrySet()) { + String value = entry.getValue(); + res= res+value+";"; + } + return res ; + } + + // 企业微信单位同步,单位列表 +// id,name,code,path,is_enable + public Map workweixinSyncBatchAccountMap(List> list) throws BusinessException, ServiceException { + ConfigVo configVo = this.cstConfigApi.getConfig(this.getPluginId()); + + Map errorMap = new HashMap<>(); + String excludeAccount = configVo.getParamVal(SyncConstants.excludeAccount.name()); + String workweixinCorpid = configVo.getParamVal(SyncConstants.workweixinCorpid.name()); + String workweixinCorpsecret = configVo.getParamVal(SyncConstants.workweixinCorpsecret.name()); + String workweixinTxlCorpsecret = configVo.getParamVal(SyncConstants.workweixinTxlCorpsecret.name()); + + log.info("遍历单位信息个数"+list.size()); + for(Map accountMap : list){ + Map from = new HashMap(); + from.put("同步类型", "单位"); + from.put("同步时间", sdf.format(new Date())); + from.put("同步对象", accountMap.get("name").toString()); +// if(accountMap.get("path").toString().startsWith("00000010") || excludeAccount.contains(accountMap.get("id").toString())){ + if(accountMap.get("path").toString().startsWith("00000010") ){ + log.info(accountMap.get("name")+ "" + accountMap.get("code") + accountMap.get("id")); +// 同步单位单位信息,同步流程平台,检查流程平台是否存在 + long accountId = Long.parseLong(accountMap.get("id").toString()); + String accountName = accountMap.get("name").toString(); +// 根据OA单位ID查询绑定关系表中是否存在 + Map map = syncQywxDao.getAccountBinding(accountId+""); + accountMap.put("qywx_account_id",map.get("qywx_account_id")); +// 判断当前部门是否存在绑定关系 + if(map.size()>0){ + if("1".equals(accountMap.get("is_enable")!=null?accountMap.get("is_enable").toString():null)){ +// 封装当前环境单位数据,调用部门修改接口,修改企业微信部门信息 + JSONObject req = new JSONObject(); +// 部门ID + req.put("id",Long.parseLong(map.get("qywx_account_id").toString())); +// 获取单位路径 + String accountPath = accountMap.get("path").toString(); + if(excludeAccount.contains(accountMap.get("id")+"")){ + V3xOrgAccount superiorAccount = orgManager.getAccountByPath("00000011"); +// 根据上级单位ID查询绑定关系表中的企业微信部门ID + Map superiorAccountMap = syncQywxDao.getAccountBinding(superiorAccount.getId()+""); + if(superiorAccountMap.size()<0){ +// 未查询到上级单位绑定关系,同步企业微信失败, + errorMap.put(accountId+"","企业微信同步单位失败:"+accountName+"未查询到上级单位绑定关系,同步企业微信失败"); + continue; + } +// 上级部门 + req.put("parentid",Long.parseLong(superiorAccountMap.get("qywx_account_id").toString())); + }else{ + accountPath = accountPath.substring(0,accountPath.length()-4); + if("0000".equals(accountPath)){ +// 上级单位为根部门 + req.put("parentid",1); +// req.setParentId(1L); + }else{ + V3xOrgAccount superiorAccount = orgManager.getAccountByPath(accountPath); +// 根据上级单位ID查询绑定关系表中的企业微信部门ID + Map superiorAccountMap = syncQywxDao.getAccountBinding(superiorAccount.getId()+""); + if(superiorAccountMap.size()<0){ +// 未查询到上级单位绑定关系,同步企业微信失败, + errorMap.put(accountId+"","企业微信同步单位失败:"+accountName+"未查询到上级单位绑定关系,同步企业微信失败"); + continue; + } +// 上级部门 + req.put("parentid",Long.parseLong(superiorAccountMap.get("qywx_account_id").toString())); + } + } +// 部门名称 + if("第一大区".equals(accountName)){ + req.put("name","华中地区"); + }else if ("第二大区".equals(accountName)){ + req.put("name","华南地区"); + }else if ("第三大区".equals(accountName)){ + req.put("name","华北地区"); + }else{ + req.put("name",accountName); + } +// req.put("name",accountName); +// 调用接口修改企业微信部门信息 + String departmentUpdate = WorkweixinProtUtil.departmentUpdate(workweixinCorpid,workweixinTxlCorpsecret,req); + JSONObject departmentUpdateJson = JSONObject.parseObject(departmentUpdate); +// 更新绑定关系数据 + if("0".equals(departmentUpdateJson.getString("errcode"))){ + from.put("是否成功", "成功"); + from.put("同步结果", "企业微信修改同步成功"); +// 修改部门成功,修改绑定关系数据 + int ii = syncQywxDao.updateAccountBinding(accountId+"",accountName,map.get("qywx_account_id").toString(),accountMap.get("name").toString()); + }else{ + from.put("是否成功", "失败"); + from.put("同步结果", accountName+departmentUpdateJson.getString("errmsg")); +// 调用企业微信接口失败 + errorMap.put(accountId+"","企业微信修改同步单位失败:"+accountName+departmentUpdateJson.getString("errmsg")); + } + FormExport formExport = new FormExport(); + from.put("同步动作", "修改"); + from.put("主要信息", accountMap.toString()); + List valueExports = formExportUtil.setFormValue(from); + formExport.setValues(valueExports); + formFactory.importBusinessFormData(configVo.getParamVal(SyncConstants.workweixinLogloginName.name()), + configVo.getParamVal(SyncConstants.workweixinLog.name()), + formExport, new String[] {}); + }else{ + log.info(accountMap.toString()+"当前单位状态为停用状态,执行企业微信部门删除操作"); + String departmentDelete = WorkweixinProtUtil.departmentDelete(workweixinCorpid,workweixinTxlCorpsecret,map.get("qywx_account_id").toString()); + JSONObject departmentDeleteJson = JSONObject.parseObject(departmentDelete); +// 更新绑定关系数据 + if("0".equals(departmentDeleteJson.getString("errcode"))){ + from.put("是否成功", "成功"); + from.put("同步结果", "企业微信删除同步成功"); +// 删除部门成功,修改绑定关系数据 + int ii = syncQywxDao.deleteDepartmentBinding(accountId+""); + }else{ + from.put("是否成功", "失败"); + from.put("同步结果", accountName+departmentDeleteJson.getString("errmsg")); +// 调用企业微信接口失败 + errorMap.put(accountId+"","企业微信删除同步部门失败:"+accountName+departmentDeleteJson.getString("errmsg")); + } + FormExport formExport = new FormExport(); + from.put("同步动作", "删除"); + from.put("主要信息", accountMap.toString()); + List valueExports = formExportUtil.setFormValue(from); + formExport.setValues(valueExports); + formFactory.importBusinessFormData(configVo.getParamVal(SyncConstants.workweixinLogloginName.name()), + configVo.getParamVal(SyncConstants.workweixinLog.name()), + formExport, new String[] {}); + } + }else{ +// 封装当前单位数据,调用部门新增接口,新增企业微信部门信息 + JSONObject req = new JSONObject(); +// 获取单位路径 + String accountPath = accountMap.get("path").toString(); + if(excludeAccount.contains(accountId+"")){ + V3xOrgAccount superiorAccount = orgManager.getAccountByPath("00000011"); +// 根据上级单位ID查询绑定关系表中的企业微信部门ID + Map superiorAccountMap = syncQywxDao.getAccountBinding(superiorAccount.getId()+""); + if(superiorAccountMap.size()<0){ +// 未查询到上级单位绑定关系,同步企业微信失败, + errorMap.put(accountId+"","企业微信同步单位失败:"+accountName+"未查询到上级单位绑定关系,同步企业微信失败"); + continue; + } +// 上级部门 + req.put("parentid",Long.parseLong(superiorAccountMap.get("qywx_account_id").toString())); + }else{ + accountPath = accountPath.substring(0,accountPath.length()-4); + if("0000".equals(accountPath)){ +// 上级单位为根部门 + req.put("parentid",1); + }else{ + V3xOrgAccount superiorAccount = orgManager.getAccountByPath(accountPath); +// 根据上级单位ID查询绑定关系表中的企业微信部门ID + Map superiorAccountMap = syncQywxDao.getAccountBinding(superiorAccount.getId()+""); + if(superiorAccountMap.size()==0){ +// 未查询到上级单位绑定关系,同步企业微信失败, + errorMap.put(accountId+"","企业微信同步单位失败:"+accountName+"未查询到上级单位绑定关系,同步企业微信失败"); + continue; + } +// 上级部门 + req.put("parentid",Long.parseLong(superiorAccountMap.get("qywx_account_id").toString())); + } + } +// 部门名称,调用接口时去掉特殊字符 + accountName = accountName.replace("-", ""); + if("第一大区".equals(accountName)){ + req.put("name","华中地区"); + }else if ("第二大区".equals(accountName)){ + req.put("name","华南地区"); + }else if ("第三大区".equals(accountName)){ + req.put("name","华北地区"); + }else{ + req.put("name",accountName); + } +// req.put("name",accountName); + String departmentCreate = WorkweixinProtUtil.departmentCreate(workweixinCorpid,workweixinTxlCorpsecret,req); + JSONObject departmentCreateJson = JSONObject.parseObject(departmentCreate); + if("0".equals(departmentCreateJson.getString("errcode"))){ + from.put("是否成功", "成功"); + from.put("同步结果", "企业微信新增同步成功"); +// 新增部门成功,新增绑定关系数据 + String qywxAccoungId = departmentCreateJson.getString("id"); + int ii = syncQywxDao.saveAccountBinding(accountId+"",accountName,qywxAccoungId,accountName); + }else{ + from.put("是否成功", "失败"); + from.put("同步结果", accountName+departmentCreateJson.getString("errmsg")); +// 调用企业微信接口失败 + errorMap.put(accountId+"","企业微信同步单位失败:"+accountName+departmentCreateJson.getString("errmsg")); + } + FormExport formExport = new FormExport(); + from.put("同步动作", "新增"); + from.put("主要信息", accountMap.toString()); + List valueExports = formExportUtil.setFormValue(from); + formExport.setValues(valueExports); + formFactory.importBusinessFormData(configVo.getParamVal(SyncConstants.workweixinLogloginName.name()), + configVo.getParamVal(SyncConstants.workweixinLog.name()), + formExport, new String[] {}); + } + } + } + return errorMap; + } + + public String workweixinSyncAllDepartments() throws BusinessException, ServiceException { + String res = ""; +// 根据上一次同步时间获取最新修改的单位信息 + List> incrementDepartments = srcDepartmentDao.getAllDepartments(); +// 根据列表查询生成列表部门对象 + Map errorMap = workweixinSyncBatchDeptMap(incrementDepartments); + log.info("部门异常数"+errorMap.size()); + for (Map.Entry entry : errorMap.entrySet()) { + String value = entry.getValue(); + res= res+value+";"; + } + return res ; + + } + + // 通过最新修改时间查询变化部门数据,将变化的数据保存到企业微信中 + public String workweixinSyncBatchDepartment (String startDate) throws BusinessException, ServiceException { + String res = ""; +// 根据上一次同步时间获取最新修改的单位信息 + List> incrementDepartments = srcDepartmentDao.getIncrementDepartmentByUpdateTime(startDate); +// 根据列表查询生成列表部门对象 + Map errorMap = workweixinSyncBatchDeptMap(incrementDepartments); + log.info("部门异常数"+errorMap.size()); + for (Map.Entry entry : errorMap.entrySet()) { + String value = entry.getValue(); + res= res+value+";"; + } + return res ; + } + + // 企业微信单部门同步 +// id,code,name,path,is_enable + public Map workweixinSyncBatchDeptMap (List> list) throws BusinessException, ServiceException { + ConfigVo configVo = this.cstConfigApi.getConfig(this.getPluginId()); + + Map errorMap = new HashMap<>(); + String workweixinCorpid = configVo.getParamVal(SyncConstants.workweixinCorpid.name()); + String workweixinCorpsecret = configVo.getParamVal(SyncConstants.workweixinCorpsecret.name()); + String workweixinTxlCorpsecret = configVo.getParamVal(SyncConstants.workweixinTxlCorpsecret.name()); + + for(Map departmentMap : list){ + long departmentId = Long.parseLong(departmentMap.get("id").toString()); +// 根据当前部门信息查询部门自定义信息项 + AddressBook addressBook = addressBookCustomerFieldInfoManager.getByMemberId(departmentId); + if("1".equals(departmentMap.get("is_enable")!=null?departmentMap.get("is_enable").toString():null)){ +// 判断自定义项是否为空 + if(addressBook!=null){ +// 获取自定义查询项信息 + String xt = addressBook.getExtAttr31(); + if(StringUtil.isNotEmpty(xt) && !"-1".equals(xt)){ +// 获取自定义查询项数据 + CtpEnumItem ctpEnumItem = getEnumManagerNew().getCtpEnumItem(Long.parseLong(xt)); + String xtValue = ctpEnumItem.getValue(); + if("1".equals(xtValue)||"3".equals(xtValue)||"5".equals(xtValue)||"6".equals(xtValue)){ +// 当前部门自定义数据项中存在企业微信 + errorMap.putAll(departmentSynchronization(departmentMap,true,workweixinCorpid,workweixinCorpsecret,workweixinTxlCorpsecret)); + }else{ +// 当前部门重定义数据项中不存在企业微信 + errorMap.putAll(departmentSynchronization(departmentMap,false,workweixinCorpid,workweixinCorpsecret,workweixinTxlCorpsecret)); + } + }else{ +// 当前部门同步系统自定义查询项数据为空 + errorMap.putAll(departmentSynchronization(departmentMap,false,workweixinCorpid,workweixinCorpsecret,workweixinTxlCorpsecret)); + } + }else{ +// 当前部门自定义查询项数据为空 + errorMap.putAll(departmentSynchronization(departmentMap,false,workweixinCorpid,workweixinCorpsecret,workweixinTxlCorpsecret)); + } + }else{ +// 当前部门状态为停用状态 + errorMap.putAll(departmentSynchronization(departmentMap,false,workweixinCorpid,workweixinCorpsecret,workweixinTxlCorpsecret)); + } + } + return errorMap; + } + + public Map excelDepartmentSynchronization(Map excelDataMap,Map departmentMap,boolean state) throws ApiException, BusinessException { +// 当前人员所在单位在企业微信绑定表中存在。 + Map departmentBinding = syncQywxDao.getDepartmentBinding(departmentMap.get("id")+""); +// 查询上级部门信息 + String path = departmentMap.get("path").toString(); + String superPath = path.substring(0,path.length()-4); + String superDepartmentId = srcDepartmentDao.getSuperUnitIdByPath(superPath); + V3xOrgDepartment v3xOrgDepartment = orgManager.getDepartmentById(Long.parseLong(departmentMap.get("id")+"")); + V3xOrgAccount v3xOrgAccount = orgManager.getAccountById(v3xOrgDepartment.getOrgAccountId()); + excelDataMap.put("accountId",v3xOrgAccount.getId().toString()); + excelDataMap.put("accountName",v3xOrgAccount.getName()); + + if(departmentBinding.size()>0){ +// 判断当前同步状态 + if(state){ +// 部门ID + excelDataMap.put("qywxdeptId",departmentBinding.get("qywx_department_id")!=null?departmentBinding.get("qywx_department_id").toString():""); + if(superDepartmentId.equals(departmentMap.get("org_account_id")!=null?departmentMap.get("org_account_id").toString():null)){ +// 获取上级部门ID,如果当前部门是一级部门那么上级部门ID则查询所在单位ID。 + Map accountBinding = syncQywxDao.getAccountBinding(departmentMap.get("org_account_id")+""); + log.info("上级部门与所属单位相同,在OA中是一级部门,取单位绑定中的企业微信ID"+accountBinding.get("qywx_account_id")); + excelDataMap.put("qywxsuperdeptId",accountBinding.get("qywx_account_id")!=null?accountBinding.get("qywx_account_id").toString():""); + excelDataMap.put("qywxsuperdeptName",accountBinding.get("qywx_account_name")!=null?accountBinding.get("qywx_account_name").toString():""); + } else{ +// 如果当前部门不是一级部门,则直接获取上级部门ID查询企业微信绑定 + Map superDepartmentBinding = syncQywxDao.getDepartmentBinding(superDepartmentId); + if(superDepartmentBinding.size()<0){ + return excelDataMap; + } + log.info("根据上级部门ID查询企业微信部门绑定表中的信息获取企业微信ID"+superDepartmentBinding.get("qywx_department_id").toString()); + excelDataMap.put("qywxsuperdeptId",superDepartmentBinding.get("qywx_department_id")!=null?superDepartmentBinding.get("qywx_department_id").toString():""); + excelDataMap.put("qywxsuperdeptName",superDepartmentBinding.get("qywx_department_name")!=null?superDepartmentBinding.get("qywx_department_name").toString():""); + } +// 排序号 +// req.setOrder(10L); +// 部门名称 + excelDataMap.put("deptName",departmentMap.get("name")!=null?departmentMap.get("name").toString():""); +// 部门唯一标识 + excelDataMap.put("sourcedeptId",departmentMap.get("id")!=null?departmentMap.get("id").toString():""); + } + }else{ + if(state){ + log.info(superDepartmentId+"=="+departmentMap.get("org_account_id")); + if(superDepartmentId.equals(departmentMap.get("org_account_id")!=null?departmentMap.get("org_account_id").toString():"")){ +// 获取上级部门ID,如果当前部门是一级部门那么上级部门ID则查询所在单位ID。 + Map accountBinding = syncQywxDao.getAccountBinding(departmentMap.get("org_account_id").toString()); + log.info("上级部门与所属单位相同,在OA中是一级部门,取单位绑定中的企业微信ID"+accountBinding.get("qywx_account_id")); + excelDataMap.put("qywxsuperdeptId",accountBinding.get("qywx_account_id")!=null?accountBinding.get("qywx_account_id").toString():""); + excelDataMap.put("qywxsuperdeptName",accountBinding.get("qywx_account_name")!=null?accountBinding.get("qywx_account_name").toString():""); + } else{ +// 如果当前部门不是一级部门,则直接获取上级部门ID查询企业微信绑定\ + Map superDepartmentBinding = syncQywxDao.getDepartmentBinding(superDepartmentId); + log.info("当前部门信息为"+departmentMap.get("id")+departmentMap.get("name")+"上级部门id为"+superDepartmentId); + if(superDepartmentBinding.size()==0){ +// 未查询到上级单部门绑定关系,同步企业微信失败, + return excelDataMap; + } + log.info(superDepartmentBinding+"根据上级部门ID查询企业微信部门绑定表中的信息获取企业微信ID"+superDepartmentBinding.get("qywx_department_id")); + excelDataMap.put("qywxsuperdeptId",superDepartmentBinding.get("qywx_department_id")!=null?superDepartmentBinding.get("qywx_department_id").toString():""); + excelDataMap.put("qywxsuperdeptName",superDepartmentBinding.get("qywx_department_name")!=null?superDepartmentBinding.get("qywx_department_name").toString():""); + } +// 部门名称 + excelDataMap.put("deptName",departmentMap.get("name").toString()); +// 外部绑定ID + excelDataMap.put("sourcedeptId",departmentMap.get("id").toString()); + } + } + return excelDataMap; + } + + + public Map departmentSynchronization(Map departmentMap,boolean state,String corpid,String corpsecret,String txlCorpsecret) throws ServiceException { + ConfigVo configVo = this.cstConfigApi.getConfig(this.getPluginId()); + FormExport formExport = new FormExport(); + Map from = new HashMap(); + from.put("同步类型", "部门"); + from.put("同步时间", sdf.format(new Date())); + from.put("同步对象", departmentMap.get("name").toString()); + + Map errorMap = new HashMap<>(); + log.info("查询当前部门是否在企业微信绑定表中是否存在"); +// 当前人员所在单位在企业微信绑定表中存在。 + System.out.println(departmentMap); + Map departmentBinding = syncQywxDao.getDepartmentBinding(departmentMap.get("id")+""); + departmentMap.put("qywx_department_id",departmentBinding.get("qywx_department_id")); + from.put("主要信息", departmentMap.toString()); +// 查询上级部门信息 + String path = departmentMap.get("path").toString(); + String superPath = path.substring(0,path.length()-4); + String superDepartmentId = srcDepartmentDao.getSuperUnitIdByPath(superPath); + if(departmentBinding.size()>0){ +// 判断当前同步状态 + if(state){ +// 部门信息在绑定表中存在调用企业微信修改接口 + JSONObject req = new JSONObject(); +// 部门ID + req.put("id",Long.parseLong(departmentBinding.get("qywx_department_id").toString())); + + if(superDepartmentId.equals(departmentMap.get("org_account_id")!=null?departmentMap.get("org_account_id").toString():null)){ +// 获取上级部门ID,如果当前部门是一级部门那么上级部门ID则查询所在单位ID。 + Map accountBinding = syncQywxDao.getAccountBinding(departmentMap.get("org_account_id")+""); + log.info("上级部门与所属单位相同,在OA中是一级部门,取单位绑定中的企业微信ID"+accountBinding.get("qywx_account_id")); + req.put("parentid",1); + } else{ +// 如果当前部门不是一级部门,则直接获取上级部门ID查询企业微信绑定 + Map superDepartmentBinding = syncQywxDao.getDepartmentBinding(superDepartmentId); + if(superDepartmentBinding.get("org_department_id")==null){ +// 未查询到上级单位绑定关系,同步企业微信失败, + errorMap.put(departmentMap.get("id").toString(),"企业微信同步单位失败:"+departmentMap.get("name")+"未查询到上级部门绑定关系,同步企业微信失败"); + return errorMap; + } + log.info("根据上级部门ID查询企业微信部门绑定表中的信息获取企业微信ID"+superDepartmentBinding.get("qywx_department_id")); + req.put("parentid",Long.parseLong(superDepartmentBinding.get("qywx_department_id").toString())); + } +// 部门名称 + if("第一大区".equals(departmentMap.get("name").toString())){ + req.put("name","华中地区"); + }else if ("第二大区".equals(departmentMap.get("name").toString())){ + req.put("name","华南地区"); + }else if ("第三大区".equals(departmentMap.get("name").toString())){ + req.put("name","华北地区"); + }else{ + req.put("name",departmentMap.get("name").toString()); + } +// req.put("name",departmentMap.get("name").toString()); + String departmentUpdate = WorkweixinProtUtil.departmentUpdate(corpid,txlCorpsecret,req); + JSONObject departmentUpdateJson = JSONObject.parseObject(departmentUpdate); +// 更新绑定关系数据(不可直接更新绑定关系) + if("0".equals(departmentUpdateJson.getString("errcode"))){ + from.put("是否成功", "成功"); + from.put("同步结果", "企业微信修改同步成功"); + }else{ + from.put("是否成功", "失败"); + from.put("同步结果", departmentMap.get("name").toString()+departmentUpdateJson.getString("errmsg")); +// 调用企业微信接口失败 + errorMap.put(departmentMap.get("id").toString(),"企业微信同步部门失败:"+departmentMap.get("name").toString()+departmentUpdateJson.getString("errmsg")); + } + from.put("同步动作", "修改"); + }else{ +// 部门信息在绑定表中不存在调用企业微信删除接口 + log.info(departmentMap.toString()+"部门信息在绑定表中不存在调用企业微信删除接口"); + String departmentDelete = WorkweixinProtUtil.departmentDelete(corpid,txlCorpsecret,departmentBinding.get("qywx_department_id").toString()); + JSONObject departmentDeleteJson = JSONObject.parseObject(departmentDelete); +// 更新绑定关系数据 + if("0".equals(departmentDeleteJson.getString("errcode"))){ + from.put("是否成功", "成功"); + from.put("同步结果", "企业微信删除同步成功"); +// 删除部门成功,修改绑定关系数据 + int ii = syncQywxDao.deleteDepartmentBinding(departmentMap.get("id").toString()); + log.info("删除绑定关系"+ii); + }else{ + from.put("是否成功", "失败"); + from.put("同步结果", departmentMap.get("name").toString()+departmentDeleteJson.getString("errmsg")); +// 调用企业微信接口失败 + errorMap.put(departmentMap.get("id").toString(),"企业微信同步部门失败:"+departmentMap.get("name").toString()+departmentDeleteJson.getString("errmsg")); + } + from.put("同步动作", "删除"); + } + }else{ + if(state){ +// 部门信息在绑定表中存在调用企业微信新增接口 + log.info("当前部门在绑定关系中不存在"); + JSONObject req = new JSONObject(); + log.info(superDepartmentId+"=="+departmentMap.get("org_account_id")); + if(superDepartmentId.equals(departmentMap.get("org_account_id")!=null?departmentMap.get("org_account_id").toString():null)){ +// 获取上级部门ID,如果当前部门是一级部门那么上级部门ID则查询所在单位ID。 + Map accountBinding = syncQywxDao.getAccountBinding(departmentMap.get("org_account_id").toString()); + if(accountBinding.size()!=0){ + log.info("上级部门与所属单位相同,在OA中是一级部门,取单位绑定中的企业微信ID"+accountBinding.get("qywx_account_id")); + req.put("parentid",1); + }else{ +// 当前为查询到对应的部门信息跳过同步当前对象 + errorMap.put(departmentMap.get("id").toString(),"当前部门所属单位信息未进行企业微信绑定,跳过当前部门处理"); + return errorMap; + } + } else{ +// 如果当前部门不是一级部门,则直接获取上级部门ID查询企业微信绑定\ + Map superDepartmentBinding = syncQywxDao.getDepartmentBinding(superDepartmentId); + log.info("当前部门信息为"+departmentMap.get("id")+departmentMap.get("name")+"上级部门id为"+superDepartmentId); + if(superDepartmentBinding.size()==0){ +// 未查询到上级单部门绑定关系,同步企业微信失败, + errorMap.put(departmentMap.get("id").toString(),"企业微信同步单位失败:"+departmentMap.get("name")+"未查询到上级部门绑定关系,同步企业微信失败"); + return errorMap; + } + log.info(superDepartmentBinding+"根据上级部门ID查询企业微信部门绑定表中的信息获取企业微信ID"+superDepartmentBinding.get("qywx_department_id")); + if(superDepartmentBinding.get("qywx_department_id")!=null){ + req.put("parentid",Long.parseLong(superDepartmentBinding.get("qywx_department_id").toString())); + }else{ + errorMap.put(departmentMap.get("id").toString(),"当前部门的所属上级部门未进行企业微信绑定,跳过当前部门处理"); + return errorMap; + } + } +// 部门名称 + String departmentName = departmentMap.get("name").toString().replace("-", ""); + if("第一大区".equals(departmentName)){ + req.put("name","华中地区"); + }else if ("第二大区".equals(departmentName)){ + req.put("name","华南地区"); + }else if ("第三大区".equals(departmentName)){ + req.put("name","华北地区"); + }else{ + req.put("name",departmentName); + } +// req.put("name",departmentName); + String departmentCreate = WorkweixinProtUtil.departmentCreate(corpid,txlCorpsecret,req); + JSONObject departmentCreateJson = JSONObject.parseObject(departmentCreate); + if("0".equals(departmentCreateJson.getString("errcode"))){ + from.put("是否成功", "成功"); + from.put("同步结果", "企业微信新建同步成功"); +// 新增部门成功,新增绑定关系数据 + String quwxDepartmentId = departmentCreateJson.getString("id"); + int ii = syncQywxDao.saveDepartmentBinding(departmentMap.get("id").toString(),departmentMap.get("name").toString(),quwxDepartmentId,departmentMap.get("name").toString()); + log.info("新增绑定关系"+ii); + }else{ + from.put("是否成功", "失败"); + from.put("同步结果", departmentMap.get("name").toString()+departmentCreateJson.getString("errmsg")); +// 调用企业微信接口失败 + errorMap.put(departmentMap.get("id").toString()+"","企业微信同步部门失败:"+departmentMap.get("name").toString()+departmentCreateJson.getString("errmsg")); + } + from.put("同步动作", "新增"); + } + } + List valueExports = formExportUtil.setFormValue(from); + formExport.setValues(valueExports); + if(StringUtil.isNotEmpty(from.get("同步动作"))){ + formFactory.importBusinessFormData(configVo.getParamVal(SyncConstants.workweixinLogloginName.name()), + configVo.getParamVal(SyncConstants.workweixinLog.name()), + formExport, new String[] {}); + } + return errorMap; + } + + public String workweixinSyncAllMembers() throws BusinessException, ApiException, ServiceException { +// 首先删除所有人员数据 +// ConfigVo configVo = this.cstConfigApi.getConfig(this.getPluginId()); +// String workweixinCorpid = configVo.getParamVal(SyncConstants.workweixinCorpid.name()); +// String workweixinCorpsecret = configVo.getParamVal(SyncConstants.workweixinCorpsecret.name()); +// String workweixinTxlCorpsecret = configVo.getParamVal(SyncConstants.workweixinTxlCorpsecret.name()); +// String json = WorkweixinProtUtil.userListId(workweixinCorpid,workweixinCorpsecret); +// JSONObject jsonObject = JSONObject.parseObject(json); +// JSONArray deptUsers = jsonObject.getJSONArray("dept_user"); +// log.info("人员列表"+deptUsers.toString()); +// for(int i = 0 ; i < deptUsers.size();i++){ +// JSONObject deptUser = deptUsers.getJSONObject(i); +// String openUserid = deptUser.getString("open_userid"); +// String res = WorkweixinProtUtil.memberDelete(workweixinCorpid,workweixinTxlCorpsecret,openUserid); +// log.info("删除ID为:"+openUserid+"删除结果:"+res); +// } + + + String res = ""; +// 根据上一次同步时间获取最新修改的单位信息 + List> incrementMembers = srcMemberDao.getAllMembers(); + log.info("人员数大于0才能进行处理"+incrementMembers.size()); + if(incrementMembers.size()>0){ +// 根据列表查询生成列表部门对象 + Map errorMap = workweixinSyncBatchMemberMap(incrementMembers); + log.info("人员异常数"+errorMap.size()); + for (Map.Entry entry : errorMap.entrySet()) { + String value = entry.getValue(); + res= res+value+";"; + } + } + + return res ; + } + + // 通过人员列表ID查询人员对象列表 + public List> memberMaptoV3xOrgMember(List> incrementMembers) { + List> orgMembers = new ArrayList<>(); + for(Map incrementMember :incrementMembers){ + if(incrementMember.get("member_id")!=null){ + String memberId = incrementMember.get("member_id").toString(); +// 此方法无法查询已经离职人员信息 + Map v3xOrgMember = srcMemberDao.getMemberById(memberId); + orgMembers.add(v3xOrgMember); + } + } + return orgMembers; + } + + // 通过最新修改时间查询变化人员数据,将变化的数据保存到企业微信中 + public String workweixinSyncBatchMember (String startDate) throws BusinessException, ApiException, ServiceException { + String res = ""; +// 根据上一次同步时间获取最新修改的单位信息 + List> incrementMembers = archiveDao.getIncrementDataByModifyDate(startDate); +// 根据列表查询生成列表部门对象 + List> orgMembers = memberMaptoV3xOrgMember(incrementMembers); + Map errorMap = workweixinSyncBatchMemberMap(orgMembers); + log.info("人员异常数"+errorMap.size()); + for (Map.Entry entry : errorMap.entrySet()) { + String value = entry.getValue(); + res= res+value+";"; + } + return res ; + } + + public Map workweixinSyncBatchMemberMap (List> list) throws ApiException, BusinessException, ServiceException { + ConfigVo configVo = this.cstConfigApi.getConfig(this.getPluginId()); + Map errorMap = new HashMap<>(); +// 获取企业微信基础数据 + String workweixinCorpid = configVo.getParamVal(SyncConstants.workweixinCorpid.name()); + String workweixinCorpsecret = configVo.getParamVal(SyncConstants.workweixinCorpsecret.name()); + String workweixinTxlCorpsecret = configVo.getParamVal(SyncConstants.workweixinTxlCorpsecret.name()); + +// 查询岗位黑名单 + List postBlackList = archiveDao.getPostBlackList(); + String postBlackString = ""; + for (String postBlack:postBlackList) { + postBlackString = postBlackString+ postBlack+ ","; + } + List postBlackStringList = Arrays.asList(postBlackString.split(",")); +// 查询人员白名单 + List memberWhiteList = archiveDao.getMemberWhiteList(); + String memberWhiteString = ""; + for (String memberWhite:memberWhiteList) { + memberWhiteString = memberWhiteString+ memberWhite+ ","; + } + List memberWhiteStringList = Arrays.asList(memberWhiteString.split(",")); + for(Map memberMap : list){ +// 遍历所有人员信息 + System.out.println( memberMap ); + if("1".equals(memberMap.get("is_enable")!=null?memberMap.get("is_enable").toString():null)){ + long departmentId = Long.parseLong(memberMap.get("org_department_id").toString()); +// 根据人员所在部门信息,查询部门对象 + V3xOrgDepartment orgDepartment = orgManager.getDepartmentById(departmentId); + if(orgDepartment==null){ + log.info(memberMap.get("name")+"查询部门为空,跳过处理"); + errorMap.put(memberMap.get("name").toString(),memberMap.get("name")+"查询部门为空,跳过处理"); + continue; + } +// 根据部门ID,查询部门主数据对象 + AddressBook departmentAddressBook = addressBookCustomerFieldInfoManager.getByMemberId(orgDepartment.getId()); +// 根据同步系统枚举字段 + if(departmentAddressBook!=null){ +// 获取部门同步系统自定义参数 + String xt = departmentAddressBook.getExtAttr31(); + if(StringUtil.isNotEmpty(xt) && !"-1".equals(xt)){ +// 获取部门同步系统数据值 + CtpEnumItem xtEnum = getEnumManagerNew().getCtpEnumItem(Long.parseLong(xt)); + String xtValue = xtEnum.getEnumvalue(); + if("1".equals(xtValue)||"3".equals(xtValue)||"5".equals(xtValue)||"6".equals(xtValue)){ +// 如果同步则检索岗位信息是否出现在黑名单 + if(memberMap.get("org_post_id")!=null){ + if(postBlackStringList.contains(memberMap.get("org_post_id").toString())){ +// 如果岗位在黑名单中则检索人员白名单 + if(memberWhiteStringList.contains(memberMap.get("id").toString())){ +// 如果人员在白名单中则设置新增逻辑 + errorMap.putAll(memberSynchronization(memberMap,true,workweixinCorpid,workweixinCorpsecret,workweixinTxlCorpsecret)); + }else{ +// 如果人员不在白名单中则设置删除逻辑 + errorMap.putAll(memberSynchronization(memberMap,false,workweixinCorpid,workweixinCorpsecret,workweixinTxlCorpsecret)); + } + }else{ +// 如果岗位不在黑名单中,设置新增逻辑。 + errorMap.putAll(memberSynchronization(memberMap,true,workweixinCorpid,workweixinCorpsecret,workweixinTxlCorpsecret)); + } + }else{ + errorMap.putAll(memberSynchronization(memberMap,false,workweixinCorpid,workweixinCorpsecret,workweixinTxlCorpsecret)); + } + }else{ +// 如果人员不在白名单中则设置删除逻辑 + errorMap.putAll(memberSynchronization(memberMap,false,workweixinCorpid,workweixinCorpsecret,workweixinTxlCorpsecret)); + } + }else{ + errorMap.putAll(memberSynchronization(memberMap,false,workweixinCorpid,workweixinCorpsecret,workweixinTxlCorpsecret)); + } + }else{ + errorMap.putAll(memberSynchronization(memberMap,false,workweixinCorpid,workweixinCorpsecret,workweixinTxlCorpsecret)); + } + }else{ + errorMap.putAll(memberSynchronization(memberMap,false,workweixinCorpid,workweixinCorpsecret,workweixinTxlCorpsecret)); + } + + } + return errorMap; + } + + public Map memberSynchronization(Map v3xOrgMember,boolean state,String corpid,String corpsecret,String txlCorpsecret) throws ApiException, ServiceException, BusinessException { + ConfigVo configVo = this.cstConfigApi.getConfig(this.getPluginId()); + FormExport formExport = new FormExport(); + Map from = new HashMap(); + from.put("同步类型", "人员"); + from.put("同步时间", sdf.format(new Date())); + from.put("同步对象", v3xOrgMember.get("name").toString()); + from.put("主要信息", v3xOrgMember.toString()); + + Map errorMap = new HashMap<>(); + Map memberMap = new HashMap<>(); + long accountId = Long.parseLong(v3xOrgMember.get("org_account_id").toString()); + Map accountBinding = syncQywxDao.getAccountBinding(accountId+""); + if(accountBinding.size()==0){ + log.info("当前修改人员所在单位不在企业微信绑定表中跳过处理"); + errorMap.put(v3xOrgMember.get("id").toString(),v3xOrgMember.get("name").toString()+"当前修改人员所在单位不在企业微信绑定表中跳过处理"); + }else{ + Map memberArchiveMap = archiveDao.getMemberArchiveById(Long.parseLong(v3xOrgMember.get("id").toString())); + if(memberArchiveMap.get("telnumber") == null){ + errorMap.put(v3xOrgMember.get("id").toString(),"当前人员未维护手机号,同步失败。"); + return errorMap; + } + String telnumber = memberArchiveMap.get("telnumber").toString(); + log.info("查询当前人员是否在企业微信绑定表中是否存在"+telnumber); +// 当前人员所在单位在企业微信绑定表中存在。 + Map memberBinding = syncQywxDao.getMemberBinding(v3xOrgMember.get("id").toString()); + v3xOrgMember.put("qywx_member_id",memberBinding.get("qywx_member_id")); + System.out.println(v3xOrgMember); + if(memberBinding.size()>0){ + if(state){ + if(telnumber.equals(memberBinding.get("qywx_member_telnumber")!=null?memberBinding.get("qywx_member_telnumber").toString():null)){ +// 手机号相同,执行修改 + log.info("当前人员在企业微信人员绑定表中存在,执行人员修改方法,修改企业微信中的人员信息,修改企业微信绑定关系"); + Map deptMap = syncQywxDao.getDepartmentBinding(v3xOrgMember.get("org_department_id").toString()); + if(deptMap!=null){ +// 根据当前人员获取当前部门,并且通过部门ID获取企业微信部门ID + memberMap.put("deptId",deptMap.get("qywx_department_id").toString()); + memberMap.put("telNumber",telnumber); + String orgPostId = v3xOrgMember.get("org_post_id").toString(); + V3xOrgPost post = orgManager.getPostById(Long.parseLong(orgPostId)); + memberMap.put("postName",post.getName()); +// 查询当前人员是否已经存在 + String qywxMember = WorkweixinProtUtil.userGet(corpid,corpsecret,v3xOrgMember.get("qywx_member_id").toString()); + JSONObject qywxMemberJson = JSONObject.parseObject(qywxMember); + String errcode = qywxMemberJson.getString("errcode"); + if("0".equals(errcode)){ +// 封装人员修改参数,执行人员修改方法 + String memberUpdate = WorkweixinProtUtil.memberUpdate(corpid,txlCorpsecret,v3xOrgMember,memberMap); + JSONObject memberUpdateJson = JSONObject.parseObject(memberUpdate); + if("0".equals(memberUpdateJson.getString("errcode"))){ + from.put("是否成功", "成功"); + from.put("同步结果","企业微信修改同步成功"); + }else{ + from.put("是否成功", "失败"); + from.put("同步结果",v3xOrgMember.get("name").toString()+memberUpdateJson.getString("errmsg")); +// 调用企业微信接口失败 + errorMap.put(v3xOrgMember.get("id").toString(),"企业微信同步人员失败:"+v3xOrgMember.get("name").toString()+memberUpdateJson.getString("errmsg")); + } + from.put("同步动作","修改"); + }else{ +// 调用工具类企业微信人员新建对象 + String memberCreate = WorkweixinProtUtil.memberCreate(corpid,txlCorpsecret,v3xOrgMember,memberMap); + JSONObject memberCreateJson = JSONObject.parseObject(memberCreate); +// 绑定关系已存在只用判断是否执行新增 + if("0".equals(memberCreateJson.getString("errcode"))){ + from.put("是否成功", "成功"); + from.put("同步结果","企业微信新增同步成功"); +// 新增人员成功,新增绑定关系数据 +// String qywxMemberId = memberCreateJson.getString("userid"); + Long userId = Long.parseLong(v3xOrgMember.get("id").toString()); + if(userId>0){ + int ii = syncQywxDao.saveMemberBinding(v3xOrgMember.get("id").toString(),v3xOrgMember.get("name").toString(),userId.toString(),v3xOrgMember.get("name").toString(),telnumber); + }else{ + userId = userId*-1; + int ii = syncQywxDao.saveMemberBinding(v3xOrgMember.get("id").toString(),v3xOrgMember.get("name").toString(),userId.toString(),v3xOrgMember.get("name").toString(),telnumber); + } + }else{ + from.put("是否成功", "失败"); + from.put("同步结果",v3xOrgMember.get("name").toString()+memberCreateJson.getString("errmsg")); +// 调用企业微信接口失败 + errorMap.put(v3xOrgMember.get("id").toString(),"企业微信添加人员失败:"+v3xOrgMember.get("name").toString()+memberCreateJson.getString("errmsg")); + } + from.put("同步动作","新增"); + } + }else{ + from.put("是否成功", "失败"); + from.put("同步结果","企业微信部门未同步成功,请先进行部门同步"); + from.put("同步动作","修改"); + } + }else{ + log.info("当前人员在企业微信人员绑定表不存在,执行人员新增方法,新增企业微信中的人员信息,新增企业微信绑定关系"); + Map deptMap = syncQywxDao.getDepartmentBinding(v3xOrgMember.get("org_department_id").toString()); + if(deptMap!=null){ +// 根据当前人员获取当前部门,并且通过部门ID获取企业微信部门ID + memberMap.put("deptId",deptMap.get("qywx_department_id").toString()); + memberMap.put("telNumber",telnumber); + String orgPostId = v3xOrgMember.get("org_post_id").toString(); + V3xOrgPost post = orgManager.getPostById(Long.parseLong(orgPostId)); + memberMap.put("postName",post.getName()); +// 调用工具类企业微信人员新建对象 + String memberCreate = WorkweixinProtUtil.memberCreate(corpid,txlCorpsecret,v3xOrgMember,memberMap); + JSONObject memberCreateJson = JSONObject.parseObject(memberCreate); + if("0".equals(memberCreateJson.getString("errcode")) ){ + from.put("是否成功", "成功"); + from.put("同步结果","企业微信新增同步成功"); +// 新增人员成功,新增绑定关系数据 +// String qywxMemberId = memberCreateJson.getString("userid"); + Long userId = Long.parseLong(v3xOrgMember.get("id").toString()); + if(userId>0){ + int ii = syncQywxDao.saveMemberBinding(v3xOrgMember.get("id").toString(),v3xOrgMember.get("name").toString(),userId.toString(),v3xOrgMember.get("name").toString(),telnumber); + }else{ + userId = userId*-1; + int ii = syncQywxDao.saveMemberBinding(v3xOrgMember.get("id").toString(),v3xOrgMember.get("name").toString(),userId.toString(),v3xOrgMember.get("name").toString(),telnumber); + } + }else{ + from.put("是否成功", "失败"); + from.put("同步结果",v3xOrgMember.get("name").toString()+memberCreateJson.getString("errmsg")); +// 调用企业微信接口失败 + errorMap.put(v3xOrgMember.get("id").toString(),"企业微信添加人员失败:"+v3xOrgMember.get("name").toString()+memberCreateJson.getString("errmsg")); + } + from.put("同步动作","新增"); + }else{ + from.put("是否成功", "失败"); + from.put("同步结果","企业微信部门未同步成功,请先进行部门同步"); + from.put("同步动作","新增"); + } + } + }else{ + log.info(v3xOrgMember.toString()+"当前人员在企业微信人员绑定表中存在,当前人员已经停用执行删除操作"); +// 当前人员已经停用执行人员删除方法 + String memberDelete =WorkweixinProtUtil.memberDelete(corpid,txlCorpsecret,memberBinding.get("qywx_member_id").toString()); + JSONObject memberDeleteJson = JSONObject.parseObject(memberDelete); + if("0".equals(memberDeleteJson.getString("errcode"))){ + from.put("是否成功", "成功"); + from.put("同步结果","企业微信删除同步成功"); + }else{ + from.put("是否成功", "失败"); + from.put("同步结果",v3xOrgMember.get("name").toString()+memberDeleteJson.getString("errmsg")); +// 调用企业微信接口失败 + errorMap.put(v3xOrgMember.get("id").toString(),"企业微信人员同步失败"+v3xOrgMember.get("name").toString()+memberDeleteJson.getString("errmsg")); + } + int ii = syncQywxDao.deleteMemberBinding(v3xOrgMember.get("id").toString()); + from.put("同步动作","删除"); + } + }else{ + if(state){ + log.info("当前人员在企业微信人员绑定表不存在,执行人员新增方法,新增企业微信中的人员信息,新增企业微信绑定关系"); + Map deptMap = syncQywxDao.getDepartmentBinding(v3xOrgMember.get("org_department_id").toString()); +// if(deptMap!=null){} +// 根据当前人员获取当前部门,并且通过部门ID获取企业微信部门ID + memberMap.put("deptId",deptMap.get("qywx_department_id").toString()); + memberMap.put("telNumber",telnumber); + log.info("当前人员所在部门对应企业微信的部门ID"+deptMap); +// 调用工具类企业微信人员新建对象 +// OapiV2UserCreateRequest req = DingdingProtUtil.getMemberCreateParam(v3xOrgMember,memberMap); + String memberCreate = WorkweixinProtUtil.memberCreate(corpid,txlCorpsecret,v3xOrgMember,memberMap); +// String memberCreate = DingdingProtUtil.memberCreate(req,accessToken); + JSONObject memberCreateJson = JSONObject.parseObject(memberCreate); + if("0".equals(memberCreateJson.getString("errcode")) ){ + from.put("是否成功", "成功"); + from.put("同步结果","企业微信新增同步成功"); +// 新增人员成功,新增绑定关系数据 +// String qywxMemberId = memberCreateJson.getString("userid"); + Long userId = Long.parseLong(v3xOrgMember.get("id").toString()); + if(userId>0){ + int ii = syncQywxDao.saveMemberBinding(v3xOrgMember.get("id").toString(),v3xOrgMember.get("name").toString(),userId.toString(),v3xOrgMember.get("name").toString(),telnumber); + }else{ + userId = userId*-1; + int ii = syncQywxDao.saveMemberBinding(v3xOrgMember.get("id").toString(),v3xOrgMember.get("name").toString(),userId.toString(),v3xOrgMember.get("name").toString(),telnumber); + } + }else{ + from.put("是否成功", "失败"); + from.put("同步结果",v3xOrgMember.get("name").toString()+memberCreateJson.getString("errmsg")); +// 调用企业微信接口失败 + errorMap.put(v3xOrgMember.get("id").toString(),"企业微信同步人员失败:"+v3xOrgMember.get("name").toString()+memberCreateJson.getString("errmsg")); + } + from.put("同步动作","新增"); + }else{ + log.info(state+"-"+memberBinding+v3xOrgMember); + } + } + } + List valueExports = formExportUtil.setFormValue(from); + formExport.setValues(valueExports); + if(StringUtil.isNotEmpty(from.get("同步动作"))){ + formFactory.importBusinessFormData(configVo.getParamVal(SyncConstants.workweixinLogloginName.name()), + configVo.getParamVal(SyncConstants.workweixinLog.name()), + formExport, new String[] {}); + } + return errorMap; + } + + public String workweixinSyncAllServiceBrokers() throws BusinessException, ApiException, ServiceException { + String res = ""; +// 根据上一次同步时间获取最新修改的单位信息 + List> serviceBrokers = archiveDao.getServiceBrokers(); +// 根据列表查询生成列表部门对象 + Map errorMap = workweixinSyncServiceBroker(serviceBrokers); + log.info("业代异常数"+errorMap.size()); + for (Map.Entry entry : errorMap.entrySet()) { + String value = entry.getValue(); + res= res+value+";"; + } + return res ; + } + + // 企业微信业代人员同步 + public Map workweixinSyncServiceBroker (List> list) throws ApiException, BusinessException, ServiceException { + ConfigVo configVo = this.cstConfigApi.getConfig(this.getPluginId()); + Map errorMap = new HashMap<>(); +// 获取企业微信基础数据 + String workweixinCorpid = configVo.getParamVal(SyncConstants.workweixinCorpid.name()); + String workweixinCorpsecret = configVo.getParamVal(SyncConstants.workweixinCorpsecret.name()); + String workweixinTxlCorpsecret = configVo.getParamVal(SyncConstants.workweixinTxlCorpsecret.name()); + +// 查询岗位黑名单 + List postBlackList = archiveDao.getPostBlackList(); + String postBlackString = ""; + for (String postBlack:postBlackList) { + postBlackString =postBlackString+ postBlack+ ","; + } + List postBlackStringList = Arrays.asList(postBlackString.split(",")); +// 查询人员白名单 + List memberWhiteList = archiveDao.getMemberWhiteList(); + String memberWhiteString = ""; + for (String memberWhite:memberWhiteList) { + memberWhiteString = memberWhiteString+ memberWhite+ ","; + } + List memberWhiteStringList = Arrays.asList(memberWhiteString.split(",")); + for(int i = 0 ; i < list.size() ; i++){ +// 遍历所有人员信息 + Map serviceBroker = list.get(i); + String memberState = serviceBroker.get("state")!=null?serviceBroker.get("state").toString():""; + boolean isenum = false; + if(StringUtil.isNotEmpty(memberState)){ + CtpEnumItem memberStateItem = enumManagerNew.getCtpEnumItem(Long.parseLong(memberState)); + if(memberStateItem.getShowvalue().equals("在职")||memberStateItem.getShowvalue().equals("试用")||memberStateItem.getShowvalue().equals("待岗")){ + isenum = true; + } + } + if(isenum){ + long departmentId; + if(serviceBroker.get("dept_id")!=null){ + serviceBroker.put("org_department_id",serviceBroker.get("dept_id")); + departmentId = Long.parseLong(serviceBroker.get("dept_id").toString()); + V3xOrgDepartment orgDepartment = orgManager.getDepartmentById(departmentId); + if(orgDepartment==null){ + log.info(serviceBroker.get("name")+"查询部门为空,跳过处理"); + errorMap.put(serviceBroker.get("id")+"",serviceBroker.get("name")+"查询部门为空,跳过处理"); + continue; + } + serviceBroker.put("org_account_id","-9194677677107822293");//设置固定值营销门户ID +// 根据部门ID,查询部门主数据对象 + AddressBook departmentAddressBook = addressBookCustomerFieldInfoManager.getByMemberId(orgDepartment.getId()); +// 根据同步系统枚举字段 + if(departmentAddressBook!=null){ +// 获取部门同步系统自定义参数 + String xt = departmentAddressBook.getExtAttr31(); + if(StringUtil.isNotEmpty(xt) && !"-1".equals(xt)){ +// 获取部门同步系统数据值 + CtpEnumItem xtEnum = getEnumManagerNew().getCtpEnumItem(Long.parseLong(xt)); + String xtValue = xtEnum.getEnumvalue(); + if("1".equals(xtValue)||"3".equals(xtValue)||"5".equals(xtValue)||"6".equals(xtValue)){ + // 如果同步则检索岗位信息是否出现在黑名单 + if(postBlackStringList.contains(serviceBroker.get("post_id"))){ + errorMap.putAll(serviceBrokerSynchronization(serviceBroker,false,workweixinCorpid,workweixinCorpsecret,workweixinTxlCorpsecret)); + }else{ +// 如果岗位不在黑名单中,设置新增逻辑。 + errorMap.putAll(serviceBrokerSynchronization(serviceBroker,true,workweixinCorpid,workweixinCorpsecret,workweixinTxlCorpsecret)); + } + }else{ +// 如果人员不在白名单中则设置删除逻辑 + errorMap.putAll(serviceBrokerSynchronization(serviceBroker,false,workweixinCorpid,workweixinCorpsecret,workweixinTxlCorpsecret)); + } + }else{ + errorMap.putAll(serviceBrokerSynchronization(serviceBroker,false,workweixinCorpid,workweixinCorpsecret,workweixinTxlCorpsecret)); + } + }else{ + errorMap.putAll(serviceBrokerSynchronization(serviceBroker,false,workweixinCorpid,workweixinCorpsecret,workweixinTxlCorpsecret)); + } + }else{ + log.info("当前人员档案中所属部门为空跳过处理"+serviceBroker.get("name")); + } + }else{ + errorMap.putAll(serviceBrokerSynchronization(serviceBroker,false,workweixinCorpid,workweixinCorpsecret,workweixinTxlCorpsecret)); + } + } + + return errorMap; + } + + public String workweixinSyncServiceBroker(String startDate) throws BusinessException, ApiException, ServiceException { + String res = ""; +// 根据上一次同步时间获取最新修改的单位信息 + List> serviceBrokers = archiveDao.getServiceBrokers(startDate); +// 根据列表查询生成列表部门对象 + Map errorMap = workweixinSyncServiceBroker(serviceBrokers); + log.info("业代异常数"+errorMap.size()); + for (Map.Entry entry : errorMap.entrySet()) { + String value = entry.getValue(); + res= res+value+";"; + } + return res ; + } + + public Map serviceBrokerSynchronization (Map serviceBroker ,boolean state,String corpid,String corpsecret,String txlCorpsecret) throws ApiException, ServiceException, BusinessException { + ConfigVo configVo = this.cstConfigApi.getConfig(this.getPluginId()); + FormExport formExport = new FormExport(); + Map from = new HashMap(); + from.put("同步类型", "业代/客户人员"); + from.put("同步时间", sdf.format(new Date())); + from.put("同步对象", serviceBroker.get("name").toString()); + from.put("主要信息", serviceBroker.toString()); + + Map errorMap = new HashMap<>(); + Map memberMap = new HashMap<>(); + if(serviceBroker.get("org_account_id")!=null){ + Map accountBinding = syncQywxDao.getAccountBinding(serviceBroker.get("org_account_id").toString()); + if(accountBinding.size()==0){ + log.info("当前修改人员所在单位不在企业微信绑定表中跳过处理"); + errorMap.put(serviceBroker.get("id")+"",serviceBroker.get("name")+"当前修改人员所在单位不在企业微信绑定表中跳过处理"); + }else{ + if(serviceBroker.get("telnumber") == null){ + errorMap.put(serviceBroker.get("id")+"",serviceBroker.get("name")+"当前人员未维护手机号,同步失败。"); + return errorMap; + } + String telnumber = serviceBroker.get("telnumber").toString(); + log.info("查询当前人员是否在企业微信绑定表中是否存在"); +// 当前人员所在单位在企业微信绑定表中存在。 + Map memberBinding = syncQywxDao.getMemberBinding(serviceBroker.get("id")+""); + serviceBroker.put("qywx_member_id",memberBinding.get("qywx_member_id")); + System.out.println("memberBinding.size():"+memberBinding.size()); + if(memberBinding.size()>0){ + if(state){ + if(telnumber.equals(memberBinding.get("qywx_member_telnumber")!=null?memberBinding.get("qywx_member_telnumber").toString():null)){ +// 手机号相同,执行修改 + log.info("当前人员在企业微信人员绑定表中存在,执行人员修改方法,修改企业微信中的人员信息,修改企业微信绑定关系"); + Map deptMap = syncQywxDao.getDepartmentBinding(serviceBroker.get("org_department_id").toString()); + if(deptMap!=null){ +// 首先查询一下当前人员在企业微信中存在如果存在则执行修改方法,如果不存在则执行新增方法 + String qywxMember = WorkweixinProtUtil.userGet(corpid,corpsecret,serviceBroker.get("qywx_member_id").toString()); +// String qywxMember = DingdingProtUtil.userGet(serviceBroker.4get("qywx_member_id")+"",accessToken); + JSONObject qywxMemberJson = JSONObject.parseObject(qywxMember); + String errcode = qywxMemberJson.getString("errcode"); +// 根据当前人员获取当前部门,并且通过部门ID获取企业微信部门ID + memberMap.put("deptId",deptMap.get("qywx_department_id").toString()); + memberMap.put("telNumber",telnumber); + V3xOrgPost v3xOrgPost = orgManager.getPostById(Long.parseLong(serviceBroker.get("post_id").toString())); + memberMap.put("postName",v3xOrgPost.getName()); + if("0".equals(errcode)){ +// 封装人员修改参数,执行人员修改方法 +// OapiV2UserUpdateRequest req = DingdingProtUtil.getMemberUpdateParam(serviceBroker,memberMap); + String memberUpdate = WorkweixinProtUtil.memberUpdate(corpid,txlCorpsecret,serviceBroker,memberMap); +// String memberUpdate = DingdingProtUtil.memberUpdate(req,accessToken); + JSONObject memberUpdateJson = JSONObject.parseObject(memberUpdate); + if("0".equals(memberUpdateJson.getString("errcode"))){ + from.put("是否成功", "成功"); + from.put("同步结果","企业微信修改同步成功"); + }else{ + from.put("是否成功", "失败"); + from.put("同步结果",serviceBroker.get("name").toString()+memberUpdateJson.getString("errmsg")); +// 调用企业微信接口失败 + errorMap.put(serviceBroker.get("id")+"","企业微信同步人员失败:"+serviceBroker.get("name").toString()+memberUpdateJson.getString("errmsg")); + } + from.put("同步动作","修改"); + }else{ +// 调用工具类企业微信人员新建对象 + String memberCreate = WorkweixinProtUtil.memberCreate(corpid,txlCorpsecret,serviceBroker,memberMap); + JSONObject memberCreateJson = JSONObject.parseObject(memberCreate); + if("0".equals(memberCreateJson.getString("errcode")) ){ + from.put("是否成功", "成功"); + from.put("同步结果","企业微信新增同步成功"); +// String qywxMemberId = memberCreateJson.getString("userid"); + Long userId = Long.parseLong(serviceBroker.get("id").toString()); + if(userId>0){ + int ii = syncQywxDao.saveMemberBinding(serviceBroker.get("id").toString(),serviceBroker.get("name").toString(),userId.toString(),serviceBroker.get("name").toString(),telnumber); + }else{ + userId = userId*-1; + int ii = syncQywxDao.saveMemberBinding(serviceBroker.get("id").toString(),serviceBroker.get("name").toString(),userId.toString(),serviceBroker.get("name").toString(),telnumber); + } +// String quwxMemberId = memberCreateJson.getString("userid"); +// int ii = syncQywxDao.saveMemberBinding(serviceBroker.get("id")+"",serviceBroker.get("name").toString(),quwxMemberId,serviceBroker.get("name").toString(),telnumber); + }else{ + from.put("是否成功", "失败"); + from.put("同步结果",serviceBroker.get("name")+memberCreateJson.getString("errmsg")); +// 调用企业微信接口失败 + errorMap.put(serviceBroker.get("id")+"","企业微信同步人员失败:"+serviceBroker.get("name")+memberCreateJson.getString("errmsg")); + } + from.put("同步动作","新增"); + } + }else{ + from.put("是否成功", "失败"); + from.put("同步结果","企业微信部门未同步成功,请先进行部门同步"); + from.put("同步动作","修改"); + } + }else{ + log.info("当前人员在企业微信人员绑定表不存在,执行人员新增方法,新增企业微信中的人员信息,新增企业微信绑定关系"); + Map deptMap = syncQywxDao.getDepartmentBinding(serviceBroker.get("org_department_id")+""); + if(deptMap!=null){ +// 根据当前人员获取当前部门,并且通过部门ID获取企业微信部门ID + memberMap.put("deptId",deptMap.get("qywx_department_id").toString()); + memberMap.put("telNumber",telnumber); + V3xOrgPost v3xOrgPost = orgManager.getPostById(Long.parseLong(serviceBroker.get("post_id").toString())); + memberMap.put("postName",v3xOrgPost.getName()); +// 调用工具类企业微信人员新建对象 +// OapiV2UserCreateRequest req = DingdingProtUtil.getMemberCreateParam(serviceBroker,memberMap); + String memberCreate = WorkweixinProtUtil.memberCreate(corpid,txlCorpsecret,serviceBroker,memberMap); +// String memberCreate = DingdingProtUtil.memberCreate(req,accessToken); + JSONObject memberCreateJson = JSONObject.parseObject(memberCreate); + if("0".equals(memberCreateJson.getString("errcode")) ){ + from.put("是否成功", "成功"); + from.put("同步结果","企业微信新增同步成功"); +// 新增人员成功,新增绑定关系数据 +// String qywxMemberId = memberCreateJson.getString("userid"); + Long userId = Long.parseLong(serviceBroker.get("id").toString()); + if(userId>0){ + int ii = syncQywxDao.saveMemberBinding(serviceBroker.get("id").toString(),serviceBroker.get("name").toString(),userId.toString(),serviceBroker.get("name").toString(),telnumber); + }else{ + userId = userId*-1; + int ii = syncQywxDao.saveMemberBinding(serviceBroker.get("id").toString(),serviceBroker.get("name").toString(),userId.toString(),serviceBroker.get("name").toString(),telnumber); + } +// String quwxMemberId = memberCreateJson.getString("userid"); +// int ii = syncQywxDao.saveMemberBinding(serviceBroker.get("id")+"",serviceBroker.get("name").toString(),quwxMemberId,serviceBroker.get("name").toString(),telnumber); + }else{ + from.put("是否成功", "失败"); + from.put("同步结果",serviceBroker.get("name")+memberCreateJson.getString("errmsg")); +// 调用企业微信接口失败 + errorMap.put(serviceBroker.get("id")+"","企业微信同步人员失败:"+serviceBroker.get("name")+memberCreateJson.getString("errmsg")); + } + from.put("同步动作","新增"); + }else{ + from.put("是否成功", "失败"); + from.put("同步结果","企业微信部门未同步成功,请先进行部门同步"); + from.put("同步动作","新增"); + } + } + }else{ + log.info(serviceBroker.toString()+"当前人员在企业微信人员绑定表中存在,当前人员已经停用执行删除造作"); +// 当前人员已经停用执行人员删除方法 + String memberDelete = WorkweixinProtUtil.memberDelete(corpid,txlCorpsecret,memberBinding.get("qywx_member_id").toString()); + JSONObject memberDeleteJson = JSONObject.parseObject(memberDelete); + if("0".equals(memberDeleteJson.getString("errcode"))){ + from.put("是否成功", "成功"); + from.put("同步结果","企业微信删除同步成功"); + int ii = syncQywxDao.deleteMemberBinding(serviceBroker.get("id")+""); + }else{ + from.put("是否成功", "失败"); + from.put("同步结果",serviceBroker.get("name")+memberDeleteJson.getString("errmsg")); + int ii = syncQywxDao.deleteMemberBinding(serviceBroker.get("id")+""); +// 调用企业微信接口失败 + errorMap.put(serviceBroker.get("id")+"","企业微信人员同步失败"+serviceBroker.get("name")+memberDeleteJson.getString("errmsg")); + } + from.put("同步动作","删除"); + } + }else{ + if(state){ + log.info("当前人员在企业微信人员绑定表不存在,执行人员新增方法,新增企业微信中的人员信息,新增企业微信绑定关系"); + Map deptMap = syncQywxDao.getDepartmentBinding(serviceBroker.get("org_department_id")+""); + if(deptMap!=null){ +// 根据当前人员获取当前部门,并且通过部门ID获取企业微信部门ID + if(deptMap.size()==0){ + log.info(serviceBroker.get("name").toString()+"当前人员所在部门在绑定表不存在,跳过同步处理"); + from.put("是否成功", "失败"); + from.put("同步结果",serviceBroker.get("name").toString()+"当前人员所在部门在绑定表不存在,跳过同步处理"); + }else{ + memberMap.put("deptId",deptMap.get("qywx_department_id").toString()); + memberMap.put("telNumber",telnumber); + log.info("serviceBroker:"+serviceBroker); + if(serviceBroker.get("post_id")==null){ + memberMap.put("postName",""); + }else{ + V3xOrgPost v3xOrgPost = orgManager.getPostById(Long.parseLong(serviceBroker.get("post_id").toString())); + memberMap.put("postName",v3xOrgPost.getName()); + } +// 调用工具类企业微信人员新建对象 +// OapiV2UserCreateRequest req = DingdingProtUtil.getMemberCreateParam(serviceBroker,memberMap); + String memberCreate = WorkweixinProtUtil.memberCreate(corpid,txlCorpsecret,serviceBroker,memberMap); +// String memberCreate = DingdingProtUtil.memberCreate(req,accessToken); + JSONObject memberCreateJson = JSONObject.parseObject(memberCreate); + if("0".equals(memberCreateJson.getString("errcode")) ){ + from.put("是否成功", "成功"); + from.put("同步结果","企业微信新增同步成功"); +// 新增人员成功,新增绑定关系数据 +// String qywxMemberId = memberCreateJson.getString("userid"); + Long userId = Long.parseLong(serviceBroker.get("id").toString()); + if(userId>0){ + int ii = syncQywxDao.saveMemberBinding(serviceBroker.get("id").toString(),serviceBroker.get("name").toString(),userId.toString(),serviceBroker.get("name").toString(),telnumber); + }else{ + userId = userId*-1; + int ii = syncQywxDao.saveMemberBinding(serviceBroker.get("id").toString(),serviceBroker.get("name").toString(),userId.toString(),serviceBroker.get("name").toString(),telnumber); + } +// String qywxMemberId = memberCreateJson.getString("userid"); +// int ii = syncQywxDao.saveMemberBinding(serviceBroker.get("id")+"",serviceBroker.get("name").toString(),qywxMemberId,serviceBroker.get("name").toString(),telnumber); + }else{ + from.put("是否成功", "成功"); + from.put("同步结果",serviceBroker.get("name")+memberCreateJson.getString("errmsg")); +// 调用企业微信接口失败 + errorMap.put(serviceBroker.get("id")+"","企业微信同步人员失败:"+serviceBroker.get("name")+memberCreateJson.getString("errmsg")); + } + from.put("同步动作","新增"); + } + }else{ + from.put("是否成功", "失败"); + from.put("同步结果","企业微信部门未同步成功,请先进行部门同步"); + from.put("同步动作","新增"); + } + }else{ + log.info(state+""+memberBinding+serviceBroker); + } + } + } + }else{ + log.info(serviceBroker.get("name")+"所在单位为空不进行同步"); + errorMap.put(serviceBroker.get("id").toString(),serviceBroker.get("name")+"所在单位为空不进行同步"); + } + List valueExports = formExportUtil.setFormValue(from); + formExport.setValues(valueExports); + if(StringUtil.isNotEmpty(from.get("同步动作"))){ + formFactory.importBusinessFormData(configVo.getParamVal(SyncConstants.workweixinLogloginName.name()), + configVo.getParamVal(SyncConstants.workweixinLog.name()), + formExport, new String[] {}); + } + return errorMap; + } + + public String workweixinSyncAllClientMembers() throws BusinessException, ApiException, ServiceException { + String res = ""; +// 根据上一次同步时间获取最新修改的单位信息 + List> incrementMembers = srcMemberDao.getAllClientMembers(); +// 根据列表查询生成列表部门对象 + Map errorMap = workweixinSyncBatchClientMemberMap(incrementMembers); + log.info("客户异常数"+errorMap.size()); + for (Map.Entry entry : errorMap.entrySet()) { + String value = entry.getValue(); + res= res+value+";"; + } + return res ; + } + + public String workweixinSyncBatchClientMember(String startDate) throws BusinessException, ApiException, ServiceException { + String res = ""; +// 根据上一次同步时间获取最新修改的单位信息 + List> incrementMembers = archiveDao.getClientMembersByModifyDate(startDate); +// 根据列表查询生成列表部门对象 + Map errorMap = workweixinSyncBatchClientMemberMap(incrementMembers); + log.info("客户异常数"+errorMap.size()); + for (Map.Entry entry : errorMap.entrySet()) { + String value = entry.getValue(); + res= res+value+";"; + } + return res ; + } + + public Map workweixinSyncBatchClientMemberMap (List> list) throws ApiException, BusinessException, ServiceException { + Map errorMap = new HashMap<>(); + ConfigVo configVo = this.cstConfigApi.getConfig(this.getPluginId()); +// 获取企业微信基础数据 + String workweixinCorpid = configVo.getParamVal(SyncConstants.workweixinCorpid.name()); + String workweixinCorpsecret = configVo.getParamVal(SyncConstants.workweixinCorpsecret.name()); + String workweixinTxlCorpsecret = configVo.getParamVal(SyncConstants.workweixinTxlCorpsecret.name()); + +// 查询岗位黑名单 + List postBlackList = archiveDao.getPostBlackList(); + String postBlackString = ""; + for (String postBlack:postBlackList) { + postBlackString = postBlackString+ postBlack+ ","; + } + List postBlackStringList = Arrays.asList(postBlackString.split(",")); +// 查询人员白名单 + List memberWhiteList = archiveDao.getMemberWhiteList(); + String memberWhiteString = ""; + for (String memberWhite:memberWhiteList) { + memberWhiteString = memberWhiteString+ memberWhite+ ","; + } + List memberWhiteStringList = Arrays.asList(memberWhiteString.split(",")); + + for(Map memberMap: list){ +// 客户所在单位默认带入营销门户单位 + memberMap.put("org_account_id","-9194677677107822293"); + log.info( memberMap.toString() ); +// 根据当前人员获取人员档案表中的部门信息 + Map memberArchive = archiveDao.getMemberArchiveById(Long.parseLong(memberMap.get("id").toString())); + if(memberArchive.get("area_dept")==null) { + log.info(memberMap.get("name") + ":当前人员档案表中所属区域为空跳过同步"); + }else{ + V3xOrgDepartment orgDepartment = orgManager.getDepartmentById(Long.parseLong(memberArchive.get("area_dept").toString())); + if(orgDepartment==null){ + log.info(memberMap.get("name")+"查询部门为空,跳过处理"); + errorMap.put(memberMap.get("id").toString(),memberMap.get("name")+"查询部门为空,跳过处理"); + continue; + } + memberMap.put("org_department_id",memberArchive.get("area_dept")); + memberMap.putAll(memberArchive); +// 根据部门ID,查询部门主数据对象 + AddressBook departmentAddressBook = addressBookCustomerFieldInfoManager.getByMemberId(orgDepartment.getId()); +// 查询部门信息中的同步系统是否选择有企业微信 + if(departmentAddressBook!=null){ +// 获取部门同步系统自定义参数 + String xt = departmentAddressBook.getExtAttr31(); + if(StringUtil.isNotEmpty(xt) && !"-1".equals(xt)){ +// 获取部门同步系统数据值 + CtpEnumItem xtEnum = getEnumManagerNew().getCtpEnumItem(Long.parseLong(xt)); + String xtValue = xtEnum.getEnumvalue(); + if("1".equals(xtValue)||"3".equals(xtValue)||"5".equals(xtValue)||"6".equals(xtValue)){ +// 如果同步则检索岗位信息是否出现在黑名单 + if(postBlackStringList.contains(memberMap.get("org_post_id"))){ +// 判断是否在人员白名单中存在 + if(memberWhiteStringList.contains(memberMap.get("id"))){ +// 存在人员白名单,执行人员新增方法 + errorMap.putAll(serviceBrokerSynchronization(memberMap,true,workweixinCorpid,workweixinCorpsecret,workweixinTxlCorpsecret)); + }else{ + errorMap.putAll(serviceBrokerSynchronization(memberMap,false,workweixinCorpid,workweixinCorpsecret,workweixinTxlCorpsecret)); + } + }else{ +// 如果岗位不在黑名单中,设置新增逻辑。 + errorMap.putAll(serviceBrokerSynchronization(memberMap,true,workweixinCorpid,workweixinCorpsecret,workweixinTxlCorpsecret)); + } + }else{ +// 如果人员不在白名单中则设置删除逻辑 + errorMap.putAll(serviceBrokerSynchronization(memberMap,false,workweixinCorpid,workweixinCorpsecret,workweixinTxlCorpsecret)); + } + }else{ + errorMap.putAll(serviceBrokerSynchronization(memberMap,false,workweixinCorpid,workweixinCorpsecret,workweixinTxlCorpsecret)); + } + }else{ + errorMap.putAll(serviceBrokerSynchronization(memberMap,false,workweixinCorpid,workweixinCorpsecret,workweixinTxlCorpsecret)); + } + } + } + return errorMap; + } + +} diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/servlet/WorkWeixinbindingServlet.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/servlet/WorkWeixinbindingServlet.java new file mode 100644 index 0000000..1743391 --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/servlet/WorkWeixinbindingServlet.java @@ -0,0 +1,70 @@ +package com.seeyon.apps.src_mainorganization.servlet; + +import com.qq.weixin.mp.aes.AesException; +import com.qq.weixin.mp.aes.WXBizJsonMsgCrypt; +import com.seeyon.apps.common.config.ICstConfigApi; +import com.seeyon.apps.common.plugin.vo.ConfigVo; +import com.seeyon.apps.src_mainorganization.constans.SyncConstants; +import com.seeyon.ctp.common.AppContext; + +import javax.inject.Inject; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class WorkWeixinbindingServlet extends HttpServlet { + + private String token = "rtfmfptSSM64EEedffcWcnvw6zukb9lG"; +// private String corpId = "ww69c49385cee3746c"; + private String corpId = "ww26d46dab95703763"; + + private String encodingAESKey = "cuDqCFGORfqjdPx3Yn9D11AAmijNh7Lpq2SdLQcvQkr"; + + public String getPluginId() { + return SyncConstants.getPluginId(); + } + + public void doGet(HttpServletRequest request, HttpServletResponse response)throws IOException { + ServletOutputStream servletout = response.getOutputStream(); + String msgSignature = request.getParameter("msg_signature"); + System.out.println(msgSignature); + String timestamp = request.getParameter("timestamp"); + System.out.println(timestamp); + String nonce = request.getParameter("nonce"); + System.out.println(nonce); + String echostr = request.getParameter("echostr"); + System.out.println(echostr); + try { + WXBizJsonMsgCrypt wxcpt = new WXBizJsonMsgCrypt(token, encodingAESKey, corpId); + + String str2 = wxcpt.VerifyURL(msgSignature,timestamp,nonce,echostr); + System.out.println(str2); + byte[] buf = str2.getBytes("UTF-8"); + servletout.write(buf); + servletout.flush(); + servletout.close(); +// String str1 = wxcpt.DecryptMsg(msgSignature,timestamp,nonce,""); +// System.out.println(str1); + } catch (AesException e) { + e.printStackTrace(); + } + + + } + + + public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException{ + doGet(request,response); + } + + + public void init() throws ServletException { } + + public void destroy() { + super.destroy(); + } + +} diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/util/ProtUtil.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/util/ProtUtil.java index f84e2aa..84fd6fa 100644 --- a/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/util/ProtUtil.java +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/util/ProtUtil.java @@ -2,6 +2,7 @@ package com.seeyon.apps.src_mainorganization.util; import cn.hutool.log.Log; import com.alibaba.fastjson.JSONObject; +import com.dingtalk.api.request.OapiV2UserCreateRequest; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; @@ -19,8 +20,7 @@ import java.io.*; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; -import java.util.HashMap; -import java.util.Map; +import java.util.*; public class ProtUtil { private static Log log = Log.get(ProtUtil.class); @@ -291,5 +291,4 @@ public class ProtUtil { return content; } - } diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/util/WorkweixinProtUtil.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/util/WorkweixinProtUtil.java new file mode 100644 index 0000000..22303c5 --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_mainorganization/util/WorkweixinProtUtil.java @@ -0,0 +1,179 @@ +package com.seeyon.apps.src_mainorganization.util; + +import cn.hutool.log.Log; +import com.alibaba.fastjson.JSONObject; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.util.EntityUtils; + +import java.util.*; + +public class WorkweixinProtUtil { + private static Log log = Log.get(WorkweixinProtUtil.class); + + /** + * 调用get接口 + * @param strUrl 需要调用的url对应的配置文件的key + * @return + */ + public static String doGet( String strUrl) { + return ProtUtil.doGet(strUrl , new HashMap<>()); + } + + /** + * 调用post接口 + * @param str 调用接口传递的参数json + * @param urlStr 需要调用的url对应的参数文件中的编码 + * @return + */ + public static String doPost(String str, String urlStr) { + return ProtUtil.doPost(str,urlStr ,new HashMap<>()); + } + + // 获取企业微信token验证信息 + public static String getAccessToken(String corpid,String corpsecret) throws RuntimeException { + StringBuilder address = new StringBuilder("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=") + .append(corpid).append("&corpsecret=").append(corpsecret); + DefaultHttpClient client = new DefaultHttpClient(); + String result = ""; + HttpGet get = new HttpGet(address.toString()); + String accessToken = ""; + try { + HttpResponse res = client.execute(get); + if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + result = EntityUtils.toString(res.getEntity()); + JSONObject resultJSON = JSONObject.parseObject(result); + accessToken = resultJSON.getString("access_token"); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + return accessToken; + } + + // 调用企业微信部门新增接口 + public static String departmentCreate(String corpid,String corpsecret,JSONObject req) { + String accessToken = getAccessToken(corpid,corpsecret); + String rsp = doPost(req.toString(),"https://qyapi.weixin.qq.com/cgi-bin/department/create?access_token="+accessToken); + System.out.println("创建部门:"+rsp); + return rsp; + } + + // 调用企业微信部门修改接口 + public static String departmentUpdate(String corpid,String corpsecret,JSONObject req) { + String accessToken = getAccessToken(corpid,corpsecret); + String rsp = doPost(req.toString(),"https://qyapi.weixin.qq.com/cgi-bin/department/update?access_token="+accessToken); + System.out.println("修改部门:"+rsp); + return rsp; + } + + // 调用企业微信部门删除接口 + public static String departmentDelete(String corpid,String corpsecret,String deptId) { + String accessToken = getAccessToken(corpid,corpsecret); + String rsp = doGet("https://qyapi.weixin.qq.com/cgi-bin/department/delete?access_token="+accessToken+"&id="+deptId); + System.out.println("删除部门"+rsp); + return rsp; + } + + // 调用企业微信人员新增接口 + public static String memberCreate(String corpid,String corpsecret,Map serviceBroker, Map memberMap) { + JSONObject req = new JSONObject(); +// 企业微信人员ID + long l = Long.parseLong(serviceBroker.get("id").toString()); + if(l>0){ + req.put("userid",serviceBroker.get("id")); + }else{ + req.put("userid",l*-1); + } +// 人员名称 + req.put("name",serviceBroker.get("name")); +// 人员手机号,企业微信内唯一值 + req.put("mobile",memberMap.get("telNumber")); +// 职位 + req.put("position",memberMap.get("postName")); +// 所属部门ID + List departments = new ArrayList<>(); + departments.add(Long.parseLong(memberMap.get("deptId"))); + req.put("department",departments); + log.info("请求参数为:"+req.toString()); + String accessToken = getAccessToken(corpid,corpsecret); + String rsp = doPost(req.toString(),"https://qyapi.weixin.qq.com/cgi-bin/user/create?access_token="+accessToken); + System.out.println("新增人员:"+rsp); + return rsp; + } + + // 调用企业微信人员修改接口 + public static String memberUpdate(String corpid,String corpsecret,Map serviceBroker, Map memberMap) { + JSONObject req = new JSONObject(); +// 企业微信用户ID + req.put("userid",serviceBroker.get("qywx_member_id")); +// 人员名称 + req.put("name",serviceBroker.get("name")); +// 职位 + req.put("position",memberMap.get("postName")); + List departments = new ArrayList<>(); + departments.add(Long.parseLong(memberMap.get("deptId"))); + req.put("department",departments); + + String accessToken = getAccessToken(corpid,corpsecret); + String rsp = doPost(req.toString(),"https://qyapi.weixin.qq.com/cgi-bin/user/update?access_token="+accessToken); + System.out.println("修改人员:"+rsp); + return rsp; + } + + // 调用企业微信人员删除接口,根据企业微信人员ID删除人员 + public static String memberDelete(String corpid,String corpsecret,String userId ){ + String accessToken = getAccessToken(corpid,corpsecret); + String rsp = doGet("https://qyapi.weixin.qq.com/cgi-bin/user/delete?access_token="+accessToken+"&id="+userId); + System.out.println("删除人员:"+rsp); + return rsp; + } + + + // 调用企业微信接口获取部门下级部门ID + public static String departmentListsubid(String corpid,String corpsecret,long parentId){ + String accessToken = getAccessToken(corpid,corpsecret); + String rsp = doGet("https://qyapi.weixin.qq.com/cgi-bin/department/simplelist?access_token="+accessToken+"&id="+parentId); + System.out.println("查询下级部门"+rsp); + return rsp; + } + + + //调用企业微信接口,根据企业微信部门ID获取部门信息 + public static String departmentGet(String corpid,String corpsecret,long parentId) { + String accessToken = getAccessToken(corpid,corpsecret); + String rsp = doGet("https://qyapi.weixin.qq.com/cgi-bin/department/get?access_token="+accessToken+"&id="+parentId); + System.out.println("查询部门对应信息"+rsp); + return rsp; + } + + // 调用企业微信接口,根据企业微信部门ID获取部门下所有人员 + public static String userListId(String corpid,String corpsecret) { + String accessToken = getAccessToken(corpid,corpsecret); + JSONObject req = new JSONObject(); + req.put("limit",10000); + String rsp = doPost(req.toString(),"https://qyapi.weixin.qq.com/cgi-bin/user/list_id?access_token="+accessToken); + System.out.println(rsp); + return rsp; + } + + // 调用企业微信接口,调用企业微信人员ID信息获取企业微信中人员详细信息 + public static String userGet(String corpid,String corpsecret,String userId) { + String accessToken = getAccessToken(corpid,corpsecret); + String rsp = doGet("https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token="+accessToken+"&id="+userId); + System.out.println("查询人员信息:"+rsp); + return rsp; + } + + public static String getUserIdByMobile(String corpid,String corpsecret,String mobile){ + String accessToken = getAccessToken(corpid,corpsecret); + JSONObject req = new JSONObject(); + req.put("mobile",mobile); + String rsp = doPost(req.toString(),"https://qyapi.weixin.qq.com/cgi-bin/user/getuserid?access_token="+accessToken); + System.out.println(rsp); + return rsp; + } + +} diff --git a/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_mainorganization/spring/spring-dao.xml b/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_mainorganization/spring/spring-dao.xml index d088d3b..5029bcb 100644 --- a/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_mainorganization/spring/spring-dao.xml +++ b/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_mainorganization/spring/spring-dao.xml @@ -9,6 +9,7 @@ + diff --git a/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_mainorganization/spring/spring-quartz.xml b/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_mainorganization/spring/spring-quartz.xml index 0d8e0cc..689e79e 100644 --- a/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_mainorganization/spring/spring-quartz.xml +++ b/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_mainorganization/spring/spring-quartz.xml @@ -2,5 +2,6 @@ + \ No newline at end of file diff --git a/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_mainorganization/spring/spring-server.xml b/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_mainorganization/spring/spring-server.xml index 987fa82..09405e3 100644 --- a/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_mainorganization/spring/spring-server.xml +++ b/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_mainorganization/spring/spring-server.xml @@ -5,7 +5,9 @@ + + \ No newline at end of file