Explorar o código

Merge branch '20251208-wyp-videoCustomTitleCover' into test

# Conflicts:
#	api-module/src/main/java/com/tzld/piaoquan/api/job/contentplatform/ContentPlatformDatastatJob.java
#	api-module/src/main/java/com/tzld/piaoquan/api/service/contentplatform/impl/ContentPlatformPlanServiceImpl.java
#	api-module/src/main/resources/mapper/contentplatform/ContentPlatformGzhPlanVideoMapper.xml
wangyunpeng hai 2 semanas
pai
achega
cea7e1d141
Modificáronse 36 ficheiros con 1192 adicións e 404 borrados
  1. 2 0
      api-module/src/main/java/com/tzld/piaoquan/api/common/enums/ExceptionEnum.java
  2. 76 0
      api-module/src/main/java/com/tzld/piaoquan/api/component/ManagerApiService.java
  3. 46 14
      api-module/src/main/java/com/tzld/piaoquan/api/job/contentplatform/ContentPlatformDatastatJob.java
  4. 1 1
      api-module/src/main/java/com/tzld/piaoquan/api/job/contentplatform/ContentPlatformGzhAccountJob.java
  5. 85 55
      api-module/src/main/java/com/tzld/piaoquan/api/job/wecom/thirdpart/WeComSendMsgJob.java
  6. 42 25
      api-module/src/main/java/com/tzld/piaoquan/api/job/wecom/thirdpart/WeComUserDetailJob.java
  7. 42 30
      api-module/src/main/java/com/tzld/piaoquan/api/job/wecom/thirdpart/WeComVideoJob.java
  8. 22 11
      api-module/src/main/java/com/tzld/piaoquan/api/model/po/contentplatform/ContentPlatformAccount.java
  9. 140 70
      api-module/src/main/java/com/tzld/piaoquan/api/model/po/contentplatform/ContentPlatformAccountExample.java
  10. 22 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/po/contentplatform/ContentPlatformGzhPlanVideo.java
  11. 120 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/po/contentplatform/ContentPlatformGzhPlanVideoExample.java
  12. 3 2
      api-module/src/main/java/com/tzld/piaoquan/api/service/GhAccessTokenService.java
  13. 82 27
      api-module/src/main/java/com/tzld/piaoquan/api/service/contentplatform/impl/ContentPlatformPlanServiceImpl.java
  14. 24 6
      api-module/src/main/java/com/tzld/piaoquan/api/service/impl/GhAccessTokenServiceImpl.java
  15. 45 0
      api-module/src/main/java/com/tzld/piaoquan/api/service/strategy/ReplyStrategyService.java
  16. 16 14
      api-module/src/main/java/com/tzld/piaoquan/api/service/strategy/impl/BuckStrategyV1.java
  17. 8 8
      api-module/src/main/java/com/tzld/piaoquan/api/service/strategy/impl/ThirdPartyPushMessageStrategyV1.java
  18. 8 7
      api-module/src/main/java/com/tzld/piaoquan/api/service/strategy/impl/WeComPushMessageStrategyV1.java
  19. 2 2
      api-module/src/main/java/com/tzld/piaoquan/api/service/wecom/WeComService.java
  20. 10 10
      api-module/src/main/java/com/tzld/piaoquan/api/service/wecom/impl/ThirdPartyServiceImpl.java
  21. 14 1
      api-module/src/main/java/com/tzld/piaoquan/api/service/wecom/impl/WeComAutoReplyImpl.java
  22. 1 4
      api-module/src/main/java/com/tzld/piaoquan/api/service/wecom/impl/WeComServiceImpl.java
  23. 3 0
      api-module/src/main/java/com/tzld/piaoquan/api/service/wecom/thirdparty/impl/WeComThirdPartyRoomServiceImpl.java
  24. 7 0
      api-module/src/main/java/com/tzld/piaoquan/api/service/wecom/thirdparty/impl/WeComThirdPartyServiceImpl.java
  25. 47 34
      api-module/src/main/resources/mapper/contentplatform/ContentPlatformAccountMapper.xml
  26. 42 10
      api-module/src/main/resources/mapper/contentplatform/ContentPlatformGzhPlanVideoMapper.xml
  27. 9 9
      api-module/src/main/resources/mapper/contentplatform/ext/ContentPlatformDataStatMapperExt.xml
  28. 1 0
      api-module/src/main/resources/mapper/wecom/thirdpart/ext/ThirdPartWeComMapperExt.xml
  29. 22 0
      api-module/src/test/java/com/tzld/piaoquan/api/WeComTest.java
  30. 3 0
      common-module/src/main/java/com/tzld/piaoquan/growth/common/common/constant/WeComConstant.java
  31. 1 1
      common-module/src/main/java/com/tzld/piaoquan/growth/common/service/Impl/MessageAttachmentServiceImpl.java
  32. 1 1
      common-module/src/main/java/com/tzld/piaoquan/growth/common/service/Impl/MessageServiceImpl.java
  33. 24 1
      common-module/src/main/java/com/tzld/piaoquan/growth/common/utils/LarkRobotUtil.java
  34. 94 54
      offline-module/src/main/java/com/tzld/piaoquan/offline/job/WeComHistoryDataJob.java
  35. 93 2
      offline-module/src/main/java/com/tzld/piaoquan/offline/job/WeComMessageDataJob.java
  36. 34 5
      offline-module/src/main/java/com/tzld/piaoquan/offline/job/WeComStaffDataJob.java

+ 2 - 0
api-module/src/main/java/com/tzld/piaoquan/api/common/enums/ExceptionEnum.java

