|
@@ -1,373 +0,0 @@
|
|
|
-package com.kingdee.eas.custom.sendmessage.utils;
|
|
|
-
|
|
|
-import com.alibaba.fastjson.JSONObject;
|
|
|
-import com.kingdee.bos.BOSException;
|
|
|
-import com.kingdee.bos.Context;
|
|
|
-import com.kingdee.bos.ctrl.swing.StringUtils;
|
|
|
-import com.kingdee.bos.metadata.entity.EntityViewInfo;
|
|
|
-import com.kingdee.bos.metadata.entity.FilterInfo;
|
|
|
-import com.kingdee.bos.metadata.entity.FilterItemInfo;
|
|
|
-import com.kingdee.bos.metadata.entity.SelectorItemCollection;
|
|
|
-import com.kingdee.bos.metadata.query.util.CompareType;
|
|
|
-import com.kingdee.eas.basedata.person.PersonInfo;
|
|
|
-import com.kingdee.eas.common.EASBizException;
|
|
|
-import com.kingdee.eas.custom.logs.IMessageLogs;
|
|
|
-import com.kingdee.eas.custom.logs.MessageLogsFactory;
|
|
|
-import com.kingdee.eas.custom.logs.MessageLogsInfo;
|
|
|
-import com.kingdee.eas.custom.logs.app.SendStatusEnum;
|
|
|
-import com.kingdee.eas.custom.sendmessage.handler.ResignCertificationBillHRListHandlerEx;
|
|
|
-import com.kingdee.eas.hr.affair.*;
|
|
|
-import com.kingdee.eas.hr.ats.AtsUtil;
|
|
|
-import com.kingdee.eas.hr.emp.IPersonContactMethod;
|
|
|
-import com.kingdee.eas.hr.emp.PersonContactMethodFactory;
|
|
|
-import com.kingdee.eas.hr.emp.PersonContactMethodInfo;
|
|
|
-import com.kingdee.shr.base.syssetting.exception.SHRWebException;
|
|
|
-import com.kingdee.shr.base.syssetting.exception.ShrWebBizException;
|
|
|
-import com.kingdee.shr.certificationservice.*;
|
|
|
-import okhttp3.*;
|
|
|
-import org.apache.commons.codec.digest.DigestUtils;
|
|
|
-import org.apache.log4j.Logger;
|
|
|
-
|
|
|
-import javax.crypto.Cipher;
|
|
|
-import javax.crypto.spec.SecretKeySpec;
|
|
|
-import java.io.FileInputStream;
|
|
|
-import java.io.IOException;
|
|
|
-import java.nio.charset.StandardCharsets;
|
|
|
-import java.nio.file.Files;
|
|
|
-import java.nio.file.Paths;
|
|
|
-import java.text.SimpleDateFormat;
|
|
|
-import java.util.*;
|
|
|
-import java.util.concurrent.TimeUnit;
|
|
|
-
|
|
|
-/**
|
|
|
- * @author qingwu
|
|
|
- * @date 2024/11/19
|
|
|
- * @apiNote
|
|
|
- */
|
|
|
-public class SendMessageUtil {
|
|
|
- private static Logger logger =
|
|
|
- Logger.getLogger(ResignCertificationBillHRListHandlerEx.class);
|
|
|
- private Properties propt = new Properties();
|
|
|
-
|
|
|
- public SendMessageUtil() throws BOSException {
|
|
|
- String syncOAConfigPath = System.getProperty("EAS_HOME") + "/server/properties/gyt/sendMessage.properties";
|
|
|
- try {
|
|
|
- propt.load(Files.newBufferedReader(Paths.get(syncOAConfigPath), StandardCharsets.UTF_8));
|
|
|
- //propt.load(new FileInputStream(syncOAConfigPath));
|
|
|
- } catch (IOException e) {
|
|
|
- e.printStackTrace();
|
|
|
- String errorMsg = "获取配置文件报错,请检查配置:" + syncOAConfigPath + " " + e.getMessage();
|
|
|
- throw new BOSException(errorMsg);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 发送消息
|
|
|
- *
|
|
|
- * @throws SHRWebException
|
|
|
- */
|
|
|
- public void sendMessage(Context ctx, String billId) throws ShrWebBizException, BOSException, EASBizException {
|
|
|
- MessageLogsInfo messageLogsInfo = new MessageLogsInfo();
|
|
|
- IMessageLogs iMessageLogs = MessageLogsFactory.getLocalInstance(ctx);
|
|
|
- //成功条数
|
|
|
- int seccuss = 0;
|
|
|
- //失败条数
|
|
|
- int error = 0;
|
|
|
- try {
|
|
|
- Set<String> setBillId = AtsUtil.toSet(billId);
|
|
|
- //总条数
|
|
|
- messageLogsInfo.setCount(setBillId.size());
|
|
|
- //hr单据证明
|
|
|
- IHRCertificationBill ihrCertificationBill = HRCertificationBillFactory.getLocalInstance(ctx);
|
|
|
- SelectorItemCollection sic = new SelectorItemCollection();
|
|
|
- sic.add("*");
|
|
|
- sic.add("person.name");
|
|
|
- sic.add("person.number");
|
|
|
- sic.add("person.id");
|
|
|
- sic.add("certificationTemplet.name");
|
|
|
- sic.add("certificationTemplet.number");
|
|
|
- sic.add("certificationTemplet.id");
|
|
|
- sic.add("certificationTemplet.certificationBillType.name");
|
|
|
- sic.add("certificationTemplet.certificationBillType.number");
|
|
|
- sic.add("certificationTemplet.certificationBillType.id");
|
|
|
- sic.add("certificationTemplet.templateId");
|
|
|
- FilterInfo filterInfo = new FilterInfo();
|
|
|
- filterInfo.getFilterItems().add(new FilterItemInfo("id", setBillId, CompareType.INCLUDE));
|
|
|
- EntityViewInfo entityViewInfo = EntityViewInfo.getInstance(filterInfo, sic, null);
|
|
|
- HRCertificationBillCollection hrCertificationBillCollection = ihrCertificationBill.getHRCertificationBillCollection(entityViewInfo);
|
|
|
- for (int i = 0; i < hrCertificationBillCollection.size(); i++) {
|
|
|
- HRCertificationBillInfo hrCertificationBillInfo = hrCertificationBillCollection.get(i);
|
|
|
- //手机号
|
|
|
- String callPhone = hrCertificationBillInfo.getCallPhone();
|
|
|
- //证明模板
|
|
|
- CertificationTempletInfo certificationTemplet = hrCertificationBillInfo.getCertificationTemplet();
|
|
|
- String templateName = certificationTemplet.getName();
|
|
|
- String templateId = (String) certificationTemplet.get("templateId");
|
|
|
- //证明模板
|
|
|
- HRCertificationBillTypeInfo certificationBillType = certificationTemplet.getCertificationBillType();
|
|
|
- //模版名称
|
|
|
- messageLogsInfo.setReserved1(templateName);
|
|
|
- messageLogsInfo.setReserved2(certificationBillType.getName());
|
|
|
- if (StringUtils.isEmpty(templateId)) {
|
|
|
- throw new ShrWebBizException(templateName + "模板的消息id为空,请问维护!!");
|
|
|
- }
|
|
|
-
|
|
|
- String md5Sign = null;
|
|
|
- //过滤封装手机号
|
|
|
- //Map<String, Set> phoneMap = disposeCollFillterPhone(hrCertificationBillCollection, messageLogsInfo);
|
|
|
- //密钥
|
|
|
- String appSecret = propt.getProperty("appSecret");
|
|
|
- //uuid
|
|
|
- String uuid = UUID.randomUUID().toString();
|
|
|
- System.out.println("uuid---" + uuid);
|
|
|
- //应用类型
|
|
|
- String appType = propt.getProperty("appType");
|
|
|
- //应用id
|
|
|
- String appId = propt.getProperty("appId");
|
|
|
- //url
|
|
|
- String url = propt.getProperty("url");
|
|
|
- String signName = propt.getProperty("signName");
|
|
|
- logger.error("url---" + url);
|
|
|
- //时间戳
|
|
|
- Date date = new Date();
|
|
|
- String time = String.valueOf(date.getTime());
|
|
|
- messageLogsInfo.setTime(date);
|
|
|
- logger.error("time---" + time);
|
|
|
- //参数
|
|
|
- JSONObject params = new JSONObject();
|
|
|
- params.put("appId", appId);
|
|
|
- params.put("templateId", templateId);
|
|
|
- params.put("signName", signName);
|
|
|
- //批量发送才需要这个参数
|
|
|
- //params.put("phone", phone);
|
|
|
- params.put("phone", "15574198273");
|
|
|
- params.put("appId", appId);
|
|
|
- //消息模板
|
|
|
- Map<String, String> resultMap = SaveFileForDisk.getPDFInfo(ctx, hrCertificationBillInfo);
|
|
|
- JSONObject param = getTemplate(ctx, templateId, callPhone, resultMap.get("urlPath"), messageLogsInfo);
|
|
|
- params.put("params", param);
|
|
|
- //请求参数
|
|
|
- JSONObject jsonObject = new JSONObject();
|
|
|
- //jsonObject.put("params", params.toString());
|
|
|
- jsonObject.put("time", time);
|
|
|
- jsonObject.put("uuid", uuid);
|
|
|
- jsonObject.put("phones", callPhone);
|
|
|
- md5Sign = md5Sign(appSecret, url, params, appType, time, uuid, jsonObject);
|
|
|
- jsonObject.put("md5Sign", md5Sign);
|
|
|
- jsonObject.put("resultMap", resultMap);
|
|
|
- messageLogsInfo.setRequestParams(resultMap.get("urlPath"));
|
|
|
- messageLogsInfo.setRequestParams(jsonObject.toString());
|
|
|
- logger.error("md5Sign---" + md5Sign);
|
|
|
- logger.error("params---" + params);
|
|
|
- Response resultResponse = sendMeesage(params, appType, appId, uuid, md5Sign, time);
|
|
|
- String body = resultResponse.body().string();
|
|
|
- logger.error("body---" + body);
|
|
|
- JSONObject result = JSONObject.parseObject(body);
|
|
|
- String code = result.get("code").toString();
|
|
|
- if (!code.equals("200")) {
|
|
|
- error++;
|
|
|
- messageLogsInfo.setStatus(SendStatusEnum.fail);
|
|
|
- } else {
|
|
|
- seccuss++;
|
|
|
- messageLogsInfo.setStatus(SendStatusEnum.succeed);
|
|
|
- }
|
|
|
- //返回结果
|
|
|
- messageLogsInfo.setResult(body);
|
|
|
- messageLogsInfo.setSuccessNum(seccuss);
|
|
|
- messageLogsInfo.setFailNum(error);
|
|
|
- iMessageLogs.save(messageLogsInfo);
|
|
|
- }
|
|
|
-
|
|
|
- } catch (Exception e) {
|
|
|
- error++;
|
|
|
- //返回结果
|
|
|
- messageLogsInfo.setFailNum(error);
|
|
|
- messageLogsInfo.setResult(e.getMessage());
|
|
|
- messageLogsInfo.setStatus(SendStatusEnum.fail);
|
|
|
- iMessageLogs.save(messageLogsInfo);
|
|
|
- e.printStackTrace();
|
|
|
- throw new ShrWebBizException(e);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /***
|
|
|
- * 获取消息模板
|
|
|
- * @param ctx
|
|
|
- * @param templateId
|
|
|
- * @param phone
|
|
|
- * @return
|
|
|
- */
|
|
|
- public JSONObject getTemplate(Context ctx, String templateId, String phone, String urlPath, MessageLogsInfo messageLogsInfo) throws BOSException {
|
|
|
- JSONObject param = new JSONObject();
|
|
|
- IPersonContactMethod iPersonContactMethod = PersonContactMethodFactory.getLocalInstance(ctx);
|
|
|
- PersonContactMethodInfo personContactMethodInfo = iPersonContactMethod
|
|
|
- .getPersonContactMethodCollection("select * ,person.* where nCell = '" + phone + "'").get(0);
|
|
|
- PersonInfo person = personContactMethodInfo.getPerson();
|
|
|
- messageLogsInfo.setPerson(person);
|
|
|
- SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
|
|
|
- //SHR发送电子证明
|
|
|
- if (templateId.equals("MSG_2411190001")) {
|
|
|
- param.put("name", person.getName());
|
|
|
- param.put("urlPath", urlPath);
|
|
|
- }
|
|
|
- //SHR发送离职通知
|
|
|
- if (templateId.equals("MSG_2411200002")) {
|
|
|
- IResignBizBillEntry iResignBizBillEntry = ResignBizBillEntryFactory.getLocalInstance(ctx);
|
|
|
- ResignBizBillEntryInfo resignBizBillEntryInfo = iResignBizBillEntry
|
|
|
- .getResignBizBillEntryCollection("where person = '" + person.getId().toString() + "'").get(0);
|
|
|
- Date bizDate = resignBizBillEntryInfo.getBizDate();
|
|
|
- String lzDate = format.format(bizDate);
|
|
|
- param.put("name", person.getName());
|
|
|
- param.put("lzDate", lzDate);
|
|
|
- param.put("urlPath", urlPath);
|
|
|
- }
|
|
|
- return param;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * 通过模板id 分组过滤手机号以及校验是否有模板Id未维护
|
|
|
- *
|
|
|
- * @param hrCertificationBillCollection
|
|
|
- * @return
|
|
|
- */
|
|
|
- public Map disposeCollFillterPhone(HRCertificationBillCollection hrCertificationBillCollection, MessageLogsInfo messageLogsInfo) throws ShrWebBizException {
|
|
|
- Map<String, Set> certificationBillTypeMap = new HashMap<>();
|
|
|
- for (int i = 0; i < hrCertificationBillCollection.size(); i++) {
|
|
|
- HRCertificationBillInfo hrCertificationBillInfo = hrCertificationBillCollection.get(i);
|
|
|
- //手机号
|
|
|
- String callPhone = hrCertificationBillInfo.getCallPhone();
|
|
|
- //证明模板
|
|
|
- CertificationTempletInfo certificationTemplet = hrCertificationBillInfo.getCertificationTemplet();
|
|
|
- String templateName = certificationTemplet.getName();
|
|
|
- String templateId = (String) certificationTemplet.get("templateId");
|
|
|
- //证明模板
|
|
|
- HRCertificationBillTypeInfo certificationBillType = certificationTemplet.getCertificationBillType();
|
|
|
- //模版名称
|
|
|
- messageLogsInfo.setReserved1(templateName);
|
|
|
- messageLogsInfo.setReserved2(certificationBillType.getName());
|
|
|
- if (StringUtils.isEmpty(templateId)) {
|
|
|
- throw new ShrWebBizException(templateName + "模板的消息id为空,请问维护!!");
|
|
|
- }
|
|
|
- if (!certificationBillTypeMap.containsKey(templateId)) {
|
|
|
- certificationBillTypeMap.put(templateId, new HashSet<>());
|
|
|
- }
|
|
|
- certificationBillTypeMap.get(templateId).add(callPhone);
|
|
|
- }
|
|
|
- Map<String, Set> phoneMap = new HashMap<String, Set>();
|
|
|
- // 遍历输出结果map
|
|
|
- certificationBillTypeMap.forEach((templateId, callPhoneSet) -> {
|
|
|
- //多个人的手机号 用逗号隔开
|
|
|
- //String phones = deleteCharAt(callPhoneSet);
|
|
|
- phoneMap.put(templateId, callPhoneSet);
|
|
|
- });
|
|
|
- return phoneMap;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 处理集合 封装数据
|
|
|
- *
|
|
|
- * @param set
|
|
|
- * @return
|
|
|
- */
|
|
|
- public String deleteCharAt(Set<String> set) {
|
|
|
- StringBuilder callPhoneBuilder = new StringBuilder();
|
|
|
- for (String phone : set) {
|
|
|
- callPhoneBuilder.append(phone).append(",");
|
|
|
- }
|
|
|
- callPhoneBuilder.deleteCharAt(callPhoneBuilder.lastIndexOf(","));
|
|
|
- return callPhoneBuilder.toString();
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * 发送信息
|
|
|
- *
|
|
|
- * @param params
|
|
|
- * @param appType
|
|
|
- * @param appId
|
|
|
- * @param uuid
|
|
|
- * @param md5Sign
|
|
|
- * @throws IOException
|
|
|
- */
|
|
|
- private Response sendMeesage(JSONObject params, String appType, String appId, String uuid, String md5Sign, String time) throws IOException {
|
|
|
- //发送请求
|
|
|
- OkHttpClient client = new OkHttpClient.Builder()
|
|
|
- .connectTimeout(30, TimeUnit.SECONDS)
|
|
|
- .writeTimeout(30, TimeUnit.SECONDS)
|
|
|
- .readTimeout(30, TimeUnit.SECONDS)
|
|
|
- .build();
|
|
|
- MediaType mediaType = MediaType.parse("application/json");
|
|
|
- RequestBody body = RequestBody.create(mediaType, params.toString());
|
|
|
- Request request = new Request.Builder()
|
|
|
- //.url(propt.getProperty("sendMessageTaskUrl")) //批量发送消息
|
|
|
- .url(propt.getProperty("sendMessageUrl"))
|
|
|
- .post(body)
|
|
|
- //X-*-Sign 指定的算法,可选范围目前只有 md5,后续如有必要会增添其他算法
|
|
|
- .addHeader("X-message-Algorithm", "md5")
|
|
|
- //时间戳,请求时间,防止重放攻击,目前后台最多延时 15 分钟
|
|
|
- .addHeader("X-message-Time", time)
|
|
|
- //终端应用类型,比如小程序设置为 1、WEB 端设置为 2、APP 端设 置为 3,建议设置 2
|
|
|
- .addHeader("X-message-AppType", appType)
|
|
|
- //应用唯一标识,用于判断是那个应用调用消息中心
|
|
|
- .addHeader("X-message-AppID", appId)
|
|
|
- //随机码,防止重放攻击,延时时间之内不能重复,客户端可以采 用 UUID 生成
|
|
|
- .addHeader("X-message-Nonce", uuid)
|
|
|
- //签名 Sign,具体说明看下文
|
|
|
- //MD5( APPSECRET+路径+参数 +X-*-AppType +X-*-Time +X-*-Nonce )
|
|
|
- .addHeader("X-message-Sign", md5Sign)
|
|
|
- .addHeader("Content-Type", "application/json")
|
|
|
- .addHeader("User-Agent", "PostmanRuntime-ApipostRuntime/1.1.0")
|
|
|
- .addHeader("Connection", "keep-alive")
|
|
|
- .addHeader("Accept", "*/*")
|
|
|
- .build();
|
|
|
- return client.newCall(request).execute();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取 sign
|
|
|
- *
|
|
|
- * @param appSecret 密钥
|
|
|
- * @param url url
|
|
|
- * @param params 参数
|
|
|
- * @param appType 类型 建议为2
|
|
|
- * @param appTime 时间戳
|
|
|
- * @param nonce 随机码
|
|
|
- * @return
|
|
|
- */
|
|
|
- public String md5Sign(String appSecret, String url, Map params, String appType, String appTime, String nonce, JSONObject jsonObject) {
|
|
|
- //System.out.println(params.toString());
|
|
|
- String code = appSecret + url + params.toString() + appType + appTime + nonce;
|
|
|
- logger.error("code---" + code);
|
|
|
- jsonObject.put("code", code);
|
|
|
- return DigestUtils.md5Hex(code).toLowerCase();
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * aes加密
|
|
|
- *
|
|
|
- * @param phone
|
|
|
- * @param appSecret
|
|
|
- * @return
|
|
|
- * @throws Exception
|
|
|
- */
|
|
|
- public static String encrypt(String phone, String appSecret) throws Exception {
|
|
|
- // 将自定义的字符串密钥转换为字节数组,注意要确保长度符合要求(AES 128位对应16字节等)
|
|
|
- byte[] keyBytes = appSecret.getBytes(StandardCharsets.UTF_8);
|
|
|
- // 如果密钥长度不符合要求,这里可以进行适当处理,比如截取或填充等,示例采用简单截取到16字节长度(仅针对128位AES示例)
|
|
|
- if (keyBytes.length > 16) {
|
|
|
- keyBytes = java.util.Arrays.copyOf(keyBytes, 16);
|
|
|
- } else if (keyBytes.length < 16) {
|
|
|
- byte[] newKeyBytes = new byte[16];
|
|
|
- System.arraycopy(keyBytes, 0, newKeyBytes, 0, keyBytes.length);
|
|
|
- keyBytes = newKeyBytes;
|
|
|
- }
|
|
|
-
|
|
|
- SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
|
|
|
- Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
|
|
|
- cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
|
|
|
- byte[] encryptedBytes = cipher.doFinal(phone.getBytes(StandardCharsets.UTF_8));
|
|
|
- return Base64.getEncoder().encodeToString(encryptedBytes);
|
|
|
- }
|
|
|
-}
|