WeComMessageDataJob.java 27 KB

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