WeComMessageDataJob.java 28 KB

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