@@ -62,6 +62,8 @@ public enum ExceptionEnum {
     PQ_ACCOUNT_NOT_BINDING(6006, "票圈账号未绑定"),
     VIDEO_CITED(6007, "视频已被引用,不能删除"),
     VIDEO_GET_FAILED(6008, "视频获取失败"),
+    VIDEO_MULTI_TITLE_SAVE_FAILED(6009, "视频多标题保存失败"),
+    VIDEO_MULTI_COVER_SAVE_FAILED(6010, "视频多封面保存失败"),
 
     // 用户收藏视频
     VIDEO_NOT_EXIST(7001, "视频不存在"),

+ 76 - 0
api-module/src/main/java/com/tzld/piaoquan/api/component/ManagerApiService.java

@@ -0,0 +1,76 @@
+package com.tzld.piaoquan.api.component;
+
+import com.alibaba.fastjson.JSONObject;
+import com.tzld.piaoquan.api.common.enums.ExceptionEnum;
+import com.tzld.piaoquan.api.common.exception.CommonException;
+import com.tzld.piaoquan.growth.common.component.HttpPoolClient;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.Objects;
+
+@Slf4j
+@Component
+public class ManagerApiService {
+
+    @Autowired
+    private HttpPoolClient httpPoolClient;
+
+    @Value("${manager.api.host:https://testadmin.piaoquantv.com/manager}")
+    private String managerApiHost;
+
+    public JSONObject videoMultiTitleSave(Long videoId, String title) {
+        String url = managerApiHost + "/video/multiTitleV2/saveNoAuth";
+        JSONObject res = null;
+        try {
+            JSONObject param = new JSONObject();
+            param.put("videoId", videoId);
+            param.put("title", title);
+            param.put("source", 1);
+            String post = httpPoolClient.post(url, param.toJSONString());
+            res = JSONObject.parseObject(post);
+        } catch (Exception e) {
+            log.error("ManagerApiService videoMultiTitleSave error, videoId={} title={}",
+                    videoId, title, e);
+        }
+        if (Objects.isNull(res)) {
+            throw new CommonException(ExceptionEnum.VIDEO_MULTI_TITLE_SAVE_FAILED);
+        }
+        if (res.getInteger("code") != 0) {
+            log.error("ManagerApiService videoMultiTitleSave error, videoId={} title={} res={}",
+                    videoId, title, res);
+            throw new CommonException(ExceptionEnum.VIDEO_MULTI_TITLE_SAVE_FAILED.getCode(),
+                    ExceptionEnum.VIDEO_MULTI_TITLE_SAVE_FAILED.getMsg() + "," + res.getString("msg"));
+        }
+        return res.getJSONObject("content");
+    }
+
+    public JSONObject videoMultiCoverSave(Long videoId, String coverUrl) {
+        String url = managerApiHost + "/video/multiCover/saveNoAuth";
+        JSONObject res = null;
+        try {
+            JSONObject param = new JSONObject();
+            param.put("videoId", videoId);
+            param.put("coverUrl", coverUrl);
+            param.put("source", 1);
+            String post = httpPoolClient.post(url, param.toJSONString());
+            res = JSONObject.parseObject(post);
+        } catch (Exception e) {
+            log.error("ManagerApiService videoMultiCoverSave error, videoId={} coverUrl={}",
+                    videoId, coverUrl, e);
+        }
+        if (Objects.isNull(res)) {
+            throw new CommonException(ExceptionEnum.VIDEO_MULTI_COVER_SAVE_FAILED);
+        }
+        if (res.getInteger("code") != 0) {
+            log.error("ManagerApiService videoMultiCoverSave error, videoId={} coverUrl={} res={}",
+                    videoId, coverUrl, res);
+            throw new CommonException(ExceptionEnum.VIDEO_MULTI_COVER_SAVE_FAILED.getCode(),
+                    ExceptionEnum.VIDEO_MULTI_COVER_SAVE_FAILED.getMsg() + "," + res.getString("msg"));
+        }
+        return res.getJSONObject("content");
+    }
+
+}

+ 46 - 14
api-module/src/main/java/com/tzld/piaoquan/api/job/contentplatform/ContentPlatformDatastatJob.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.aliyun.odps.data.Record;
 import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
 import com.tzld.piaoquan.api.common.enums.contentplatform.AccountStatusEnum;
+import com.google.common.collect.Lists;
 import com.tzld.piaoquan.api.common.enums.contentplatform.BussinessTypeEnum;
 import com.tzld.piaoquan.api.component.AigcApiService;
 import com.tzld.piaoquan.api.dao.mapper.contentplatform.*;
@@ -586,25 +587,39 @@ public class ContentPlatformDatastatJob {
         }
         Map<Long, ContentPlatformQwPlan> planMap = qwPlanList.stream()
                 .collect(Collectors.toMap(ContentPlatformQwPlan::getId, plan -> plan));
-        List<ContentPlatformQwDataStat> existList = getQwDatastatCount(dt);
-        List<String> existRootSourceIds = existList.stream().map(ContentPlatformQwDataStat::getRootSourceId)
-                .collect(Collectors.toList());
         Map<String, Long> rootSourceIdMap = qwPlanList.stream()
                 .collect(Collectors.toMap(ContentPlatformQwPlan::getRootSourceId, ContentPlatformQwPlan::getId));
         List<Long> planIds = qwPlanList.stream().map(ContentPlatformQwPlan::getId).collect(Collectors.toList());
-        List<ContentPlatformQwPlanVideo> planVideoList = planService.getQwPlanVideoList(planIds);
+        List<ContentPlatformQwPlanVideo> planVideoList = new ArrayList<>();
+        List<List<Long>> partitionList = Lists.partition(planIds, 2000);
+        for (List<Long> partition : partitionList) {
+            planVideoList.addAll(planService.getQwPlanVideoList(partition));
+        }
         Map<Long, Long> planVideoMap = planVideoList.stream()
                 .collect(Collectors.toMap(ContentPlatformQwPlanVideo::getPlanId, ContentPlatformQwPlanVideo::getVideoId));
         List<Long> videoIds = planVideoList.stream().map(ContentPlatformQwPlanVideo::getVideoId).collect(Collectors.toList());
-        List<ContentPlatformVideoAgg> videoList = planService.getVideoContentAggListByVideoIds(videoIds);
+        List<ContentPlatformVideoAgg> videoList = new ArrayList<>();
+        List<List<Long>> videoIdPartitionList = Lists.partition(videoIds, 2000);
+        for (List<Long> partition : videoIdPartitionList) {
+            videoList.addAll(planService.getVideoContentAggListByVideoIds(partition));
+        }
         Map<Long, Double> videoScoreMap = videoList.stream()
                 .collect(Collectors.toMap(ContentPlatformVideoAgg::getVideoId, ContentPlatformVideoAgg::getScore, (a, b) -> a));
         List<ContentPlatformQwDataStat> saveList = new ArrayList<>();
         List<String> rootSourceIds = qwPlanList.stream().map(ContentPlatformQwPlan::getRootSourceId).collect(Collectors.toList());
-        String outSql = String.format("SELECT * FROM loghubods.qw_out_touliu_behavior_detail WHERE dt=%s;", dt);
-        List<Record> outDataList = OdpsUtil.getOdpsData(outSql);
+        List<String> existRootSourceIds = new ArrayList<>();
         Long now = System.currentTimeMillis();
-        if (CollectionUtils.isNotEmpty(outDataList)) {
+        int pageSize = 5000;
+        int pageNum = 1;
+        while (true) {
+            Integer offset = (pageNum - 1) * pageSize;
+            String outSql = String.format("SELECT rootsourceid, 首层访问人数 " +
+                    "FROM loghubods.qw_out_touliu_behavior_detail " +
+                    "WHERE dt=%s and 首层访问人数 > 0 limit %s,%s;", dt, offset, pageSize);
+            List<Record> outDataList = OdpsUtil.getOdpsData(outSql);
+            if (CollectionUtils.isEmpty(outDataList)) {
+                break;
+            }
             for (Record record : outDataList) {
                 ContentPlatformQwDataStat item = new ContentPlatformQwDataStat();
                 String rootSourceId = (String) record.get(0);
@@ -614,7 +629,7 @@ public class ContentPlatformDatastatJob {
                 if (existRootSourceIds.contains(rootSourceId)) {
                     continue;
                 }
-                int firstLevelCount = Integer.parseInt((String) record.get(8));
+                int firstLevelCount = Integer.parseInt((String) record.get(1));
                 if (firstLevelCount == 0) {
                     continue;
                 }
@@ -633,12 +648,24 @@ public class ContentPlatformDatastatJob {
                 item.setFirstLevelCount(firstLevelCount);
                 item.setCreateTimestamp(now);
                 saveList.add(item);
+                existRootSourceIds.add(rootSourceId);
+            }
+            if (outDataList.size() < pageSize) {
+                break;
             }
+            pageNum++;
         }
-        String out2Sql = String.format("SELECT * FROM loghubods.qw_out2_touliu_behavior_detail WHERE dt=%s;", dt);
-        List<Record> out2DataList = OdpsUtil.getOdpsData(out2Sql);
-        if (CollectionUtils.isNotEmpty(out2DataList)) {
-            for (Record record : out2DataList) {
+        pageNum = 1;
+        while (true) {
+            Integer offset = (pageNum - 1) * pageSize;
+            String out2Sql = String.format("SELECT rootsourceid, 首层访问人数 " +
+                    "FROM loghubods.qw_out2_touliu_behavior_detail " +
+                    "WHERE dt=%s and 首层访问人数 > 0 limit %s,%s;", dt, offset, pageSize);
+            List<Record> outDataList = OdpsUtil.getOdpsData(out2Sql);
+            if (CollectionUtils.isEmpty(outDataList)) {
+                break;
+            }
+            for (Record record : outDataList) {
                 ContentPlatformQwDataStat item = new ContentPlatformQwDataStat();
                 String rootSourceId = (String) record.get(0);
                 if (!rootSourceIds.contains(rootSourceId)) {
@@ -647,7 +674,7 @@ public class ContentPlatformDatastatJob {
                 if (existRootSourceIds.contains(rootSourceId)) {
                     continue;
                 }
-                int firstLevelCount = Integer.parseInt((String) record.get(8));
+                int firstLevelCount = Integer.parseInt((String) record.get(1));
                 if (firstLevelCount == 0) {
                     continue;
                 }
@@ -664,7 +691,12 @@ public class ContentPlatformDatastatJob {
                 item.setFirstLevelCount(firstLevelCount);
                 item.setCreateTimestamp(now);
                 saveList.add(item);
+                existRootSourceIds.add(rootSourceId);
+            }
+            if (outDataList.size() < pageSize) {
+                break;
             }
+            pageNum++;
         }
         if (CollectionUtils.isNotEmpty(saveList)) {
             dataStatMapperExt.deleteQwDatastat(dt);

+ 1 - 1
api-module/src/main/java/com/tzld/piaoquan/api/job/contentplatform/ContentPlatformGzhAccountJob.java

@@ -57,7 +57,7 @@ public class ContentPlatformGzhAccountJob {
 
     private List<ContentPlatformGzhAccount> getNeedSyncAccountInfo() {
         ContentPlatformGzhAccountExample example = new ContentPlatformGzhAccountExample();
-        example.createCriteria().andExternalIdIsNotNull();
+        example.createCriteria().andExternalIdIsNotNull().andStatusEqualTo(1);
         return gzhAccountMapper.selectByExample(example);
     }
 }

+ 85 - 55
api-module/src/main/java/com/tzld/piaoquan/api/job/wecom/thirdpart/WeComSendMsgJob.java

@@ -91,74 +91,104 @@ public class WeComSendMsgJob {
                 continue;
             }
             List<ThirdPartWeComRoom> roomList = weComThirdPartyService.getStaffRoomList(staff.getId());
+            if (CollectionUtils.isEmpty(roomList)) {
+                continue;
+            }
             List<Long> roomIds = roomList.stream().map(ThirdPartWeComRoom::getId).collect(Collectors.toList());
             List<ThirdPartWeComRoomConfig> roomConfigList = weComThirdPartyRoomService.getRoomConfigListByRoomIds(roomIds);
+            if (CollectionUtils.isEmpty(roomConfigList)) {
+                continue;
+            }
             Map<Long, ThirdPartWeComRoomConfig> roomConfigMap = roomConfigList.stream().collect(Collectors.toMap(ThirdPartWeComRoomConfig::getRoomId, a -> a));
             List<String> configIds = roomConfigList.stream().map(ThirdPartWeComRoomConfig::getId).map(String::valueOf).collect(Collectors.toList());
             List<ThirdPartWeComRoomConfigTask> roomConfigTaskList = weComThirdPartyRoomService.getRoomConfigTasks(configIds);
+            if (CollectionUtils.isEmpty(roomConfigTaskList)) {
+                continue;
+            }
             Map<String, List<ThirdPartWeComRoomConfigTask>> roomConfigTaskMap = roomConfigTaskList.stream()
                     .filter(o -> o.getSwitchFlag() == 1).collect(Collectors.groupingBy(ThirdPartWeComRoomConfigTask::getConfigId));
-            for (ThirdPartWeComRoom room : roomList) {
-                if (room.getSendStatus() != 1) {
+            sendStaffRoomMsg(staff, time, roomList, roomConfigMap, roomConfigTaskMap);
+        }
+        return ReturnT.SUCCESS;
+    }
+
+    private void sendStaffRoomMsg(ThirdPartWeComStaff staff,
+                                  String time,
+                                  List<ThirdPartWeComRoom> roomList,
+                                  Map<Long, ThirdPartWeComRoomConfig> roomConfigMap,
+                                  Map<String, List<ThirdPartWeComRoomConfigTask>> roomConfigTaskMap) {
+        for (ThirdPartWeComRoom room : roomList) {
+            if (room.getSendStatus() != 1) {
+                continue;
+            }
+            pool.execute(() -> {
+                ThirdPartWeComRoomConfig roomConfig = roomConfigMap.get(room.getId());
+                if (roomConfig == null) {
+                    return;
+                }
+                List<ThirdPartWeComRoomConfigTask> taskList = roomConfigTaskMap.getOrDefault(roomConfig.getId(), new ArrayList<>());
+                if (taskList.isEmpty()) {
+                    return;
+                }
+                List<String> configTaskIds = taskList.stream().map(ThirdPartWeComRoomConfigTask::getId).collect(Collectors.toList());
+                List<ThirdPartWeComRoomConfigTaskContent> taskContentList = weComThirdPartyRoomService.getRoomConfigTaskContents(configTaskIds);
+                if (CollectionUtils.isEmpty(taskContentList)) {
+                    return;
+                }
+                Map<String, List<ThirdPartWeComRoomConfigTaskContent>> taskContentMap = taskContentList.stream()
+                        .collect(Collectors.groupingBy(ThirdPartWeComRoomConfigTaskContent::getTaskId));
+                ThirdPartWeComStaff pushStaff = getSendStaff(roomConfig);
+                if (Objects.isNull(pushStaff)) {
+                    LarkRobotUtil.sendWeComThirdPartMessage(
+                            "【账号发送群消息,推送账号获取失败通知】\n" +
+                                    "账号名称:" + staff.getName() + "\n" +
+                                    "账号VID:" + staff.getThirdStaffId() + "\n" +
+                                    "群名称:" + room.getName());
+                    return;
+                }
+                sendRoomConfigTaskMsg(staff, pushStaff, time, room, roomConfig, taskList, taskContentMap);
+            });
+        }
+    }
+
+    private void sendRoomConfigTaskMsg(ThirdPartWeComStaff staff,
+                                       ThirdPartWeComStaff pushStaff,
+                                       String time,
+                                       ThirdPartWeComRoom room,
+                                       ThirdPartWeComRoomConfig roomConfig,
+                                       List<ThirdPartWeComRoomConfigTask> taskList,
+                                       Map<String, List<ThirdPartWeComRoomConfigTaskContent>> taskContentMap) {
+        for (ThirdPartWeComRoomConfigTask configTask : taskList) {
+            List<String> timeList = getRoomSendTime(room, roomConfig, configTask);
+            if (timeList.contains(time)) {
+                // 选取视频
+                List<ThirdPartWeComRoomConfigTaskContent> contentList = taskContentMap.get(configTask.getId());
+                if (Objects.isNull(contentList) || contentList.isEmpty()) {
                     continue;
                 }
-                pool.execute(() -> {
-                    ThirdPartWeComRoomConfig roomConfig = roomConfigMap.get(room.getId());
-                    if (roomConfig == null) {
-                        return;
-                    }
-                    List<ThirdPartWeComRoomConfigTask> taskList = roomConfigTaskMap.getOrDefault(roomConfig.getId(), new ArrayList<>());
-                    if (taskList.isEmpty()) {
-                        return;
-                    }
-                    List<String> configTaskIds = taskList.stream().map(ThirdPartWeComRoomConfigTask::getId).collect(Collectors.toList());
-                    List<ThirdPartWeComRoomConfigTaskContent> taskContentList = weComThirdPartyRoomService.getRoomConfigTaskContents(configTaskIds);
-                    Map<String, List<ThirdPartWeComRoomConfigTaskContent>> taskContentMap = taskContentList.stream()
-                            .collect(Collectors.groupingBy(ThirdPartWeComRoomConfigTaskContent::getTaskId));
-                    ThirdPartWeComStaff pushStaff = getSendStaff(roomConfig);
-                    if (Objects.isNull(pushStaff)) {
-                        LarkRobotUtil.sendWeComThirdPartMessage(
-                                "【账号发送群消息,推送账号获取失败通知】\n" +
-                                        "账号名称:" + staff.getName() + "\n" +
-                                        "账号VID:" + staff.getThirdStaffId() + "\n" +
-                                        "群名称:" + room.getName());
-                        return;
-                    }
-                    for (ThirdPartWeComRoomConfigTask configTask : taskList) {
-                        List<String> timeList = getRoomSendTime(room, roomConfig, configTask);
-                        if (timeList.contains(time)) {
-                            // 选取视频
-                            List<ThirdPartWeComRoomConfigTaskContent> contentList = taskContentMap.get(configTask.getId());
-                            if (Objects.isNull(contentList) || contentList.isEmpty()) {
-                                continue;
-                            }
-                            contentList = contentList.stream().sorted(Comparator.comparing(ThirdPartWeComRoomConfigTaskContent::getSeq)).collect(Collectors.toList());
-                            for (ThirdPartWeComRoomConfigTaskContent configTaskContent : contentList) {
-                                if (ConfigTaskContentTypeEnum.TEXT.getVal() == configTaskContent.getType()) {
-                                    // build发送体
-                                    SendTextMsgRequest request = buildSendTextMsgRequest(configTaskContent.getContent(), pushStaff, room);
-                                    // 发送消息
-                                    CommonResponse<SendTextMsgResponse> response = weComThirdPartyService.sendTextMsg(pushStaff, room, request);
-                                    // 存储消息
-                                    saveTextWeComMsg(pushStaff.getId(), configTaskContent.getContent(), request, response);
-                                } else if (ConfigTaskContentTypeEnum.MINI_PROGRAM.getVal() == configTaskContent.getType()) {
-                                    List<CgiReplyBucketData> cgiReplyBucketDataList = getCgiReplyBucketData(room.getThirdRoomId(), staff, roomConfig, configTaskContent);
-                                    for (CgiReplyBucketData cgiReplyBucketData : cgiReplyBucketDataList) {
-                                        // build发送体
-                                        SendAppMsgRequest request = buildSendAppMsgRequest(cgiReplyBucketData, pushStaff, room);
-                                        // 发送消息
-                                        CommonResponse<SendAppMsgResponse> response = weComThirdPartyService.sendAppMsg(pushStaff, room, request);
-                                        // 存储消息
-                                        saveAppWeComMsg(pushStaff.getId(), cgiReplyBucketData.getMiniVideoId(), request, response);
-                                    }
-                                }
-                            }
+                contentList = contentList.stream().sorted(Comparator.comparing(ThirdPartWeComRoomConfigTaskContent::getSeq)).collect(Collectors.toList());
+                for (ThirdPartWeComRoomConfigTaskContent configTaskContent : contentList) {
+                    if (ConfigTaskContentTypeEnum.TEXT.getVal() == configTaskContent.getType()) {
+                        // build发送体
+                        SendTextMsgRequest request = buildSendTextMsgRequest(configTaskContent.getContent(), pushStaff, room);
+                        // 发送消息
+                        CommonResponse<SendTextMsgResponse> response = weComThirdPartyService.sendTextMsg(pushStaff, room, request);
+                        // 存储消息
+                        saveTextWeComMsg(pushStaff.getId(), configTaskContent.getContent(), request, response);
+                    } else if (ConfigTaskContentTypeEnum.MINI_PROGRAM.getVal() == configTaskContent.getType()) {
+                        List<CgiReplyBucketData> cgiReplyBucketDataList = getCgiReplyBucketData(room.getThirdRoomId(), staff, roomConfig, configTaskContent);
+                        for (CgiReplyBucketData cgiReplyBucketData : cgiReplyBucketDataList) {
+                            // build发送体
+                            SendAppMsgRequest request = buildSendAppMsgRequest(cgiReplyBucketData, pushStaff, room);
+                            // 发送消息
+                            CommonResponse<SendAppMsgResponse> response = weComThirdPartyService.sendAppMsg(pushStaff, room, request);
+                            // 存储消息
+                            saveAppWeComMsg(pushStaff.getId(), cgiReplyBucketData.getMiniVideoId(), request, response);
                         }
                     }
-                });
+                }
             }
         }
-        return ReturnT.SUCCESS;
     }
 
     private ThirdPartWeComStaff getSendStaff(ThirdPartWeComRoomConfig roomConfig) {

+ 42 - 25
api-module/src/main/java/com/tzld/piaoquan/api/job/wecom/thirdpart/WeComUserDetailJob.java

@@ -79,27 +79,7 @@ public class WeComUserDetailJob {
         for (ThirdPartWeComStaff staff : activeStaffList) {
             pool.execute(() -> {
                 try {
-                    String uuid = staff.getThirdUuid();
-                    String offLineKey = "wecom:thirdpart:offline:" + uuid;
-                    if (redisUtils.containsKey(offLineKey)) {
-                        return;
-                    }
-                    String response = apiClient.getRunClientByUuid(new UuidRequest(uuid));
-                    CommonResponse<LoginInfo> commonResponse =
-                            JSONObject.parseObject(response, new TypeReference<CommonResponse<LoginInfo>>() {
-                            });
-                    if (commonResponse.getErrcode() == 0) {
-                        LoginInfo loginInfo = commonResponse.getData();
-                        staff.setName(loginInfo.getUser_info().getObject().getNickname());
-                        staff.setRealName(loginInfo.getUser_info().getObject().getRealname());
-                        staff.setMobile(loginInfo.getUser_info().getObject().getMobile());
-                        staff.setAvatar(loginInfo.getUser_info().getObject().getAvatar());
-                        staff.setName(loginInfo.getUser_info().getObject().getNickname());
-                        staff.setUpdateTime(new Date());
-                        staffMapper.updateByPrimaryKeySelective(staff);
-                    }
-                    syncRoomList(staff);
-                    syncStaffUserList(staff);
+                    syncStaffUserDetail(staff);
                 } catch (Exception e) {
                     log.error("syncUserDetail error", e);
                 } finally {
@@ -115,6 +95,37 @@ public class WeComUserDetailJob {
         return ReturnT.SUCCESS;
     }
 
+    public void syncStaffUserDetail(ThirdPartWeComStaff staff) {
+        // redis锁
+        String lockKey = "wecom:thirdpart:userDetail:lock:" + staff.getThirdUuid();
+        if (!redisUtils.tryLock(lockKey, "1", 5 * 60)) {
+            return;
+        }
+        String uuid = staff.getThirdUuid();
+        String offLineKey = "wecom:thirdpart:offline:" + uuid;
+        if (redisUtils.containsKey(offLineKey)) {
+            return;
+        }
+        String response = apiClient.getRunClientByUuid(new UuidRequest(uuid));
+        CommonResponse<LoginInfo> commonResponse =
+                JSONObject.parseObject(response, new TypeReference<CommonResponse<LoginInfo>>() {
+                });
+        if (commonResponse.getErrcode() == 0) {
+            LoginInfo loginInfo = commonResponse.getData();
+            staff.setName(loginInfo.getUser_info().getObject().getNickname());
+            staff.setRealName(loginInfo.getUser_info().getObject().getRealname());
+            staff.setMobile(loginInfo.getUser_info().getObject().getMobile());
+            staff.setAvatar(loginInfo.getUser_info().getObject().getAvatar());
+            staff.setName(loginInfo.getUser_info().getObject().getNickname());
+            staff.setUpdateTime(new Date());
+            staffMapper.updateByPrimaryKeySelective(staff);
+        }
+        syncRoomList(staff);
+        syncStaffUserList(staff);
+        // 清除redis锁
+        redisUtils.del(lockKey);
+    }
+
     private void syncStaffUserList(ThirdPartWeComStaff staff) {
         List<ExternalContactsResponse.ContactItem> contactItemList = thirdPartyService.getExternalContacts(
                 new GetExternalContactsRequest(staff.getThirdUuid(), 100, 0));
@@ -125,7 +136,16 @@ public class WeComUserDetailJob {
         List<ThirdPartWeComStaffUser> existUserList = getThirdPartWeComStaffUserListByStaffId(thirdStaffId);
         List<Long> existUserIdList = existUserList.stream().map(ThirdPartWeComStaffUser::getUserId).collect(Collectors.toList());
         Map<Long, ThirdPartWeComStaffUser> existUserMap = existUserList.stream()
-                .collect(Collectors.toMap(ThirdPartWeComStaffUser::getUserId, user -> user));
+                .collect(Collectors.toMap(ThirdPartWeComStaffUser::getUserId, user -> user, (a, b) -> {
+                    if (a.getAddCustomerTime() == 0) {
+                        return b;
+                    } else if (b.getAddCustomerTime() == 0) {
+                        return a;
+                    } else if (a.getAddCustomerTime() > b.getAddCustomerTime()) {
+                        return b;
+                    }
+                    return b;
+                }));
         List<ThirdPartWeComStaffUser> saveList = new ArrayList<>();
         List<ThirdPartWeComStaffUser> updateList = new ArrayList<>();
         for (ExternalContactsResponse.ContactItem contactItem : contactItemList) {
@@ -275,9 +295,6 @@ public class WeComUserDetailJob {
                     if (roomDetail.getMemberCount() >= memberMaxNums) {
                         roomDetail.setAddUserStatus(0);
                     }
-                    if (roomDetail.getMemberCount() >= sendMsgStatusNums && autoSendMsg) {
-                        roomDetail.setSendStatus(1);
-                    }
                 }
                 //roomMapper.updateByPrimaryKeySelective(roomDetail);
                 updateList.add(roomDetail);

+ 42 - 30
api-module/src/main/java/com/tzld/piaoquan/api/job/wecom/thirdpart/WeComVideoJob.java

@@ -78,42 +78,55 @@ public class WeComVideoJob {
                 saveList.add(item);
             }
             // 获取视频封面
-            for (List<ThirdPartWeComVideo> partition : Lists.partition(saveList, 20)) {
-                List<Long> videoIds = partition.stream().map(ThirdPartWeComVideo::getVideoId).distinct().collect(Collectors.toList());
-                Map<Long, VideoDetail> coverMap = messageAttachmentService.getVideoDetail(new HashSet<>(videoIds));
-                for (ThirdPartWeComVideo item : partition) {
-                    VideoDetail detail = coverMap.get(item.getVideoId());
-                    if (Objects.nonNull(detail)) {
-                        String cover = detail.getCover().substring(0, detail.getCover().indexOf("/watermark"));
-                        item.setCover(cover);
-                        if (detail.getAuditStatus() != 5) {
-                            item.setStatus(0);
-                        }
+            setVideoCover(saveList);
+            // save
+            batchSaveVideo(dt, saveList, now);
+        }
+        // 更新封面
+        updateVideoCover();
+        return ReturnT.SUCCESS;
+    }
+
+    private void setVideoCover(List<ThirdPartWeComVideo> videoList) {
+        for (List<ThirdPartWeComVideo> partition : Lists.partition(videoList, 20)) {
+            List<Long> videoIds = partition.stream().map(ThirdPartWeComVideo::getVideoId).distinct().collect(Collectors.toList());
+            Map<Long, VideoDetail> coverMap = messageAttachmentService.getVideoDetail(new HashSet<>(videoIds));
+            for (ThirdPartWeComVideo item : partition) {
+                VideoDetail detail = coverMap.get(item.getVideoId());
+                if (Objects.nonNull(detail)) {
+                    String cover = detail.getCover().substring(0, detail.getCover().indexOf("/watermark"));
+                    item.setCover(cover);
+                    if (detail.getAuditStatus() != 5) {
+                        item.setStatus(0);
                     }
                 }
             }
-            // save
-            if (CollectionUtils.isNotEmpty(saveList)) {
-                List<ThirdPartWeComVideo> videoList = getVideoList(dt);
-                List<ContentPlatformIllegalVideo> illegalVideoList = getAllIllegalVideoList();
-                List<Long> illegalVideoIds = illegalVideoList.stream().map(ContentPlatformIllegalVideo::getVideoId).collect(Collectors.toList());
-                if (CollectionUtils.isNotEmpty(illegalVideoIds)) {
-                    saveList = saveList.stream().filter(item -> !illegalVideoIds.contains(item.getVideoId())).collect(Collectors.toList());
-                }
-                if (CollectionUtils.isNotEmpty(videoList)) {
-                    List<Long> tempExistVideoIds = videoList.stream().map(ThirdPartWeComVideo::getVideoId).collect(Collectors.toList());
-                    List<Long> videoIdList = saveList.stream().map(ThirdPartWeComVideo::getVideoId).collect(Collectors.toList());
-                    videoMapperExt.updateOtherVideoStatus(dt, videoIdList, now);
-                    saveList = saveList.stream().filter(item -> !tempExistVideoIds.contains(item.getVideoId())).collect(Collectors.toList());
-                    if (CollectionUtils.isNotEmpty(saveList)) {
-                        videoMapperExt.batchInsertThirdPartWeComVideo(saveList);
-                    }
-                } else {
+        }
+    }
+
+    private void batchSaveVideo(String dt, List<ThirdPartWeComVideo> saveList, Long now) {
+        if (CollectionUtils.isNotEmpty(saveList)) {
+            List<ThirdPartWeComVideo> videoList = getVideoList(dt);
+            List<ContentPlatformIllegalVideo> illegalVideoList = getAllIllegalVideoList();
+            List<Long> illegalVideoIds = illegalVideoList.stream().map(ContentPlatformIllegalVideo::getVideoId).collect(Collectors.toList());
+            if (CollectionUtils.isNotEmpty(illegalVideoIds)) {
+                saveList = saveList.stream().filter(item -> !illegalVideoIds.contains(item.getVideoId())).collect(Collectors.toList());
+            }
+            if (CollectionUtils.isNotEmpty(videoList)) {
+                List<Long> tempExistVideoIds = videoList.stream().map(ThirdPartWeComVideo::getVideoId).collect(Collectors.toList());
+                List<Long> videoIdList = saveList.stream().map(ThirdPartWeComVideo::getVideoId).collect(Collectors.toList());
+                videoMapperExt.updateOtherVideoStatus(dt, videoIdList, now);
+                saveList = saveList.stream().filter(item -> !tempExistVideoIds.contains(item.getVideoId())).collect(Collectors.toList());
+                if (CollectionUtils.isNotEmpty(saveList)) {
                     videoMapperExt.batchInsertThirdPartWeComVideo(saveList);
                 }
+            } else {
+                videoMapperExt.batchInsertThirdPartWeComVideo(saveList);
             }
         }
-        // 更新封面
+    }
+
+    private void updateVideoCover() {
         List<ThirdPartWeComVideo> nullCoverVideoList = getVideoNullCover();
         if (CollectionUtils.isNotEmpty(nullCoverVideoList)) {
             for (List<ThirdPartWeComVideo> partition : Lists.partition(nullCoverVideoList, 20)) {
@@ -138,7 +151,6 @@ public class WeComVideoJob {
                 }
             }
         }
-        return ReturnT.SUCCESS;
     }
 
     private List<ContentPlatformIllegalVideo> getAllIllegalVideoList() {

+ 22 - 11
api-module/src/main/java/com/tzld/piaoquan/api/model/po/contentplatform/ContentPlatformAccount.java

@@ -9,6 +9,8 @@ public class ContentPlatformAccount {
 
     private String channel;
 
+    private String layerType;
+
     private String contactName;
 
     private String telNum;
@@ -21,6 +23,8 @@ public class ContentPlatformAccount {
 
     private Long tokenExpireTimestamp;
 
+    private String replySecret;
+
     private Integer status;
 
     private String createAccount;
@@ -31,8 +35,6 @@ public class ContentPlatformAccount {
 
     private Long updateTimestamp;
 
-    private String layerType;
-
     public Long getId() {
         return id;
     }
@@ -65,6 +67,14 @@ public class ContentPlatformAccount {
         this.channel = channel;
     }
 
+    public String getLayerType() {
+        return layerType;
+    }
+
+    public void setLayerType(String layerType) {
+        this.layerType = layerType;
+    }
+
     public String getContactName() {
         return contactName;
     }
@@ -113,6 +123,14 @@ public class ContentPlatformAccount {
         this.tokenExpireTimestamp = tokenExpireTimestamp;
     }
 
+    public String getReplySecret() {
+        return replySecret;
+    }
+
+    public void setReplySecret(String replySecret) {
+        this.replySecret = replySecret;
+    }
+
     public Integer getStatus() {
         return status;
     }
@@ -153,14 +171,6 @@ public class ContentPlatformAccount {
         this.updateTimestamp = updateTimestamp;
     }
 
-    public String getLayerType() {
-        return layerType;
-    }
-
-    public void setLayerType(String layerType) {
-        this.layerType = layerType;
-    }
-
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
@@ -171,18 +181,19 @@ public class ContentPlatformAccount {
         sb.append(", name=").append(name);
         sb.append(", identity=").append(identity);
         sb.append(", channel=").append(channel);
+        sb.append(", layerType=").append(layerType);
         sb.append(", contactName=").append(contactName);
         sb.append(", telNum=").append(telNum);
         sb.append(", price=").append(price);
         sb.append(", password=").append(password);
         sb.append(", token=").append(token);
         sb.append(", tokenExpireTimestamp=").append(tokenExpireTimestamp);
+        sb.append(", replySecret=").append(replySecret);
         sb.append(", status=").append(status);
         sb.append(", createAccount=").append(createAccount);
         sb.append(", createTimestamp=").append(createTimestamp);
         sb.append(", updateAccount=").append(updateAccount);
         sb.append(", updateTimestamp=").append(updateTimestamp);
-        sb.append(", layerType=").append(layerType);
         sb.append("]");
         return sb.toString();
     }

+ 140 - 70
api-module/src/main/java/com/tzld/piaoquan/api/model/po/contentplatform/ContentPlatformAccountExample.java

@@ -375,6 +375,76 @@ public class ContentPlatformAccountExample {
             return (Criteria) this;
         }
 
+        public Criteria andLayerTypeIsNull() {
+            addCriterion("layer_type is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andLayerTypeIsNotNull() {
+            addCriterion("layer_type is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andLayerTypeEqualTo(String value) {
+            addCriterion("layer_type =", value, "layerType");
+            return (Criteria) this;
+        }
+
+        public Criteria andLayerTypeNotEqualTo(String value) {
+            addCriterion("layer_type <>", value, "layerType");
+            return (Criteria) this;
+        }
+
+        public Criteria andLayerTypeGreaterThan(String value) {
+            addCriterion("layer_type >", value, "layerType");
+            return (Criteria) this;
+        }
+
+        public Criteria andLayerTypeGreaterThanOrEqualTo(String value) {
+            addCriterion("layer_type >=", value, "layerType");
+            return (Criteria) this;
+        }
+
+        public Criteria andLayerTypeLessThan(String value) {
+            addCriterion("layer_type <", value, "layerType");
+            return (Criteria) this;
+        }
+
+        public Criteria andLayerTypeLessThanOrEqualTo(String value) {
+            addCriterion("layer_type <=", value, "layerType");
+            return (Criteria) this;
+        }
+
+        public Criteria andLayerTypeLike(String value) {
+            addCriterion("layer_type like", value, "layerType");
+            return (Criteria) this;
+        }
+
+        public Criteria andLayerTypeNotLike(String value) {
+            addCriterion("layer_type not like", value, "layerType");
+            return (Criteria) this;
+        }
+
+        public Criteria andLayerTypeIn(List<String> values) {
+            addCriterion("layer_type in", values, "layerType");
+            return (Criteria) this;
+        }
+
+        public Criteria andLayerTypeNotIn(List<String> values) {
+            addCriterion("layer_type not in", values, "layerType");
+            return (Criteria) this;
+        }
+
+        public Criteria andLayerTypeBetween(String value1, String value2) {
+            addCriterion("layer_type between", value1, value2, "layerType");
+            return (Criteria) this;
+        }
+
+        public Criteria andLayerTypeNotBetween(String value1, String value2) {
+            addCriterion("layer_type not between", value1, value2, "layerType");
+            return (Criteria) this;
+        }
+
         public Criteria andContactNameIsNull() {
             addCriterion("contact_name is null");
             return (Criteria) this;
@@ -785,6 +855,76 @@ public class ContentPlatformAccountExample {
             return (Criteria) this;
         }
 
+        public Criteria andReplySecretIsNull() {
+            addCriterion("reply_secret is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andReplySecretIsNotNull() {
+            addCriterion("reply_secret is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andReplySecretEqualTo(String value) {
+            addCriterion("reply_secret =", value, "replySecret");
+            return (Criteria) this;
+        }
+
+        public Criteria andReplySecretNotEqualTo(String value) {
+            addCriterion("reply_secret <>", value, "replySecret");
+            return (Criteria) this;
+        }
+
+        public Criteria andReplySecretGreaterThan(String value) {
+            addCriterion("reply_secret >", value, "replySecret");
+            return (Criteria) this;
+        }
+
+        public Criteria andReplySecretGreaterThanOrEqualTo(String value) {
+            addCriterion("reply_secret >=", value, "replySecret");
+            return (Criteria) this;
+        }
+
+        public Criteria andReplySecretLessThan(String value) {
+            addCriterion("reply_secret <", value, "replySecret");
+            return (Criteria) this;
+        }
+
+        public Criteria andReplySecretLessThanOrEqualTo(String value) {
+            addCriterion("reply_secret <=", value, "replySecret");
+            return (Criteria) this;
+        }
+
+        public Criteria andReplySecretLike(String value) {
+            addCriterion("reply_secret like", value, "replySecret");
+            return (Criteria) this;
+        }
+
+        public Criteria andReplySecretNotLike(String value) {
+            addCriterion("reply_secret not like", value, "replySecret");
+            return (Criteria) this;
+        }
+
+        public Criteria andReplySecretIn(List<String> values) {
+            addCriterion("reply_secret in", values, "replySecret");
+            return (Criteria) this;
+        }
+
+        public Criteria andReplySecretNotIn(List<String> values) {
+            addCriterion("reply_secret not in", values, "replySecret");
+            return (Criteria) this;
+        }
+
+        public Criteria andReplySecretBetween(String value1, String value2) {
+            addCriterion("reply_secret between", value1, value2, "replySecret");
+            return (Criteria) this;
+        }
+
+        public Criteria andReplySecretNotBetween(String value1, String value2) {
+            addCriterion("reply_secret not between", value1, value2, "replySecret");
+            return (Criteria) this;
+        }
+
         public Criteria andStatusIsNull() {
             addCriterion("`status` is null");
             return (Criteria) this;
@@ -1104,76 +1244,6 @@ public class ContentPlatformAccountExample {
             addCriterion("update_timestamp not between", value1, value2, "updateTimestamp");
             return (Criteria) this;
         }
-
-        public Criteria andLayerTypeIsNull() {
-            addCriterion("layer_type is null");
-            return (Criteria) this;
-        }
-
-        public Criteria andLayerTypeIsNotNull() {
-            addCriterion("layer_type is not null");
-            return (Criteria) this;
-        }
-
-        public Criteria andLayerTypeEqualTo(String value) {
-            addCriterion("layer_type =", value, "layerType");
-            return (Criteria) this;
-        }
-
-        public Criteria andLayerTypeNotEqualTo(String value) {
-            addCriterion("layer_type <>", value, "layerType");
-            return (Criteria) this;
-        }
-
-        public Criteria andLayerTypeGreaterThan(String value) {
-            addCriterion("layer_type >", value, "layerType");
-            return (Criteria) this;
-        }
-
-        public Criteria andLayerTypeGreaterThanOrEqualTo(String value) {
-            addCriterion("layer_type >=", value, "layerType");
-            return (Criteria) this;
-        }
-
-        public Criteria andLayerTypeLessThan(String value) {
-            addCriterion("layer_type <", value, "layerType");
-            return (Criteria) this;
-        }
-
-        public Criteria andLayerTypeLessThanOrEqualTo(String value) {
-            addCriterion("layer_type <=", value, "layerType");
-            return (Criteria) this;
-        }
-
-        public Criteria andLayerTypeLike(String value) {
-            addCriterion("layer_type like", value, "layerType");
-            return (Criteria) this;
-        }
-
-        public Criteria andLayerTypeNotLike(String value) {
-            addCriterion("layer_type not like", value, "layerType");
-            return (Criteria) this;
-        }
-
-        public Criteria andLayerTypeIn(List<String> values) {
-            addCriterion("layer_type in", values, "layerType");
-            return (Criteria) this;
-        }
-
-        public Criteria andLayerTypeNotIn(List<String> values) {
-            addCriterion("layer_type not in", values, "layerType");
-            return (Criteria) this;
-        }
-
-        public Criteria andLayerTypeBetween(String value1, String value2) {
-            addCriterion("layer_type between", value1, value2, "layerType");
-            return (Criteria) this;
-        }
-
-        public Criteria andLayerTypeNotBetween(String value1, String value2) {
-            addCriterion("layer_type not between", value1, value2, "layerType");
-            return (Criteria) this;
-        }
     }
 
     public static class Criteria extends GeneratedCriteria {

+ 22 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/po/contentplatform/ContentPlatformGzhPlanVideo.java

@@ -9,10 +9,14 @@ public class ContentPlatformGzhPlanVideo {
 
     private String title;
 
+    private Long customTitleId;
+
     private String customTitle;
 
     private String cover;
 
+    private Long customCoverId;
+
     private String customCover;
 
     private Integer customCoverType;
@@ -59,6 +63,14 @@ public class ContentPlatformGzhPlanVideo {
         this.title = title;
     }
 
+    public Long getCustomTitleId() {
+        return customTitleId;
+    }
+
+    public void setCustomTitleId(Long customTitleId) {
+        this.customTitleId = customTitleId;
+    }
+
     public String getCustomTitle() {
         return customTitle;
     }
@@ -75,6 +87,14 @@ public class ContentPlatformGzhPlanVideo {
         this.cover = cover;
     }
 
+    public Long getCustomCoverId() {
+        return customCoverId;
+    }
+
+    public void setCustomCoverId(Long customCoverId) {
+        this.customCoverId = customCoverId;
+    }
+
     public String getCustomCover() {
         return customCover;
     }
@@ -141,8 +161,10 @@ public class ContentPlatformGzhPlanVideo {
         sb.append(", planId=").append(planId);
         sb.append(", videoId=").append(videoId);
         sb.append(", title=").append(title);
+        sb.append(", customTitleId=").append(customTitleId);
         sb.append(", customTitle=").append(customTitle);
         sb.append(", cover=").append(cover);
+        sb.append(", customCoverId=").append(customCoverId);
         sb.append(", customCover=").append(customCover);
         sb.append(", customCoverType=").append(customCoverType);
         sb.append(", video=").append(video);

+ 120 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/po/contentplatform/ContentPlatformGzhPlanVideoExample.java

@@ -365,6 +365,66 @@ public class ContentPlatformGzhPlanVideoExample {
             return (Criteria) this;
         }
 
+        public Criteria andCustomTitleIdIsNull() {
+            addCriterion("custom_title_id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCustomTitleIdIsNotNull() {
+            addCriterion("custom_title_id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCustomTitleIdEqualTo(Long value) {
+            addCriterion("custom_title_id =", value, "customTitleId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCustomTitleIdNotEqualTo(Long value) {
+            addCriterion("custom_title_id <>", value, "customTitleId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCustomTitleIdGreaterThan(Long value) {
+            addCriterion("custom_title_id >", value, "customTitleId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCustomTitleIdGreaterThanOrEqualTo(Long value) {
+            addCriterion("custom_title_id >=", value, "customTitleId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCustomTitleIdLessThan(Long value) {
+            addCriterion("custom_title_id <", value, "customTitleId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCustomTitleIdLessThanOrEqualTo(Long value) {
+            addCriterion("custom_title_id <=", value, "customTitleId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCustomTitleIdIn(List<Long> values) {
+            addCriterion("custom_title_id in", values, "customTitleId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCustomTitleIdNotIn(List<Long> values) {
+            addCriterion("custom_title_id not in", values, "customTitleId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCustomTitleIdBetween(Long value1, Long value2) {
+            addCriterion("custom_title_id between", value1, value2, "customTitleId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCustomTitleIdNotBetween(Long value1, Long value2) {
+            addCriterion("custom_title_id not between", value1, value2, "customTitleId");
+            return (Criteria) this;
+        }
+
         public Criteria andCustomTitleIsNull() {
             addCriterion("custom_title is null");
             return (Criteria) this;
@@ -505,6 +565,66 @@ public class ContentPlatformGzhPlanVideoExample {
             return (Criteria) this;
         }
 
+        public Criteria andCustomCoverIdIsNull() {
+            addCriterion("custom_cover_id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCustomCoverIdIsNotNull() {
+            addCriterion("custom_cover_id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCustomCoverIdEqualTo(Long value) {
+            addCriterion("custom_cover_id =", value, "customCoverId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCustomCoverIdNotEqualTo(Long value) {
+            addCriterion("custom_cover_id <>", value, "customCoverId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCustomCoverIdGreaterThan(Long value) {
+            addCriterion("custom_cover_id >", value, "customCoverId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCustomCoverIdGreaterThanOrEqualTo(Long value) {
+            addCriterion("custom_cover_id >=", value, "customCoverId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCustomCoverIdLessThan(Long value) {
+            addCriterion("custom_cover_id <", value, "customCoverId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCustomCoverIdLessThanOrEqualTo(Long value) {
+            addCriterion("custom_cover_id <=", value, "customCoverId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCustomCoverIdIn(List<Long> values) {
+            addCriterion("custom_cover_id in", values, "customCoverId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCustomCoverIdNotIn(List<Long> values) {
+            addCriterion("custom_cover_id not in", values, "customCoverId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCustomCoverIdBetween(Long value1, Long value2) {
+            addCriterion("custom_cover_id between", value1, value2, "customCoverId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCustomCoverIdNotBetween(Long value1, Long value2) {
+            addCriterion("custom_cover_id not between", value1, value2, "customCoverId");
+            return (Criteria) this;
+        }
+
         public Criteria andCustomCoverIsNull() {
             addCriterion("custom_cover is null");
             return (Criteria) this;

+ 3 - 2
api-module/src/main/java/com/tzld/piaoquan/api/service/GhAccessTokenService.java

@@ -1,6 +1,6 @@
 package com.tzld.piaoquan.api.service;
 
-import com.tzld.piaoquan.api.common.enums.SecretEnum;
+import com.tzld.piaoquan.api.model.po.contentplatform.ContentPlatformAccount;
 import com.tzld.piaoquan.api.model.vo.AccessTokenParam;
 import com.tzld.piaoquan.api.model.vo.AccessTokenVo;
 import com.tzld.piaoquan.growth.common.common.base.CommonResponse;
@@ -11,6 +11,7 @@ public interface GhAccessTokenService {
 
     boolean validateAccessToken(String accessToken);
 
-    SecretEnum getSecretEnum(String accessToken);
+    ContentPlatformAccount getAccountByAccessToken(String accessToken);
 
+    ContentPlatformAccount getAccountBySecret(String secret);
 }

+ 82 - 27
api-module/src/main/java/com/tzld/piaoquan/api/service/contentplatform/impl/ContentPlatformPlanServiceImpl.java

@@ -43,6 +43,8 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
 
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
 import java.util.*;
 import java.util.function.Function;
 import java.util.stream.Collectors;
@@ -95,6 +97,8 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
     private TouLiuHttpClient touLiuHttpClient;
     @Autowired
     ContentPlatformCollectContentService collectService;
+    @Autowired
+    private ManagerApiService managerApiService;
 
 
     @Value("${vlog.share.appType:11}")
@@ -179,6 +183,7 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
                         }
                     }
                     videoItemVO.setShareCover(getShareCover(ContentPlatformPlanService.getVideoCover(video)));
+                    videoItemVO.setPageUrl(buildCustomPageUrl(videoItemVO, video));
                     videoVOList.add(videoItemVO);
                 }
                 planItemVO.setVideoList(videoVOList);
@@ -189,6 +194,22 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
         return result;
     }
 
+    private String buildCustomPageUrl(GzhPlanVideoContentItemVO videoItemVO, ContentPlatformGzhPlanVideo video) {
+        String pageUrl = videoItemVO.getPageUrl();
+        try {
+            if (Objects.nonNull(video.getCustomTitleId()) && StringUtils.hasText(videoItemVO.getCustomTitle())) {
+                pageUrl += URLEncoder.encode("?shareTitleId=" + video.getCustomTitleId() + "?shareTitle=" + video.getTitle(), "UTF-8");
+            }
+            if (Objects.nonNull(video.getCustomCoverId()) && StringUtils.hasText(videoItemVO.getCustomCover())) {
+                pageUrl += URLEncoder.encode("?shareImageId=" + video.getCustomCoverId() + "?shareImageUrl=" + URLEncoder.encode(video.getCustomCover(), "UTF-8"), "UTF-8");
+            }
+            return pageUrl;
+        } catch (UnsupportedEncodingException e) {
+            log.error("buildCustomPageUrl error", e);
+        }
+        return videoItemVO.getPageUrl();
+    }
+
     @Override
     public List<ContentPlatformGzhPlanVideo> getGzhPlanVideoList(List<Long> planIds) {
         ContentPlatformGzhPlanVideoExample example = new ContentPlatformGzhPlanVideoExample();
@@ -303,7 +324,7 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
             // 更新gh_detail
             updateGhDetail(account, param.getSelectVideoType(), videoIds);
             // 更新cgi_reply_bucket_data
-            updateCgiReplyBucketData(account.getGhId(), param.getVideoList());
+            updateCgiReplyBucketData(account.getGhId());
         }
         // 保存视频内容
         saveGzhPlanVideo(param, videoIds, gzhPlan.getId(), account, loginAccount);
@@ -320,26 +341,8 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
         }
     }
 
-    private void updateCgiReplyBucketData(String ghId, List<GzhPlanVideoContentItemParam> videoList) {
+    private void updateCgiReplyBucketData(String ghId) {
         cgiReplyBucketDataMapperExt.deleteBucketDataByGhId(ghId);
-//        for (GzhPlanVideoContentItemParam video : videoList) {
-//            if (!StringUtils.hasText(video.getCustomCover()) && !StringUtils.hasText(video.getCustomTitle())) {
-//                continue;
-//            }
-//            List<CgiReplyBucketData> dataList = cgiReplyService.getCgiReplyBucketDataListByVideoId(video.getVideoId());
-//            if (CollectionUtils.isEmpty(dataList)) {
-//                continue;
-//            }
-//            String existsCover = dataList.get(0).getCoverUrl();
-//            if (!existsCover.contains("?")) {
-//                continue;
-//            }
-//            String coverSuffix = existsCover.substring(existsCover.indexOf("?"));
-//            String cover = video.getCover().substring(0, existsCover.indexOf("?"));
-//            cgiReplyBucketDataMapperExt.updateBucketDataTitleCoverByGhId(ghId, video.getVideoId(),
-//                    StringUtils.hasText(video.getCustomTitle()) ? video.getCustomTitle() : video.getTitle(),
-//                    StringUtils.hasText(video.getCustomCover()) ? video.getCustomCover() : cover + coverSuffix);
-//        }
     }
 
     private void saveGzhPlanVideo(GzhPlanSaveParam param, List<Long> videoIds, Long planId,
@@ -365,9 +368,9 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
             if (existsVideoIds.contains(vo.getVideoId())) {
                 ContentPlatformGzhPlanVideo item = existsVideoMap.get(vo.getVideoId());
                 item.setTitle(vo.getTitle());
-                item.setCustomTitle(vo.getCustomTitle());
+                setCustomTitle(item, vo);
                 item.setCover(vo.getCover());
-                item.setCustomCover(vo.getCustomCover());
+                setCustomCover(item, vo);
                 item.setCustomCoverType(vo.getCustomCoverType());
                 item.setStatus(VideoStatusEnum.NORMAL.getVal());
                 gzhPlanVideoMapper.updateByPrimaryKey(item);
@@ -376,9 +379,9 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
                 item.setPlanId(planId);
                 item.setVideoId(vo.getVideoId());
                 item.setTitle(vo.getTitle());
-                item.setCustomTitle(vo.getCustomTitle());
+                setCustomTitle(item, vo);
                 item.setCover(vo.getCover());
-                item.setCustomCover(vo.getCustomCover());
+                setCustomCover(item, vo);
                 item.setCustomCoverType(vo.getCustomCoverType());
                 item.setVideo(vo.getVideo());
                 if (param.getType() == ContentPlatformGzhPlanTypeEnum.FWH_PUSH.getVal()) {
@@ -405,6 +408,54 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
         }
     }
 
+    private void setCustomTitle(ContentPlatformGzhPlanVideo item, GzhPlanVideoContentItemParam vo) {
+        if (StringUtils.hasText(vo.getCustomTitle())) {
+            List<ContentPlatformGzhPlanVideo> gzhPlanVideoList = gzhPlanVideoListByVideoTitle(vo.getVideoId());
+            if (CollectionUtils.isNotEmpty(gzhPlanVideoList)) {
+                for (ContentPlatformGzhPlanVideo gzhPlanVideo : gzhPlanVideoList) {
+                    if (gzhPlanVideo.getCustomTitle().equals(vo.getCustomTitle())) {
+                        item.setCustomTitleId(gzhPlanVideo.getCustomTitleId());
+                        break;
+                    }
+                }
+            } else {
+                JSONObject multiTitle = managerApiService.videoMultiTitleSave(vo.getVideoId(), vo.getCustomTitle());
+                item.setCustomTitleId(multiTitle.getLong("id"));
+            }
+            item.setCustomTitle(vo.getCustomTitle());
+        }
+    }
+
+    private List<ContentPlatformGzhPlanVideo> gzhPlanVideoListByVideoTitle(Long videoId) {
+        ContentPlatformGzhPlanVideoExample example = new ContentPlatformGzhPlanVideoExample();
+        example.createCriteria().andVideoIdEqualTo(videoId).andCustomTitleIdIsNotNull();
+        return gzhPlanVideoMapper.selectByExample(example);
+    }
+
+    private void setCustomCover(ContentPlatformGzhPlanVideo item, GzhPlanVideoContentItemParam vo) {
+        if (StringUtils.hasText(vo.getCustomCover())) {
+            List<ContentPlatformGzhPlanVideo> gzhPlanVideoList = gzhPlanVideoListByVideoCover(vo.getVideoId());
+            if (CollectionUtils.isNotEmpty(gzhPlanVideoList)) {
+                for (ContentPlatformGzhPlanVideo gzhPlanVideo : gzhPlanVideoList) {
+                    if (gzhPlanVideo.getCustomCover().equals(vo.getCustomCover())) {
+                        item.setCustomCoverId(gzhPlanVideo.getCustomCoverId());
+                        break;
+                    }
+                }
+            } else {
+                JSONObject multiCover = managerApiService.videoMultiCoverSave(vo.getVideoId(), vo.getCustomCover());
+                item.setCustomCoverId(multiCover.getLong("id"));
+            }
+            item.setCustomCover(vo.getCustomCover());
+        }
+    }
+
+    private List<ContentPlatformGzhPlanVideo> gzhPlanVideoListByVideoCover(Long videoId) {
+        ContentPlatformGzhPlanVideoExample example = new ContentPlatformGzhPlanVideoExample();
+        example.createCriteria().andVideoIdEqualTo(videoId).andCustomCoverIdIsNotNull();
+        return gzhPlanVideoMapper.selectByExample(example);
+    }
+
     private void saveChangeVideoLog(Long planId, List<Long> existsVideoIds, List<GzhPlanVideoContentItemParam> videoList) {
         List<Long> newVideoIds = videoList.stream().map(GzhPlanVideoContentItemParam::getVideoId).collect(Collectors.toList());
         boolean changed = false;
@@ -435,15 +486,19 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
         GhDetail ghDetail = ghDetailService.getGhDetailByGhIdType(account.getGhId(), GhTypeEnum.THIRD_PARTY_GH.type);
         GhDetailVo detailVo = new GhDetailVo();
         Integer strategyStatus = selectVideoType == 0 ? StrategyStatusEnum.DEFAULT.status : StrategyStatusEnum.STRATEGY.status;
+        ContentPlatformAccount loginUser = LoginUserContext.getUser();
         if (Objects.nonNull(ghDetail)) {
             BeanUtils.copyProperties(ghDetail, detailVo);
-            detailVo.setVideoIds(videoIds);
+            detailVo.setAccountId(account.getGhId());
+            detailVo.setAccountName(account.getName());
+            detailVo.setType(GhTypeEnum.THIRD_PARTY_GH.type);
+            detailVo.setChannel(loginUser.getChannel());
+            detailVo.setCategory1(account.getContentType());
             detailVo.setStrategyStatus(strategyStatus);
+            detailVo.setVideoIds(videoIds);
             detailVo.setAutoreplySendMinigramNum(videoIds.size());
-            detailVo.setCategory1(account.getContentType());
             ghDetailService.updateDetail(detailVo);
         } else {
-            ContentPlatformAccount loginUser = LoginUserContext.getUser();
             detailVo.setAccountId(account.getGhId());
             detailVo.setAccountName(account.getName());
             detailVo.setType(GhTypeEnum.THIRD_PARTY_GH.type);

+ 24 - 6
api-module/src/main/java/com/tzld/piaoquan/api/service/impl/GhAccessTokenServiceImpl.java

@@ -1,6 +1,8 @@
 package com.tzld.piaoquan.api.service.impl;
 
-import com.tzld.piaoquan.api.common.enums.SecretEnum;
+import com.tzld.piaoquan.api.dao.mapper.contentplatform.ContentPlatformAccountMapper;
+import com.tzld.piaoquan.api.model.po.contentplatform.ContentPlatformAccount;
+import com.tzld.piaoquan.api.model.po.contentplatform.ContentPlatformAccountExample;
 import com.tzld.piaoquan.api.model.vo.AccessTokenParam;
 import com.tzld.piaoquan.api.model.vo.AccessTokenVo;
 import com.tzld.piaoquan.api.service.GhAccessTokenService;
@@ -12,6 +14,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 import java.util.concurrent.TimeUnit;
@@ -24,6 +27,8 @@ public class GhAccessTokenServiceImpl implements GhAccessTokenService {
 
     @Autowired
     private RedisTemplate<String, String> stringRedisTemplate;
+    @Autowired
+    private ContentPlatformAccountMapper contentPlatformAccountMapper;
 
 
     @Override
@@ -31,7 +36,8 @@ public class GhAccessTokenServiceImpl implements GhAccessTokenService {
         if (param == null || StringUtils.isEmpty(param.getSecret())) {
             return CommonResponse.create(ExceptionCodeEnum.PARAMS_ERROR, "未找到 secret");
         }
-        if (!SecretEnum.contains(param.getSecret())) {
+        ContentPlatformAccount account = getAccountBySecret(param.getSecret());
+        if (account == null) {
             return CommonResponse.create(ExceptionCodeEnum.PARAMS_ERROR, "secret 不存在");
         }
         AccessTokenVo accessTokenVo = new AccessTokenVo();
@@ -77,11 +83,23 @@ public class GhAccessTokenServiceImpl implements GhAccessTokenService {
     }
 
     @Override
-    public SecretEnum getSecretEnum(String accessToken) {
-        String secret = (String) stringRedisTemplate.opsForValue().get(accessToken);
-        if(StringUtils.isEmpty(secret)){
+    public ContentPlatformAccount getAccountByAccessToken(String accessToken) {
+        String secret = stringRedisTemplate.opsForValue().get(accessToken);
+        if (StringUtils.isEmpty(secret)) {
             return null;
         }
-        return SecretEnum.get(secret);
+        return getAccountBySecret(secret);
     }
+
+    @Override
+    public ContentPlatformAccount getAccountBySecret(String secret) {
+        ContentPlatformAccountExample example = new ContentPlatformAccountExample();
+        example.createCriteria().andReplySecretEqualTo(secret);
+        List<ContentPlatformAccount> list = contentPlatformAccountMapper.selectByExample(example);
+        if (list.isEmpty()) {
+            return null;
+        }
+        return list.get(0);
+    }
+
 }

+ 45 - 0
api-module/src/main/java/com/tzld/piaoquan/api/service/strategy/ReplyStrategyService.java

@@ -3,10 +3,55 @@ package com.tzld.piaoquan.api.service.strategy;
 import com.tzld.piaoquan.api.common.enums.ReplyStrategyServiceEnum;
 import com.tzld.piaoquan.api.model.bo.BucketDataParam;
 import com.tzld.piaoquan.api.model.bo.ReplyBucketData;
+import com.tzld.piaoquan.growth.common.model.po.CgiReplyBucketData;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 public interface ReplyStrategyService {
 
     ReplyBucketData getResult(BucketDataParam bucketDataParam);
 
     Boolean support(ReplyStrategyServiceEnum key);
+
+    static List<CgiReplyBucketData> checkCgiReplyBucketDataDiff(List<CgiReplyBucketData> result,
+                                                                List<CgiReplyBucketData> existCgiReplyBucketDataList) {
+        if (CollectionUtils.isEmpty(result)) {
+            return null;
+        }
+        if (result.size() != existCgiReplyBucketDataList.size()) {
+            return result;
+        }
+        Map<Long, CgiReplyBucketData> existCgiReplyBucketDataMap = existCgiReplyBucketDataList.stream()
+                .collect(Collectors.toMap(CgiReplyBucketData::getMiniVideoId, x -> x, (a, b) -> b));
+        boolean diff = false;
+        for (CgiReplyBucketData cgiReplyBucketData : result) {
+            if (!existCgiReplyBucketDataMap.containsKey(cgiReplyBucketData.getMiniVideoId())) {
+                diff = true;
+                break;
+            }
+            if (!StringUtils.equals(cgiReplyBucketData.getTitle(), existCgiReplyBucketDataMap.get(cgiReplyBucketData.getMiniVideoId()).getTitle())) {
+                diff = true;
+                break;
+            }
+            String resultCoverUrl = cgiReplyBucketData.getCoverUrl();
+            String existCoverUrl = existCgiReplyBucketDataMap.get(cgiReplyBucketData.getMiniVideoId()).getCoverUrl();
+            // cover处理,获取url
+            if (StringUtils.isNotEmpty(resultCoverUrl)) {
+                resultCoverUrl = resultCoverUrl.split("\\?")[0];
+            }
+            if (StringUtils.isNotEmpty(existCoverUrl)) {
+                existCoverUrl = existCoverUrl.split("\\?")[0];
+            }
+            if (!StringUtils.equals(resultCoverUrl, existCoverUrl)) {
+                diff = true;
+                break;
+            }
+        }
+        return diff ? result : null;
+    }
+
 }

+ 16 - 14
api-module/src/main/java/com/tzld/piaoquan/api/service/strategy/impl/BuckStrategyV1.java

@@ -399,22 +399,22 @@ public class BuckStrategyV1 implements ReplyStrategyService {
                 .andGhIdEqualTo(bucketDataParam.getGhId());
         long allCount = cgiReplyBucketDataMapper.countByExample(countExample);
         if (!CollectionUtils.isEmpty(bucketDataParam.getMiniPageDatas())) {
+            List<CgiReplyBucketData> existCgiReplyBucketDataList = new ArrayList<>();
             if (allCount == bucketDataParam.getMiniPageDatas().size()) {
-                int existNum = 0;
                 for (int i = 0; i < bucketDataParam.getMiniPageDatas().size(); i++) {
                     int sort = i + 1;
                     MiniPageData miniPageData = bucketDataParam.getMiniPageDatas().get(i);
                     CgiReplyBucketDataExample cgiReplyBucketDataExample = new CgiReplyBucketDataExample();
                     cgiReplyBucketDataExample.createCriteria().andIsDeleteEqualTo(0).andStrategyEqualTo(key)
                             .andGhIdEqualTo(bucketDataParam.getGhId()).andMiniPagePathEqualTo(miniPageData.getPage()).andSortEqualTo(sort);
-                    long count = cgiReplyBucketDataMapper.countByExample(cgiReplyBucketDataExample);
-                    if (count > 0) {
-                        existNum++;
+                    List<CgiReplyBucketData> list = cgiReplyBucketDataMapper.selectByExample(cgiReplyBucketDataExample);
+                    if (!CollectionUtils.isEmpty(list)) {
+                        existCgiReplyBucketDataList.addAll(list);
                     }
                 }
-                if (existNum == bucketDataParam.getMiniPageDatas().size()) {
-                    return null;
-                }
+                //if (existNum == bucketDataParam.getVideos().size()) {
+                //    continue;
+                //}
             }
 
             for (int i = 0; i < bucketDataParam.getMiniPageDatas().size(); i++) {
@@ -431,23 +431,24 @@ public class BuckStrategyV1 implements ReplyStrategyService {
                 cgiReplyBucketData.setMiniAppId(SMALL_APP_Id);
                 result.add(cgiReplyBucketData);
             }
+            result = ReplyStrategyService.checkCgiReplyBucketDataDiff(result, existCgiReplyBucketDataList);
         } else if (!CollectionUtils.isEmpty(bucketDataParam.getVideos())) {
+            List<CgiReplyBucketData> existCgiReplyBucketDataList = new ArrayList<>();
             if (allCount == bucketDataParam.getVideos().size()) {
-                int existNum = 0;
                 for (int i = 0; i < bucketDataParam.getVideos().size(); i++) {
                     int sort = i + 1;
                     Long videoId = bucketDataParam.getVideos().get(i);
                     CgiReplyBucketDataExample cgiReplyBucketDataExample = new CgiReplyBucketDataExample();
                     cgiReplyBucketDataExample.createCriteria().andIsDeleteEqualTo(0).andStrategyEqualTo(key)
                             .andGhIdEqualTo(bucketDataParam.getGhId()).andMiniVideoIdEqualTo(videoId).andSortEqualTo(sort);
-                    long count = cgiReplyBucketDataMapper.countByExample(cgiReplyBucketDataExample);
-                    if (count > 0) {
-                        existNum++;
+                    List<CgiReplyBucketData> list = cgiReplyBucketDataMapper.selectByExample(cgiReplyBucketDataExample);
+                    if (!CollectionUtils.isEmpty(list)) {
+                        existCgiReplyBucketDataList.addAll(list);
                     }
                 }
-                if (existNum == bucketDataParam.getVideos().size()) {
-                    return null;
-                }
+                //if (existNum == bucketDataParam.getVideos().size()) {
+                //    continue;
+                //}
             }
             for (int i = 0; i < bucketDataParam.getVideos().size(); i++) {
                 int sort = i + 1;
@@ -485,6 +486,7 @@ public class BuckStrategyV1 implements ReplyStrategyService {
                 cgiReplyBucketData.setMiniVideoId(videoId);
                 result.add(cgiReplyBucketData);
             }
+            result = ReplyStrategyService.checkCgiReplyBucketDataDiff(result, existCgiReplyBucketDataList);
         } else {
             return null;
         }

+ 8 - 8
api-module/src/main/java/com/tzld/piaoquan/api/service/strategy/impl/ThirdPartyPushMessageStrategyV1.java

@@ -286,22 +286,22 @@ public class ThirdPartyPushMessageStrategyV1 implements ReplyStrategyService {
                         result.add(cgiReplyBucketData);
                     }
                 } else if (!CollectionUtils.isEmpty(bucketDataParam.getVideos())) {
+                    List<CgiReplyBucketData> existCgiReplyBucketDataList = new ArrayList<>();
                     if (allCount == bucketDataParam.getVideos().size()) {
-                        int existNum = 0;
                         for (int i = 0; i < bucketDataParam.getVideos().size(); i++) {
                             int sort = i + 1;
                             Long videoId = bucketDataParam.getVideos().get(i);
                             CgiReplyBucketDataExample cgiReplyBucketDataExample = new CgiReplyBucketDataExample();
                             cgiReplyBucketDataExample.createCriteria().andIsDeleteEqualTo(0).andStrategyEqualTo(key)
                                     .andGhIdEqualTo(bucketDataParam.getGhId()).andMiniVideoIdEqualTo(videoId).andSortEqualTo(sort);
-                            long count = cgiReplyBucketDataMapper.countByExample(cgiReplyBucketDataExample);
-                            if (count > 0) {
-                                existNum++;
+                            List<CgiReplyBucketData> list = cgiReplyBucketDataMapper.selectByExample(cgiReplyBucketDataExample);
+                            if (!CollectionUtils.isEmpty(list)) {
+                                existCgiReplyBucketDataList.addAll(list);
                             }
                         }
-                        if (existNum == bucketDataParam.getVideos().size()) {
-                            continue;
-                        }
+                        //if (existNum == bucketDataParam.getVideos().size()) {
+                        //    continue;
+                        //}
                     }
                     Map<Long, VideoDetail> videoDetailMap = touLiuHttpClient.getVideoDetailRequest(bucketDataParam.getVideos());
                     List<ContentPlatformGzhPlanVideo> gzhPlanVideoList = contentPlatformPlanService.getGzhPlanVideoListByCooperateAccountId(bucketDataParam.getGhId());
@@ -343,7 +343,7 @@ public class ThirdPartyPushMessageStrategyV1 implements ReplyStrategyService {
                         cgiReplyBucketData.setMiniVideoId(videoId);
                         result.add(cgiReplyBucketData);
                     }
-
+                    result = ReplyStrategyService.checkCgiReplyBucketDataDiff(result, existCgiReplyBucketDataList);
                 } else {
                     return null;
                 }

+ 8 - 7
api-module/src/main/java/com/tzld/piaoquan/api/service/strategy/impl/WeComPushMessageStrategyV1.java

@@ -238,22 +238,22 @@ public class WeComPushMessageStrategyV1 implements ReplyStrategyService {
                 countExample.createCriteria().andIsDeleteEqualTo(0).andStrategyEqualTo(key)
                         .andGhIdEqualTo(bucketDataParam.getGhId());
                 long allCount = cgiReplyBucketDataMapper.countByExample(countExample);
+                List<CgiReplyBucketData> existCgiReplyBucketDataList = new ArrayList<>();
                 if (allCount == bucketDataParam.getVideos().size()) {
-                    int existNum = 0;
                     for (int i = 0; i < bucketDataParam.getVideos().size(); i++) {
                         int sort = i + 1;
                         Long videoId = bucketDataParam.getVideos().get(i);
                         CgiReplyBucketDataExample cgiReplyBucketDataExample = new CgiReplyBucketDataExample();
                         cgiReplyBucketDataExample.createCriteria().andIsDeleteEqualTo(0).andStrategyEqualTo(key)
                                 .andGhIdEqualTo(bucketDataParam.getGhId()).andMiniVideoIdEqualTo(videoId).andSortEqualTo(sort);
-                        long count = cgiReplyBucketDataMapper.countByExample(cgiReplyBucketDataExample);
-                        if (count > 0) {
-                            existNum++;
+                        List<CgiReplyBucketData> list = cgiReplyBucketDataMapper.selectByExample(cgiReplyBucketDataExample);
+                        if (!CollectionUtils.isEmpty(list)) {
+                            existCgiReplyBucketDataList.addAll(list);
                         }
                     }
-                    if (existNum == bucketDataParam.getVideos().size()) {
-                        continue;
-                    }
+                    //if (existNum == bucketDataParam.getVideos().size()) {
+                    //    continue;
+                    //}
                 }
                 Map<Long, VideoDetail> videoDetailMap = touLiuHttpClient.getVideoDetailRequest(bucketDataParam.getVideos());
                 for (int i = 0; i < bucketDataParam.getVideos().size(); i++) {
@@ -275,6 +275,7 @@ public class WeComPushMessageStrategyV1 implements ReplyStrategyService {
                     cgiReplyBucketData.setMiniVideoId(videoId);
                     result.add(cgiReplyBucketData);
                 }
+                result = ReplyStrategyService.checkCgiReplyBucketDataDiff(result, existCgiReplyBucketDataList);
             } else {
                 // 获取最新dt的策略
                 String dtVersion = algGhAutoreplyVideoRankDataMapper.selectLatestDtVersionByStrategyKeyAndGhId(key, bucketDataParam.getGhId());

+ 2 - 2
api-module/src/main/java/com/tzld/piaoquan/api/service/wecom/WeComService.java

@@ -1,7 +1,7 @@
 package com.tzld.piaoquan.api.service.wecom;
 
 
-
+import com.tzld.piaoquan.api.model.po.ReplyStaff;
 import com.tzld.piaoquan.api.model.vo.WeComPushMessageParam;
 import com.tzld.piaoquan.api.model.vo.WeComPushMessageVo;
 import com.tzld.piaoquan.growth.common.common.base.CommonResponse;
@@ -12,5 +12,5 @@ public interface WeComService {
 
     CommonResponse<List<WeComPushMessageVo>> getPushMessage(WeComPushMessageParam param);
 
-    List<WeComPushMessageVo> getPushMessageByUserId(String userId);
+    List<WeComPushMessageVo> getPushMessageByUserId(List<ReplyStaff> replyStaffs);
 }

+ 10 - 10
api-module/src/main/java/com/tzld/piaoquan/api/service/wecom/impl/ThirdPartyServiceImpl.java

@@ -4,17 +4,17 @@ import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.aliyun.odps.data.Record;
 import com.tzld.piaoquan.api.common.enums.ReplyStrategyServiceEnum;
-import com.tzld.piaoquan.api.common.enums.SecretEnum;
 import com.tzld.piaoquan.api.dao.mapper.GhDetailExtMapper;
 import com.tzld.piaoquan.api.model.bo.*;
 import com.tzld.piaoquan.api.model.po.GhDetailExt;
 import com.tzld.piaoquan.api.model.po.GhDetailExtExample;
+import com.tzld.piaoquan.api.model.po.contentplatform.ContentPlatformAccount;
 import com.tzld.piaoquan.api.model.vo.PushMessageParam;
 import com.tzld.piaoquan.api.model.vo.PushMessageVo;
 import com.tzld.piaoquan.api.model.vo.ReportUvVo;
 import com.tzld.piaoquan.api.service.GhAccessTokenService;
-import com.tzld.piaoquan.api.service.wecom.ThirdPartyService;
 import com.tzld.piaoquan.api.service.strategy.ReplyStrategyService;
+import com.tzld.piaoquan.api.service.wecom.ThirdPartyService;
 import com.tzld.piaoquan.growth.common.common.base.CommonResponse;
 import com.tzld.piaoquan.growth.common.common.constant.TimeConstant;
 import com.tzld.piaoquan.growth.common.common.enums.ExceptionCodeEnum;
@@ -80,11 +80,11 @@ public class ThirdPartyServiceImpl implements ThirdPartyService {
         if (!ghAccessTokenService.validateAccessToken(param.getAccessToken())) {
             return CommonResponse.create(ExceptionCodeEnum.PARAMS_ERROR, "accessToken错误或者已失效");
         }
-        SecretEnum secretEnum = ghAccessTokenService.getSecretEnum(param.getAccessToken());
-        if (secretEnum == null) {
+        ContentPlatformAccount account = ghAccessTokenService.getAccountByAccessToken(param.getAccessToken());
+        if (account == null) {
             return CommonResponse.create(ExceptionCodeEnum.PARAMS_ERROR, "获取secret失败");
         }
-        log.info("getPushMessage param={} secretEnum desc={}", param, secretEnum.desc);
+        log.info("getPushMessage param={} secretEnum desc={}", param, account.getName());
         GhDetailExample example = new GhDetailExample();
         example.createCriteria().andTypeEqualTo(GhTypeEnum.THIRD_PARTY_GH.type).andGhIdEqualTo(param.getGhId())
                 .andIsDeleteEqualTo(0);
@@ -95,10 +95,10 @@ public class ThirdPartyServiceImpl implements ThirdPartyService {
         GhDetail ghDetail = ghDetails.get(0);
         String channel = ghDetail.getChannel();
         if (channel == null) {
-            LarkRobotUtil.sendMessage("channel不存在,请查看详情 ghId=", param.getGhId());
+            LarkRobotUtil.sendMessage("channel不存在,请查看详情 ghId=" + param.getGhId());
             return CommonResponse.create(404, "ghId异常,请联系管理员检查");
         }
-        if (!Objects.equals(secretEnum.channel, channel)) {
+        if (!Objects.equals(account.getChannel(), channel)) {
 //            LarkRobotUtil.sendMessage(String.format("channel异常 secretEnum.channel=%s ghDetail.channel=%s ghId=%s",
 //                    secretEnum.channel, channel, param.getGhId()));
             return CommonResponse.create(404, "ghId异常,请联系管理员检查");
@@ -140,8 +140,8 @@ public class ThirdPartyServiceImpl implements ThirdPartyService {
         if (!ghAccessTokenService.validateAccessToken(accessToken)) {
             return CommonResponse.create(ExceptionCodeEnum.PARAMS_ERROR, "accessToken错误或者已失效");
         }
-        SecretEnum secretEnum = ghAccessTokenService.getSecretEnum(accessToken);
-        if (secretEnum == null) {
+        ContentPlatformAccount account = ghAccessTokenService.getAccountByAccessToken(accessToken);
+        if (account == null) {
             return CommonResponse.create(ExceptionCodeEnum.PARAMS_ERROR, "获取secret失败");
         }
         if (!DateUtil.isValidDate(canViewReportDate)) {
@@ -151,7 +151,7 @@ public class ThirdPartyServiceImpl implements ThirdPartyService {
         long nowTimestamp = System.currentTimeMillis() / 1000;
         long limitTime = nowTimestamp - 34L * TimeConstant.HOUR;
         long targetTime = DateUtil.dateStrToTimestamp(date, "yyyy-MM-dd");
-        String desc = secretEnum.desc;
+        String desc = account.getName();
         if (targetTime > limitTime) {
             return CommonResponse.create(500, "数据不存在");
         }

+ 14 - 1
api-module/src/main/java/com/tzld/piaoquan/api/service/wecom/impl/WeComAutoReplyImpl.java

@@ -3,8 +3,11 @@ package com.tzld.piaoquan.api.service.wecom.impl;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.tzld.piaoquan.api.dao.mapper.AutoReplyMsgSendRecordMapper;
+import com.tzld.piaoquan.api.dao.mapper.ReplyStaffMapper;
 import com.tzld.piaoquan.api.model.bo.MsgData;
 import com.tzld.piaoquan.api.model.po.AutoReplyMsgSendRecord;
+import com.tzld.piaoquan.api.model.po.ReplyStaff;
+import com.tzld.piaoquan.api.model.po.ReplyStaffExample;
 import com.tzld.piaoquan.api.model.vo.WeComPushMessageVo;
 import com.tzld.piaoquan.api.service.wecom.WeComAutoReply;
 import com.tzld.piaoquan.api.service.wecom.WeComService;
@@ -50,11 +53,21 @@ public class WeComAutoReplyImpl implements WeComAutoReply {
     @Autowired
     private AutoReplyMsgSendRecordMapper autoReplyMsgSendRecordMapper;
 
+    @Autowired
+    private ReplyStaffMapper replyStaffMapper;
+
     @Override
     public void AutoReplyMessage(String welcomeCode, String externalUserId, String userId, Long corpId) {
         Corp corp = corpMapper.selectByPrimaryKey(corpId);
         String corpCorpId = corp.getCorpId();
-        List<WeComPushMessageVo> weComPushMessageVoList = weComService.getPushMessageByUserId(userId);
+        // 判断是否需要自动回复
+        ReplyStaffExample example = new ReplyStaffExample();
+        example.createCriteria().andUserIdEqualTo(userId).andIsDeleteEqualTo(0);
+        List<ReplyStaff> replyStaffs = replyStaffMapper.selectByExample(example);
+        if (CollectionUtils.isEmpty(replyStaffs)) {
+            return;
+        }
+        List<WeComPushMessageVo> weComPushMessageVoList = weComService.getPushMessageByUserId(replyStaffs);
         WeComPushMessageVo weComPushMessageVo = getRandomElement(weComPushMessageVoList);
         if (weComPushMessageVo == null) {
             LarkRobotUtil.sendMessage("自动回复消息获取失败,userId=" + userId);

+ 1 - 4
api-module/src/main/java/com/tzld/piaoquan/api/service/wecom/impl/WeComServiceImpl.java

@@ -116,10 +116,7 @@ public class WeComServiceImpl implements WeComService {
     }
 
     @Override
-    public List<WeComPushMessageVo> getPushMessageByUserId(String userId) {
-        ReplyStaffExample example = new ReplyStaffExample();
-        example.createCriteria().andUserIdEqualTo(userId).andIsDeleteEqualTo(0);
-        List<ReplyStaff> replyStaffs = replyStaffMapper.selectByExample(example);
+    public List<WeComPushMessageVo> getPushMessageByUserId(List<ReplyStaff> replyStaffs) {
         if (CollectionUtils.isEmpty(replyStaffs)) {
             return null;
         }

+ 3 - 0
api-module/src/main/java/com/tzld/piaoquan/api/service/wecom/thirdparty/impl/WeComThirdPartyRoomServiceImpl.java

@@ -210,6 +210,9 @@ public class WeComThirdPartyRoomServiceImpl implements WeComThirdPartyRoomServic
 
     @Override
     public List<ThirdPartWeComRoomConfigTask> getRoomConfigTasks(List<String> configIds) {
+        if (CollectionUtils.isEmpty(configIds)) {
+            return Collections.emptyList();
+        }
         ThirdPartWeComRoomConfigTaskExample example = new ThirdPartWeComRoomConfigTaskExample();
         example.createCriteria().andConfigIdIn(configIds);
         return roomConfigTaskMapper.selectByExample(example);

+ 7 - 0
api-module/src/main/java/com/tzld/piaoquan/api/service/wecom/thirdparty/impl/WeComThirdPartyServiceImpl.java

@@ -12,6 +12,7 @@ import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ThirdPartWeComCorpMapper
 import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ThirdPartWeComRoomMapper;
 import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ThirdPartWeComStaffMapper;
 import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ext.ThirdPartWeComMapperExt;
+import com.tzld.piaoquan.api.job.wecom.thirdpart.WeComUserDetailJob;
 import com.tzld.piaoquan.api.model.param.wecom.thirdpart.*;
 import com.tzld.piaoquan.api.model.po.wecom.thirdpart.*;
 import com.tzld.piaoquan.api.service.wecom.thirdparty.WeComThirdPartyService;
@@ -41,6 +42,8 @@ public class WeComThirdPartyServiceImpl implements WeComThirdPartyService {
     @Autowired
     private WeComThirdPartyApiClient apiClient;
     @Autowired
+    private WeComUserDetailJob weComUserDetailJob;
+    @Autowired
     private ThirdPartWeComStaffMapper thirdPartWeComStaffMapper;
     @Autowired
     private ThirdPartWeComRoomMapper thirdPartWeComRoomMapper;
@@ -177,6 +180,10 @@ public class WeComThirdPartyServiceImpl implements WeComThirdPartyService {
         }
         saveStaffQrCode(uuid);
 
+        // 同步用户详情
+        ThirdPartWeComStaff staff = getStaffByUuid(uuid);
+        weComUserDetailJob.syncStaffUserDetail(staff);
+
         // 清除掉线检测
         String offLineKey = "wecom:thirdpart:offline:" + uuid;
         redisUtils.del(offLineKey);

+ 47 - 34
api-module/src/main/resources/mapper/contentplatform/ContentPlatformAccountMapper.xml

@@ -6,18 +6,19 @@
     <result column="name" jdbcType="VARCHAR" property="name" />
     <result column="identity" jdbcType="INTEGER" property="identity" />
     <result column="channel" jdbcType="VARCHAR" property="channel" />
+    <result column="layer_type" jdbcType="VARCHAR" property="layerType" />
     <result column="contact_name" jdbcType="VARCHAR" property="contactName" />
     <result column="tel_num" jdbcType="VARCHAR" property="telNum" />
     <result column="price" jdbcType="VARCHAR" property="price" />
     <result column="password" jdbcType="VARCHAR" property="password" />
     <result column="token" jdbcType="VARCHAR" property="token" />
     <result column="token_expire_timestamp" jdbcType="BIGINT" property="tokenExpireTimestamp" />
+    <result column="reply_secret" jdbcType="VARCHAR" property="replySecret" />
     <result column="status" jdbcType="INTEGER" property="status" />
     <result column="create_account" jdbcType="VARCHAR" property="createAccount" />
     <result column="create_timestamp" jdbcType="BIGINT" property="createTimestamp" />
     <result column="update_account" jdbcType="VARCHAR" property="updateAccount" />
     <result column="update_timestamp" jdbcType="BIGINT" property="updateTimestamp" />
-    <result column="layer_type" jdbcType="VARCHAR" property="layerType" />
   </resultMap>
   <sql id="Example_Where_Clause">
     <where>
@@ -78,9 +79,9 @@
     </where>
   </sql>
   <sql id="Base_Column_List">
-    id, `name`, `identity`, channel, contact_name, tel_num, price, `password`, token,
-    token_expire_timestamp, `status`, create_account, create_timestamp, update_account,
-    update_timestamp, layer_type
+    id, `name`, `identity`, channel, layer_type, contact_name, tel_num, price, `password`, 
+    token, token_expire_timestamp, reply_secret, `status`, create_account, create_timestamp, 
+    update_account, update_timestamp
   </sql>
   <select id="selectByExample" parameterType="com.tzld.piaoquan.api.model.po.contentplatform.ContentPlatformAccountExample" resultMap="BaseResultMap">
     select
@@ -116,20 +117,18 @@
     </if>
   </delete>
   <insert id="insert" parameterType="com.tzld.piaoquan.api.model.po.contentplatform.ContentPlatformAccount">
-    insert into content_platform_account (id, `name`, `identity`,
-      channel, contact_name, tel_num,
-      price, `password`, token,
-      token_expire_timestamp, `status`, create_account,
-      create_timestamp, update_account, update_timestamp,
-      layer_type
-      )
-    values (#{id,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{identity,jdbcType=INTEGER},
-      #{channel,jdbcType=VARCHAR}, #{contactName,jdbcType=VARCHAR}, #{telNum,jdbcType=VARCHAR},
-      #{price,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, #{token,jdbcType=VARCHAR},
-      #{tokenExpireTimestamp,jdbcType=BIGINT}, #{status,jdbcType=INTEGER}, #{createAccount,jdbcType=VARCHAR},
-      #{createTimestamp,jdbcType=BIGINT}, #{updateAccount,jdbcType=VARCHAR}, #{updateTimestamp,jdbcType=BIGINT},
-      #{layerType,jdbcType=VARCHAR}
-      )
+    insert into content_platform_account (id, `name`, `identity`, 
+      channel, layer_type, contact_name, 
+      tel_num, price, `password`, 
+      token, token_expire_timestamp, reply_secret, 
+      `status`, create_account, create_timestamp, 
+      update_account, update_timestamp)
+    values (#{id,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{identity,jdbcType=INTEGER}, 
+      #{channel,jdbcType=VARCHAR}, #{layerType,jdbcType=VARCHAR}, #{contactName,jdbcType=VARCHAR}, 
+      #{telNum,jdbcType=VARCHAR}, #{price,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, 
+      #{token,jdbcType=VARCHAR}, #{tokenExpireTimestamp,jdbcType=BIGINT}, #{replySecret,jdbcType=VARCHAR}, 
+      #{status,jdbcType=INTEGER}, #{createAccount,jdbcType=VARCHAR}, #{createTimestamp,jdbcType=BIGINT}, 
+      #{updateAccount,jdbcType=VARCHAR}, #{updateTimestamp,jdbcType=BIGINT})
   </insert>
   <insert id="insertSelective" parameterType="com.tzld.piaoquan.api.model.po.contentplatform.ContentPlatformAccount">
     insert into content_platform_account
@@ -146,6 +145,9 @@
       <if test="channel != null">
         channel,
       </if>
+      <if test="layerType != null">
+        layer_type,
+      </if>
       <if test="contactName != null">
         contact_name,
       </if>
@@ -164,6 +166,9 @@
       <if test="tokenExpireTimestamp != null">
         token_expire_timestamp,
       </if>
+      <if test="replySecret != null">
+        reply_secret,
+      </if>
       <if test="status != null">
         `status`,
       </if>
@@ -179,9 +184,6 @@
       <if test="updateTimestamp != null">
         update_timestamp,
       </if>
-      <if test="layerType != null">
-        layer_type,
-      </if>
     </trim>
     <trim prefix="values (" suffix=")" suffixOverrides=",">
       <if test="id != null">
@@ -196,6 +198,9 @@
       <if test="channel != null">
         #{channel,jdbcType=VARCHAR},
       </if>
+      <if test="layerType != null">
+        #{layerType,jdbcType=VARCHAR},
+      </if>
       <if test="contactName != null">
         #{contactName,jdbcType=VARCHAR},
       </if>
@@ -214,6 +219,9 @@
       <if test="tokenExpireTimestamp != null">
         #{tokenExpireTimestamp,jdbcType=BIGINT},
       </if>
+      <if test="replySecret != null">
+        #{replySecret,jdbcType=VARCHAR},
+      </if>
       <if test="status != null">
         #{status,jdbcType=INTEGER},
       </if>
@@ -229,9 +237,6 @@
       <if test="updateTimestamp != null">
         #{updateTimestamp,jdbcType=BIGINT},
       </if>
-      <if test="layerType != null">
-        #{layerType,jdbcType=VARCHAR},
-      </if>
     </trim>
   </insert>
   <select id="countByExample" parameterType="com.tzld.piaoquan.api.model.po.contentplatform.ContentPlatformAccountExample" resultType="java.lang.Long">
@@ -255,6 +260,9 @@
       <if test="record.channel != null">
         channel = #{record.channel,jdbcType=VARCHAR},
       </if>
+      <if test="record.layerType != null">
+        layer_type = #{record.layerType,jdbcType=VARCHAR},
+      </if>
       <if test="record.contactName != null">
         contact_name = #{record.contactName,jdbcType=VARCHAR},
       </if>
@@ -273,6 +281,9 @@
       <if test="record.tokenExpireTimestamp != null">
         token_expire_timestamp = #{record.tokenExpireTimestamp,jdbcType=BIGINT},
       </if>
+      <if test="record.replySecret != null">
+        reply_secret = #{record.replySecret,jdbcType=VARCHAR},
+      </if>
       <if test="record.status != null">
         `status` = #{record.status,jdbcType=INTEGER},
       </if>
@@ -288,9 +299,6 @@
       <if test="record.updateTimestamp != null">
         update_timestamp = #{record.updateTimestamp,jdbcType=BIGINT},
       </if>
-      <if test="record.layerType != null">
-        layer_type = #{record.layerType,jdbcType=VARCHAR},
-      </if>
     </set>
     <if test="_parameter != null">
       <include refid="Update_By_Example_Where_Clause" />
@@ -302,18 +310,19 @@
       `name` = #{record.name,jdbcType=VARCHAR},
       `identity` = #{record.identity,jdbcType=INTEGER},
       channel = #{record.channel,jdbcType=VARCHAR},
+      layer_type = #{record.layerType,jdbcType=VARCHAR},
       contact_name = #{record.contactName,jdbcType=VARCHAR},
       tel_num = #{record.telNum,jdbcType=VARCHAR},
       price = #{record.price,jdbcType=VARCHAR},
       `password` = #{record.password,jdbcType=VARCHAR},
       token = #{record.token,jdbcType=VARCHAR},
       token_expire_timestamp = #{record.tokenExpireTimestamp,jdbcType=BIGINT},
+      reply_secret = #{record.replySecret,jdbcType=VARCHAR},
       `status` = #{record.status,jdbcType=INTEGER},
       create_account = #{record.createAccount,jdbcType=VARCHAR},
       create_timestamp = #{record.createTimestamp,jdbcType=BIGINT},
       update_account = #{record.updateAccount,jdbcType=VARCHAR},
-      update_timestamp = #{record.updateTimestamp,jdbcType=BIGINT},
-      layer_type = #{record.layerType,jdbcType=VARCHAR}
+      update_timestamp = #{record.updateTimestamp,jdbcType=BIGINT}
     <if test="_parameter != null">
       <include refid="Update_By_Example_Where_Clause" />
     </if>
@@ -330,6 +339,9 @@
       <if test="channel != null">
         channel = #{channel,jdbcType=VARCHAR},
       </if>
+      <if test="layerType != null">
+        layer_type = #{layerType,jdbcType=VARCHAR},
+      </if>
       <if test="contactName != null">
         contact_name = #{contactName,jdbcType=VARCHAR},
       </if>
@@ -348,6 +360,9 @@
       <if test="tokenExpireTimestamp != null">
         token_expire_timestamp = #{tokenExpireTimestamp,jdbcType=BIGINT},
       </if>
+      <if test="replySecret != null">
+        reply_secret = #{replySecret,jdbcType=VARCHAR},
+      </if>
       <if test="status != null">
         `status` = #{status,jdbcType=INTEGER},
       </if>
@@ -363,9 +378,6 @@
       <if test="updateTimestamp != null">
         update_timestamp = #{updateTimestamp,jdbcType=BIGINT},
       </if>
-      <if test="layerType != null">
-        layer_type = #{layerType,jdbcType=VARCHAR},
-      </if>
     </set>
     where id = #{id,jdbcType=BIGINT}
   </update>
@@ -374,18 +386,19 @@
     set `name` = #{name,jdbcType=VARCHAR},
       `identity` = #{identity,jdbcType=INTEGER},
       channel = #{channel,jdbcType=VARCHAR},
+      layer_type = #{layerType,jdbcType=VARCHAR},
       contact_name = #{contactName,jdbcType=VARCHAR},
       tel_num = #{telNum,jdbcType=VARCHAR},
       price = #{price,jdbcType=VARCHAR},
       `password` = #{password,jdbcType=VARCHAR},
       token = #{token,jdbcType=VARCHAR},
       token_expire_timestamp = #{tokenExpireTimestamp,jdbcType=BIGINT},
+      reply_secret = #{replySecret,jdbcType=VARCHAR},
       `status` = #{status,jdbcType=INTEGER},
       create_account = #{createAccount,jdbcType=VARCHAR},
       create_timestamp = #{createTimestamp,jdbcType=BIGINT},
       update_account = #{updateAccount,jdbcType=VARCHAR},
-      update_timestamp = #{updateTimestamp,jdbcType=BIGINT},
-      layer_type = #{layerType,jdbcType=VARCHAR}
+      update_timestamp = #{updateTimestamp,jdbcType=BIGINT}
     where id = #{id,jdbcType=BIGINT}
   </update>
 </mapper>

+ 42 - 10
api-module/src/main/resources/mapper/contentplatform/ContentPlatformGzhPlanVideoMapper.xml

@@ -6,8 +6,10 @@
     <result column="plan_id" jdbcType="BIGINT" property="planId" />
     <result column="video_id" jdbcType="BIGINT" property="videoId" />
     <result column="title" jdbcType="VARCHAR" property="title" />
+    <result column="custom_title_id" jdbcType="BIGINT" property="customTitleId" />
     <result column="custom_title" jdbcType="VARCHAR" property="customTitle" />
     <result column="cover" jdbcType="VARCHAR" property="cover" />
+    <result column="custom_cover_id" jdbcType="BIGINT" property="customCoverId" />
     <result column="custom_cover" jdbcType="VARCHAR" property="customCover" />
     <result column="custom_cover_type" jdbcType="INTEGER" property="customCoverType" />
     <result column="video" jdbcType="VARCHAR" property="video" />
@@ -75,8 +77,8 @@
     </where>
   </sql>
   <sql id="Base_Column_List">
-    id, plan_id, video_id, title, custom_title, cover, custom_cover, custom_cover_type, 
-    video, page_url, `status`, create_account_id, create_timestamp
+    id, plan_id, video_id, title, custom_title_id, custom_title, cover, custom_cover_id,
+    custom_cover, custom_cover_type, video, page_url, `status`, create_account_id, create_timestamp
   </sql>
   <select id="selectByExample" parameterType="com.tzld.piaoquan.api.model.po.contentplatform.ContentPlatformGzhPlanVideoExample" resultMap="BaseResultMap">
     select
@@ -113,15 +115,17 @@
   </delete>
   <insert id="insert" parameterType="com.tzld.piaoquan.api.model.po.contentplatform.ContentPlatformGzhPlanVideo">
     insert into content_platform_gzh_plan_video (id, plan_id, video_id, 
-      title, custom_title, cover, 
-      custom_cover, custom_cover_type, video, 
-      page_url, `status`, create_account_id, 
-      create_timestamp)
+      title, custom_title_id, custom_title,
+      cover, custom_cover_id, custom_cover,
+      custom_cover_type, video, page_url,
+      `status`, create_account_id, create_timestamp
+      )
     values (#{id,jdbcType=BIGINT}, #{planId,jdbcType=BIGINT}, #{videoId,jdbcType=BIGINT}, 
-      #{title,jdbcType=VARCHAR}, #{customTitle,jdbcType=VARCHAR}, #{cover,jdbcType=VARCHAR}, 
-      #{customCover,jdbcType=VARCHAR}, #{customCoverType,jdbcType=INTEGER}, #{video,jdbcType=VARCHAR}, 
-      #{pageUrl,jdbcType=VARCHAR}, #{status,jdbcType=INTEGER}, #{createAccountId,jdbcType=BIGINT}, 
-      #{createTimestamp,jdbcType=BIGINT})
+      #{title,jdbcType=VARCHAR}, #{customTitleId,jdbcType=BIGINT}, #{customTitle,jdbcType=VARCHAR},
+      #{cover,jdbcType=VARCHAR}, #{customCoverId,jdbcType=BIGINT}, #{customCover,jdbcType=VARCHAR},
+      #{customCoverType,jdbcType=INTEGER}, #{video,jdbcType=VARCHAR}, #{pageUrl,jdbcType=VARCHAR},
+      #{status,jdbcType=INTEGER}, #{createAccountId,jdbcType=BIGINT}, #{createTimestamp,jdbcType=BIGINT}
+      )
   </insert>
   <insert id="insertSelective" parameterType="com.tzld.piaoquan.api.model.po.contentplatform.ContentPlatformGzhPlanVideo">
     insert into content_platform_gzh_plan_video
@@ -138,12 +142,18 @@
       <if test="title != null">
         title,
       </if>
+      <if test="customTitleId != null">
+        custom_title_id,
+      </if>
       <if test="customTitle != null">
         custom_title,
       </if>
       <if test="cover != null">
         cover,
       </if>
+      <if test="customCoverId != null">
+        custom_cover_id,
+      </if>
       <if test="customCover != null">
         custom_cover,
       </if>
@@ -179,12 +189,18 @@
       <if test="title != null">
         #{title,jdbcType=VARCHAR},
       </if>
+      <if test="customTitleId != null">
+        #{customTitleId,jdbcType=BIGINT},
+      </if>
       <if test="customTitle != null">
         #{customTitle,jdbcType=VARCHAR},
       </if>
       <if test="cover != null">
         #{cover,jdbcType=VARCHAR},
       </if>
+      <if test="customCoverId != null">
+        #{customCoverId,jdbcType=BIGINT},
+      </if>
       <if test="customCover != null">
         #{customCover,jdbcType=VARCHAR},
       </if>
@@ -229,12 +245,18 @@
       <if test="record.title != null">
         title = #{record.title,jdbcType=VARCHAR},
       </if>
+      <if test="record.customTitleId != null">
+        custom_title_id = #{record.customTitleId,jdbcType=BIGINT},
+      </if>
       <if test="record.customTitle != null">
         custom_title = #{record.customTitle,jdbcType=VARCHAR},
       </if>
       <if test="record.cover != null">
         cover = #{record.cover,jdbcType=VARCHAR},
       </if>
+      <if test="record.customCoverId != null">
+        custom_cover_id = #{record.customCoverId,jdbcType=BIGINT},
+      </if>
       <if test="record.customCover != null">
         custom_cover = #{record.customCover,jdbcType=VARCHAR},
       </if>
@@ -267,8 +289,10 @@
       plan_id = #{record.planId,jdbcType=BIGINT},
       video_id = #{record.videoId,jdbcType=BIGINT},
       title = #{record.title,jdbcType=VARCHAR},
+      custom_title_id = #{record.customTitleId,jdbcType=BIGINT},
       custom_title = #{record.customTitle,jdbcType=VARCHAR},
       cover = #{record.cover,jdbcType=VARCHAR},
+      custom_cover_id = #{record.customCoverId,jdbcType=BIGINT},
       custom_cover = #{record.customCover,jdbcType=VARCHAR},
       custom_cover_type = #{record.customCoverType,jdbcType=INTEGER},
       video = #{record.video,jdbcType=VARCHAR},
@@ -292,12 +316,18 @@
       <if test="title != null">
         title = #{title,jdbcType=VARCHAR},
       </if>
+      <if test="customTitleId != null">
+        custom_title_id = #{customTitleId,jdbcType=BIGINT},
+      </if>
       <if test="customTitle != null">
         custom_title = #{customTitle,jdbcType=VARCHAR},
       </if>
       <if test="cover != null">
         cover = #{cover,jdbcType=VARCHAR},
       </if>
+      <if test="customCoverId != null">
+        custom_cover_id = #{customCoverId,jdbcType=BIGINT},
+      </if>
       <if test="customCover != null">
         custom_cover = #{customCover,jdbcType=VARCHAR},
       </if>
@@ -327,8 +357,10 @@
     set plan_id = #{planId,jdbcType=BIGINT},
       video_id = #{videoId,jdbcType=BIGINT},
       title = #{title,jdbcType=VARCHAR},
+      custom_title_id = #{customTitleId,jdbcType=BIGINT},
       custom_title = #{customTitle,jdbcType=VARCHAR},
       cover = #{cover,jdbcType=VARCHAR},
+      custom_cover_id = #{customCoverId,jdbcType=BIGINT},
       custom_cover = #{customCover,jdbcType=VARCHAR},
       custom_cover_type = #{customCoverType,jdbcType=INTEGER},
       video = #{video,jdbcType=VARCHAR},

+ 9 - 9
api-module/src/main/resources/mapper/contentplatform/ext/ContentPlatformDataStatMapperExt.xml

@@ -8,7 +8,7 @@
         join content_platform_gzh_account cpgza on cpgd.account_id = cpgza.id
         where cpgza.create_account_id = #{createAccountId}
         <if test="param.accountId!= null and param.accountId!= ''">
-            and cpgza.account_id = #{param.accountId}
+            and cpgza.id = #{param.accountId}
         </if>
     </select>
 
@@ -19,9 +19,9 @@
         join content_platform_gzh_account cpgza on cpgd.account_id = cpgza.id
         where cpgza.create_account_id = #{createAccountId}
         <if test="param.accountId!= null and param.accountId!= ''">
-            and cpgza.account_id = #{param.accountId}
+            and cpgza.id = #{param.accountId}
         </if>
-        order by cpgd.date_str desc
+        order by cpgd.date_str desc, cpgd.account_id
         limit #{offset}, #{pageSize}
     </select>
 
@@ -31,7 +31,7 @@
         join content_platform_gzh_account cpgza on cpgvd.account_id = cpgza.id
         where cpgza.create_account_id = #{createAccountId}
         <if test="param.accountId!= null and param.accountId!= ''">
-            and cpgza.account_id = #{param.accountId}
+            and cpgza.id = #{param.accountId}
         </if>
     </select>
 
@@ -42,7 +42,7 @@
         join content_platform_gzh_account cpgza on cpgvd.account_id = cpgza.id
         where cpgza.create_account_id = #{createAccountId}
         <if test="param.accountId!= null and param.accountId!= ''">
-            and cpgza.account_id = #{param.accountId}
+            and cpgza.id = #{param.accountId}
         </if>
         order by cpgvd.date_str desc
         limit #{offset}, #{pageSize}
@@ -71,7 +71,7 @@
         join content_platform_gzh_account cpgza on cpgd.account_id = cpgza.id
         where cpgza.create_account_id = #{createAccountId}
         <if test="param.accountId!= null and param.accountId!= ''">
-            and cpgza.account_id = #{param.accountId}
+            and cpgza.id = #{param.accountId}
         </if>
     </select>
 
@@ -82,7 +82,7 @@
         join content_platform_gzh_account cpgza on cpfd.account_id = cpgza.id
         where cpgza.create_account_id = #{createAccountId}
         <if test="param.accountId!= null and param.accountId!= ''">
-            and cpgza.account_id = #{param.accountId}
+            and cpgza.id = #{param.accountId}
         </if>
         order by cpfd.date_str desc
         limit #{offset}, #{pageSize}
@@ -128,7 +128,7 @@
         join content_platform_gzh_account cpgza on cpgd.account_id = cpgza.id
         where cpgza.create_account_id = #{createAccountId}
         <if test="param.accountId!= null and param.accountId!= ''">
-            and cpgza.account_id = #{param.accountId}
+            and cpgza.id = #{param.accountId}
         </if>
     </select>
 
@@ -139,7 +139,7 @@
         join content_platform_gzh_account cpgza on cpfd.account_id = cpgza.id
         where cpgza.create_account_id = #{createAccountId}
         <if test="param.accountId!= null and param.accountId!= ''">
-            and cpgza.account_id = #{param.accountId}
+            and cpgza.id = #{param.accountId}
         </if>
         order by cpfd.date_str desc
         limit #{offset}, #{pageSize}

+ 1 - 0
api-module/src/main/resources/mapper/wecom/thirdpart/ext/ThirdPartWeComMapperExt.xml

@@ -232,6 +232,7 @@
                       on room.third_room_id = room_user.third_room_id
             where staff.third_staff_id = #{thirdStaffId}) room_user on staff_user.user_id = room_user.uin
         where staff.third_staff_id = #{thirdStaffId}
+          and staff_user.status not in (0, 8, 2049)
           and room_user.uin is null
     </select>
 

+ 22 - 0
api-module/src/test/java/com/tzld/piaoquan/api/WeComTest.java

@@ -0,0 +1,22 @@
+package com.tzld.piaoquan.api;
+
+import com.tzld.piaoquan.offline.job.WeComStaffDataJob;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest(classes = GrowthServerApplication.class)
+@Slf4j
+public class WeComTest {
+
+    @Autowired
+    WeComStaffDataJob weComStaffDataJob;
+
+    @Test
+    public void syncStaffJob() {
+        weComStaffDataJob.syncStaff("");
+    }
+
+
+}

+ 3 - 0
common-module/src/main/java/com/tzld/piaoquan/growth/common/common/constant/WeComConstant.java

@@ -35,6 +35,9 @@ public interface WeComConstant {
     //获取配置了客户联系功能的成员列表
     String GET_WE_COM_FOLLOW_USER_LIST = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_follow_user_list";
 
+    //获取配置了客户联系功能的成员详情
+    String GET_WE_COM_FOLLOW_USER_DETAIL = "https://qyapi.weixin.qq.com/cgi-bin/user/get";
+
     //获取企业客户标签详情
     String POST_CORP_TAG_LIST = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_corp_tag_list";
 

+ 1 - 1
common-module/src/main/java/com/tzld/piaoquan/growth/common/service/Impl/MessageAttachmentServiceImpl.java

@@ -285,7 +285,7 @@ public class MessageAttachmentServiceImpl implements MessageAttachmentService {
         example.createCriteria().andDateEqualTo(date).andIsDeleteEqualTo(0);
         List<GuaranteesVideo> guaranteesVideos = guaranteesVideoMapper.selectByExample(example);
         if (CollectionUtils.isEmpty(guaranteesVideos)) {
-            LarkRobotUtil.sendMessage("获保底视频空,@薛一鸣");
+            LarkRobotUtil.sendMessage("获保底视频空,<at user_id=\"g6732afb\">王云鹏</at>");
             return null;
         }
         GuaranteedParam guaranteedParam = new GuaranteedParam();

+ 1 - 1
common-module/src/main/java/com/tzld/piaoquan/growth/common/service/Impl/MessageServiceImpl.java

@@ -111,7 +111,7 @@ public class MessageServiceImpl implements MessageService {
             log.info("sendAutoReplyMessage res={}", res);
             Integer code = res.getInteger("errcode");
             msgResult.setErrcode(code);
-            if (code != 0) {
+            if (code != 0 && code != 41051) {
                 msgResult.setErrmsg(res.getString("errmsg"));
                 LarkRobotUtil.sendMessage("sendAutoReplyMessage error" + "res:" + res.toJSONString());
             }

+ 24 - 1
common-module/src/main/java/com/tzld/piaoquan/growth/common/utils/LarkRobotUtil.java

@@ -21,7 +21,6 @@ public class LarkRobotUtil {
 
     private static final String WE_COM_NOT_PUSH_URL = "https://open.feishu.cn/open-apis/bot/v2/hook/6fa54ed6-12f7-45c1-a33b-020d4f4483ef";
 
-
     private static final String AUTO_REPLY_VIDEO_URL = "https://open.feishu.cn/open-apis/bot/v2/hook/0d80b7dc-47d1-4c27-a7e1-97f2fb6ba26e";
 
     private static final String WE_COM_THIRDPART_URL = "https://open.feishu.cn/open-apis/bot/v2/hook/d5a61df6-7a74-4fa1-808f-e388cfa9b16c";
@@ -50,6 +49,14 @@ public class LarkRobotUtil {
         }
     }
 
+    public static void sendMessage(JSONObject param) {
+        try {
+            HTTP_POOL_CLIENT_UTIL_DEFAULT.post(URL, param.toJSONString());
+        } catch (Exception e) {
+            log.error("Lark sendMessage error", e);
+        }
+    }
+
     public static void sendTipMessage(String msg) {
         sendTipMessage("text", "企微推送结果:" + msg);
     }
@@ -67,6 +74,14 @@ public class LarkRobotUtil {
         }
     }
 
+    public static void sendTipMessage(JSONObject param) {
+        try {
+            HTTP_POOL_CLIENT_UTIL_DEFAULT.post(TIP_URL, param.toJSONString());
+        } catch (Exception e) {
+            log.error("Lark sendMessage error", e);
+        }
+    }
+
 
     public static void sendAutoReplyVideoMessage(JSONObject param) {
         try {
@@ -106,6 +121,14 @@ public class LarkRobotUtil {
         }
     }
 
+    public static void sendNotPushMessage(JSONObject param) {
+        try {
+            HTTP_POOL_CLIENT_UTIL_DEFAULT.post(WE_COM_NOT_PUSH_URL, param.toJSONString());
+        } catch (Exception e) {
+            log.error("Lark sendMessage error", e);
+        }
+    }
+
 
     private static String getSign(long timestamp) throws NoSuchAlgorithmException, InvalidKeyException {
         //把timestamp+"\n"+密钥当做签名字符串

+ 94 - 54
offline-module/src/main/java/com/tzld/piaoquan/offline/job/WeComHistoryDataJob.java

@@ -3,16 +3,13 @@ package com.tzld.piaoquan.offline.job;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.google.common.collect.Lists;
-import com.tzld.piaoquan.growth.common.common.constant.MessageConstant;
 import com.tzld.piaoquan.growth.common.common.constant.TimeConstant;
+import com.tzld.piaoquan.growth.common.common.enums.FieshuTableColumnDataTypeEnum;
 import com.tzld.piaoquan.growth.common.common.enums.MessageAttachmentTypeEnum;
 import com.tzld.piaoquan.growth.common.component.HttpPoolClient;
 import com.tzld.piaoquan.growth.common.component.ProxyHttpPoolClient;
 import com.tzld.piaoquan.growth.common.dao.mapper.*;
-import com.tzld.piaoquan.growth.common.model.bo.ExternalUser;
-import com.tzld.piaoquan.growth.common.model.bo.MiniprogramRecord;
-import com.tzld.piaoquan.growth.common.model.bo.SendDetail;
-import com.tzld.piaoquan.growth.common.model.bo.XxlJobParam;
+import com.tzld.piaoquan.growth.common.model.bo.*;
 import com.tzld.piaoquan.growth.common.model.po.*;
 import com.tzld.piaoquan.growth.common.service.*;
 import com.tzld.piaoquan.growth.common.utils.DateUtil;
@@ -34,7 +31,6 @@ import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
 import static com.tzld.piaoquan.growth.common.common.constant.MessageConstant.MAX_VIDEO_NUM;
-import static com.tzld.piaoquan.growth.common.common.constant.MessageConstant.specialStaffIdList;
 import static com.tzld.piaoquan.growth.common.common.constant.WeComConstant.*;
 import static com.tzld.piaoquan.growth.common.common.enums.SourceEnum.HISTORICAL_TOP;
 import static com.tzld.piaoquan.growth.common.common.enums.SourceEnum.MANUAL;
@@ -151,14 +147,12 @@ public class WeComHistoryDataJob {
             sendDetail.setSendCountList(countList);
             sendDetailList.add(sendDetail);
         }
-        StringBuilder stringBuilder = new StringBuilder();
-        stringBuilder.append(corpName).append("\n");
         long allCount = 0;
         long notSendCount = 0;
         long successSendCount = 0;
         long notFriendCount = 0;
         long failSendCount = 0;
-
+        List<JSONObject> rows = new ArrayList<>();
         for (SendDetail sendDetail : sendDetailList) {
             List<Long> sendCountList = sendDetail.getSendCountList();
             if (CollectionUtils.isEmpty(sendCountList)) {
@@ -168,41 +162,82 @@ public class WeComHistoryDataJob {
             if (count == 0) {
                 continue;
             }
-            stringBuilder.append(sendDetail.getRemark());
             allCount += count;
             notSendCount += sendCountList.get(0);
             successSendCount += sendCountList.get(1);
             notFriendCount += sendCountList.get(2);
             failSendCount += sendCountList.get(3);
-            if (sendCountList.get(0) > 0 && !specialStaffIdList.contains(sendDetail.getStaffId())) {
-                LarkRobotUtil.sendMessage(sendDetail.getRemark() + "存在未发送记录,请检查");
-                LarkRobotUtil.sendTipMessage(sendDetail.getRemark() + "存在未发送记录,请检查");
-                //8点前报警
-                if (DateUtil.getHourOfDay() < 8 && (corpId == 1 || corpId == 3)) {
-                    LarkRobotUtil.sendNotPushMessage("<at user_id=\"all\">所有人</at> " + sendDetail.getRemark() + " 存在未发送记录,请检查");
-                }
-            }
-            stringBuilder.append("总发送数量:").append(count).append("   ");
-            stringBuilder.append("未发送数量:").append(sendCountList.get(0)).append("   ");
-            stringBuilder.append("已发送数量:").append(sendCountList.get(1)).append("   ");
-            stringBuilder.append("不是好友发送失败数量:").append(sendCountList.get(2)).append("   ");
-            stringBuilder.append("已经收到其他群发消息失败发送数量:").append(sendCountList.get(3)).append("   ");
-            stringBuilder.append("\n");
-        }
-        stringBuilder.append(corpName).append("汇总发送数量:").append("   ");
-        stringBuilder.append("总发送数量:").append(allCount).append("   ");
-        stringBuilder.append("未发送数量:").append(notSendCount).append("   ");
-        stringBuilder.append("已发送数量:").append(successSendCount).append("   ");
-        stringBuilder.append("不是好友发送失败数量:").append(notFriendCount).append("   ");
-        stringBuilder.append("已经收到其他群发消息失败发送数量:").append(failSendCount).append("   ");
-        stringBuilder.append("\n");
+            //if (sendCountList.get(0) > 0 && !specialStaffIdList.contains(sendDetail.getStaffId())) {
+            //    LarkRobotUtil.sendMessage(sendDetail.getRemark() + "存在未发送记录,请检查");
+            //    LarkRobotUtil.sendTipMessage(sendDetail.getRemark() + "存在未发送记录,请检查");
+            //    //8点前报警
+            //    if (DateUtil.getHourOfDay() < 9 && (corpId == 1 || corpId == 3)) {
+            //        LarkRobotUtil.sendNotPushMessage("<at user_id=\"all\">所有人</at> " + sendDetail.getRemark() + " 存在未发送记录,请检查");
+            //    }
+            //}
+
+            JSONObject row = new JSONObject();
+            row.put("name", sendDetail.getRemark());
+            row.put("totalCount", count);
+            row.put("notSendCount", sendCountList.get(0));
+            row.put("successSendCount", sendCountList.get(1));
+            row.put("notFriendCount", sendCountList.get(2));
+            row.put("failSendCount", sendCountList.get(3));
+            rows.add(row);
+        }
+
+        JSONObject row = new JSONObject();
+        row.put("name", "TOTAL");
+        row.put("totalCount", allCount);
+        row.put("notSendCount", notSendCount);
+        row.put("successSendCount", successSendCount);
+        row.put("notFriendCount", notFriendCount);
+        row.put("failSendCount", failSendCount);
+        rows.add(row);
         if (allCount > 0) {
-            LarkRobotUtil.sendMessage(stringBuilder.toString());
-            LarkRobotUtil.sendTipMessage(stringBuilder.toString());
+            JSONObject bodyParam = buildCheckQWMsg(corpName, rows);
+            LarkRobotUtil.sendMessage(bodyParam);
+            LarkRobotUtil.sendTipMessage(bodyParam);
+            if (DateUtil.getHourOfDay() < 9 && (corpId == 1 || corpId == 3)) {
+                LarkRobotUtil.sendNotPushMessage(bodyParam);
+            }
         }
         return notSendCount;
     }
 
+    private JSONObject buildCheckQWMsg(String corpName, List<JSONObject> rows) {
+        List<FeishuTableDTO.Column> columns = buildCheckQWMsgSendColumns();
+        FeishuTableDTO tableDTO = FeishuTableDTO.createTable(corpName, columns, rows, true);
+        JSONObject content = JSONObject.parseObject(JSONObject.toJSONString(tableDTO));
+        JSONObject bodyParam = new JSONObject();
+        bodyParam.put("msg_type", "interactive");
+        bodyParam.put("card", content);
+        return bodyParam;
+    }
+
+    private List<FeishuTableDTO.Column> buildCheckQWMsgSendColumns() {
+        List<FeishuTableDTO.Column> columns = new ArrayList<>();
+        FeishuTableDTO.Column nameColumn = FeishuTableDTO.createFeishuColumns(
+                FieshuTableColumnDataTypeEnum.TEXT.getType(), "name", "账号名称", null);
+        columns.add(nameColumn);
+        FeishuTableDTO.Column totalCountColumn = FeishuTableDTO.createFeishuColumns(
+                FieshuTableColumnDataTypeEnum.TEXT.getType(), "totalCount", "总发送数量", null);
+        columns.add(totalCountColumn);
+        FeishuTableDTO.Column notSendCountColumn = FeishuTableDTO.createFeishuColumns(
+                FieshuTableColumnDataTypeEnum.TEXT.getType(), "notSendCount", "未发送数量", null);
+        columns.add(notSendCountColumn);
+        FeishuTableDTO.Column successSendCountColumn = FeishuTableDTO.createFeishuColumns(
+                FieshuTableColumnDataTypeEnum.TEXT.getType(), "successSendCount", "已发送数量", null);
+        columns.add(successSendCountColumn);
+        FeishuTableDTO.Column notFriendCountColumn = FeishuTableDTO.createFeishuColumns(
+                FieshuTableColumnDataTypeEnum.TEXT.getType(), "notFriendCount", "不是好友发送失败数量", null);
+        columns.add(notFriendCountColumn);
+        FeishuTableDTO.Column failSendCountColumn = FeishuTableDTO.createFeishuColumns(
+                FieshuTableColumnDataTypeEnum.TEXT.getType(), "failSendCount", "已经收到其他群发消息失败发送数量", null);
+        columns.add(failSendCountColumn);
+        return columns;
+    }
+
 
     @XxlJob("saveHistoryMessageJob")
     public ReturnT<String> selectHistoryMessageByDay(String param) {
@@ -271,8 +306,7 @@ public class WeComHistoryDataJob {
             sendDetail.setSendCountList(countList);
             sendDetailList.add(sendDetail);
         }
-        StringBuilder stringBuilder = new StringBuilder();
-        stringBuilder.append(corpName).append("\n");
+        List<JSONObject> rows = new ArrayList<>();
         for (SendDetail sendDetail : sendDetailList) {
             List<Long> sendCountList = sendDetail.getSendCountList();
             if (CollectionUtils.isEmpty(sendCountList)) {
@@ -282,25 +316,31 @@ public class WeComHistoryDataJob {
             if (count == 0) {
                 continue;
             }
-            stringBuilder.append(sendDetail.getRemark());
 
-            if (count == sendCountList.get(0)) {
-                LarkRobotUtil.sendMessage(sendDetail.getRemark() + "存在未发送记录,请检查");
-                if (sendDetail.getStaffId() == 3) {
-                    LarkRobotUtil.sendTipMessage(sendDetail.getRemark() + "存在未发送记录,请检查");
-                } else {
-                    LarkRobotUtil.sendNotPushMessage("<at user_id=\"all\">所有人</at> " + sendDetail.getRemark() + " 存在未发送记录,请检查");
-                }
-            }
-            stringBuilder.append("总发送数量:").append(count).append("   ");
-            stringBuilder.append("未发送数量:").append(sendCountList.get(0)).append("   ");
-            stringBuilder.append("已发送数量:").append(sendCountList.get(1)).append("   ");
-            stringBuilder.append("不是好友发送失败数量:").append(sendCountList.get(2)).append("   ");
-            stringBuilder.append("已经收到其他群发消息失败发送数量:").append(sendCountList.get(3)).append("   ");
-            stringBuilder.append("\n");
-        }
-        LarkRobotUtil.sendMessage(stringBuilder.toString());
-        LarkRobotUtil.sendTipMessage(stringBuilder.toString());
+
+            //if (count == sendCountList.get(0)) {
+            //    //LarkRobotUtil.sendMessage(sendDetail.getRemark() + "存在未发送记录,请检查");
+            //    if (sendDetail.getStaffId() == 3) {
+            //        //LarkRobotUtil.sendTipMessage(sendDetail.getRemark() + "存在未发送记录,请检查");
+            //    } else {
+            //        LarkRobotUtil.sendNotPushMessage("<at user_id=\"all\">所有人</at> " + sendDetail.getRemark() + " 存在未发送记录,请检查");
+            //    }
+            //}
+            JSONObject row = new JSONObject();
+            row.put("name", sendDetail.getRemark());
+            row.put("totalCount", count);
+            row.put("notSendCount", sendCountList.get(0));
+            row.put("successSendCount", sendCountList.get(1));
+            row.put("notFriendCount", sendCountList.get(2));
+            row.put("failSendCount", sendCountList.get(3));
+            rows.add(row);
+        }
+        JSONObject bodyParam = buildCheckQWMsg(corpName, rows);
+        LarkRobotUtil.sendMessage(bodyParam);
+        LarkRobotUtil.sendTipMessage(bodyParam);
+        if (DateUtil.getHourOfDay() < 9 && (corpId == 1 || corpId == 3)) {
+            LarkRobotUtil.sendNotPushMessage(bodyParam);
+        }
     }
 
     private void selectGroupMsgList(Long startTime, Long endTime, Long corpId, Long staffId) {

+ 93 - 2
offline-module/src/main/java/com/tzld/piaoquan/offline/job/WeComMessageDataJob.java

@@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.aliyun.odps.data.Record;
 import com.google.common.collect.Lists;
+import com.tzld.piaoquan.growth.common.common.base.CommonResponse;
 import com.tzld.piaoquan.growth.common.common.constant.MessageConstant;
 import com.tzld.piaoquan.growth.common.dao.mapper.*;
 import com.tzld.piaoquan.growth.common.model.bo.*;
@@ -17,6 +18,7 @@ import com.tzld.piaoquan.growth.common.utils.*;
 import com.tzld.piaoquan.growth.common.utils.page.Page;
 import com.xxl.job.core.biz.model.ReturnT;
 import com.xxl.job.core.handler.annotation.XxlJob;
+import com.xxl.job.core.log.XxlJobLogger;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -479,7 +481,7 @@ public class WeComMessageDataJob {
         example.createCriteria().andIsSendEqualTo(0).andCreateTimeGreaterThan(DateUtil.getThatDayDate());
         long l = sendMessageMapper.countByExample(example);
         if (l > 0) {
-            LarkRobotUtil.sendMessage("存在发送失败消息,请检查@薛一鸣");
+            LarkRobotUtil.sendMessage("存在发送失败消息,请检查<at user_id=\"g6732afb\">王云鹏</at>");
         }
         return ReturnT.SUCCESS;
     }
@@ -590,10 +592,99 @@ public class WeComMessageDataJob {
         GuaranteedParam guaranteedParam = messageAttachmentService.getGuaranteedVideo(DateUtil.getNextDayDateString());
         if (guaranteedParam == null
                 || CollectionUtils.isEmpty(guaranteedParam.getVideoParamList())) {
-            LarkRobotUtil.sendMessage("@薛一鸣 保底视频异常,请检查" + DateUtil.getNextDayDateString());
+            LarkRobotUtil.sendMessage("<at user_id=\"g6732afb\">王云鹏</at> 保底视频异常,请检查" + DateUtil.getNextDayDateString());
         }
         return ReturnT.SUCCESS;
     }
 
 
+    @XxlJob("addMessageAttachmentJob")
+    public ReturnT<String> addMessageAttachment(String param) {
+        String dt = DateUtil.getBeforeDayDateString(-1, "yyyy-MM-dd");
+        List<Long> videoIds = getTopThousandVideoIds();
+        if (CollectionUtils.isEmpty(videoIds)) {
+            XxlJobLogger.log("保底视频查询异常");
+            LarkRobotUtil.sendMessage("addMessageAttachmentJob 保底视频添加任务异常,请检查 " + dt
+                    + " <at user_id=\"g6732afb\">王云鹏</at>");
+            return ReturnT.FAIL;
+        }
+
+        List<Long> currentVideoIds = new ArrayList<>();
+        int index = 0;
+
+        while (true) {
+            while (currentVideoIds.size() < MAX_VIDEO_NUM && index < videoIds.size()) {
+                currentVideoIds.add(videoIds.get(index++));
+            }
+            if (currentVideoIds.size() < MAX_VIDEO_NUM) {
+                XxlJobLogger.log("保底视频可用数量不足,无法凑齐3个有效视频");
+                LarkRobotUtil.sendMessage("addMessageAttachmentJob 保底视频可用数量不足,无法凑齐3个有效视频,请检查 " + dt
+                        + " <at user_id=\"g6732afb\">王云鹏</at>");
+                return ReturnT.FAIL;
+            }
+            GuaranteedParam guaranteedParam = new GuaranteedParam();
+            guaranteedParam.setDate(dt);
+            guaranteedParam.setVideoParamList(buildVideoParamList(new ArrayList<>(currentVideoIds)));
+            CommonResponse<Void> commonResponse = messageAttachmentService.createGuaranteedMiniProgram(guaranteedParam);
+            if (commonResponse.isSuccess() && commonResponse.getCode() == 0) {
+                return ReturnT.SUCCESS;
+            }
+
+            String msg = commonResponse.getMsg();
+            if (StringUtils.isNotEmpty(msg) && msg.contains("保底视频30天内已发送,请查看videoId=")) {
+                String errorVideoId = msg.substring(msg.indexOf("videoId=") + 8);
+                try {
+                    Long removeId = Long.parseLong(errorVideoId);
+                    currentVideoIds.remove(removeId);
+                } catch (Exception e) {
+                    XxlJobLogger.log("保底视频异常,解析videoId失败: " + errorVideoId);
+                }
+            } else {
+                XxlJobLogger.log("创建保底视频失败: " + msg);
+            }
+            if (currentVideoIds.size() == MAX_VIDEO_NUM) {
+                currentVideoIds.clear();
+            }
+        }
+    }
+
+    private List<Long> getTopThousandVideoIds() {
+        int releaseDays = 1;
+        String dt = DateUtil.getBeforeDayDateString(releaseDays, "yyyyMMdd");
+        int retryTimes = 3;
+        List<Long> videoIds = new ArrayList<>();
+        do {
+            String sql = String.format("SELECT videoid FROM loghubods.lastday_return WHERE dt=%s limit 2000;", dt);
+            List<Record> dataList = OdpsUtil.getOdpsData(sql);
+            if (!CollectionUtils.isEmpty(dataList)) {
+                for (Record record : dataList) {
+                    Long videoId = Long.parseLong((String) record.get(0));
+                    videoIds.add(videoId);
+                }
+                return videoIds;
+            }
+            retryTimes--;
+            releaseDays++;
+            dt = DateUtil.getBeforeDayDateString(releaseDays, "yyyyMMdd");
+        } while (retryTimes > 0);
+        return videoIds;
+    }
+
+    private List<VideoParam> buildVideoParamList(List<Long> videoIds) {
+        List<VideoParam> videoParamList = new ArrayList<>();
+        VideoParam videoParam = new VideoParam();
+        videoParam.setStaffIds(Arrays.asList(0L, 3L, 7L, 9L, 10L, 12L, 16L, 17L, 100L, 103L, 104L, 106L, 107L, 108L, 109L, 110L,
+                111L, 112L, 113L, 114L, 115L, 116L, 117L, 118L, 119L, 120L, 121L, 122L, 123L));
+        videoParam.setVideoIds(videoIds);
+        videoParamList.add(videoParam);
+        VideoParam videoParam2 = new VideoParam();
+        videoParam2.setStaffIds(Arrays.asList(5L, 15L));
+        videoParam2.setVideoIds(videoIds);
+        videoParamList.add(videoParam2);
+        VideoParam videoParam3 = new VideoParam();
+        videoParam3.setStaffIds(Arrays.asList(8L, 11L, 13L, 14L));
+        videoParam3.setVideoIds(videoIds);
+        videoParamList.add(videoParam3);
+        return videoParamList;
+    }
 }

+ 34 - 5
offline-module/src/main/java/com/tzld/piaoquan/offline/job/WeComStaffDataJob.java

@@ -9,9 +9,7 @@ import com.tzld.piaoquan.growth.common.dao.mapper.*;
 import com.tzld.piaoquan.growth.common.model.bo.XxlJobParam;
 import com.tzld.piaoquan.growth.common.model.po.*;
 import com.tzld.piaoquan.growth.common.service.WeComAccessTokenService;
-import com.tzld.piaoquan.growth.common.service.WeComSendService;
 import com.tzld.piaoquan.growth.common.utils.DateUtil;
-import com.tzld.piaoquan.growth.common.utils.DateUtils;
 import com.tzld.piaoquan.growth.common.utils.LarkRobotUtil;
 import com.xxl.job.core.biz.model.ReturnT;
 import com.xxl.job.core.handler.annotation.XxlJob;
@@ -25,6 +23,7 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.stream.Collectors;
 
 import static com.tzld.piaoquan.growth.common.common.constant.WeComConstant.*;
@@ -57,8 +56,8 @@ public class WeComStaffDataJob {
     @Autowired
     private CorpStatisticsTotalMapper corpStatisticsTotalMapper;
 
-    @XxlJob("insertStaffJob")
-    public ReturnT<String> insertStaff(String param) {
+    @XxlJob("syncStaffJob")
+    public ReturnT<String> syncStaff(String param) {
         try {
             XxlJobParam xxlJobParam = new XxlJobParam();
             if (StringUtils.isNotEmpty(param)) {
@@ -78,6 +77,7 @@ public class WeComStaffDataJob {
                     continue;
                 }
                 for (String carrierId : carrierIdList) {
+                    JSONObject carrierInfo = getCarrierInfo(corp.getId(), carrierId);
                     StaffExample example = new StaffExample();
                     example.createCriteria().andCarrierIdEqualTo(carrierId).andCorpIdEqualTo(corp.getId());
                     List<Staff> staffList = staffMapper.selectByExample(example);
@@ -85,8 +85,18 @@ public class WeComStaffDataJob {
                         Staff staff = new Staff();
                         staff.setCorpId(corp.getId());
                         staff.setCarrierId(carrierId);
-                        staff.setRemark("");
+                        if (Objects.nonNull(carrierInfo) && carrierInfo.containsKey("name")) {
+                            staff.setRemark(carrierInfo.getString("name"));
+                        } else {
+                            staff.setRemark("");
+                        }
                         staffMapper.insert(staff);
+                    } else {
+                        Staff staff = staffList.get(0);
+                        if (Objects.nonNull(carrierInfo) && carrierInfo.containsKey("name")) {
+                            staff.setRemark(carrierInfo.getString("name"));
+                            staffMapper.updateByPrimaryKeySelective(staff);
+                        }
                     }
                 }
             }
@@ -115,6 +125,25 @@ public class WeComStaffDataJob {
         return null;
     }
 
+    private JSONObject getCarrierInfo(Long corpId, String userId) throws IOException {
+        String weComAccessToken = weComAccessTokenService.getWeComAccessToken(corpId);
+        String url = String.format(GET_WE_COM_FOLLOW_USER_DETAIL + "?access_token=%s", weComAccessToken);
+        url = String.format(url + "&userid=%s", userId);
+        String res;
+        if (corpId == 1L) {
+            res = httpPoolClient.get(url);
+        } else {
+            res = proxyHttpPoolClient.get(url);
+        }
+        log.info("getCarrierInfo corp = {} , userId = {}, res={}", corpId, userId, res);
+        JSONObject jsonObject = JSONObject.parseObject(res);
+        Integer errcode = jsonObject.getInteger("errcode");
+        if (errcode == 0) {
+            return jsonObject;
+        }
+        return null;
+    }
+
     @XxlJob("statisticsTotalJob")
     public ReturnT<String> statisticsTotal(String param) throws IOException {
         String date;