WeComMessageDataJob.java 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  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. throw new RuntimeException();
  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("保底视频90天内已发送,请查看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. throw new RuntimeException();
  170. }
  171. log.info("保底数据获取,videoMap={}", videoMap);
  172. this.guaranteedVideoMap = videoMap;
  173. }
  174. private VideoCombination combination(List<Long> videoIds) {
  175. VideoCombination videoCombination = new VideoCombination();
  176. videoCombination.setThreeVideoList(combinedVideoList(videoIds, 3));
  177. videoCombination.setThreeVideoIndex(0);
  178. videoCombination.setTwoVideoList(combinedVideoList(videoIds, 2));
  179. videoCombination.setTwoVideoIndex(0);
  180. videoCombination.setOneVideoList(combinedVideoList(videoIds, 1));
  181. videoCombination.setOneVideoIndex(0);
  182. return videoCombination;
  183. }
  184. private List<List<Long>> combinedVideoList(List<Long> videoIds, int count) {
  185. List<List<Long>> res = new ArrayList<>();
  186. // 此处假设视频的打开率与上下文无关,只保证每个视频在每个位置都有发送
  187. for (int i = 0; i < videoIds.size(); i++) {
  188. List<Long> list = new ArrayList<>();
  189. for (int j = 0; j < count; j++) {
  190. int index = (i + j) % videoIds.size();
  191. list.add(videoIds.get(index));
  192. }
  193. res.add(list);
  194. }
  195. return res;
  196. }
  197. @XxlJob("assembleSendMessageJob")
  198. public ReturnT<String> assembleSendMessage(String param) {
  199. XxlJobParam xxlJobParam = new XxlJobParam();
  200. if (StringUtils.isNotEmpty(param)) {
  201. xxlJobParam = JSONObject.parseObject(param, XxlJobParam.class);
  202. }
  203. CorpExample corpExample = new CorpExample();
  204. if (xxlJobParam.getCorpId() != null) {
  205. corpExample.createCriteria().andIdEqualTo(xxlJobParam.getCorpId());
  206. }
  207. List<Corp> corps = corpMapper.selectByExample(corpExample);
  208. if (CollectionUtils.isEmpty(corps)) {
  209. return ReturnT.SUCCESS;
  210. }
  211. List<Long> staffIds = new ArrayList<>();
  212. if (xxlJobParam.getStaffId() != null) {
  213. staffIds.add(xxlJobParam.getStaffId());
  214. }
  215. if (!CollectionUtils.isEmpty(xxlJobParam.getStaffIds())) {
  216. staffIds.addAll(xxlJobParam.getStaffIds());
  217. }
  218. init(staffIds);
  219. List<Long> filterUserId = weComUserService.getFilterTagUserId();
  220. for (Corp corp : corps) {
  221. WeComUserExample weComUserExample = new WeComUserExample();
  222. WeComUserExample.Criteria criteria = weComUserExample.createCriteria().andExternalUserIdIsNotNull().andCorpIdEqualTo(corp.getId())
  223. .andGroupMsgDisabledEqualTo((byte) 0);
  224. if (xxlJobParam.getUserId() != null) {
  225. criteria.andIdEqualTo(xxlJobParam.getUserId());
  226. }
  227. long count = weComUserMapper.countByExample(weComUserExample);
  228. int page = 1;
  229. int pageSize = 1000;
  230. long totalPageSize = count / pageSize + 1;
  231. for (; page <= totalPageSize; page++) {
  232. weComUserExample.setPage(new Page<>(page, pageSize));
  233. List<WeComUser> weComUserList = weComUserMapper.selectByExample(weComUserExample);
  234. if (CollectionUtils.isEmpty(weComUserList)) {
  235. continue;
  236. }
  237. //过滤用户
  238. List<WeComUser> filtered = weComUserList.stream()
  239. .filter(e -> !filterUserId.contains(e.getId())).collect(Collectors.toList());
  240. //落库逻辑
  241. List<SendMessage> allSeneMessageList = new ArrayList<>();
  242. for (WeComUser weComUser : filtered) {
  243. List<SendMessage> sendMessageList = getSendMessage(weComUser, staffIds, corp.getId());
  244. if (CollectionUtils.isEmpty(sendMessageList)) {
  245. continue;
  246. }
  247. allSeneMessageList.addAll(sendMessageList);
  248. }
  249. if (CollectionUtils.isEmpty(allSeneMessageList)) {
  250. continue;
  251. }
  252. sendMessageMapper.insertList(allSeneMessageList);
  253. }
  254. }
  255. //组装好当天要发送的消息后 记录时间
  256. saveGuaranteedVideoIdList(staffIds);
  257. return ReturnT.SUCCESS;
  258. }
  259. private void saveGuaranteedVideoIdList(List<Long> staffIds) {
  260. GuaranteedParam guaranteedParam = messageAttachmentService.getGuaranteedVideo(DateUtil.getThatDayDateString());
  261. if (guaranteedParam == null || CollectionUtils.isEmpty(guaranteedParam.getVideoParamList())) {
  262. return;
  263. }
  264. if (CollectionUtils.isEmpty(staffIds)) {
  265. Set<Long> videoIdSet = new HashSet<>();
  266. for (VideoParam videoParam : guaranteedParam.getVideoParamList()) {
  267. if (CollectionUtils.isEmpty(videoParam.getVideoIds())) {
  268. continue;
  269. }
  270. videoIdSet.addAll(videoParam.getVideoIds());
  271. }
  272. List<Long> videoIdList = new ArrayList<>(videoIdSet);
  273. MessageAttachmentExample example = new MessageAttachmentExample();
  274. example.createCriteria().andMiniprogramVideoIdIn(videoIdList).andSendTimeIsNull();
  275. MessageAttachment updateMessageAttachment = new MessageAttachment();
  276. updateMessageAttachment.setSendTime(new Date());
  277. messageAttachmentMapper.updateByExampleSelective(updateMessageAttachment, example);
  278. } else {
  279. for (VideoParam videoParam : guaranteedParam.getVideoParamList()) {
  280. if (!CollectionUtils.isEmpty(staffIds) && staffIds.contains(videoParam.getStaffId())) {
  281. if (CollectionUtils.isEmpty(videoParam.getVideoIds())) {
  282. continue;
  283. }
  284. MessageAttachmentExample example = new MessageAttachmentExample();
  285. example.createCriteria().andMiniprogramVideoIdIn(videoParam.getVideoIds()).andStaffIdEqualTo(videoParam.getStaffId());
  286. MessageAttachment updateMessageAttachment = new MessageAttachment();
  287. updateMessageAttachment.setSendTime(new Date());
  288. messageAttachmentMapper.updateByExampleSelective(updateMessageAttachment, example);
  289. }
  290. }
  291. }
  292. }
  293. private List<SendMessage> getSendMessage(WeComUser weComUser, List<Long> staffIds, Long corpId) {
  294. StaffWithUserExample example = new StaffWithUserExample();
  295. StaffWithUserExample.Criteria criteria = example.createCriteria();
  296. criteria.andUserIdEqualTo(weComUser.getId());
  297. criteria.andIsDeleteEqualTo(0);
  298. if (!CollectionUtils.isEmpty(staffIds)) {
  299. criteria.andStaffIdIn(staffIds);
  300. }
  301. List<StaffWithUser> staffWithUserList = staffWithUserMapper.selectByExample(example);
  302. if (CollectionUtils.isEmpty(staffWithUserList)) {
  303. return Collections.emptyList();
  304. }
  305. List<SendMessage> sendMessageList = new ArrayList<>();
  306. for (StaffWithUser staffWithUser : staffWithUserList) {
  307. SendMessage sendMessage = new SendMessage();
  308. int n = fillHistoricalTopMessages(sendMessage, weComUser.getId(), staffWithUser.getStaffId());
  309. if (n < MAX_VIDEO_NUM) {
  310. // 保底数据
  311. n = fillGuaranteedMessages(sendMessage, staffWithUser.getStaffId(), n);
  312. }
  313. if (n < MAX_VIDEO_NUM) {
  314. LarkRobotUtil.sendMessage("组装数据失败 weComUser=" + weComUser);
  315. throw new RuntimeException("组装数据失败");
  316. }
  317. sendMessage.setCorpId(corpId);
  318. sendMessage.setStaffId(staffWithUser.getStaffId());
  319. sendMessage.setUserId(staffWithUser.getUserId());
  320. sendMessageList.add(sendMessage);
  321. }
  322. return sendMessageList;
  323. }
  324. private int fillHistoricalTopMessages(SendMessage sendMessage, Long userId, Long staffId) {
  325. List<PushMessage> pushMessages = historicalTopMap.get(staffId);
  326. if (CollectionUtils.isEmpty(pushMessages)) {
  327. return 0;
  328. }
  329. int n = 0;
  330. for (PushMessage pushMessage : pushMessages) {
  331. if (pushMessage.getUserIds().contains(userId)) {
  332. setVideoId(sendMessage, n, pushMessage.getVideoId());
  333. n++;
  334. if (n >= MAX_VIDEO_NUM) {
  335. break;
  336. }
  337. }
  338. }
  339. return n;
  340. }
  341. private int fillGuaranteedMessages(SendMessage sendMessage, Long staffId, int currentCount) {
  342. VideoCombination videoCombination = guaranteedVideoMap.get(staffId);
  343. if (videoCombination == null) {
  344. videoCombination = guaranteedVideoMap.get(0L);
  345. }
  346. if (videoCombination == null) {
  347. log.error("保底数据获取失败,staffId={}, guaranteedVideoMap={}", staffId, guaranteedVideoMap);
  348. LarkRobotUtil.sendMessage("组装数据时,保底数据获取异常");
  349. throw new RuntimeException("保底数据获取异常");
  350. }
  351. if (currentCount < MAX_VIDEO_NUM) {
  352. switch (currentCount) {
  353. case 0:
  354. currentCount = setVideoId(sendMessage, videoCombination.getThreeVideoList().get(videoCombination.getThreeVideoIndex()),
  355. currentCount);
  356. videoCombination.setThreeVideoIndex(
  357. (videoCombination.getThreeVideoIndex() + 1) % videoCombination.getThreeVideoList().size());
  358. break;
  359. case 1:
  360. currentCount = setVideoId(sendMessage, videoCombination.getTwoVideoList().get(videoCombination.getTwoVideoIndex()),
  361. currentCount);
  362. videoCombination.setTwoVideoIndex(
  363. (videoCombination.getTwoVideoIndex() + 1) % videoCombination.getTwoVideoList().size());
  364. break;
  365. case 2:
  366. currentCount = setVideoId(sendMessage, videoCombination.getOneVideoList().get(videoCombination.getOneVideoIndex()),
  367. currentCount);
  368. videoCombination.setOneVideoIndex(
  369. (videoCombination.getOneVideoIndex() + 1) % videoCombination.getOneVideoList().size());
  370. break;
  371. default:
  372. break;
  373. }
  374. }
  375. return currentCount;
  376. }
  377. private int setVideoId(SendMessage sendMessage, List<Long> videoIds, Integer currentCount) {
  378. for (Long videoId : videoIds) {
  379. setVideoId(sendMessage, currentCount, videoId);
  380. currentCount++;
  381. if (currentCount >= MAX_VIDEO_NUM) {
  382. break;
  383. }
  384. }
  385. return currentCount;
  386. }
  387. private void setVideoId(SendMessage sendMessage, int index, Long videoId) {
  388. switch (index) {
  389. case 0:
  390. sendMessage.setVideoId1(videoId);
  391. break;
  392. case 1:
  393. sendMessage.setVideoId2(videoId);
  394. break;
  395. case 2:
  396. sendMessage.setVideoId3(videoId);
  397. break;
  398. default:
  399. break;
  400. }
  401. }
  402. @XxlJob("pushSendMessageJob")
  403. public ReturnT<String> pushSendMessage(String param) {
  404. XxlJobParam xxlJobParam = new XxlJobParam();
  405. if (StringUtils.isNotEmpty(param)) {
  406. xxlJobParam = JSONObject.parseObject(param, XxlJobParam.class);
  407. }
  408. List<SendMessage> groupList = sendMessageMapper.getGroupList(DateUtil.getThatDayDate(), 0);
  409. if (xxlJobParam.getCorpId() != null) {
  410. Long corpId = xxlJobParam.getCorpId();
  411. groupList = groupList.stream().filter(e -> Objects.equals(e.getCorpId(), corpId)).collect(Collectors.toList());
  412. }
  413. if (CollectionUtils.isEmpty(groupList)) {
  414. return ReturnT.SUCCESS;
  415. }
  416. if (xxlJobParam.getStaffId() != null) {
  417. Long staffId = xxlJobParam.getStaffId();
  418. groupList = groupList.stream().filter(e -> Objects.equals(e.getStaffId(), staffId)).collect(Collectors.toList());
  419. }
  420. if (CollectionUtils.isEmpty(groupList)) {
  421. return ReturnT.SUCCESS;
  422. }
  423. for (SendMessage sendMessage : groupList) {
  424. pushAndUpdateMessage(sendMessage);
  425. }
  426. Map<Long, List<SendMessage>> groupedByStaffId = groupList.stream().collect(Collectors.groupingBy(SendMessage::getStaffId));
  427. for (Map.Entry<Long, List<SendMessage>> entry : groupedByStaffId.entrySet()) {
  428. SendMessageExample example = new SendMessageExample();
  429. example.createCriteria().andStaffIdEqualTo(entry.getKey()).andIsSendEqualTo(0)
  430. .andCreateTimeGreaterThan(DateUtil.getThatDayDate());
  431. long l = sendMessageMapper.countByExample(example);
  432. //增加重试
  433. if (l > 0) {
  434. List<SendMessage> retryGroupList = sendMessageMapper.getGroupList(DateUtil.getThatDayDate(), 0);
  435. retryGroupList = retryGroupList.stream().filter(e -> Objects.equals(e.getStaffId(), entry.getKey()))
  436. .collect(Collectors.toList());
  437. for (SendMessage sendMessage : retryGroupList) {
  438. pushAndUpdateMessage(sendMessage);
  439. }
  440. }
  441. }
  442. SendMessageExample example = new SendMessageExample();
  443. example.createCriteria().andIsSendEqualTo(0).andCreateTimeGreaterThan(DateUtil.getThatDayDate());
  444. long l = sendMessageMapper.countByExample(example);
  445. if (l > 0) {
  446. LarkRobotUtil.sendMessage("存在发送失败消息,请检查@薛一鸣");
  447. }
  448. return ReturnT.SUCCESS;
  449. }
  450. private void pushAndUpdateMessage(SendMessage sendMessage) {
  451. sendMessage.setIsSend(0);
  452. sendMessage.setCreateTime(DateUtil.getThatDayDate());
  453. List<String> sendUserList = sendMessageMapper.selectExternalUserId(sendMessage);
  454. boolean flag = pushMessage(sendUserList, sendMessage);
  455. if (flag) {
  456. SendMessage updateSendMessage = new SendMessage();
  457. updateSendMessage.setIsSend(1);
  458. SendMessageExample example = new SendMessageExample();
  459. example.createCriteria()
  460. .andVideoId1EqualTo(sendMessage.getVideoId1())
  461. .andVideoId2EqualTo(sendMessage.getVideoId2())
  462. .andVideoId3EqualTo(sendMessage.getVideoId3())
  463. .andStaffIdEqualTo(sendMessage.getStaffId())
  464. .andCreateTimeGreaterThan(DateUtil.getThatDayDate());
  465. sendMessageMapper.updateByExampleSelective(updateSendMessage, example);
  466. }
  467. }
  468. private boolean pushMessage(List<String> sendUserList, SendMessage sendMessage) {
  469. List<JSONObject> pushList = new ArrayList<>();
  470. StaffExample staffExample = new StaffExample();
  471. staffExample.createCriteria().andIdEqualTo(sendMessage.getStaffId());
  472. List<Staff> staffList = staffMapper.selectByExample(staffExample);
  473. Staff staff = staffList.get(0);
  474. JSONObject jsonObject = new JSONObject();
  475. jsonObject.put("chat_type", "single");
  476. JSONObject text = new JSONObject();
  477. String content = messageService.getMessageText(staff.getId());
  478. text.put("content", content);
  479. jsonObject.put("text", text);
  480. jsonObject.put("sender", staff.getCarrierId());
  481. JSONArray attachments = new JSONArray();
  482. List<Long> videoIdList = new ArrayList<>();
  483. videoIdList.add(sendMessage.getVideoId1());
  484. videoIdList.add(sendMessage.getVideoId2());
  485. videoIdList.add(sendMessage.getVideoId3());
  486. for (Long videoId : videoIdList) {
  487. JSONObject attachment = new JSONObject();
  488. attachment.put("msgtype", "miniprogram");
  489. MessageAttachmentExample example = new MessageAttachmentExample();
  490. example.createCriteria().andMiniprogramVideoIdEqualTo(videoId);
  491. List<MessageAttachment> messageAttachmentList = messageAttachmentMapper.selectByExample(example);
  492. if (CollectionUtils.isEmpty(messageAttachmentList)) {
  493. log.error("附件信息查询异常");
  494. return false;
  495. }
  496. MessageAttachment messageAttachment = messageAttachmentList.get(0);
  497. JSONObject miniprogram = new JSONObject();
  498. miniprogram.put("appid", MessageConstant.appid);
  499. String title = messageAttachment.getTitle();
  500. if (title.getBytes(StandardCharsets.UTF_8).length > MAX_BYTES) {
  501. title = ToolUtils.truncateString(title, MAX_BYTES - 3) + "...";
  502. }
  503. miniprogram.put("title", title);
  504. String picMediaId = messageAttachmentService.getPicMediaId(messageAttachment.getCover(), sendMessage.getCorpId());
  505. if (StringUtils.isEmpty(picMediaId)) {
  506. log.error("pushMessage getPicMediaId error cover={}", messageAttachment.getCover());
  507. return false;
  508. }
  509. miniprogram.put("pic_media_id", picMediaId);
  510. String page = "";
  511. String key = staff.getCarrierId() + "_" + videoId;
  512. if (pageMap.containsKey(key)) {
  513. page = pageMap.get(key);
  514. } else {
  515. page = messageAttachmentService.getPage(staff, videoId);
  516. pageMap.put(key, page);
  517. }
  518. if (StringUtils.isEmpty(page)) {
  519. log.error("pushMessage get page error videoId={} staff={}", videoId, staff);
  520. return false;
  521. }
  522. miniprogram.put("page", page);
  523. attachment.put("miniprogram", miniprogram);
  524. attachments.add(0, attachment);
  525. }
  526. jsonObject.put("attachments", attachments);
  527. List<List<String>> lists = Lists.partition(sendUserList, 10000);
  528. for (List<String> list : lists) {
  529. JSONArray externalUserIds = JSONArray.parseArray(JSON.toJSONString(list));
  530. JSONObject newJSONObject = new JSONObject();
  531. newJSONObject.putAll(jsonObject);
  532. newJSONObject.put("external_userid", externalUserIds);
  533. pushList.add(newJSONObject);
  534. }
  535. if (CollectionUtils.isEmpty(pushList)) {
  536. return false;
  537. }
  538. for (JSONObject pushJsonObject : pushList) {
  539. log.info("pushMessage pushJsonObject={}", pushJsonObject);
  540. boolean flag = messageService.pushWeComMessage(pushJsonObject, sendMessage.getCorpId());
  541. if (!flag) {
  542. return flag;
  543. }
  544. }
  545. return true;
  546. }
  547. @XxlJob("existGuaranteesJob")
  548. public ReturnT<String> existGuarantees(String param) {
  549. //保底视频获取
  550. GuaranteedParam guaranteedParam = messageAttachmentService.getGuaranteedVideo(DateUtil.getNextDayDateString());
  551. if (guaranteedParam == null
  552. || CollectionUtils.isEmpty(guaranteedParam.getVideoParamList())) {
  553. LarkRobotUtil.sendMessage("@薛一鸣 保底视频异常,请检查" + DateUtil.getNextDayDateString());
  554. }
  555. return ReturnT.SUCCESS;
  556. }
  557. }