WeComMessageDataJob.java 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  1. package com.tzld.piaoquan.wecom.job;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONArray;
  4. import com.alibaba.fastjson.JSONObject;
  5. import com.aliyun.odps.data.Record;
  6. import com.google.common.collect.Lists;
  7. import com.tzld.piaoquan.wecom.dao.mapper.*;
  8. import com.tzld.piaoquan.wecom.model.bo.PushMessage;
  9. import com.tzld.piaoquan.wecom.model.bo.VideoCombination;
  10. import com.tzld.piaoquan.wecom.model.bo.VideoParam;
  11. import com.tzld.piaoquan.wecom.model.bo.XxlJobParam;
  12. import com.tzld.piaoquan.wecom.model.po.*;
  13. import com.tzld.piaoquan.wecom.model.vo.GuaranteedParam;
  14. import com.tzld.piaoquan.wecom.service.MessageAttachmentService;
  15. import com.tzld.piaoquan.wecom.service.MessageService;
  16. import com.tzld.piaoquan.wecom.utils.DateUtil;
  17. import com.tzld.piaoquan.wecom.utils.LarkRobotUtil;
  18. import com.tzld.piaoquan.wecom.utils.OdpsUtil;
  19. import com.tzld.piaoquan.wecom.utils.ToolUtils;
  20. import com.tzld.piaoquan.wecom.utils.page.Page;
  21. import com.xxl.job.core.biz.model.ReturnT;
  22. import com.xxl.job.core.handler.annotation.XxlJob;
  23. import lombok.extern.log4j.Log4j2;
  24. import org.apache.commons.lang3.StringUtils;
  25. import org.springframework.beans.factory.annotation.Autowired;
  26. import org.springframework.data.redis.core.RedisTemplate;
  27. import org.springframework.stereotype.Component;
  28. import org.springframework.util.CollectionUtils;
  29. import java.nio.charset.StandardCharsets;
  30. import java.util.*;
  31. import java.util.stream.Collectors;
  32. import static com.tzld.piaoquan.wecom.common.constant.MessageConstant.MAX_VIDEO_NUM;
  33. import static com.tzld.piaoquan.wecom.common.constant.RedisConstant.GUARANTEED_MINI_PROGRAM_KEY;
  34. import static com.tzld.piaoquan.wecom.common.constant.TimeConstant.MILLISECOND_DAY;
  35. @Log4j2
  36. @Component
  37. public class WeComMessageDataJob {
  38. @Autowired
  39. private UserMapper userMapper;
  40. @Autowired
  41. private MessageAttachmentMapper messageAttachmentMapper;
  42. @Autowired
  43. private RedisTemplate<String, Object> redisTemplate;
  44. @Autowired
  45. private MessageService messageService;
  46. @Autowired
  47. private MessageAttachmentService messageAttachmentService;
  48. @Autowired
  49. private StaffWithUserMapper staffWithUserMapper;
  50. @Autowired
  51. private StaffMapper staffMapper;
  52. @Autowired
  53. private SendMessageMapper sendMessageMapper;
  54. @Autowired
  55. private CorpMapper corpMapper;
  56. //发送小程序标题限制字节数
  57. private static final int MAX_BYTES = 64;
  58. //历史优质视频可推送用户列表
  59. Map<Long, List<PushMessage>> historicalTopMap = new HashMap<>();
  60. //保底视频列表
  61. Map<Long, VideoCombination> guaranteedVideoMap = new HashMap<>();
  62. Map<String, String> pageMap = new HashMap<>();
  63. //初始化操作
  64. private void init(List<Long> staffIds) {
  65. //历史优质视频获取
  66. String sql = String.format("SELECT * FROM loghubods.history_good_video_can_push_user_list where dt = %s;",
  67. DateUtil.getBeforeDayDateString());
  68. List<Record> recordList = OdpsUtil.getOdpsData(sql);
  69. if (CollectionUtils.isEmpty(recordList)) {
  70. LarkRobotUtil.sendMessage("历史优质视频为空");
  71. } else {
  72. List<PushMessage> list = new ArrayList<>();
  73. for (Record record : recordList) {
  74. PushMessage pushMessage = new PushMessage();
  75. Long videoId = Long.parseLong((String) record.get(0));
  76. Set<Long> userIds = new HashSet<>(JSONObject.parseArray((String) record.get(1), Long.class));
  77. Long staffId = Long.parseLong((String) record.get(2));
  78. Double score = Double.parseDouble((String) record.get(3));
  79. pushMessage.setVideoId(videoId);
  80. pushMessage.setUserIds(userIds);
  81. pushMessage.setStaffId(staffId);
  82. pushMessage.setScore(score);
  83. list.add(pushMessage);
  84. }
  85. historicalTopMap = list.stream()
  86. .collect(Collectors.groupingBy(PushMessage::getStaffId,
  87. Collectors.mapping(pushMessage -> pushMessage,
  88. Collectors.toList())))
  89. .entrySet()
  90. .stream()
  91. .collect(Collectors.toMap(
  92. Map.Entry::getKey,
  93. entry -> entry.getValue().stream()
  94. .sorted(Comparator.comparing(PushMessage::getScore).reversed()) // 根据 score 降序排序
  95. .collect(Collectors.toList())
  96. ));
  97. }
  98. //保底视频获取
  99. String key = String.format(GUARANTEED_MINI_PROGRAM_KEY, DateUtil.getThatDayDateString());
  100. GuaranteedParam guaranteedParam = (GuaranteedParam) redisTemplate.opsForValue().get(key);
  101. if (guaranteedParam == null
  102. || CollectionUtils.isEmpty(guaranteedParam.getVideoParamList())) {
  103. LarkRobotUtil.sendMessage("保底视频获取异常,请检查" + DateUtil.getThatDayDateString());
  104. throw new RuntimeException();
  105. }
  106. Map<Long, VideoCombination> videoMap = new HashMap<>();
  107. for (VideoParam videoParam : guaranteedParam.getVideoParamList()) {
  108. if (videoParam.getStaffId() == null) {
  109. LarkRobotUtil.sendMessage("保底视频获取异常,StaffId为空" + DateUtil.getThatDayDateString());
  110. continue;
  111. }
  112. if (videoParam.getStaffId() != 0) {
  113. if (!CollectionUtils.isEmpty(staffIds) && !staffIds.contains(videoParam.getStaffId())) {
  114. continue;
  115. }
  116. }
  117. //默认组视频不做查询
  118. if (videoParam.getStaffId() == 0L) {
  119. if (videoParam.getVideoIds().size() < MAX_VIDEO_NUM) {
  120. LarkRobotUtil.sendMessage("默认组视频数量不足" + DateUtil.getThatDayDateString());
  121. }
  122. videoMap.put(videoParam.getStaffId(), combination(videoParam.getVideoIds()));
  123. continue;
  124. }
  125. if (CollectionUtils.isEmpty(videoParam.getVideoIds()) || videoParam.getVideoIds().size() < MAX_VIDEO_NUM) {
  126. LarkRobotUtil.sendMessage("保底视频数量异常,请查看" + guaranteedParam.getDate() + videoParam.getStaffId());
  127. throw new RuntimeException();
  128. }
  129. for (Long videoId : videoParam.getVideoIds()) {
  130. MessageAttachmentExample example = new MessageAttachmentExample();
  131. example.createCriteria().andMiniprogramVideoIdEqualTo(videoId).andStaffIdEqualTo(videoParam.getStaffId());
  132. List<MessageAttachment> messageAttachmentList = messageAttachmentMapper.selectByExample(example);
  133. if (CollectionUtils.isEmpty(messageAttachmentList)) {
  134. LarkRobotUtil.sendMessage("保底视频不存在,请查看videoId=" + videoId);
  135. continue;
  136. }
  137. MessageAttachment messageAttachment = messageAttachmentList.get(0);
  138. if (messageAttachment.getSendTime() != null
  139. && DateUtil.dateDifference(new Date(), messageAttachment.getSendTime()) < 90 * MILLISECOND_DAY) {
  140. LarkRobotUtil.sendMessage("保底视频半年内已发送,请查看videoId=" + videoId);
  141. }
  142. }
  143. //重新组合视频id
  144. videoMap.put(videoParam.getStaffId(), combination(videoParam.getVideoIds()));
  145. }
  146. if (!videoMap.containsKey(0L)) {
  147. LarkRobotUtil.sendMessage("保底视频没有默认组,请查看" + guaranteedParam.getDate());
  148. throw new RuntimeException();
  149. }
  150. log.info("保底数据获取,videoMap={}", videoMap);
  151. this.guaranteedVideoMap = videoMap;
  152. }
  153. private VideoCombination combination(List<Long> videoIds) {
  154. VideoCombination videoCombination = new VideoCombination();
  155. videoCombination.setThreeVideoList(combinedVideoList(videoIds, 3));
  156. videoCombination.setThreeVideoIndex(0);
  157. videoCombination.setTwoVideoList(combinedVideoList(videoIds, 2));
  158. videoCombination.setTwoVideoIndex(0);
  159. videoCombination.setOneVideoList(combinedVideoList(videoIds, 1));
  160. videoCombination.setOneVideoIndex(0);
  161. return videoCombination;
  162. }
  163. private List<List<Long>> combinedVideoList(List<Long> videoIds, int count) {
  164. List<List<Long>> res = new ArrayList<>();
  165. // 此处假设视频的打开率与上下文无关,只保证每个视频在每个位置都有发送
  166. for (int i = 0; i < videoIds.size(); i++) {
  167. List<Long> list = new ArrayList<>();
  168. for (int j = 0; j < count; j++) {
  169. int index = (i + j) % videoIds.size();
  170. list.add(videoIds.get(index));
  171. }
  172. res.add(list);
  173. }
  174. return res;
  175. }
  176. @XxlJob("assembleSendMessageJob")
  177. public ReturnT<String> assembleSendMessage(String param) {
  178. XxlJobParam xxlJobParam = new XxlJobParam();
  179. if (StringUtils.isNotEmpty(param)) {
  180. xxlJobParam = JSONObject.parseObject(param, XxlJobParam.class);
  181. }
  182. CorpExample corpExample = new CorpExample();
  183. if (xxlJobParam.getCorpId() != null) {
  184. corpExample.createCriteria().andIdEqualTo(xxlJobParam.getCorpId());
  185. }
  186. List<Corp> corps = corpMapper.selectByExample(corpExample);
  187. if (CollectionUtils.isEmpty(corps)) {
  188. return ReturnT.SUCCESS;
  189. }
  190. List<Long> staffIds = new ArrayList<>();
  191. if (xxlJobParam.getStaffId() != null) {
  192. staffIds.add(xxlJobParam.getStaffId());
  193. }
  194. if (!CollectionUtils.isEmpty(xxlJobParam.getStaffIds())) {
  195. staffIds.addAll(xxlJobParam.getStaffIds());
  196. }
  197. init(staffIds);
  198. for (Corp corp : corps) {
  199. UserExample userExample = new UserExample();
  200. userExample.createCriteria().andExternalUserIdIsNotNull().andCorpIdEqualTo(corp.getId());
  201. if (xxlJobParam.getUserId() != null) {
  202. userExample.createCriteria().andIdEqualTo(xxlJobParam.getUserId());
  203. }
  204. long count = userMapper.countByExample(userExample);
  205. int page = 1;
  206. int pageSize = 1000;
  207. long totalPageSize = count / pageSize + 1;
  208. for (; page <= totalPageSize; page++) {
  209. userExample.setPage(new Page<>(page, pageSize));
  210. List<User> userList = userMapper.selectByExample(userExample);
  211. if (CollectionUtils.isEmpty(userList)) {
  212. continue;
  213. }
  214. //落库逻辑
  215. List<SendMessage> allSeneMessageList = new ArrayList<>();
  216. for (User user : userList) {
  217. List<SendMessage> sendMessageList = getSendMessage(user, staffIds, corp.getId());
  218. if (CollectionUtils.isEmpty(sendMessageList)) {
  219. continue;
  220. }
  221. allSeneMessageList.addAll(sendMessageList);
  222. }
  223. if (CollectionUtils.isEmpty(allSeneMessageList)) {
  224. continue;
  225. }
  226. sendMessageMapper.insertList(allSeneMessageList);
  227. }
  228. }
  229. //组装好当天要发送的消息后 记录时间
  230. saveGuaranteedVideoIdList(staffIds);
  231. return ReturnT.SUCCESS;
  232. }
  233. private void saveGuaranteedVideoIdList(List<Long> staffIds) {
  234. String key = String.format(GUARANTEED_MINI_PROGRAM_KEY, DateUtil.getThatDayDateString());
  235. GuaranteedParam guaranteedParam = (GuaranteedParam) redisTemplate.opsForValue().get(key);
  236. if (guaranteedParam == null || CollectionUtils.isEmpty(guaranteedParam.getVideoParamList())) {
  237. return;
  238. }
  239. if (CollectionUtils.isEmpty(staffIds)) {
  240. Set<Long> videoIdSet = new HashSet<>();
  241. for (VideoParam videoParam : guaranteedParam.getVideoParamList()) {
  242. if (CollectionUtils.isEmpty(videoParam.getVideoIds())) {
  243. continue;
  244. }
  245. videoIdSet.addAll(videoParam.getVideoIds());
  246. }
  247. List<Long> videoIdList = new ArrayList<>(videoIdSet);
  248. MessageAttachmentExample example = new MessageAttachmentExample();
  249. example.createCriteria().andMiniprogramVideoIdIn(videoIdList).andSendTimeIsNull();
  250. MessageAttachment updateMessageAttachment = new MessageAttachment();
  251. updateMessageAttachment.setSendTime(new Date());
  252. messageAttachmentMapper.updateByExampleSelective(updateMessageAttachment, example);
  253. } else {
  254. for (VideoParam videoParam : guaranteedParam.getVideoParamList()) {
  255. if (!CollectionUtils.isEmpty(staffIds) && staffIds.contains(videoParam.getStaffId())) {
  256. if (CollectionUtils.isEmpty(videoParam.getVideoIds())) {
  257. continue;
  258. }
  259. MessageAttachmentExample example = new MessageAttachmentExample();
  260. example.createCriteria().andMiniprogramVideoIdIn(videoParam.getVideoIds()).andStaffIdEqualTo(videoParam.getStaffId());
  261. MessageAttachment updateMessageAttachment = new MessageAttachment();
  262. updateMessageAttachment.setSendTime(new Date());
  263. messageAttachmentMapper.updateByExampleSelective(updateMessageAttachment, example);
  264. }
  265. }
  266. }
  267. }
  268. private List<SendMessage> getSendMessage(User user, List<Long> staffIds, Long corpId) {
  269. StaffWithUserExample example = new StaffWithUserExample();
  270. StaffWithUserExample.Criteria criteria = example.createCriteria();
  271. criteria.andUserIdEqualTo(user.getId());
  272. criteria.andIsDeleteEqualTo(0);
  273. if (!CollectionUtils.isEmpty(staffIds)) {
  274. criteria.andStaffIdIn(staffIds);
  275. }
  276. List<StaffWithUser> staffWithUserList = staffWithUserMapper.selectByExample(example);
  277. if (CollectionUtils.isEmpty(staffWithUserList)) {
  278. return Collections.emptyList();
  279. }
  280. List<SendMessage> sendMessageList = new ArrayList<>();
  281. for (StaffWithUser staffWithUser : staffWithUserList) {
  282. SendMessage sendMessage = new SendMessage();
  283. int n = fillHistoricalTopMessages(sendMessage, user.getId(), staffWithUser.getStaffId());
  284. if (n < MAX_VIDEO_NUM) {
  285. // 保底数据
  286. n = fillGuaranteedMessages(sendMessage, staffWithUser.getStaffId(), n);
  287. }
  288. if (n < MAX_VIDEO_NUM) {
  289. LarkRobotUtil.sendMessage("组装数据失败 user=" + user);
  290. throw new RuntimeException("组装数据失败");
  291. }
  292. sendMessage.setCorpId(corpId);
  293. sendMessage.setStaffId(staffWithUser.getStaffId());
  294. sendMessage.setUserId(staffWithUser.getUserId());
  295. sendMessageList.add(sendMessage);
  296. }
  297. return sendMessageList;
  298. }
  299. private int fillHistoricalTopMessages(SendMessage sendMessage, Long userId, Long staffId) {
  300. List<PushMessage> pushMessages = historicalTopMap.get(staffId);
  301. if (CollectionUtils.isEmpty(pushMessages)) {
  302. return 0;
  303. }
  304. int n = 0;
  305. for (PushMessage pushMessage : pushMessages) {
  306. if (pushMessage.getUserIds().contains(userId)) {
  307. setVideoId(sendMessage, n, pushMessage.getVideoId());
  308. n++;
  309. if (n >= MAX_VIDEO_NUM) {
  310. break;
  311. }
  312. }
  313. }
  314. return n;
  315. }
  316. private int fillGuaranteedMessages(SendMessage sendMessage, Long staffId, int currentCount) {
  317. VideoCombination videoCombination = guaranteedVideoMap.get(staffId);
  318. if (videoCombination == null) {
  319. videoCombination = guaranteedVideoMap.get(0L);
  320. }
  321. if (videoCombination == null) {
  322. log.error("保底数据获取失败,staffId={}, guaranteedVideoMap={}", staffId, guaranteedVideoMap);
  323. LarkRobotUtil.sendMessage("组装数据时,保底数据获取异常");
  324. throw new RuntimeException("保底数据获取异常");
  325. }
  326. if (currentCount < MAX_VIDEO_NUM) {
  327. switch (currentCount) {
  328. case 0:
  329. currentCount = setVideoId(sendMessage, videoCombination.getThreeVideoList().get(videoCombination.getThreeVideoIndex()),
  330. currentCount);
  331. videoCombination.setThreeVideoIndex(
  332. (videoCombination.getThreeVideoIndex() + 1) % videoCombination.getThreeVideoList().size());
  333. break;
  334. case 1:
  335. currentCount = setVideoId(sendMessage, videoCombination.getTwoVideoList().get(videoCombination.getTwoVideoIndex()),
  336. currentCount);
  337. videoCombination.setTwoVideoIndex(
  338. (videoCombination.getTwoVideoIndex() + 1) % videoCombination.getTwoVideoList().size());
  339. break;
  340. case 2:
  341. currentCount = setVideoId(sendMessage, videoCombination.getOneVideoList().get(videoCombination.getOneVideoIndex()),
  342. currentCount);
  343. videoCombination.setOneVideoIndex(
  344. (videoCombination.getOneVideoIndex() + 1) % videoCombination.getOneVideoList().size());
  345. break;
  346. default:
  347. break;
  348. }
  349. }
  350. return currentCount;
  351. }
  352. private int setVideoId(SendMessage sendMessage, List<Long> videoIds, Integer currentCount) {
  353. for (Long videoId : videoIds) {
  354. setVideoId(sendMessage, currentCount, videoId);
  355. currentCount++;
  356. if (currentCount >= MAX_VIDEO_NUM) {
  357. break;
  358. }
  359. }
  360. return currentCount;
  361. }
  362. private void setVideoId(SendMessage sendMessage, int index, Long videoId) {
  363. switch (index) {
  364. case 0:
  365. sendMessage.setVideoId1(videoId);
  366. break;
  367. case 1:
  368. sendMessage.setVideoId2(videoId);
  369. break;
  370. case 2:
  371. sendMessage.setVideoId3(videoId);
  372. break;
  373. default:
  374. break;
  375. }
  376. }
  377. @XxlJob("pushSendMessageJob")
  378. public ReturnT<String> pushSendMessage(String param) {
  379. XxlJobParam xxlJobParam = new XxlJobParam();
  380. if (StringUtils.isNotEmpty(param)) {
  381. xxlJobParam = JSONObject.parseObject(param, XxlJobParam.class);
  382. }
  383. List<SendMessage> groupList = sendMessageMapper.getGroupList(DateUtil.getThatDayDate(), 0);
  384. if (xxlJobParam.getCorpId() != null) {
  385. Long corpId = xxlJobParam.getCorpId();
  386. groupList = groupList.stream().filter(e -> Objects.equals(e.getCorpId(), corpId)).collect(Collectors.toList());
  387. }
  388. if (CollectionUtils.isEmpty(groupList)) {
  389. return ReturnT.SUCCESS;
  390. }
  391. if (xxlJobParam.getStaffId() != null) {
  392. Long staffId = xxlJobParam.getStaffId();
  393. groupList = groupList.stream().filter(e -> Objects.equals(e.getStaffId(), staffId)).collect(Collectors.toList());
  394. }
  395. if (CollectionUtils.isEmpty(groupList)) {
  396. return ReturnT.SUCCESS;
  397. }
  398. for (SendMessage sendMessage : groupList) {
  399. pushAndUpdateMessage(sendMessage);
  400. }
  401. Map<Long, List<SendMessage>> groupedByStaffId = groupList.stream().collect(Collectors.groupingBy(SendMessage::getStaffId));
  402. for (Map.Entry<Long, List<SendMessage>> entry : groupedByStaffId.entrySet()) {
  403. SendMessageExample example = new SendMessageExample();
  404. example.createCriteria().andStaffIdEqualTo(entry.getKey()).andIsSendEqualTo(0)
  405. .andCreateTimeGreaterThan(DateUtil.getThatDayDate());
  406. long l = sendMessageMapper.countByExample(example);
  407. //增加重试
  408. if (l > 0) {
  409. List<SendMessage> retryGroupList = sendMessageMapper.getGroupList(DateUtil.getThatDayDate(), 0);
  410. retryGroupList = retryGroupList.stream().filter(e -> Objects.equals(e.getStaffId(), entry.getKey()))
  411. .collect(Collectors.toList());
  412. for (SendMessage sendMessage : retryGroupList) {
  413. pushAndUpdateMessage(sendMessage);
  414. }
  415. }
  416. }
  417. SendMessageExample example = new SendMessageExample();
  418. example.createCriteria().andIsSendEqualTo(0).andCreateTimeGreaterThan(DateUtil.getThatDayDate());
  419. long l = sendMessageMapper.countByExample(example);
  420. if (l > 0) {
  421. LarkRobotUtil.sendMessage("存在发送失败消息,请检查@薛一鸣");
  422. }
  423. return ReturnT.SUCCESS;
  424. }
  425. private void pushAndUpdateMessage(SendMessage sendMessage) {
  426. sendMessage.setIsSend(0);
  427. sendMessage.setCreateTime(DateUtil.getThatDayDate());
  428. List<String> sendUserList = sendMessageMapper.selectExternalUserId(sendMessage);
  429. boolean flag = pushMessage(sendUserList, sendMessage);
  430. if (flag) {
  431. SendMessage updateSendMessage = new SendMessage();
  432. updateSendMessage.setIsSend(1);
  433. SendMessageExample example = new SendMessageExample();
  434. example.createCriteria()
  435. .andVideoId1EqualTo(sendMessage.getVideoId1())
  436. .andVideoId2EqualTo(sendMessage.getVideoId2())
  437. .andVideoId3EqualTo(sendMessage.getVideoId3())
  438. .andStaffIdEqualTo(sendMessage.getStaffId())
  439. .andCreateTimeGreaterThan(DateUtil.getThatDayDate());
  440. sendMessageMapper.updateByExampleSelective(updateSendMessage, example);
  441. }
  442. }
  443. private boolean pushMessage(List<String> sendUserList, SendMessage sendMessage) {
  444. List<JSONObject> pushList = new ArrayList<>();
  445. StaffExample staffExample = new StaffExample();
  446. staffExample.createCriteria().andIdEqualTo(sendMessage.getStaffId());
  447. List<Staff> staffList = staffMapper.selectByExample(staffExample);
  448. Staff staff = staffList.get(0);
  449. JSONObject jsonObject = new JSONObject();
  450. jsonObject.put("chat_type", "single");
  451. JSONObject text = new JSONObject();
  452. String content = messageService.getMessageText();
  453. text.put("content", content);
  454. jsonObject.put("text", text);
  455. jsonObject.put("sender", staff.getCarrierId());
  456. JSONArray attachments = new JSONArray();
  457. List<Long> videoIdList = new ArrayList<>();
  458. videoIdList.add(sendMessage.getVideoId1());
  459. videoIdList.add(sendMessage.getVideoId2());
  460. videoIdList.add(sendMessage.getVideoId3());
  461. for (Long videoId : videoIdList) {
  462. JSONObject attachment = new JSONObject();
  463. attachment.put("msgtype", "miniprogram");
  464. MessageAttachmentExample example = new MessageAttachmentExample();
  465. example.createCriteria().andMiniprogramVideoIdEqualTo(videoId);
  466. List<MessageAttachment> messageAttachmentList = messageAttachmentMapper.selectByExample(example);
  467. if (CollectionUtils.isEmpty(messageAttachmentList)) {
  468. log.error("附件信息查询异常");
  469. return false;
  470. }
  471. MessageAttachment messageAttachment = messageAttachmentList.get(0);
  472. JSONObject miniprogram = new JSONObject();
  473. miniprogram.put("appid", messageAttachment.getAppid());
  474. String title = messageAttachment.getTitle();
  475. if (title.getBytes(StandardCharsets.UTF_8).length > MAX_BYTES) {
  476. title = ToolUtils.truncateString(title, MAX_BYTES - 3) + "...";
  477. }
  478. miniprogram.put("title", title);
  479. String picMediaId = messageAttachmentService.getPicMediaId(messageAttachment.getCover(), sendMessage.getCorpId());
  480. if (StringUtils.isEmpty(picMediaId)) {
  481. log.error("pushMessage getPicMediaId error cover={}", messageAttachment.getCover());
  482. return false;
  483. }
  484. miniprogram.put("pic_media_id", picMediaId);
  485. String page = "";
  486. String key = staff.getCarrierId() + "_" + videoId;
  487. if (pageMap.containsKey(key)) {
  488. page = pageMap.get(key);
  489. } else {
  490. page = messageAttachmentService.getPage(staff, videoId);
  491. pageMap.put(key, page);
  492. }
  493. if (StringUtils.isEmpty(page)) {
  494. log.error("pushMessage get page error videoId={} staff={}", videoId, staff);
  495. return false;
  496. }
  497. miniprogram.put("page", page);
  498. attachment.put("miniprogram", miniprogram);
  499. attachments.add(0, attachment);
  500. }
  501. jsonObject.put("attachments", attachments);
  502. List<List<String>> lists = Lists.partition(sendUserList, 10000);
  503. for (List<String> list : lists) {
  504. JSONArray externalUserIds = JSONArray.parseArray(JSON.toJSONString(list));
  505. JSONObject newJSONObject = new JSONObject();
  506. newJSONObject.putAll(jsonObject);
  507. newJSONObject.put("external_userid", externalUserIds);
  508. pushList.add(newJSONObject);
  509. }
  510. if (CollectionUtils.isEmpty(pushList)) {
  511. return false;
  512. }
  513. for (JSONObject pushJsonObject : pushList) {
  514. log.info("pushMessage pushJsonObject={}", pushJsonObject);
  515. boolean flag = messageService.pushWeComMessage(pushJsonObject, sendMessage.getCorpId());
  516. if (!flag) {
  517. return flag;
  518. }
  519. }
  520. return true;
  521. }
  522. @XxlJob("existGuaranteesJob")
  523. public ReturnT<String> existGuarantees(String param) {
  524. //保底视频获取
  525. String key = String.format(GUARANTEED_MINI_PROGRAM_KEY, DateUtil.getNextDayDateString());
  526. GuaranteedParam guaranteedParam = (GuaranteedParam) redisTemplate.opsForValue().get(key);
  527. if (guaranteedParam == null
  528. || CollectionUtils.isEmpty(guaranteedParam.getVideoParamList())) {
  529. LarkRobotUtil.sendMessage("保底视频异常,请检查" + DateUtil.getNextDayDateString());
  530. }
  531. return ReturnT.SUCCESS;
  532. }
  533. }