|
|
@@ -0,0 +1,271 @@
|
|
|
+package com.fs.company.controller.company;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
|
|
+import com.fs.common.core.redis.RedisCacheT;
|
|
|
+import com.fs.common.utils.date.DateUtil;
|
|
|
+import com.fs.course.domain.FsCourseWatchLog;
|
|
|
+import com.fs.course.service.IFsCourseWatchLogService;
|
|
|
+import com.fs.qw.domain.QwUser;
|
|
|
+import com.fs.qw.mapper.QwIpadServerMapper;
|
|
|
+import com.fs.qw.mapper.QwPushCountMapper;
|
|
|
+import com.fs.qw.mapper.QwUserMapper;
|
|
|
+import com.fs.qw.service.impl.AsyncSopTestService;
|
|
|
+import com.fs.qw.vo.QwSopCourseFinishTempSetting;
|
|
|
+import com.fs.qw.vo.QwSopTempSetting;
|
|
|
+import com.fs.sop.domain.QwSopLogs;
|
|
|
+import com.fs.sop.mapper.QwSopLogsMapper;
|
|
|
+import com.fs.sop.service.IQwSopLogsService;
|
|
|
+import com.fs.sop.service.impl.QwSopLogsServiceImpl;
|
|
|
+import com.fs.system.mapper.SysConfigMapper;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.web.bind.annotation.PostMapping;
|
|
|
+import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
+import org.springframework.web.bind.annotation.RestController;
|
|
|
+
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.util.*;
|
|
|
+import java.util.concurrent.ConcurrentHashMap;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+@Slf4j
|
|
|
+@RestController()
|
|
|
+@RequestMapping("/test")
|
|
|
+public class TestController {
|
|
|
+ private final QwUserMapper qwUserMapper;
|
|
|
+ private final QwSopLogsMapper qwSopLogsMapper;
|
|
|
+ //private final IpadSendServer sendServer;
|
|
|
+ private final SysConfigMapper sysConfigMapper;
|
|
|
+ private final IQwSopLogsService qwSopLogsService;
|
|
|
+ private final AsyncSopTestService asyncSopTestService;
|
|
|
+ private final QwIpadServerMapper qwIpadServerMapper;
|
|
|
+ private final RedisCacheT<Long> redisCache;
|
|
|
+ private final QwPushCountMapper qwPushCountMapper;
|
|
|
+ // private final QwRestrictionPushRecordMapper qwRestrictionPushRecordMapper;
|
|
|
+ private final IFsCourseWatchLogService watchLogService;
|
|
|
+ private final List<QwUser> qwUserList = Collections.synchronizedList(new ArrayList<>());
|
|
|
+ private final Map<Long, Long> qwMap = new ConcurrentHashMap<>();
|
|
|
+
|
|
|
+ public TestController(QwUserMapper qwUserMapper, QwSopLogsMapper qwSopLogsMapper, SysConfigMapper sysConfigMapper, IQwSopLogsService qwSopLogsService, AsyncSopTestService asyncSopTestService, QwIpadServerMapper qwIpadServerMapper, RedisCacheT<Long> redisCache, QwPushCountMapper qwPushCountMapper, IFsCourseWatchLogService watchLogService) {
|
|
|
+ this.qwUserMapper = qwUserMapper;
|
|
|
+ this.qwSopLogsMapper = qwSopLogsMapper;
|
|
|
+// this.sendServer = sendServer;
|
|
|
+ this.sysConfigMapper = sysConfigMapper;
|
|
|
+ this.qwSopLogsService = qwSopLogsService;
|
|
|
+ this.asyncSopTestService = asyncSopTestService;
|
|
|
+ this.qwIpadServerMapper = qwIpadServerMapper;
|
|
|
+ this.redisCache = redisCache;
|
|
|
+ this.qwPushCountMapper = qwPushCountMapper;
|
|
|
+ this.watchLogService = watchLogService;
|
|
|
+ }
|
|
|
+
|
|
|
+ @PostMapping("/sendCourse")
|
|
|
+ public void sendCourse()
|
|
|
+ {
|
|
|
+// List<QwUser> qwUsers = qwUserMapper.selectList(new QueryWrapper<QwUser>().eq("id",26296L).in("server_id", 9));
|
|
|
+ QwUser qwUser = qwUserMapper.selectQwUserById(10482L);
|
|
|
+ long start1 = System.currentTimeMillis();
|
|
|
+ // 获取当前企微的app待发送记录
|
|
|
+ List<QwSopLogs> qwSopLogList = qwSopLogsMapper.selectAllAppEByQwUserId(qwUser.getId());
|
|
|
+ if (qwSopLogList.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ List<String> typeList = Arrays.asList("9", "15", "16");
|
|
|
+ // 获取企微用户
|
|
|
+ QwUser user = qwUserMapper.selectById(qwUser.getId());
|
|
|
+ long end1 = System.currentTimeMillis();
|
|
|
+ log.info("SendAppMsg-销售:{}, 消息:{}, 耗时: {}, 时间:{}", user.getQwUserName(), qwSopLogList.size(), end1 - start1, qwMap.get(qwUser.getId()));
|
|
|
+ long start3 = System.currentTimeMillis();
|
|
|
+ Map<String, Integer> pushCountMap = new HashMap<>();
|
|
|
+ qwPushCountMapper.selectQwPushCountListByType(typeList).forEach(e -> {String key = e.getCompanyId() != null ? String.valueOf(e.getCompanyId()) : String.valueOf(e.getType());
|
|
|
+ pushCountMap.put(key, Math.toIntExact(e.getPushCount()));});
|
|
|
+ // 循环待发送消息
|
|
|
+ for (QwSopLogs qwSopLogs : qwSopLogList) {
|
|
|
+ long start2 = System.currentTimeMillis();
|
|
|
+ QwSopCourseFinishTempSetting setting = JSON.parseObject(qwSopLogs.getContentJson(), QwSopCourseFinishTempSetting.class);
|
|
|
+ // 判断消息状态是否满足发送条件
|
|
|
+ if (!isSendLogs(qwSopLogs, setting, user)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ String key = "qw:logs:pad:send:id:" + qwSopLogs.getId();
|
|
|
+ Long time = redisCache.getCacheObject(key);
|
|
|
+ // 判断这个消息有没有进入过发送,如果进了就不要再发了,防止重复发送,,,,, TODO 千万不能动!!!!!
|
|
|
+// if (redisCache.getCacheObject(key) != null) {
|
|
|
+// log.error("{}已有发送:{}, :{}", qwUser.getQwUserName(), qwSopLogs.getId(), time);
|
|
|
+// continue;
|
|
|
+// }
|
|
|
+ List<QwSopTempSetting.Content.Setting> settings = JSON.parseArray(JSON.toJSONString(setting.getSetting()), QwSopTempSetting.Content.Setting.class);
|
|
|
+ List<QwSopCourseFinishTempSetting.Setting> allContent = setting.getSetting();
|
|
|
+
|
|
|
+ if (setting.getType() != 4 && !CollectionUtils.isEmpty(settings) && settings.stream().anyMatch(e -> typeList.contains(e.getContentType()))) {
|
|
|
+ // 发送前次数限制校验
|
|
|
+ Long qwUserId = qwUser.getId();
|
|
|
+ Long customerId = qwSopLogs.getFsUserId();
|
|
|
+ Long companyId = qwSopLogs.getCompanyId();
|
|
|
+ boolean txtSendStatus = true;
|
|
|
+ boolean mp3SendStatus = true;
|
|
|
+ boolean courseSendStatus = true;
|
|
|
+
|
|
|
+
|
|
|
+ redisCache.setCacheObject(key, System.currentTimeMillis(), 3, TimeUnit.HOURS);
|
|
|
+
|
|
|
+ // 推送 APP
|
|
|
+ if (!setting.getSetting().isEmpty()) {
|
|
|
+ try {
|
|
|
+// settings = JSON.parseArray(JSON.toJSONString(setting.getSetting()), QwSopTempSetting.Content.Setting.class).stream().filter(e -> "9".equals(e.getContentType())).collect(Collectors.toList());
|
|
|
+ List<QwSopCourseFinishTempSetting.Setting> linkList = allContent.stream().filter(e -> "9".equals(e.getContentType())&& !Integer.valueOf(2).equals(e.getSendStatus())).collect(Collectors.toList());
|
|
|
+
|
|
|
+ if (!linkList.isEmpty()) {
|
|
|
+ courseSendStatus = asyncSopTestService.asyncSendMsgBySopAppLinkNormalIM(linkList, qwSopLogs.getCorpId(), user.getCompanyUserId(), qwSopLogs.getFsUserId(), qwSopLogs.getId());
|
|
|
+ }
|
|
|
+ //app文本消息
|
|
|
+ log.info("开始发送app文本消息消息开始,消息{},用户{}", com.alibaba.fastjson.JSONObject.toJSONString(allContent), user.getQwUserName());
|
|
|
+// settings = JSON.parseArray(JSON.toJSONString(setting.getSetting()), QwSopTempSetting.Content.Setting.class).stream().filter(e -> "15".equals(e.getContentType())).collect(Collectors.toList());
|
|
|
+ List<QwSopCourseFinishTempSetting.Setting> txtList = allContent.stream().filter(e -> "15".equals(e.getContentType())&& e.getSendStatus() == null).collect(Collectors.toList());
|
|
|
+
|
|
|
+ if (!txtList.isEmpty()) {
|
|
|
+ txtSendStatus = asyncSopTestService.asyncSendMsgBySopAppTxtNormalIM(txtList, qwSopLogs.getCorpId(), qwUser.getCompanyUserId(), qwSopLogs.getFsUserId(), qwSopLogs.getId());
|
|
|
+ }
|
|
|
+ //app语音消息
|
|
|
+ log.info("开始发送app语音消息消息开始,消息{},用户{}", com.alibaba.fastjson.JSONObject.toJSONString(allContent), user.getQwUserName());
|
|
|
+// settings = JSON.parseArray(JSON.toJSONString(setting.getSetting()), QwSopTempSetting.Content.Setting.class).stream().filter(e -> "16".equals(e.getContentType())).collect(Collectors.toList());
|
|
|
+ List<QwSopCourseFinishTempSetting.Setting> voiceList = allContent.stream().filter(e -> "16".equals(e.getContentType())&& e.getSendStatus() == null).collect(Collectors.toList());
|
|
|
+ if (!voiceList.isEmpty()) {
|
|
|
+ mp3SendStatus = asyncSopTestService.asyncSendMsgBySopAppMP3NormalIM(voiceList, qwSopLogs.getCorpId(), qwUser.getCompanyUserId(), qwSopLogs.getFsUserId(), qwSopLogs.getId());
|
|
|
+ }
|
|
|
+ // 发送成功后记录次数
|
|
|
+ // 发送成功后记录次数(只记录真正发送的 content)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("推送APP失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+// qwSopLogs.setSend(true);
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
+ QwSopLogs updateQwSop = new QwSopLogs();
|
|
|
+ if (courseSendStatus&&txtSendStatus&&mp3SendStatus){
|
|
|
+ updateQwSop.setAppSendRemark("APP全部发送成功");
|
|
|
+ updateQwSop.setAppSendStatus(1);
|
|
|
+ }else if(!courseSendStatus&&!txtSendStatus&&!mp3SendStatus){
|
|
|
+ updateQwSop.setAppSendRemark("APP全部发送失败");
|
|
|
+ updateQwSop.setAppSendStatus(2);
|
|
|
+ }else {
|
|
|
+ updateQwSop.setAppSendRemark("APP部分发送失败");
|
|
|
+ updateQwSop.setAppSendStatus(2);
|
|
|
+ }
|
|
|
+ Set<String> contentTypes = allContent.stream()
|
|
|
+ .map(QwSopCourseFinishTempSetting.Setting::getContentType)
|
|
|
+ .collect(Collectors.toSet());
|
|
|
+
|
|
|
+ if (contentTypes.stream().allMatch(typeList::contains)) {
|
|
|
+ updateQwSop.setReceivingStatus(1L);
|
|
|
+ updateQwSop.setSendStatus(1L);
|
|
|
+ }
|
|
|
+ updateQwSop.setId(qwSopLogs.getId());
|
|
|
+ updateQwSop.setRealSendTime(sdf.format(new Date()));
|
|
|
+ updateQwSop.setContentJson(JSON.toJSONString(setting));
|
|
|
+// long end2 = System.currentTimeMillis();
|
|
|
+ int i = qwSopLogsService.updateQwSopLogsSendType(updateQwSop);
|
|
|
+// log.info("SendAppMsg-销售:{}, 修改条数{}, 发送方消息完成:{}, 耗时: {}", user.getQwUserName(), i, qwSopLogs.getId(), end2 - start2);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ Thread.sleep(500);
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ Thread.currentThread().interrupt();
|
|
|
+ log.warn("SendAppMsg-休眠被中断:{}", qwUser.getQwUserName());
|
|
|
+ }
|
|
|
+ long end3 = System.currentTimeMillis();
|
|
|
+ log.info("SendAppMsg-销售执行完成:{}, 耗时:{}", user.getQwUserName(), end3 - start3);
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean isSendLogs(QwSopLogs qwSopLogs, QwSopCourseFinishTempSetting setting, QwUser qwUser) {
|
|
|
+ if(qwSopLogs.getIsHaveApp()!=1){
|
|
|
+ log.info("不包含app课程:{}, LOGID: {}", qwUser.getQwUserName(), qwSopLogs.getId());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if(redisCache.getCacheObject("qw:user:id:" + qwUser.getId()) != null){
|
|
|
+ log.info("频率异常不发送:{}", qwUser.getQwUserName());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ boolean noSop = qwSopLogs.getSendType() != 3 && qwSopLogs.getSendType() != 7;
|
|
|
+
|
|
|
+ if (qwSopLogs.getExpiryTime() == null && noSop) {
|
|
|
+ // 作废消息
|
|
|
+ log.warn("SOP_LOG_ID:{}, SOP任务被删除", qwSopLogs.getId());
|
|
|
+ qwSopLogsService.updateQwSopLogsByWatchLogType(qwSopLogs.getId(), "SOP任务被删除");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ LocalDateTime sendTime = DateUtil.stringToLocalDateTime(qwSopLogs.getSendTime());
|
|
|
+ LocalDateTime expiryDateTime;
|
|
|
+
|
|
|
+ // 判断是否过期
|
|
|
+ if(qwSopLogs.getSendType() == 3 || qwSopLogs.getSendType() == 7){
|
|
|
+ expiryDateTime = sendTime.plusHours(16);
|
|
|
+ }else{
|
|
|
+ expiryDateTime = sendTime.plusHours(qwSopLogs.getExpiryTime());
|
|
|
+ }
|
|
|
+
|
|
|
+ if (LocalDateTime.now().isAfter(expiryDateTime) ) {
|
|
|
+ // 作废消息
|
|
|
+ log.warn("SOP_LOG_ID:{}, 已过期,不发送", qwSopLogs.getId());
|
|
|
+ qwSopLogsService.updateQwSopLogsByWatchLogType(qwSopLogs.getId(), "已过期,不发送");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (setting.getCourseType() == null && noSop && setting.getType() == 2) {
|
|
|
+ log.warn("SOP_LOG_ID:{}, 模板未选消息类型,不发送", qwSopLogs.getId());
|
|
|
+ qwSopLogsService.updateQwSopLogsByWatchLogType(qwSopLogs.getId(), "模板未选消息类型,不发送");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ Long cacheValue = redisCache.getCacheObject("sopCourse:video:isPause:" + setting.getVideoId());
|
|
|
+ Long isPause = (cacheValue != null) ? cacheValue : 0l;
|
|
|
+ log.info("SOP_LOG_ID:{},判断课程({})当前状态:{}", qwSopLogs.getId(), setting.getVideoId(), isPause);
|
|
|
+ if (isPause == 1){
|
|
|
+ log.info("SOP_LOG_ID:{}, 课程暂停,不发送", qwSopLogs.getId());
|
|
|
+ qwSopLogsService.updateQwSopLogsByWatchLogType(qwSopLogs.getId(), "课程暂停,AI不发送");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (qwSopLogs.getSendType() != 16 && noSop) {
|
|
|
+ // 客户的信息
|
|
|
+// QwExternalContactHParam contactHParam = new QwExternalContactHParam();
|
|
|
+// contactHParam.setUserId(qwUser.getQwUserId().trim());
|
|
|
+// contactHParam.setExternalUserId(qwSopLogs.getExternalUserId().trim());
|
|
|
+// contactHParam.setCorpId(qwUser.getCorpId().trim());
|
|
|
+ Integer courseType = setting.getCourseType();
|
|
|
+ if (setting.getType() == 2 && courseType != 0) {// 课程消息,进行复杂的条件判断
|
|
|
+// log.debug("企微查询:{}", contactHParam);
|
|
|
+// Long qwExternalContactId = qwExternalContactMapper.getQwExternalContactId(contactHParam);
|
|
|
+ FsCourseWatchLog watchLog = watchLogService.getWatchCourseLogVideoBySop(
|
|
|
+ setting.getVideoId().longValue(),
|
|
|
+ String.valueOf(qwUser.getId()),
|
|
|
+ qwSopLogs.getExternalId()
|
|
|
+ );
|
|
|
+ log.debug("ID:{}-看课记录参数:videoID:{}, qwUserID:{}, extID:{}", qwSopLogs.getId(), setting.getVideoId().longValue(), qwUser.getId(), qwSopLogs.getExternalId());
|
|
|
+ log.debug("ID:{}-看课记录:{}", qwSopLogs.getId(), watchLog);
|
|
|
+ String logId = qwSopLogs.getId();
|
|
|
+ if (watchLog != null) {
|
|
|
+ //新逻辑
|
|
|
+ if (!QwSopLogsServiceImpl.isCourseTypeValid(courseType, watchLog.getLogType())) {
|
|
|
+ // 作废消息
|
|
|
+ log.warn("SOP_LOG_ID:{}, 看课状态未满足,不发送", qwSopLogs.getId());
|
|
|
+ qwSopLogsService.updateQwSopLogsByWatchLogType(logId, "看课状态未满足,不发送");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ log.warn("SOP_LOG_ID:{}, 无观看记录,不发送", qwSopLogs.getId());
|
|
|
+ qwSopLogsService.updateQwSopLogsByWatchLogType(logId, "无观看记录,不发送");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+}
|