2025-01-08稻花香主数据企业微信同步

This commit is contained in:
2026-04-08 15:55:54 +08:00
parent 88cdba2a68
commit 41c0df6104
24 changed files with 3164 additions and 60 deletions

View File

@@ -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;
}
}

View File

@@ -0,0 +1,26 @@
package com.qq.weixin.mp.aes;
import java.util.ArrayList;
class ByteGroup {
ArrayList<Byte> byteContainer = new ArrayList<Byte>();
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();
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}

View File

@@ -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编码的字符串).
* <ol>
* <li>第三方回复加密消息给企业微信</li>
* <li>第三方收到企业微信发送的消息,验证消息的安全性,并对消息进行解密。</li>
* </ol>
* 说明异常java.security.InvalidKeyException:illegal Key Size的解决方案
* <ol>
* <li>在官方网站下载JCE无限制权限策略文件JDK7的下载地址
* http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html</li>
* <li>下载后解压可以看到local_policy.jar和US_export_policy.jar以及readme.txt</li>
* <li>如果安装了JRE将两个jar文件放到%JRE_HOME%\lib\security目录下覆盖原来的文件</li>
* <li>如果安装了JDK将两个jar文件放到%JDK_HOME%\jre\lib\security目录下覆盖原来文件</li>
* </ol>
*/
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;
}
/**
* 将企业微信回复用户的消息加密打包.
* <ol>
* <li>对要发送的消息进行AES-CBC加密</li>
* <li>生成安全签名</li>
* <li>将消息密文和安全签名打包成json格式</li>
* </ol>
*
* @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;
}
/**
* 检验消息的真实性,并且获取解密后的明文.
* <ol>
* <li>利用收到的密文生成安全签名,进行签名验证</li>
* <li>若验证通过则提取json中的加密消息</li>
* <li>对消息进行解密</li>
* </ol>
*
* @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;
}
}

View File

@@ -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&timestamp=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返回给企业微信
第23步可以用企业微信提供的库函数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&timestamp=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"标签的内容进行解密,解密出来的明文即是用户回复消息的明文,明文格式请参考官方文档
第23步可以用企业微信提供的库函数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格式的字符串发送给企业。
以上234步可以用企业微信提供的库函数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();
// 加密失败
}
}
}

View File

@@ -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;
}

View File

@@ -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"),

View File

@@ -13,9 +13,6 @@ public interface ISyncDdDao {
public List<Long> getMemberByMobile(String mobile);
// 查询钉钉单位绑定信息
public Map<String,Object> getAccountBinding(String orgAccountId);

View File

@@ -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<Long> getAccountsBinding();
public Map<String,Object> getAccountBindingByQywxAccount(String qywxAccountId);
public Map<String,Object> getDepartmentBindingByQywxDepartment(String qywxDepartmentId);
// 新增钉钉部门绑定信息
public int saveDepartmentBinding(String departmentId,String departmentName ,String ddDepartmentId ,String ddDepartmentName);
public List<Long> getDepartmentsBinding();
public List<Long> getDepartmentsOABinding();
// 新增钉钉人员绑定信息
public int saveMemberBinding(String memberId,String membertName ,String ddMemberId ,String ddMemberName,String telnumber);
public Map<String,Object> getMaxSynchronizationDate();
// 查询钉钉单位绑定信息
public Map<String,Object> getAccountBinding(String orgAccountId);
// 根据单位ID修改钉钉单位绑定信息
public int updateAccountBinding(String accountId,String accountName,String ddAccountId ,String ddAccountName);
// 根据部门ID删除钉钉部门绑定信息
public int deleteDepartmentBinding(String departmentId);
// 查询钉钉部门绑定信息
public Map<String,Object> getDepartmentBinding(String orgDepartmentId);
// 查询钉钉人员绑定信息
public Map<String,Object> getMemberBinding(String orgMemberId);
// 根据人员ID删除钉钉人员绑定信息
public int deleteMemberBinding(String memberId);
}

View File

@@ -297,7 +297,6 @@ public class ArchiveDaoImpl implements IArchiveDao {
List<Object> p = new ArrayList();
agent.execute(sql.toString(), p);
List<Map> list = agent.resultSetToList();
for(int i = 0; i < list.size(); ++i) {
if (list.size() != 0) {
Map<String,Object> map = (Map)list.get(i);

View File

@@ -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<Object> p = new ArrayList<Object>();
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<Long> getAccountsBinding(){
JDBCAgent agent = new JDBCAgent();
List<Long> res = new ArrayList<>();
try {
StringBuilder sql = new StringBuilder(getAccountsBinding);
List<Object> p = new ArrayList();
agent.execute(sql.toString(), p);
List<Map> 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<String,Object> getAccountBindingByQywxAccount(String qywxAccountId){
JDBCAgent agent = new JDBCAgent();
Map<String,Object> res = new HashMap<>();
try {
StringBuilder sql = new StringBuilder(getAccountBindingByQywxAccount);
List<Object> p = new ArrayList();
p.add(qywxAccountId);
agent.execute(sql.toString(), p);
List<Map> 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<String,Object> getDepartmentBindingByQywxDepartment(String qywxDepartmentId){
JDBCAgent agent = new JDBCAgent();
Map<String,Object> res = new HashMap<>();
try {
StringBuilder sql = new StringBuilder(getDepartmentBindingByQywxDepartment);
List<Object> p = new ArrayList();
p.add(qywxDepartmentId);
agent.execute(sql.toString(), p);
List<Map> 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<Object> p = new ArrayList<Object>();
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<Long> getDepartmentsBinding(){
JDBCAgent agent = new JDBCAgent();
List<Long> res = new ArrayList<>();
try {
StringBuilder sql = new StringBuilder(getDepartmentsBinding);
List<Object> p = new ArrayList();
agent.execute(sql.toString(), p);
List<Map> 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<Long> getDepartmentsOABinding(){
JDBCAgent agent = new JDBCAgent();
List<Long> res = new ArrayList<>();
try {
StringBuilder sql = new StringBuilder(getDepartmentsOABinding);
List<Object> p = new ArrayList();
agent.execute(sql.toString(), p);
List<Map> 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<Object> p = new ArrayList<Object>();
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<String,Object> getMaxSynchronizationDate (){
JDBCAgent agent = new JDBCAgent();
Map<String,Object> res = new HashMap<>();
try {
StringBuilder sql = new StringBuilder(getMaxSynchronizationDate);
List<Object> p = new ArrayList();
agent.execute(sql.toString(), p);
List<Map> 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<String,Object> getAccountBinding(String orgAccountId) {
JDBCAgent agent = new JDBCAgent();
Map<String,Object> res = new HashMap<>();
try {
StringBuilder sql = new StringBuilder(getAccountBinding);
List<Object> p = new ArrayList();
p.add(orgAccountId);
agent.execute(sql.toString(), p);
List<Map> 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<Object> p = new ArrayList<Object>();
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<Object> p = new ArrayList<Object>();
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<String, Object> getDepartmentBinding(String orgDepartmentId) {
JDBCAgent agent = new JDBCAgent();
Map<String,Object> res = new HashMap<>();
try {
StringBuilder sql = new StringBuilder(getDepartmentBinding);
List<Object> p = new ArrayList();
p.add(orgDepartmentId);
agent.execute(sql.toString(), p);
List<Map> 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<String, Object> getMemberBinding(String orgMemberId) {
JDBCAgent agent = new JDBCAgent();
Map<String,Object> res = new HashMap<>();
try {
StringBuilder sql = new StringBuilder(getMemberBinding);
List<Object> p = new ArrayList();
p.add(orgMemberId);
agent.execute(sql.toString(), p);
List<Map> 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<Object> p = new ArrayList<Object>();
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;
}
}

View File

@@ -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<String,String> errorMapAccount = initializeWorkweixinSyncServer.initializeWorkweixinAccount();
log.info("单位添加完成,部门添加开始");
Map<String,String> errorMapDepartment = initializeWorkweixinSyncServer.initializeWorkweixinDepartment();
log.info("部门添加完成,人员添加开始");
Map<String,String> errorMapMember = initializeWorkweixinSyncServer.initializeWorkweixinMember();
log.info("人员添加完成");
return "初始化完成";
}
log.info("进入企业微信通讯录同步定时任务,参数为:"+s);
ConfigVo configVo = this.cstConfigApi.getConfig(this.getPluginId());
String res = "";
// 查询上一次同步时间
Map<String,Object> 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;
}
}

View File

@@ -216,9 +216,4 @@ public class InitializeDingdingSyncServer {
return errorMap;
}
}

View File

@@ -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<String,String> initializeWorkweixinAccount() throws BusinessException {
Map<String,String> 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<Long> superDepartments = new ArrayList<>();
superDepartments.add(1l);
// 通过跟部门ID查询部门下级信息
while(superDepartments.size()!=0){
List<Long> departmentIds = new ArrayList<>();
departmentIds.addAll(superDepartments);
superDepartments.clear();
for (Long superDepartmentId: departmentIds) {
// 调用企业微信接口查询下级部门信息
List<Long> 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<String,String> initializeWorkweixinDepartment() throws BusinessException {
Map<String,String> 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<Long> superDepartments = syncQywxDao.getAccountsBinding();
while(superDepartments.size()!=0){
// 创建临时储存列表
List<Long> 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<Long> subordinateDepartmentIdList = new ArrayList<>();
// 根据上级部门信息,筛选子集部门信息
for(int i = 0 ; i <subordinateDepartmentIds.size();i++){
JSONObject subordinateDepartmentId = subordinateDepartmentIds.getJSONObject(i);
String subordinateDepartmentParentId = subordinateDepartmentId.getString("parentid");
if(subordinateDepartmentParentId.equals(superDepartmentId+"")){
subordinateDepartmentIdList.add(subordinateDepartmentId.getLongValue("id"));
}
}
// 遍历当前子部门信息,保存绑定关系。
for(int i = 0 ; i < subordinateDepartmentIdList.size() ; i++){
long subordinateDepartmentId = subordinateDepartmentIdList.get(i);
String departmentGet = WorkweixinProtUtil.departmentGet(workweixinCorpid,workweixinCorpsecret,subordinateDepartmentId);
JSONObject departmentGetJson = JSONObject.parseObject(departmentGet);
if("0".equals(departmentGetJson.getString("errcode"))){
JSONObject departmentJSON = departmentGetJson.getJSONObject("department");
Map<String,Object> superAccountMap = syncQywxDao.getAccountBindingByQywxAccount(superDepartmentId+"");
Map<String,Object> superDepartmentMap = syncQywxDao.getDepartmentBindingByQywxDepartment(superDepartmentId+"");
// 判断当前获取的企业微信部门是否为指定部门
List<V3xOrgDepartment> 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 <v3xOrgDepartments.size() ; n++){
V3xOrgDepartment department = v3xOrgDepartments.get(n);
if(department.getName().equals(departmentJSON.getString("name"))){
// 添加到临时储存,为下一个循环的请求参数
superDepartments.add(subordinateDepartmentId);
// 当前查询单位在钉钉中存在,添加绑定关系表
int saveAccountBindingnum = syncQywxDao.saveDepartmentBinding(department.getId()+"",department.getName(),departmentJSON.getString("id"),departmentJSON.getString("name"));
if(saveAccountBindingnum>0){
// log.info("添加成功"+saveAccountBindingnum);
}else{
log.info("添加部门失败"+department.getId()+department.getName());
}
}
}
}else{
log.info("企业微信部门参数查询失败"+subordinateDepartmentId+departmentGetJson);
}
}
}
}
}
return errorMap;
}
// 进行钉钉人员信息关系绑定初始化
public Map<String,String> initializeWorkweixinMember() throws BusinessException {
Map<String,String> 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<Long> superOADepartments = syncQywxDao.getDepartmentsOABinding();
// 遍历当前部门,在钉钉中查询各部门下的人员
for (Long superOADepartmentId: superOADepartments) {
V3xOrgDepartment v3xOrgDepartment = orgManager.getDepartmentById(superOADepartmentId);
List<V3xOrgMember> 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;
}
}

View File

@@ -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<String,Object> 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<String,String> errorMap = new HashMap<>();
Map<String,String> memberMap = new HashMap<>();
if(serviceBroker.get("account_id")!=null){
if(serviceBroker.get("account_id")!=null){
Map<String,Object> accountBinding = syncDdDao.getAccountBinding(serviceBroker.get("account_id").toString());
if(accountBinding.size()==0){
log.info("当前修改人员所在单位不在钉钉绑定表中跳过处理");
@@ -1206,7 +1218,7 @@ public class OrganizationOrgDingdingSyncServer {
List<String> postBlackList = archiveDao.getPostBlackList();
String postBlackString = "";
for (String postBlack:postBlackList) {
postBlackString = postBlackString+ postBlack+ ",";
postBlackString = postBlackString+postBlack+ ",";
}
List<String> postBlackStringList = Arrays.asList(postBlackString.split(","));
// 查询人员白名单

View File

@@ -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();
}
}

View File

@@ -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;
}
}

View File

@@ -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<String,Object> serviceBroker, Map<String,String> 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<Long> 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<String,Object> serviceBroker, Map<String,String> 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<Long> 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;
}
}

View File

@@ -9,6 +9,7 @@
<bean id="srcEnumDao" class="com.seeyon.apps.src_mainorganization.dao.impl.SrcEnumDaoImpl"></bean>
<bean id="srcMemberDao" class="com.seeyon.apps.src_mainorganization.dao.impl.SrcMemberDaoImpl"></bean>
<bean id="syncDdDao" class="com.seeyon.apps.src_mainorganization.dao.impl.SyncDdDaoImpl"></bean>
<bean id="syncQywxDao" class="com.seeyon.apps.src_mainorganization.dao.impl.SyncQywxDaoImpl"></bean>
<bean id="srcPostDao" class="com.seeyon.apps.src_mainorganization.dao.impl.SrcPostDaoImpl"></bean>
<bean id="srcLevelDao" class="com.seeyon.apps.src_mainorganization.dao.impl.SrcLevelDaoImpl"></bean>
<bean id="srcFormTableDao" class="com.seeyon.apps.src_mainorganization.dao.impl.SrcFormTableDaoImpl"></bean>

View File

@@ -2,5 +2,6 @@
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-autowire="byName">
<bean id="organizationQuartz" class="com.seeyon.apps.src_mainorganization.quartz.OrganizationQuartz" />
<bean id="organizationWorkweixinQuartz" class="com.seeyon.apps.src_mainorganization.quartz.OrganizationWorkweixinQuartz" />
<bean id="qixuexingOrganizationQuartz" class="com.seeyon.apps.src_mainorganization.quartz.QixuexingOrganizationQuartz" />
</beans>

View File

@@ -5,7 +5,9 @@
<bean id="organizationOrgFlowSyncServer" class="com.seeyon.apps.src_mainorganization.server.OrganizationOrgFlowSyncServer"></bean>
<bean id="organizationOrgGroupSyncServer" class="com.seeyon.apps.src_mainorganization.server.OrganizationOrgGroupSyncServer"></bean>
<bean id="organizationOrgDingdingSyncServer" class="com.seeyon.apps.src_mainorganization.server.OrganizationOrgDingdingSyncServer"></bean>
<bean id="organizationOrgWorkweixinSyncServer" class="com.seeyon.apps.src_mainorganization.server.OrganizationOrgWorkweixinSyncServer"></bean>
<bean id="organizationOrgQixuexingSyncServer" class="com.seeyon.apps.src_mainorganization.server.OrganizationOrgQixuexingSyncServer"></bean>
<bean id="initializeDingdingSyncServer" class="com.seeyon.apps.src_mainorganization.server.InitializeDingdingSyncServer"></bean>
<bean id="initializeWorkweixinSyncServer" class="com.seeyon.apps.src_mainorganization.server.InitializeWorkweixinSyncServer"></bean>
</beans>