SendMsgToWeChatOA.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. package nckd.fi.er.message;
  2. import com.alibaba.fastjson.JSONObject;
  3. import com.grapecity.documents.excel.S;
  4. import kd.bos.context.RequestContext;
  5. import kd.bos.dataentity.entity.DynamicObject;
  6. import kd.bos.dataentity.entity.DynamicObjectCollection;
  7. import kd.bos.exception.KDBizException;
  8. import kd.bos.logging.Log;
  9. import kd.bos.logging.LogFactory;
  10. import kd.bos.orm.query.QCP;
  11. import kd.bos.orm.query.QFilter;
  12. import kd.bos.servicehelper.BusinessDataServiceHelper;
  13. import kd.bos.servicehelper.QueryServiceHelper;
  14. import kd.bos.servicehelper.parameter.SystemParamServiceHelper;
  15. import kd.bos.workflow.engine.msg.AbstractMessageServiceHandler;
  16. import kd.bos.workflow.engine.msg.ctx.MessageContext;
  17. import kd.bos.workflow.engine.msg.info.MessageInfo;
  18. import kd.bos.workflow.engine.msg.info.ToDoInfo;
  19. import nckd.base.common.utils.DateUtil;
  20. import nckd.base.common.utils.HttpUtils;
  21. import nckd.base.common.utils.ParamUtils;
  22. import org.apache.commons.lang3.ObjectUtils;
  23. import org.apache.commons.lang3.StringUtils;
  24. import java.io.IOException;
  25. import java.util.*;
  26. /**
  27. * @description:TODO
  28. * @author: dingsixi
  29. * @create: 2025/12/27 0:09
  30. */
  31. public class SendMsgToWeChatOA extends AbstractMessageServiceHandler {
  32. private Log log = LogFactory.getLog(SendMsgToWeChatOA.class);
  33. @Override
  34. public void createToDo(MessageContext messageContext, ToDoInfo toDoInfo) {
  35. }
  36. @Override
  37. public void dealToDo(MessageContext messageContext, ToDoInfo toDoInfo) {
  38. }
  39. @Override
  40. public void deleteToDo(MessageContext messageContext, ToDoInfo toDoInfo) {
  41. }
  42. //重写sendMessage,给微信公众号发消息
  43. @Override
  44. public void sendMessage(MessageContext ctx, MessageInfo message) {
  45. super.sendMessage(ctx, message);
  46. log.info("-----------------------------------------"+"微信公众号发送提醒信息:" +message.getMessageContent().getLocaleValue_zh_CN()+" begin--------------------------------------------------");
  47. //微信公众号消息推送地址
  48. String mobUrl = message.getMobContentUrl();
  49. //微信公众号消息推送地址
  50. String contentUrl = message.getContentUrl();
  51. //表单数据id
  52. Long bizDataId = message.getBizDataId();
  53. if(bizDataId == null){
  54. log.info("表单数据id为空");
  55. return;
  56. }
  57. //表单标识
  58. String entityNumber = message.getEntityNumber();
  59. if(StringUtils.isEmpty(entityNumber)){
  60. log.info("表单标识为空");
  61. return;
  62. }
  63. Long id = message.getId();
  64. //从系统参数中获取以下参数值
  65. Map<String, Object> sysCtrlParamMap = sysCtrlParam(entityNumber);
  66. //微信获取token地址
  67. String url = (String) sysCtrlParamMap.get("nckd_tokenurl");
  68. //公众号appid
  69. String appid = (String) sysCtrlParamMap.get("nckd_appid");
  70. //公众号密码
  71. String appsecret = (String) sysCtrlParamMap.get("nckd_appsecret");
  72. //公众号模板消息 模板id
  73. String templateid = (String) sysCtrlParamMap.get("nckd_textfield");
  74. String accessToken = "";
  75. //请求token接口参数
  76. Map<String,Object> data = new HashMap<>();
  77. data.put("appid",appid);
  78. data.put("secret",appsecret);
  79. data.put("grant_type","client_credential");
  80. //获取token
  81. String responseStr = null;
  82. try {
  83. responseStr = HttpUtils.postJson(url,data);
  84. } catch (IOException e) {
  85. throw new RuntimeException(e);
  86. }
  87. //是否推送成功
  88. if(!StringUtils.isEmpty(responseStr)){
  89. JSONObject jsonObject = JSONObject.parseObject(responseStr);
  90. accessToken = jsonObject.getString("access_token");
  91. if(StringUtils.isEmpty(accessToken)){
  92. String errmsg = jsonObject.getString("errmsg");
  93. }
  94. }
  95. //当前消息发送人用户id
  96. List<Long> userIds = message.getUserIds();
  97. List<Long> errUserIds = new ArrayList<Long>();
  98. if(!StringUtils.isEmpty(accessToken)){
  99. //微信公众号模板消息接口url 配置成参数
  100. url = (String) sysCtrlParamMap.get("nckd_msgurl");
  101. url = url+accessToken;
  102. //模板消息接口请求参数
  103. Map<String,Object> requestJson = new HashMap<>();
  104. requestJson.put("template_id",templateid);
  105. //微信公众号对应跳转信息
  106. Map<String, String> nckdRes = getResMap(entityNumber, (String) sysCtrlParamMap.get("nckd_res"));
  107. //拼接移动端供应商跳转路径
  108. String msgUrl = "http://erp-test.jxctly.com/ierp/mobile.html?"+nckdRes.get("nckd_rescode")+bizDataId +"&accountId="+ RequestContext.get().getAccountId();
  109. log.info("供应商跳转路径msgUrl:"+msgUrl);
  110. requestJson.put("url",msgUrl);
  111. requestJson.put("client_msg_id",id);
  112. //组装data参数
  113. JSONObject dataJson = madeJsonObject(entityNumber,bizDataId);
  114. // 转换为字符串
  115. String dataStr = dataJson.toJSONString();
  116. Map map = JSONObject.parseObject(dataStr, Map.class);
  117. requestJson.put("data",map);
  118. //获取当前用户id对应得微信公众号openid,每个用户都需要发送
  119. for(Long userId:userIds){
  120. //只有通过微信公众号单点登陆过的用户,苍穹平台才会留存openid,否则无法正常推送消息
  121. String openid = getUserOpenId(userId);
  122. if(StringUtils.isEmpty(openid)){
  123. continue;
  124. }
  125. requestJson.put("touser",openid);
  126. String response = null;
  127. try {
  128. response = HttpUtils.postJson(url, requestJson);
  129. } catch (IOException e) {
  130. throw new RuntimeException(e);
  131. }
  132. log.info("公众号:"+response);
  133. if(StringUtils.isEmpty(response)){
  134. errUserIds.add(userId);
  135. }else{
  136. JSONObject json = JSONObject.parseObject(response);
  137. Integer errcode = json.getInteger("errcode");
  138. if(errcode!=0){
  139. errUserIds.add(userId);
  140. }
  141. }
  142. }
  143. if(errUserIds.size()>0){
  144. message.setUserIds(errUserIds);
  145. throw new KDBizException("推送公众号消息失败,请联系管理员!");
  146. }
  147. }else{
  148. throw new KDBizException("推送公众号消息失败,获取token失败!");
  149. }
  150. }
  151. /**
  152. * 组装Json
  153. * @param entityNumber
  154. * @param bizDataId
  155. * @return
  156. */
  157. private JSONObject madeJsonObject(String entityNumber,Long bizDataId) {
  158. //获取表单名称 、 单据编号
  159. Map<String, String> queryEntityMap = queryEntityObject(entityNumber,bizDataId);
  160. // 动态构建 JSON 对象
  161. JSONObject dataJson = new JSONObject();
  162. // first 部分
  163. JSONObject firstObj = new JSONObject();
  164. firstObj.put("value", "【您有新的任务通知】 您有新的待办消息任务,请及时反馈执行进度");
  165. // msgType 部分
  166. JSONObject msgTypeObj = new JSONObject();
  167. msgTypeObj.put("value", queryEntityMap.get("entityName"));
  168. // orderNumber 部分
  169. JSONObject orderNumberObj = new JSONObject();
  170. orderNumberObj.put("value", queryEntityMap.get("billno"));
  171. // 组装完整 JSON
  172. dataJson.put("first", firstObj);
  173. dataJson.put("msgType", msgTypeObj);
  174. dataJson.put("orderNumber", orderNumberObj);
  175. return dataJson;
  176. }
  177. /**
  178. * 查询表单对象
  179. * @param entityNumber
  180. * @param bizDataId
  181. * @return
  182. */
  183. private Map<String, String> queryEntityObject(String entityNumber, Long bizDataId) {
  184. Map<String, String> map = new HashMap<>();
  185. //查询主实体对象 获取表单名称
  186. DynamicObject entityobject = BusinessDataServiceHelper.loadSingle("bos_entityobject","name",new QFilter[]{
  187. new QFilter("number", QCP.equals, entityNumber)});
  188. String entityName = entityobject.getString("name");
  189. map.put("entityName",entityName);
  190. //查询表单
  191. DynamicObject hotelcheckingbill = BusinessDataServiceHelper.loadSingle(entityNumber,"billno",new QFilter[]{
  192. new QFilter("id", QCP.equals, String.valueOf(bizDataId))
  193. });
  194. //单据编码
  195. String billno = hotelcheckingbill.getString("billno");
  196. map.put("billno",billno);
  197. return map;
  198. }
  199. //根据用户id获取微信openid
  200. private String getUserOpenId(Long userId) {
  201. String openid = "";
  202. //普通微信表里存了1
  203. QFilter filter = new QFilter("imtype", QCP.equals,"1");
  204. filter = filter.and(new QFilter("userid", QCP.equals,userId));
  205. DynamicObjectCollection openids = QueryServiceHelper.query("bas_immapping", "openid", new QFilter[]{filter});
  206. if(openids.size()>0){
  207. openid = openids.get(0).getString("openid");
  208. }
  209. return openid;
  210. }
  211. /**
  212. * 获取公共参数
  213. */
  214. private Map<String, Object> sysCtrlParam(String entityNumber) {
  215. //获取采购应用参数
  216. Map<String, Object> sysCtrlParamMap = ParamUtils.getSysCtrlParameter(ParamUtils.PM);
  217. //微信获取token地址
  218. sysCtrlParamMap.get("nckd_tokenurl");
  219. //公众号appid
  220. sysCtrlParamMap.get("nckd_appid");
  221. //公众号密码
  222. sysCtrlParamMap.get("nckd_appsecret");
  223. //公众号模板消息 模板id
  224. sysCtrlParamMap.get("nckd_textfield");
  225. //模板消息接口url
  226. sysCtrlParamMap.get("nckd_msgurl");
  227. //对应跳转信息
  228. sysCtrlParamMap.get("nckd_res");
  229. return sysCtrlParamMap;
  230. }
  231. /**
  232. * 获取采购应用参数
  233. * @param entityNumber
  234. * @param resStr
  235. * @return
  236. */
  237. public static Map<String, String> getResMap(String entityNumber, String resStr) {
  238. if (StringUtils.isEmpty(resStr)) {
  239. throw new KDBizException("请前往系统参数-应用-供应链云-采购应用参数 配置对应跳转信息");
  240. }
  241. //资源代号信息
  242. Map<String, String> res = ((List<Map<String, String>>) JSONObject.parseObject(resStr, List.class))
  243. .stream().filter(it -> it.get("nckd_rescaption").equals(entityNumber)).findAny().orElse(null);
  244. if (null == res) {
  245. throw new KDBizException("请前往系统参数-应用-供应链云-采购应用参数 对应跳转信息,配置供应商访问页面路径");
  246. }
  247. return res;
  248. }
  249. }