Parcourir la source

Merge branch 'master' into 20251105-wyp-videoCollect

# Conflicts:
#	api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/contentplatform/ext/ContentPlatformPlanMapperExt.java
#	api-module/src/main/java/com/tzld/piaoquan/api/job/contentplatform/ContentPlatformDatastatJob.java
#	api-module/src/main/java/com/tzld/piaoquan/api/model/po/contentplatform/ContentPlatformGzhPlanVideo.java
#	api-module/src/main/java/com/tzld/piaoquan/api/model/po/contentplatform/ContentPlatformGzhPlanVideoExample.java
#	api-module/src/main/java/com/tzld/piaoquan/api/service/contentplatform/ContentPlatformPlanService.java
#	api-module/src/main/java/com/tzld/piaoquan/api/service/contentplatform/impl/ContentPlatformPlanServiceImpl.java
#	api-module/src/main/resources/mapper/contentplatform/ContentPlatformGzhPlanVideoMapper.xml
#	api-module/src/main/resources/mapper/contentplatform/ext/ContentPlatformPlanMapperExt.xml
wangyunpeng il y a 1 jour
Parent
commit
3088e5c57c
100 fichiers modifiés avec 4628 ajouts et 308 suppressions
  1. 29 0
      api-module/src/main/java/com/tzld/piaoquan/api/annotation/RateLimit.java
  2. 88 0
      api-module/src/main/java/com/tzld/piaoquan/api/aop/RateLimitAop.java
  3. 7 0
      api-module/src/main/java/com/tzld/piaoquan/api/common/Constant.java
  4. 5 0
      api-module/src/main/java/com/tzld/piaoquan/api/common/enums/ExceptionEnum.java
  5. 33 0
      api-module/src/main/java/com/tzld/piaoquan/api/common/enums/wecom/ConfigSyncEnum.java
  6. 32 0
      api-module/src/main/java/com/tzld/piaoquan/api/common/enums/wecom/ConfigTaskContentTypeEnum.java
  7. 31 0
      api-module/src/main/java/com/tzld/piaoquan/api/common/enums/wecom/MsgSendStatusEnum.java
  8. 34 0
      api-module/src/main/java/com/tzld/piaoquan/api/common/enums/wecom/ThirdPartWeComStaffStatusEnum.java
  9. 43 0
      api-module/src/main/java/com/tzld/piaoquan/api/common/enums/wecom/WeComThirdPartyCallBackTypeEnum.java
  10. 21 0
      api-module/src/main/java/com/tzld/piaoquan/api/component/AdApiService.java
  11. 54 0
      api-module/src/main/java/com/tzld/piaoquan/api/component/AigcApiService.java
  12. 93 0
      api-module/src/main/java/com/tzld/piaoquan/api/component/DeepSeekApiService.java
  13. 138 0
      api-module/src/main/java/com/tzld/piaoquan/api/component/ManagerApiService.java
  14. 23 17
      api-module/src/main/java/com/tzld/piaoquan/api/component/VideoApiService.java
  15. 19 1
      api-module/src/main/java/com/tzld/piaoquan/api/component/WeComThirdPartyApiClient.java
  16. 5 5
      api-module/src/main/java/com/tzld/piaoquan/api/config/CrossOriginConfig.java
  17. 11 4
      api-module/src/main/java/com/tzld/piaoquan/api/config/JwtInterceptor.java
  18. 20 4
      api-module/src/main/java/com/tzld/piaoquan/api/controller/AccountDetailController.java
  19. 13 0
      api-module/src/main/java/com/tzld/piaoquan/api/controller/CgiReplyController.java
  20. 33 0
      api-module/src/main/java/com/tzld/piaoquan/api/controller/VideoMultiController.java
  21. 12 8
      api-module/src/main/java/com/tzld/piaoquan/api/controller/contentplatform/ContentPlatformAccountController.java
  22. 7 0
      api-module/src/main/java/com/tzld/piaoquan/api/controller/contentplatform/ContentPlatformPlanController.java
  23. 1 1
      api-module/src/main/java/com/tzld/piaoquan/api/controller/wecom/MessageController.java
  24. 3 6
      api-module/src/main/java/com/tzld/piaoquan/api/controller/wecom/TencentWeComController.java
  25. 5 2
      api-module/src/main/java/com/tzld/piaoquan/api/controller/wecom/ThirdPartyController.java
  26. 3 3
      api-module/src/main/java/com/tzld/piaoquan/api/controller/wecom/WeComController.java
  27. 2 2
      api-module/src/main/java/com/tzld/piaoquan/api/controller/wecom/WeComUserController.java
  28. 92 0
      api-module/src/main/java/com/tzld/piaoquan/api/controller/wecom/thirdpart/WeComThirdPartyAccountController.java
  29. 26 0
      api-module/src/main/java/com/tzld/piaoquan/api/controller/wecom/thirdpart/WeComThirdPartyCallBackController.java
  30. 8 2
      api-module/src/main/java/com/tzld/piaoquan/api/controller/wecom/thirdpart/WeComThirdPartyController.java
  31. 87 0
      api-module/src/main/java/com/tzld/piaoquan/api/controller/wecom/thirdpart/WeComThirdPartyJobController.java
  32. 52 0
      api-module/src/main/java/com/tzld/piaoquan/api/controller/wecom/thirdpart/WeComThirdPartyRoomController.java
  33. 3 3
      api-module/src/main/java/com/tzld/piaoquan/api/dao/generator/MybatisGeneratorMain.java
  34. 0 5
      api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/GhDetailExtMapper.java
  35. 24 0
      api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/GhDetailMapperExt.java
  36. 30 0
      api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/GzhAutoreplyBehaviorUvTotalMapper.java
  37. 30 0
      api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/contentplatform/VideoGrowthMultiCoverMapper.java
  38. 30 0
      api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/contentplatform/VideoGrowthMultiTitleMapper.java
  39. 3 1
      api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/contentplatform/ext/ContentPlatformPlanMapperExt.java
  40. 13 0
      api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/contentplatform/ext/VideoMultiMapperExt.java
  41. 30 0
      api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/wecom/thirdpart/ThirdPartWeComRoomConfigMapper.java
  42. 30 0
      api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/wecom/thirdpart/ThirdPartWeComRoomConfigTaskContentMapper.java
  43. 30 0
      api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/wecom/thirdpart/ThirdPartWeComRoomConfigTaskMapper.java
  44. 30 0
      api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/wecom/thirdpart/ThirdPartWeComStaffConfigMapper.java
  45. 30 0
      api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/wecom/thirdpart/ThirdPartWeComStaffConfigTaskContentMapper.java
  46. 30 0
      api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/wecom/thirdpart/ThirdPartWeComStaffConfigTaskMapper.java
  47. 30 0
      api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/wecom/thirdpart/ThirdPartWeComVideoMapper.java
  48. 13 0
      api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/wecom/thirdpart/ext/ThirdPartWeComMapperExt.java
  49. 20 0
      api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/wecom/thirdpart/ext/ThirdPartWeComRoomMapperExt.java
  50. 21 0
      api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/wecom/thirdpart/ext/ThirdPartWeComStaffMapperExt.java
  51. 28 0
      api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/wecom/thirdpart/ext/ThirdPartWeComVideoMapperExt.java
  52. 412 0
      api-module/src/main/java/com/tzld/piaoquan/api/job/GzhReplyVideoRefreshJob.java
  53. 193 99
      api-module/src/main/java/com/tzld/piaoquan/api/job/contentplatform/ContentPlatformDatastatJob.java
  54. 1 1
      api-module/src/main/java/com/tzld/piaoquan/api/job/contentplatform/ContentPlatformGzhAccountJob.java
  55. 7 0
      api-module/src/main/java/com/tzld/piaoquan/api/job/contentplatform/ContentPlatformIllegalVideoJob.java
  56. 2 0
      api-module/src/main/java/com/tzld/piaoquan/api/job/contentplatform/ContentPlatformVideoJob.java
  57. 101 6
      api-module/src/main/java/com/tzld/piaoquan/api/job/wecom/WeComMessageDataJob.java
  58. 18 3
      api-module/src/main/java/com/tzld/piaoquan/api/job/wecom/thirdpart/WeComAccountJob.java
  59. 1 1
      api-module/src/main/java/com/tzld/piaoquan/api/job/wecom/thirdpart/WeComCreateRoomJob.java
  60. 306 95
      api-module/src/main/java/com/tzld/piaoquan/api/job/wecom/thirdpart/WeComSendMsgJob.java
  61. 141 32
      api-module/src/main/java/com/tzld/piaoquan/api/job/wecom/thirdpart/WeComUserDetailJob.java
  62. 215 0
      api-module/src/main/java/com/tzld/piaoquan/api/job/wecom/thirdpart/WeComVideoJob.java
  63. 36 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/bo/AdPutCreativeComponentCostData.java
  64. 0 1
      api-module/src/main/java/com/tzld/piaoquan/api/model/bo/BucketDataParam.java
  65. 28 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/bo/GoogleLLMResult.java
  66. 13 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/bo/bucketDataGenerateParam.java
  67. 39 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/dto/AIOfficialApiResponse.java
  68. 11 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/dto/AIResult.java
  69. 11 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/dto/PageUrlExtData.java
  70. 1 1
      api-module/src/main/java/com/tzld/piaoquan/api/model/param/AccessTokenParam.java
  71. 1 1
      api-module/src/main/java/com/tzld/piaoquan/api/model/param/CallbackParam.java
  72. 1 1
      api-module/src/main/java/com/tzld/piaoquan/api/model/param/PushMessageParam.java
  73. 1 1
      api-module/src/main/java/com/tzld/piaoquan/api/model/param/WeComPushMessageParam.java
  74. 1 1
      api-module/src/main/java/com/tzld/piaoquan/api/model/param/WeComUserNameAvatarParam.java
  75. 2 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/param/contentplatform/AccountSaveParam.java
  76. 8 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/ExternalBusinessCardResponse.java
  77. 1 1
      api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/GetRoomUserListResponse.java
  78. 10 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/LoginOutResponse.java
  79. 21 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/SendTextMsgResponse.java
  80. 4 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/SetCallbackUrlRequest.java
  81. 37 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/ThirdPartyAccountConfigParam.java
  82. 19 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/ThirdPartyAccountConfigTaskContentParam.java
  83. 21 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/ThirdPartyAccountConfigTaskParam.java
  84. 16 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/ThirdPartyAccountListParam.java
  85. 10 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/ThirdPartyAccountLogOutParam.java
  86. 14 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/ThirdPartyConfigGetParam.java
  87. 31 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/ThirdPartyRoomConfigParam.java
  88. 19 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/ThirdPartyRoomConfigTaskContentParam.java
  89. 21 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/ThirdPartyRoomConfigTaskParam.java
  90. 18 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/ThirdPartyRoomListParam.java
  91. 10 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/WeComThirdPartyCallBackParam.java
  92. 33 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/po/GhDetailExt.java
  93. 180 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/po/GhDetailExtExample.java
  94. 90 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/po/GzhAutoreplyBehaviorUvTotal.java
  95. 661 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/po/GzhAutoreplyBehaviorUvTotalExample.java
  96. 22 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/po/contentplatform/ContentPlatformAccount.java
  97. 140 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/po/contentplatform/ContentPlatformAccountExample.java
  98. 33 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/po/contentplatform/ContentPlatformGzhPlanVideo.java
  99. 190 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/po/contentplatform/ContentPlatformGzhPlanVideoExample.java
  100. 22 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/po/contentplatform/ContentPlatformIllegalMsg.java

+ 29 - 0
api-module/src/main/java/com/tzld/piaoquan/api/annotation/RateLimit.java

@@ -0,0 +1,29 @@
+package com.tzld.piaoquan.api.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * IP 限流注解
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface RateLimit {
+    
+    /**
+     * 限流时间窗口,单位秒
+     */
+    long timeWindow() default 60;
+    
+    /**
+     * 时间窗口内最大请求数
+     */
+    long maxRequests() default 10;
+    
+    /**
+     * 限流提示信息
+     */
+    String message() default "请求过于频繁,请稍后再试";
+}

+ 88 - 0
api-module/src/main/java/com/tzld/piaoquan/api/aop/RateLimitAop.java

@@ -0,0 +1,88 @@
+package com.tzld.piaoquan.api.aop;
+
+import com.google.common.base.Strings;
+import com.tzld.piaoquan.api.annotation.RateLimit;
+import com.tzld.piaoquan.api.common.enums.ExceptionEnum;
+import com.tzld.piaoquan.api.common.exception.CommonException;
+import com.tzld.piaoquan.growth.common.utils.IpUtil;
+import com.tzld.piaoquan.growth.common.utils.RedisUtils;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.Method;
+import java.util.Objects;
+
+/**
+ * IP 限流 AOP 切面
+ */
+@Aspect
+@Component
+public class RateLimitAop {
+    
+    private static final Logger log = LoggerFactory.getLogger(RateLimitAop.class);
+    
+    @Autowired
+    private RedisUtils redisUtils;
+    
+    @Pointcut("@annotation(com.tzld.piaoquan.api.annotation.RateLimit)")
+    public void rateLimit() {
+    }
+    
+    /**
+     * 环绕通知,执行限流逻辑
+     */
+    @Around("rateLimit()")
+    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
+        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+        Method method = signature.getMethod();
+        
+        // 获取注解信息
+        RateLimit rateLimit = method.getAnnotation(RateLimit.class);
+        long timeWindow = rateLimit.timeWindow();
+        long maxRequests = rateLimit.maxRequests();
+        String message = rateLimit.message();
+        
+        // 获取请求对象
+        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();
+        
+        // 获取客户端 IP
+        String clientIp = IpUtil.getIpAddr(request);
+        
+        if (Strings.isNullOrEmpty(clientIp)) {
+            log.warn("Rate limit - client IP is empty");
+            return joinPoint.proceed();
+        }
+        
+        // 构建 Redis key: rate_limit:{method_name}:{ip}
+        String methodName = method.getName();
+        String redisKey = String.format("rate_limit:%s:%s", methodName, clientIp);
+        
+        // 获取当前请求次数
+        Long currentRequests = redisUtils.getLong(redisKey);
+        
+        if (currentRequests >= maxRequests) {
+            log.warn("Rate limit exceeded - IP: {}, Method: {}, Requests: {}, Max: {}", 
+                    clientIp, methodName, currentRequests, maxRequests);
+            throw new CommonException(ExceptionEnum.PARAM_ERROR.getCode(), message);
+        }
+        
+        // 增加请求计数
+        redisUtils.setIncrementValue(redisKey, 1, timeWindow);
+        
+        log.debug("Rate limit - IP: {}, Method: {}, Current Requests: {}, Max: {}", 
+                clientIp, methodName, currentRequests + 1, maxRequests);
+        
+        return joinPoint.proceed();
+    }
+}

+ 7 - 0
api-module/src/main/java/com/tzld/piaoquan/api/common/Constant.java

@@ -0,0 +1,7 @@
+package com.tzld.piaoquan.api.common;
+
+public class Constant {
+
+    public static String loginStatusKey = "login:status:uuid:{uuid}";
+
+}

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

@@ -51,6 +51,7 @@ public enum ExceptionEnum {
     // 三方平台 自动拉群群发
     // 三方平台 自动拉群群发
     THIRD_PART_STAFF_NOT_FOUND(5001, "账号不存在"),
     THIRD_PART_STAFF_NOT_FOUND(5001, "账号不存在"),
     THIRD_PART_ROOM_NOT_FOUND(5002, "群不存在"),
     THIRD_PART_ROOM_NOT_FOUND(5002, "群不存在"),
+    THIRD_PART_LOGOUT_FAILED(5003, "企微账号退出失败"),
 
 
     // 用户上传内容管理
     // 用户上传内容管理
     PQ_LOGIN_FAIL(6001, "票圈登录失败"),
     PQ_LOGIN_FAIL(6001, "票圈登录失败"),
@@ -61,6 +62,10 @@ public enum ExceptionEnum {
     PQ_ACCOUNT_NOT_BINDING(6006, "票圈账号未绑定"),
     PQ_ACCOUNT_NOT_BINDING(6006, "票圈账号未绑定"),
     VIDEO_CITED(6007, "视频已被引用,不能删除"),
     VIDEO_CITED(6007, "视频已被引用,不能删除"),
     VIDEO_GET_FAILED(6008, "视频获取失败"),
     VIDEO_GET_FAILED(6008, "视频获取失败"),
+    VIDEO_MULTI_TITLE_SAVE_FAILED(6009, "视频多标题保存失败"),
+    VIDEO_MULTI_COVER_SAVE_FAILED(6010, "视频多封面保存失败"),
+    VIDEO_MULTI_COVER_LIST_FAILED(6011, "视频多封面列表获取失败"),
+    VIDEO_MULTI_TITLE_LIST_FAILED(6012, "视频多标题列表获取失败"),
 
 
     // 用户收藏视频
     // 用户收藏视频
     VIDEO_NOT_EXIST(7001, "视频不存在"),
     VIDEO_NOT_EXIST(7001, "视频不存在"),

+ 33 - 0
api-module/src/main/java/com/tzld/piaoquan/api/common/enums/wecom/ConfigSyncEnum.java

@@ -0,0 +1,33 @@
+package com.tzld.piaoquan.api.common.enums.wecom;
+
+import lombok.Getter;
+
+@Getter
+public enum ConfigSyncEnum {
+    NEW(0, "仅对新建群生效"),
+    ALL(1, "所有群"),
+    SPECIFY(2, "指定群生效"),
+
+    other(999, "其他");
+
+    // 0-仅对新建群生效 1-所有群 2-指定群生效
+    private final int val;
+    private final String description;
+
+    ConfigSyncEnum(int val, String description) {
+        this.val = val;
+        this.description = description;
+    }
+
+    public static ConfigSyncEnum from(int val) {
+        for (ConfigSyncEnum statusEnum : ConfigSyncEnum.values()) {
+            if (statusEnum.getVal() == val) {
+                return statusEnum;
+            }
+        }
+
+        return other;
+    }
+
+
+}

+ 32 - 0
api-module/src/main/java/com/tzld/piaoquan/api/common/enums/wecom/ConfigTaskContentTypeEnum.java

@@ -0,0 +1,32 @@
+package com.tzld.piaoquan.api.common.enums.wecom;
+
+import lombok.Getter;
+
+@Getter
+public enum ConfigTaskContentTypeEnum {
+    TEXT(0, "文案"),
+    MINI_PROGRAM(1, "小程序"),
+
+    other(999, "其他");
+
+    // 0-文案 1-小程序
+    private final int val;
+    private final String description;
+
+    ConfigTaskContentTypeEnum(int val, String description) {
+        this.val = val;
+        this.description = description;
+    }
+
+    public static ConfigTaskContentTypeEnum from(int val) {
+        for (ConfigTaskContentTypeEnum typeEnum : ConfigTaskContentTypeEnum.values()) {
+            if (typeEnum.getVal() == val) {
+                return typeEnum;
+            }
+        }
+
+        return other;
+    }
+
+
+}

+ 31 - 0
api-module/src/main/java/com/tzld/piaoquan/api/common/enums/wecom/MsgSendStatusEnum.java

@@ -0,0 +1,31 @@
+package com.tzld.piaoquan.api.common.enums.wecom;
+
+import lombok.Getter;
+
+@Getter
+public enum MsgSendStatusEnum {
+    FAIL(0, "失败"),
+    NORMAL(1, "正常"),
+
+    other(999, "其他");
+
+    private final int val;
+    private final String description;
+
+    MsgSendStatusEnum(int val, String description) {
+        this.val = val;
+        this.description = description;
+    }
+
+    public static MsgSendStatusEnum from(int val) {
+        for (MsgSendStatusEnum statusEnum : MsgSendStatusEnum.values()) {
+            if (statusEnum.getVal() == val) {
+                return statusEnum;
+            }
+        }
+
+        return other;
+    }
+
+
+}

+ 34 - 0
api-module/src/main/java/com/tzld/piaoquan/api/common/enums/wecom/ThirdPartWeComStaffStatusEnum.java

@@ -0,0 +1,34 @@
+package com.tzld.piaoquan.api.common.enums.wecom;
+
+import lombok.Getter;
+
+@Getter
+public enum ThirdPartWeComStaffStatusEnum {
+    
+    NORMAL(0, "正常"),
+    OFFLINE(1, "掉线"),
+    QUIT(2, "离线"),
+
+    other(999, "其他");
+
+    // 0正常,1掉线,2离线
+    private final int val;
+    private final String description;
+
+    ThirdPartWeComStaffStatusEnum(int val, String description) {
+        this.val = val;
+        this.description = description;
+    }
+
+    public static ThirdPartWeComStaffStatusEnum from(int val) {
+        for (ThirdPartWeComStaffStatusEnum statusEnum : ThirdPartWeComStaffStatusEnum.values()) {
+            if (statusEnum.getVal() == val) {
+                return statusEnum;
+            }
+        }
+
+        return other;
+    }
+
+
+}

+ 43 - 0
api-module/src/main/java/com/tzld/piaoquan/api/common/enums/wecom/WeComThirdPartyCallBackTypeEnum.java

@@ -0,0 +1,43 @@
+package com.tzld.piaoquan.api.common.enums.wecom;
+
+import lombok.Getter;
+
+import java.util.Objects;
+
+@Getter
+public enum WeComThirdPartyCallBackTypeEnum {
+
+    // 登录回调
+    SCAN_CODE(100001, "扫码返回数据"),
+    CONFIRM_SCAN_CODE(100002, "确认扫码返回数据"),
+    CANCEL_SCAN_CODE(100003, "取消扫码返回"),
+    NEED_VERIFY_CODE(100004, "需要输入验证码消息回调"),
+    LOGIN_SUCCESS(104001, "登录成功返回数据"),
+
+    // 断开回调
+    SECOND_VERIFY_NOTIFY(100012, "二次验证消息通知"),
+    LOGIN_END(100005, "手机端结束登录"),
+    OTHER_DEVICE_LOGIN(100008, "当前账号在其他设备登录"),
+    QR_CODE_SCAN_TIMEOUT(100009, "初始化接口二维码扫码超时断开"),
+    EXCEPTION_DISCONNECT(100007, "异常断开"),
+
+    other(999, "其他");
+
+    private final Integer val;
+    private final String description;
+
+    WeComThirdPartyCallBackTypeEnum(Integer val, String description) {
+        this.val = val;
+        this.description = description;
+    }
+
+    public static WeComThirdPartyCallBackTypeEnum from(Integer val) {
+        for (WeComThirdPartyCallBackTypeEnum typeEnum : WeComThirdPartyCallBackTypeEnum.values()) {
+            if (Objects.equals(typeEnum.getVal(), val)) {
+                return typeEnum;
+            }
+        }
+
+        return other;
+    }
+}

+ 21 - 0
api-module/src/main/java/com/tzld/piaoquan/api/component/AdApiService.java

@@ -2,6 +2,7 @@ package com.tzld.piaoquan.api.component;
 
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.JSONObject;
+import com.tzld.piaoquan.api.model.bo.AdPutCreativeComponentCostData;
 import com.tzld.piaoquan.api.model.bo.AdPutFlowRecordTencent;
 import com.tzld.piaoquan.api.model.bo.AdPutFlowRecordTencent;
 import com.tzld.piaoquan.growth.common.component.HttpPoolClient;
 import com.tzld.piaoquan.growth.common.component.HttpPoolClient;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
@@ -52,4 +53,24 @@ public class AdApiService {
         }
         }
         return new ArrayList<>();
         return new ArrayList<>();
     }
     }
+
+    /**
+     * 获取投放广告创意花费
+     * @param dt 2025-12-23
+     * @return
+     */
+    public List<AdPutCreativeComponentCostData> getCreativeComponentsCost(String dt) {
+        String url = "https://api.piaoquantv.com/ad" + "/put/tencent/getCreativeComponentsCost?dt=" + dt;
+        try {
+            String post = httpPoolClient.get(url);
+            JSONObject res = JSONObject.parseObject(post);
+            JSONArray data = res.getJSONArray("data");
+            if (Objects.nonNull(data) && !data.isEmpty()) {
+                return data.toJavaList(AdPutCreativeComponentCostData.class);
+            }
+        } catch (Exception e) {
+            log.error("getPutFlowListTencent error", e);
+        }
+        return new ArrayList<>();
+    }
 }
 }

+ 54 - 0
api-module/src/main/java/com/tzld/piaoquan/api/component/AigcApiService.java

@@ -2,10 +2,13 @@ package com.tzld.piaoquan.api.component;
 
 
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.JSONObject;
 import com.tzld.piaoquan.api.common.exception.CommonException;
 import com.tzld.piaoquan.api.common.exception.CommonException;
+import com.tzld.piaoquan.api.model.bo.GoogleLLMResult;
 import com.tzld.piaoquan.api.model.vo.WxAccountDatastatVO;
 import com.tzld.piaoquan.api.model.vo.WxAccountDatastatVO;
 import com.tzld.piaoquan.growth.common.component.HttpPoolClient;
 import com.tzld.piaoquan.growth.common.component.HttpPoolClient;
 import com.tzld.piaoquan.growth.common.utils.DateUtil;
 import com.tzld.piaoquan.growth.common.utils.DateUtil;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Component;
@@ -26,6 +29,9 @@ public class AigcApiService {
     @Value("${aigc.api.token:9ebfcb397e954c41986971f183eb1707}")
     @Value("${aigc.api.token:9ebfcb397e954c41986971f183eb1707}")
     private String aigcApiToken;
     private String aigcApiToken;
 
 
+    @Value("${spring.profiles.active:dev}")
+    private String env;
+
     private String getAigcPostParam(JSONObject params) {
     private String getAigcPostParam(JSONObject params) {
         JSONObject baseInfo = JSONObject.parseObject("{\n" +
         JSONObject baseInfo = JSONObject.parseObject("{\n" +
                 "    \"token\": \"" + aigcApiToken + "\",\n" +
                 "    \"token\": \"" + aigcApiToken + "\",\n" +
@@ -211,6 +217,9 @@ public class AigcApiService {
     }
     }
 
 
     public void refreshGzhAutoReplyMsgData(String ghId) {
     public void refreshGzhAutoReplyMsgData(String ghId) {
+        if (!"prod".equals(env)) {
+            return;
+        }
         String url = aigcApiHost + "/publish/api/refreshGzhAutoReplyMsgData?ghId=" + ghId;
         String url = aigcApiHost + "/publish/api/refreshGzhAutoReplyMsgData?ghId=" + ghId;
         try {
         try {
             httpPoolClient.get(url);
             httpPoolClient.get(url);
@@ -285,4 +294,49 @@ public class AigcApiService {
         }
         }
         return false;
         return false;
     }
     }
+
+    public String gpt(String model, String prompt, JSONObject responseFormat, List<String> imageList) {
+        if (StringUtils.isEmpty(model) || StringUtils.isEmpty(prompt)) {
+            return null;
+        }
+        String url = "http://aigc-api.cybertogether.net/aigc" + "/dev/test/gpt";
+        JSONObject params = new JSONObject();
+        params.put("model", model);
+        params.put("prompt", prompt);
+        if (Objects.nonNull(responseFormat)) {
+            params.put("responseFormat", responseFormat);
+        }
+        if (CollectionUtils.isNotEmpty(imageList)) {
+            params.put("imageList", imageList);
+        }
+
+        try {
+            String post = httpPoolClient.post(url, params.toJSONString());
+            JSONObject res = JSONObject.parseObject(post);
+            return res.getString("data");
+        } catch (Exception e) {
+            log.error("gpt error", e);
+        }
+        return null;
+    }
+
+    public GoogleLLMResult gemini(String model, String prompt, List<String> imageList) {
+        if (StringUtils.isEmpty(model) || StringUtils.isEmpty(prompt)) {
+            return null;
+        }
+        String url = "http://aigc-api.cybertogether.net/aigc" + "/infrastructure/gemini/requestWithMedia?model=" + model;
+        JSONObject params = new JSONObject();
+        params.put("prompt", prompt);
+        if (CollectionUtils.isNotEmpty(imageList)) {
+            params.put("mediaList", imageList);
+        }
+
+        try {
+            String post = httpPoolClient.post(url, params.toJSONString());
+            return JSONObject.parseObject(post, GoogleLLMResult.class);
+        } catch (Exception e) {
+            log.error("gemini error", e);
+        }
+        return null;
+    }
 }
 }

+ 93 - 0
api-module/src/main/java/com/tzld/piaoquan/api/component/DeepSeekApiService.java

@@ -0,0 +1,93 @@
+package com.tzld.piaoquan.api.component;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.tzld.piaoquan.api.model.dto.AIOfficialApiResponse;
+import com.tzld.piaoquan.api.model.dto.AIResult;
+import com.tzld.piaoquan.growth.common.utils.MapBuilder;
+import lombok.extern.slf4j.Slf4j;
+import okhttp3.*;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.http.util.TextUtils;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+
+@Service
+@Slf4j
+public class DeepSeekApiService {
+
+    private OkHttpClient client;
+
+    @PostConstruct
+    public void init() {
+        client = new OkHttpClient().newBuilder()
+                .connectTimeout(5, TimeUnit.MINUTES)
+                .readTimeout(5, TimeUnit.MINUTES)
+                .writeTimeout(5, TimeUnit.MINUTES)
+                .build();
+    }
+
+    public AIResult requestOfficialApi(String prompt, String model, Double temperature, Boolean isJSON) {
+        AIResult result = new AIResult();
+        result.setSuccess(false);
+        if (TextUtils.isBlank(prompt) || TextUtils.isBlank(prompt.trim())) {
+            result.setFailReason("prompt is empty");
+            return result;
+        }
+
+        try {
+            JSONArray jsonArray = new JSONArray();
+            JSONObject message = new JSONObject();
+            message.put("role", "user");
+            message.put("content", prompt);
+            jsonArray.add(message);
+
+            Map<Object, Object> bodyParam = MapBuilder
+                    .builder()
+                    .put("model", Optional.ofNullable(model).orElse("deepseek-chat"))
+                    .put("temperature", Optional.ofNullable(temperature).orElse(0.3))
+                    .put("messages", jsonArray)
+                    .build();
+            if (isJSON) {
+                JSONObject formatJSON = new JSONObject();
+                formatJSON.put("type", "json_object");
+                bodyParam.put("response_format", formatJSON);
+            }
+
+            MediaType mediaType = MediaType.parse("application/json");
+            RequestBody body = RequestBody.create(mediaType, JSONObject.toJSONString(bodyParam));
+            Request request = new Request.Builder()
+                    .url("https://api.deepseek.com/chat/completions")
+                    .method("POST", body)
+                    .addHeader("Content-Type", "application/json")
+                    .addHeader("Accept", "application/json")
+                    .addHeader("Authorization", "Bearer sk-62d7b2c37f824735aa4985852c919c1f")
+                    .build();
+            Response response = client.newCall(request).execute();
+
+            String responseContent = response.body().string();
+            result.setResponseStr(responseContent);
+            log.info("deepseek api responseContent = {}", responseContent);
+            if (response.isSuccessful()) {
+                AIOfficialApiResponse obj = JSONObject.parseObject(responseContent, AIOfficialApiResponse.class);
+                if (CollectionUtils.isNotEmpty(obj.getChoices())) {
+                    result.setSuccess(true);
+                    result.setResponse(obj);
+                } else {
+                    result.setFailReason("response empty");
+                }
+            } else {
+                JSONObject json = JSONObject.parseObject(responseContent);
+                result.setFailReason("request error code:" + response.code() + " message:" + json.getString("error"));
+            }
+        } catch (Exception e) {
+            log.error("deepseek official api fail: " + e.getMessage());
+            result.setFailReason(e.getMessage());
+        }
+        return result;
+    }
+}

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

@@ -0,0 +1,138 @@
+package com.tzld.piaoquan.api.component;
+
+import com.alibaba.fastjson.JSONArray;
+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");
+    }
+
+    public JSONArray videoMultiCoverListV2(Long videoId) {
+        String url = managerApiHost + "/video/multiCover/listV2";
+        JSONObject res = null;
+        int retry = 0;
+        while (retry < 3) {
+            try {
+                JSONObject param = new JSONObject();
+                param.put("videoId", videoId);
+                param.put("range", "2h");
+                String post = httpPoolClient.post(url, param.toJSONString());
+                res = JSONObject.parseObject(post);
+                break;
+            } catch (Exception e) {
+                log.error("ManagerApiService videoMultiCoverListV2 error, videoId={} range={}",
+                        videoId, "2h", e);
+                retry++;
+            }
+        }
+        if (Objects.isNull(res)) {
+            throw new CommonException(ExceptionEnum.VIDEO_MULTI_COVER_LIST_FAILED);
+        }
+        if (res.getInteger("code") != 0) {
+            log.error("ManagerApiService videoMultiCoverListV2 error, videoId={} range={} res={}",
+                    videoId, "2h", res);
+            throw new CommonException(ExceptionEnum.VIDEO_MULTI_COVER_LIST_FAILED.getCode(),
+                    ExceptionEnum.VIDEO_MULTI_COVER_LIST_FAILED.getMsg() + "," + res.getString("msg"));
+        }
+        return res.getJSONArray("content");
+    }
+
+    public JSONArray videoMultiTitleListV2(Long videoId) {
+        String url = managerApiHost + "/video/multiTitleV2/listV2";
+        JSONObject res = null;
+        int retry = 0;
+        while (retry < 3) {
+            try {
+                JSONObject param = new JSONObject();
+                param.put("videoId", videoId);
+                param.put("range", "4h");
+                String post = httpPoolClient.post(url, param.toJSONString());
+                res = JSONObject.parseObject(post);
+                break;
+            } catch (Exception e) {
+                log.error("ManagerApiService videoMultiCoverListV2 error, videoId={} range={}",
+                        videoId, "4h", e);
+                retry++;
+            }
+        }
+        if (Objects.isNull(res)) {
+            throw new CommonException(ExceptionEnum.VIDEO_MULTI_TITLE_LIST_FAILED);
+        }
+        if (res.getInteger("code") != 0) {
+            log.error("ManagerApiService videoMultiTitleListV2 error, videoId={} range={} res={}",
+                    videoId, "4h", res);
+            throw new CommonException(ExceptionEnum.VIDEO_MULTI_TITLE_LIST_FAILED.getCode(),
+                    ExceptionEnum.VIDEO_MULTI_TITLE_LIST_FAILED.getMsg() + "," + res.getString("msg"));
+        }
+        return res.getJSONArray("content");
+    }
+
+
+}

+ 23 - 17
api-module/src/main/java/com/tzld/piaoquan/api/component/VideoApiService.java

@@ -162,23 +162,29 @@ public class VideoApiService {
 
 
     public void deleteVideo(Long uid, Long videoId) {
     public void deleteVideo(Long uid, Long videoId) {
         String url = videoApiHost + "/longvideoapi/openapi/video/delete";
         String url = videoApiHost + "/longvideoapi/openapi/video/delete";
-        JSONObject res = null;
-        try {
-            JSONObject param = new JSONObject();
-            param.put("loginUid", uid);
-            param.put("videoId", videoId);
-            String post = httpPoolClient.post(url, param.toJSONString());
-            res = JSONObject.parseObject(post);
-        } catch (Exception e) {
-            log.error("VideoApiService deleteVideo error", e);
-        }
-        if (Objects.isNull(res)) {
-            throw new CommonException(ExceptionEnum.VIDEO_DELETE_FAILED);
-        }
-        if (res.getInteger("code") != 0) {
-            log.error("VideoApiService deleteVideo error, videoId={} res={}", videoId, res);
-            throw new CommonException(ExceptionEnum.VIDEO_DELETE_FAILED.getCode(),
-                    ExceptionEnum.VIDEO_DELETE_FAILED.getMsg() + "," + res.getString("msg"));
+        int retryCount = 3;
+        while (retryCount > 0) {
+            try {
+                JSONObject param = new JSONObject();
+                param.put("loginUid", uid);
+                param.put("videoId", videoId);
+                String post = httpPoolClient.post(url, param.toJSONString());
+                JSONObject res = JSONObject.parseObject(post);
+                if (Objects.isNull(res)) {
+                    throw new CommonException(ExceptionEnum.VIDEO_DELETE_FAILED);
+                }
+                if (res.getInteger("code") != 0) {
+                    log.error("VideoApiService deleteVideo error, videoId={} res={}", videoId, res);
+                    throw new CommonException(ExceptionEnum.VIDEO_DELETE_FAILED.getCode(),
+                            ExceptionEnum.VIDEO_DELETE_FAILED.getMsg() + "," + res.getString("msg"));
+                } else {
+                    log.info("VideoApiService deleteVideo success, uid:{} videoId={}", uid, videoId);
+                    return;
+                }
+            } catch (Exception e) {
+                log.error("VideoApiService deleteVideo error", e);
+            }
+            retryCount--;
         }
         }
     }
     }
 
 

+ 19 - 1
api-module/src/main/java/com/tzld/piaoquan/api/component/WeComThirdPartyApiClient.java

@@ -8,13 +8,21 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Component;
 
 
 import java.io.IOException;
 import java.io.IOException;
+import java.util.concurrent.TimeUnit;
 
 
 @Slf4j
 @Slf4j
 @Component
 @Component
 public class WeComThirdPartyApiClient {
 public class WeComThirdPartyApiClient {
 
 
     private static final MediaType JSON = MediaType.get("application/json; charset=utf-8");
     private static final MediaType JSON = MediaType.get("application/json; charset=utf-8");
-    private final OkHttpClient client = new OkHttpClient();
+    private final OkHttpClient client;
+
+    {
+        client = new OkHttpClient().newBuilder()
+                .connectTimeout(3, TimeUnit.MINUTES)
+                .readTimeout(3, TimeUnit.MINUTES)
+                .writeTimeout(3, TimeUnit.MINUTES).build();
+    }
 
 
     @Value("${wecom.thirdpart.baseUrl:http://47.96.102.58:8083}")
     @Value("${wecom.thirdpart.baseUrl:http://47.96.102.58:8083}")
     private String baseUrl;
     private String baseUrl;
@@ -79,6 +87,16 @@ public class WeComThirdPartyApiClient {
         return postRequest("/wxwork/GetRunClientByUuid", request);
         return postRequest("/wxwork/GetRunClientByUuid", request);
     }
     }
 
 
+    /**
+     * 获取当前账号对外名片二维码
+     *
+     * @param request 请求体
+     * @return 响应结果
+     */
+    public String getExternalBusinessCard(UuidRequest request) {
+        return postRequest("/wxwork/ExternalBusinessCard", request);
+    }
+
     /**
     /**
      * 获取内部联系人列表
      * 获取内部联系人列表
      *
      *

+ 5 - 5
api-module/src/main/java/com/tzld/piaoquan/api/config/CrossOriginConfig.java

@@ -23,11 +23,11 @@ public class CrossOriginConfig implements WebMvcConfigurer {
 
 
     @Override
     @Override
     public void addCorsMappings(CorsRegistry registry) {
     public void addCorsMappings(CorsRegistry registry) {
-//        registry.addMapping("/**")
-//                .allowedOrigins("*")
-//                .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
-//                .maxAge(3600)
-//                .allowCredentials(false);
+        registry.addMapping("/**")
+                .allowedOrigins("*")
+                .allowedMethods("*")
+                .maxAge(3600)
+                .allowCredentials(false);
     }
     }
 
 
 }
 }

+ 11 - 4
api-module/src/main/java/com/tzld/piaoquan/api/config/JwtInterceptor.java

@@ -42,6 +42,17 @@ public class JwtInterceptor implements HandlerInterceptor {
 
 
     @Override
     @Override
     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+
+        if (HttpMethod.OPTIONS.name().equals(request.getMethod())) {
+            response.setStatus(HttpServletResponse.SC_OK);
+            response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
+            response.setHeader("Access-Control-Allow-Credentials", "true");
+            response.setHeader("Access-Control-Allow-Methods", "*");
+            response.setHeader("Access-Control-Allow-Headers", "*");
+            response.setHeader("Access-Control-Max-Age", "3600");
+            return true;
+        }
+
         if ((StringUtils.isNotBlank(request.getRequestURI()) && request.getRequestURI().contains("auth")) ||
         if ((StringUtils.isNotBlank(request.getRequestURI()) && request.getRequestURI().contains("auth")) ||
                 (Objects.nonNull(request.getRequestURL()) && request.getRequestURL().toString().contains("auth"))
                 (Objects.nonNull(request.getRequestURL()) && request.getRequestURL().toString().contains("auth"))
         ) {
         ) {
@@ -55,10 +66,6 @@ public class JwtInterceptor implements HandlerInterceptor {
                 return Boolean.TRUE;
                 return Boolean.TRUE;
             }
             }
         }
         }
-        if (HttpMethod.OPTIONS.name().equals(request.getMethod())) {
-            response.setStatus(HttpServletResponse.SC_OK);
-            return true;
-        }
         String uri = request.getServletPath();
         String uri = request.getServletPath();
         if (this.exclude(uri)) {
         if (this.exclude(uri)) {
             //放行excludePaths包含的目录路径和excludeUris包含的URI
             //放行excludePaths包含的目录路径和excludeUris包含的URI

+ 20 - 4
api-module/src/main/java/com/tzld/piaoquan/api/controller/AccountDetailController.java

@@ -1,12 +1,13 @@
 package com.tzld.piaoquan.api.controller;
 package com.tzld.piaoquan.api.controller;
 
 
-import com.tzld.piaoquan.growth.common.common.enums.GhTypeEnum;
-import com.tzld.piaoquan.growth.common.common.enums.StrategyStatusEnum;
+import com.tzld.piaoquan.api.job.GzhReplyVideoRefreshJob;
 import com.tzld.piaoquan.api.model.vo.GhDetailVo;
 import com.tzld.piaoquan.api.model.vo.GhDetailVo;
 import com.tzld.piaoquan.api.model.vo.GhTypeVo;
 import com.tzld.piaoquan.api.model.vo.GhTypeVo;
 import com.tzld.piaoquan.api.model.vo.StrategyStatusVo;
 import com.tzld.piaoquan.api.model.vo.StrategyStatusVo;
 import com.tzld.piaoquan.api.service.GhDetailService;
 import com.tzld.piaoquan.api.service.GhDetailService;
 import com.tzld.piaoquan.growth.common.common.base.CommonResponse;
 import com.tzld.piaoquan.growth.common.common.base.CommonResponse;
+import com.tzld.piaoquan.growth.common.common.enums.GhTypeEnum;
+import com.tzld.piaoquan.growth.common.common.enums.StrategyStatusEnum;
 import com.tzld.piaoquan.growth.common.utils.page.Page;
 import com.tzld.piaoquan.growth.common.utils.page.Page;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -25,13 +26,16 @@ public class AccountDetailController {
 
 
     @Autowired
     @Autowired
     private GhDetailService ghDetailService;
     private GhDetailService ghDetailService;
+    @Autowired
+    private GzhReplyVideoRefreshJob gzhReplyVideoRefreshJob;
 
 
     @GetMapping("/getList")
     @GetMapping("/getList")
     public CommonResponse<Page<GhDetailVo>> getAccountDetailList(@RequestParam(defaultValue = "1") Integer pageNum,
     public CommonResponse<Page<GhDetailVo>> getAccountDetailList(@RequestParam(defaultValue = "1") Integer pageNum,
                                                                  @RequestParam(defaultValue = "20") Integer pageSize,
                                                                  @RequestParam(defaultValue = "20") Integer pageSize,
                                                                  @RequestParam(defaultValue = "") String accountId,
                                                                  @RequestParam(defaultValue = "") String accountId,
-                                                                 @RequestParam(defaultValue = "") String accountName) {
-        return ghDetailService.getGhDetailList(pageNum, pageSize, accountId, accountName);
+                                                                 @RequestParam(defaultValue = "") String accountName,
+                                                                 @RequestParam(required = false) Long videoId) {
+        return ghDetailService.getGhDetailList(pageNum, pageSize, accountId, accountName, videoId);
     }
     }
 
 
     @PostMapping("/add")
     @PostMapping("/add")
@@ -62,4 +66,16 @@ public class AccountDetailController {
                 .map(strategyStatusEnum -> new StrategyStatusVo(strategyStatusEnum.status, strategyStatusEnum.name))
                 .map(strategyStatusEnum -> new StrategyStatusVo(strategyStatusEnum.status, strategyStatusEnum.name))
                 .collect(Collectors.toList()));
                 .collect(Collectors.toList()));
     }
     }
+
+    @GetMapping("/job/gzhReplyVideoRefreshJob")
+    public CommonResponse<Void> gzhReplyVideoRefreshJob() {
+        gzhReplyVideoRefreshJob.gzhReplyVideoRefreshJob(null);
+        return CommonResponse.success();
+    }
+
+    @GetMapping("/job/syncGzhAutoreplyBehaviorUvTotalJob")
+    public CommonResponse<Void> syncGzhAutoreplyBehaviorUvTotalJob() {
+        gzhReplyVideoRefreshJob.syncGzhAutoreplyBehaviorUvTotalJob(null);
+        return CommonResponse.success();
+    }
 }
 }

+ 13 - 0
api-module/src/main/java/com/tzld/piaoquan/api/controller/CgiReplyController.java

@@ -1,7 +1,9 @@
 package com.tzld.piaoquan.api.controller;
 package com.tzld.piaoquan.api.controller;
 
 
 import com.tzld.piaoquan.api.model.bo.BucketDataParam;
 import com.tzld.piaoquan.api.model.bo.BucketDataParam;
+import com.tzld.piaoquan.api.model.bo.MsgData;
 import com.tzld.piaoquan.api.model.bo.ReplyBucketData;
 import com.tzld.piaoquan.api.model.bo.ReplyBucketData;
+import com.tzld.piaoquan.api.model.bo.bucketDataGenerateParam;
 import com.tzld.piaoquan.api.model.vo.VideoCharacteristicVO;
 import com.tzld.piaoquan.api.model.vo.VideoCharacteristicVO;
 import com.tzld.piaoquan.api.service.CgiReplyService;
 import com.tzld.piaoquan.api.service.CgiReplyService;
 import com.tzld.piaoquan.growth.common.common.base.CommonResponse;
 import com.tzld.piaoquan.growth.common.common.base.CommonResponse;
@@ -23,8 +25,19 @@ public class CgiReplyController {
         return CommonResponse.success(replyBucketData);
         return CommonResponse.success(replyBucketData);
     }
     }
 
 
+    @PostMapping("/bucketDataGenerate")
+    public CommonResponse<MsgData> bucketDataGenerate(@RequestBody bucketDataGenerateParam param) {
+        MsgData data = cgiReplyService.bucketDataGenerate(param);
+        return CommonResponse.success(data);
+    }
+
     @GetMapping("/getVideoCharacteristic")
     @GetMapping("/getVideoCharacteristic")
     public CommonResponse<VideoCharacteristicVO> getVideoCharacteristicByRootSourceId(@RequestParam String rootSourceId) {
     public CommonResponse<VideoCharacteristicVO> getVideoCharacteristicByRootSourceId(@RequestParam String rootSourceId) {
         return CommonResponse.success(cgiReplyService.getVideoCharacteristicByRootSourceId(rootSourceId));
         return CommonResponse.success(cgiReplyService.getVideoCharacteristicByRootSourceId(rootSourceId));
     }
     }
+
+    @GetMapping("/checkExistRootSourceId")
+    public CommonResponse<Boolean> checkExistRootSourceId(@RequestParam String rootSourceId) {
+        return CommonResponse.success(cgiReplyService.checkExistRootSourceId(rootSourceId));
+    }
 }
 }

+ 33 - 0
api-module/src/main/java/com/tzld/piaoquan/api/controller/VideoMultiController.java

@@ -0,0 +1,33 @@
+package com.tzld.piaoquan.api.controller;
+
+import com.tzld.piaoquan.api.model.po.contentplatform.VideoGrowthMultiCover;
+import com.tzld.piaoquan.api.model.po.contentplatform.VideoGrowthMultiTitle;
+import com.tzld.piaoquan.api.service.VideoMultiService;
+import com.tzld.piaoquan.growth.common.common.base.CommonResponse;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/video/multi")
+@Slf4j
+public class VideoMultiController {
+
+    @Autowired
+    private VideoMultiService videoMultiService;
+
+    @GetMapping("/title/list")
+    public CommonResponse<List<VideoGrowthMultiTitle>> getMultiTitleByVideoId(@RequestParam Long videoId) {
+        return CommonResponse.success(videoMultiService.getMultiTitleByVideoId(videoId));
+    }
+
+    @GetMapping("/cover/list")
+    public CommonResponse<List<VideoGrowthMultiCover>> getMultiCoverByVideoId(@RequestParam Long videoId) {
+        return CommonResponse.success(videoMultiService.getMultiCoverByVideoId(videoId));
+    }
+}

+ 12 - 8
api-module/src/main/java/com/tzld/piaoquan/api/controller/contentplatform/ContentPlatformAccountController.java

@@ -1,7 +1,10 @@
 package com.tzld.piaoquan.api.controller.contentplatform;
 package com.tzld.piaoquan.api.controller.contentplatform;
 
 
 import com.tzld.piaoquan.api.annotation.JwtIgnore;
 import com.tzld.piaoquan.api.annotation.JwtIgnore;
-import com.tzld.piaoquan.api.model.param.contentplatform.*;
+import com.tzld.piaoquan.api.model.param.contentplatform.AccountForbiddenParam;
+import com.tzld.piaoquan.api.model.param.contentplatform.AccountListParam;
+import com.tzld.piaoquan.api.model.param.contentplatform.AccountLoginParam;
+import com.tzld.piaoquan.api.model.param.contentplatform.AccountSaveParam;
 import com.tzld.piaoquan.api.model.vo.contentplatform.AccountLoginVO;
 import com.tzld.piaoquan.api.model.vo.contentplatform.AccountLoginVO;
 import com.tzld.piaoquan.api.model.vo.contentplatform.AccountVO;
 import com.tzld.piaoquan.api.model.vo.contentplatform.AccountVO;
 import com.tzld.piaoquan.api.service.contentplatform.ContentPlatformAccountService;
 import com.tzld.piaoquan.api.service.contentplatform.ContentPlatformAccountService;
@@ -26,13 +29,14 @@ public class ContentPlatformAccountController {
         return CommonResponse.success(accountService.login(param));
         return CommonResponse.success(accountService.login(param));
     }
     }
 
 
-    @ApiOperation(value = "发送短信验证码")
-    @PostMapping("/sendMessageVerifyCode")
-    @JwtIgnore
-    public CommonResponse<Void> sendMessageVerifyCode(@RequestBody AccountSendMessageParam param) {
-        accountService.sendMessageVerifyCode(param);
-        return CommonResponse.success();
-    }
+    //@ApiOperation(value = "发送短信验证码")
+    //@PostMapping("/sendMessageVerifyCode")
+    //@JwtIgnore
+    //@RateLimit(timeWindow = 3600, maxRequests = 3, message = "请求过于频繁,请稍后再试")
+    //public CommonResponse<Void> sendMessageVerifyCode(@RequestBody AccountSendMessageParam param) {
+    //    accountService.sendMessageVerifyCode(param);
+    //    return CommonResponse.success();
+    //}
 
 
     @ApiOperation(value = "分页获取账户")
     @ApiOperation(value = "分页获取账户")
     @PostMapping(value = "/list")
     @PostMapping(value = "/list")

+ 7 - 0
api-module/src/main/java/com/tzld/piaoquan/api/controller/contentplatform/ContentPlatformPlanController.java

@@ -169,4 +169,11 @@ public class ContentPlatformPlanController {
         videoJob.calContentPlatformVideoDatastatAggRecommendRateJob(dateStr);
         videoJob.calContentPlatformVideoDatastatAggRecommendRateJob(dateStr);
         return CommonResponse.success();
         return CommonResponse.success();
     }
     }
+
+    @ApiOperation(value = "公众号推送-检查rootSourceId是否存在", hidden = true)
+    @JwtIgnore
+    @GetMapping("/gzhPush/checkExistRootSourceId")
+    public CommonResponse<Boolean> gzhPushCheckExistRootSourceId(String rootSourceId) {
+        return CommonResponse.success(planService.gzhPushCheckExistRootSourceId(rootSourceId));
+    }
 }
 }

+ 1 - 1
api-module/src/main/java/com/tzld/piaoquan/api/controller/MessageController.java → api-module/src/main/java/com/tzld/piaoquan/api/controller/wecom/MessageController.java

@@ -1,4 +1,4 @@
-package com.tzld.piaoquan.api.controller;
+package com.tzld.piaoquan.api.controller.wecom;
 
 
 
 
 import com.tzld.piaoquan.growth.common.common.base.CommonResponse;
 import com.tzld.piaoquan.growth.common.common.base.CommonResponse;

+ 3 - 6
api-module/src/main/java/com/tzld/piaoquan/api/controller/TencentWeComController.java → api-module/src/main/java/com/tzld/piaoquan/api/controller/wecom/TencentWeComController.java

@@ -1,20 +1,17 @@
-package com.tzld.piaoquan.api.controller;
+package com.tzld.piaoquan.api.controller.wecom;
 
 
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.JSONObject;
-import com.tzld.piaoquan.growth.common.model.vo.SendRequestParam;
-import com.tzld.piaoquan.api.service.WeComAutoReply;
+import com.tzld.piaoquan.api.service.wecom.WeComAutoReply;
 import com.tzld.piaoquan.growth.common.common.constant.WeComServerConstant;
 import com.tzld.piaoquan.growth.common.common.constant.WeComServerConstant;
 import com.tzld.piaoquan.growth.common.component.HttpPoolClient;
 import com.tzld.piaoquan.growth.common.component.HttpPoolClient;
+import com.tzld.piaoquan.growth.common.model.vo.SendRequestParam;
 import com.tzld.piaoquan.growth.common.service.WeComUserService;
 import com.tzld.piaoquan.growth.common.service.WeComUserService;
 import com.tzld.piaoquan.growth.common.utils.wecom.WXBizMsgCrypt;
 import com.tzld.piaoquan.growth.common.utils.wecom.WXBizMsgCrypt;
 import com.tzld.piaoquan.growth.common.utils.wecom.WxUtil;
 import com.tzld.piaoquan.growth.common.utils.wecom.WxUtil;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
-import lombok.val;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.ibatis.annotations.Param;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.bind.annotation.*;
-import org.springframework.web.multipart.MultipartFile;
 
 
 import javax.servlet.ServletInputStream;
 import javax.servlet.ServletInputStream;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequest;

+ 5 - 2
api-module/src/main/java/com/tzld/piaoquan/api/controller/ThirdPartyController.java → api-module/src/main/java/com/tzld/piaoquan/api/controller/wecom/ThirdPartyController.java

@@ -1,10 +1,13 @@
-package com.tzld.piaoquan.api.controller;
+package com.tzld.piaoquan.api.controller.wecom;
 
 
 
 
+import com.tzld.piaoquan.api.model.param.AccessTokenParam;
+import com.tzld.piaoquan.api.model.param.CallbackParam;
+import com.tzld.piaoquan.api.model.param.PushMessageParam;
 import com.tzld.piaoquan.api.model.vo.*;
 import com.tzld.piaoquan.api.model.vo.*;
 import com.tzld.piaoquan.api.mq.MessageCallbackProducer;
 import com.tzld.piaoquan.api.mq.MessageCallbackProducer;
 import com.tzld.piaoquan.api.service.GhAccessTokenService;
 import com.tzld.piaoquan.api.service.GhAccessTokenService;
-import com.tzld.piaoquan.api.service.ThirdPartyService;
+import com.tzld.piaoquan.api.service.wecom.ThirdPartyService;
 import com.tzld.piaoquan.growth.common.common.base.CommonResponse;
 import com.tzld.piaoquan.growth.common.common.base.CommonResponse;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.bind.annotation.*;

+ 3 - 3
api-module/src/main/java/com/tzld/piaoquan/api/controller/WeComController.java → api-module/src/main/java/com/tzld/piaoquan/api/controller/wecom/WeComController.java

@@ -1,8 +1,8 @@
-package com.tzld.piaoquan.api.controller;
+package com.tzld.piaoquan.api.controller.wecom;
 
 
-import com.tzld.piaoquan.api.model.vo.WeComPushMessageParam;
+import com.tzld.piaoquan.api.model.param.WeComPushMessageParam;
 import com.tzld.piaoquan.api.model.vo.WeComPushMessageVo;
 import com.tzld.piaoquan.api.model.vo.WeComPushMessageVo;
-import com.tzld.piaoquan.api.service.WeComService;
+import com.tzld.piaoquan.api.service.wecom.WeComService;
 import com.tzld.piaoquan.growth.common.common.base.CommonResponse;
 import com.tzld.piaoquan.growth.common.common.base.CommonResponse;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;

+ 2 - 2
api-module/src/main/java/com/tzld/piaoquan/api/controller/WeComUserController.java → api-module/src/main/java/com/tzld/piaoquan/api/controller/wecom/WeComUserController.java

@@ -1,6 +1,6 @@
-package com.tzld.piaoquan.api.controller;
+package com.tzld.piaoquan.api.controller.wecom;
 
 
-import com.tzld.piaoquan.api.model.vo.WeComUserNameAvatarParam;
+import com.tzld.piaoquan.api.model.param.WeComUserNameAvatarParam;
 import com.tzld.piaoquan.growth.common.common.base.CommonResponse;
 import com.tzld.piaoquan.growth.common.common.base.CommonResponse;
 import com.tzld.piaoquan.growth.common.model.bo.GroupSendWeComUserParam;
 import com.tzld.piaoquan.growth.common.model.bo.GroupSendWeComUserParam;
 import com.tzld.piaoquan.growth.common.model.vo.UserTagParam;
 import com.tzld.piaoquan.growth.common.model.vo.UserTagParam;

+ 92 - 0
api-module/src/main/java/com/tzld/piaoquan/api/controller/wecom/thirdpart/WeComThirdPartyAccountController.java

@@ -0,0 +1,92 @@
+package com.tzld.piaoquan.api.controller.wecom.thirdpart;
+
+import com.tzld.piaoquan.api.model.param.wecom.thirdpart.*;
+import com.tzld.piaoquan.api.model.vo.IdNameVO;
+import com.tzld.piaoquan.api.model.vo.contentplatform.AccountQrCodeVO;
+import com.tzld.piaoquan.api.model.vo.wecom.thirdpart.CheckPushAccountExistVO;
+import com.tzld.piaoquan.api.model.vo.wecom.thirdpart.ThirdPartyAccountConfigVO;
+import com.tzld.piaoquan.api.model.vo.wecom.thirdpart.ThirdPartyAccountVO;
+import com.tzld.piaoquan.api.service.wecom.thirdparty.WeComThirdPartyAccountService;
+import com.tzld.piaoquan.growth.common.common.base.CommonResponse;
+import com.tzld.piaoquan.growth.common.utils.page.Page;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@Slf4j
+@RestController
+@RequestMapping("/wecom/thirdparty/account")
+@CrossOrigin(origins = "*")
+public class WeComThirdPartyAccountController {
+
+    @Autowired
+    private WeComThirdPartyAccountService service;
+
+    @ApiOperation(value = "获取登录二维码")
+    @GetMapping("/getQrCode")
+    public CommonResponse<AccountQrCodeVO> getQrCode(@RequestParam(required = false) Long id) {
+        return CommonResponse.success(service.getQrCode(id));
+    }
+
+    @ApiOperation(value = "检查登录状态")
+    @GetMapping("/checkLogin")
+    public CommonResponse<Integer> checkLogin(@RequestParam String uuid) {
+        return CommonResponse.success(service.checkLogin(uuid));
+    }
+
+    @ApiOperation(value = "设置验证码")
+    @PostMapping("/setCheckCode")
+    public CommonResponse<Void> setCheckCode(@RequestBody CheckCodeRequest param) {
+        service.setCheckCode(param);
+        return CommonResponse.success();
+    }
+
+    @ApiOperation(value = "账号列表")
+    @PostMapping("/list")
+    public CommonResponse<Page<ThirdPartyAccountVO>> list(@RequestBody ThirdPartyAccountListParam param) {
+        return CommonResponse.success(service.list(param));
+    }
+
+    @ApiOperation(value = "获取推送人员列表")
+    @GetMapping("/getPushAccountList")
+    public CommonResponse<List<IdNameVO<Long>>> getPushAccountList(@RequestParam Long accountId, @RequestParam(required = false) String name) {
+        return CommonResponse.success(service.getPushAccountList(accountId, name));
+    }
+
+    @ApiOperation(value = "获取账号配置")
+    @PostMapping("/getAccountConfig")
+    public CommonResponse<ThirdPartyAccountConfigVO> getAccountConfig(@RequestBody ThirdPartyConfigGetParam param) {
+        return CommonResponse.success(service.getAccountConfig(param));
+    }
+
+    @ApiOperation(value = "检查推送人员是否在所有群内")
+    @PostMapping("/checkPushAccountExist")
+    public CommonResponse<CheckPushAccountExistVO> checkPushAccountExist(@RequestBody ThirdPartyAccountConfigParam param) {
+        return CommonResponse.success(service.checkPushAccountExist(param));
+    }
+
+    @ApiOperation(value = "账号配置保存")
+    @PostMapping("/saveAccountConfig")
+    public CommonResponse<Void> saveAccountConfig(@RequestBody ThirdPartyAccountConfigParam param) {
+        service.saveAccountConfig(param);
+        return CommonResponse.success();
+    }
+
+    @ApiOperation(value = "登出")
+    @PostMapping("/logout")
+    public CommonResponse<Void> logout(@RequestBody ThirdPartyAccountLogOutParam param) {
+        service.logout(param);
+        return CommonResponse.success();
+    }
+
+    @ApiOperation(value = "初始化账号配置")
+    @PostMapping("/initAccountConfig")
+    public CommonResponse<Void> initAccountConfig() {
+        service.initAccountConfig();
+        return CommonResponse.success();
+    }
+
+}

+ 26 - 0
api-module/src/main/java/com/tzld/piaoquan/api/controller/wecom/thirdpart/WeComThirdPartyCallBackController.java

@@ -0,0 +1,26 @@
+package com.tzld.piaoquan.api.controller.wecom.thirdpart;
+
+import com.tzld.piaoquan.api.model.param.wecom.thirdpart.WeComThirdPartyCallBackParam;
+import com.tzld.piaoquan.api.service.wecom.thirdparty.WeComThirdPartyCallBackService;
+import com.tzld.piaoquan.growth.common.common.base.CommonResponse;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@Slf4j
+@RestController
+@RequestMapping("/wecom/thirdparty")
+public class WeComThirdPartyCallBackController {
+
+    @Autowired
+    private WeComThirdPartyCallBackService service;
+
+    @PostMapping("/callback")
+    public CommonResponse<String> callback(@RequestBody WeComThirdPartyCallBackParam param) {
+        service.handleCallback(param);
+        return CommonResponse.success();
+    }
+}

+ 8 - 2
api-module/src/main/java/com/tzld/piaoquan/api/controller/WeComThirdPartyController.java → api-module/src/main/java/com/tzld/piaoquan/api/controller/wecom/thirdpart/WeComThirdPartyController.java

@@ -1,7 +1,7 @@
-package com.tzld.piaoquan.api.controller;
+package com.tzld.piaoquan.api.controller.wecom.thirdpart;
 
 
 import com.tzld.piaoquan.api.model.param.wecom.thirdpart.*;
 import com.tzld.piaoquan.api.model.param.wecom.thirdpart.*;
-import com.tzld.piaoquan.api.service.WeComThirdPartyService;
+import com.tzld.piaoquan.api.service.wecom.thirdparty.WeComThirdPartyService;
 import com.tzld.piaoquan.growth.common.common.base.CommonResponse;
 import com.tzld.piaoquan.growth.common.common.base.CommonResponse;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -96,4 +96,10 @@ public class WeComThirdPartyController {
         return CommonResponse.success();
         return CommonResponse.success();
     }
     }
 
 
+    @PostMapping("/automaticLogin")
+    public CommonResponse<Void> automaticLogin(@RequestBody UuidRequest request) {
+        service.automaticLogin(request);
+        return CommonResponse.success();
+    }
+
 }
 }

+ 87 - 0
api-module/src/main/java/com/tzld/piaoquan/api/controller/wecom/thirdpart/WeComThirdPartyJobController.java

@@ -0,0 +1,87 @@
+package com.tzld.piaoquan.api.controller.wecom.thirdpart;
+
+import com.tzld.piaoquan.api.job.wecom.thirdpart.*;
+import com.tzld.piaoquan.growth.common.common.base.CommonResponse;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@Slf4j
+@RestController
+@RequestMapping("/wecom/thirdpart/job")
+public class WeComThirdPartyJobController {
+
+    @Autowired
+    WeComSendMsgJob weComSendMsgJob;
+    @Autowired
+    WeComAccountJob weComAccountJob;
+    @Autowired
+    WeComUserDetailJob weComUserDetailJob;
+    @Autowired
+    WeComCreateRoomJob weComCreateRoomJob;
+    @Autowired
+    WeComVideoJob weComVideoJob;
+
+    @GetMapping("/autoSendAppMsg")
+    public CommonResponse<Void> autoSendAppMsg() {
+        weComSendMsgJob.autoSendAppMsg(null);
+        return CommonResponse.success();
+    }
+
+    @GetMapping("/autoOpenSendStatusJob")
+    public CommonResponse<Void> autoOpenSendStatusJob() {
+        weComSendMsgJob.autoOpenSendStatusJob(null);
+        return CommonResponse.success();
+    }
+
+    @GetMapping("/randomRoomSendTimeJob")
+    public CommonResponse<Void> randomRoomSendTimeJob() {
+        weComSendMsgJob.randomRoomSendTimeJob(null);
+        return CommonResponse.success();
+    }
+
+    @GetMapping("/checkAccountOnline")
+    public CommonResponse<Void> checkAccountOnline() {
+        weComAccountJob.checkAccountOnline(null);
+        return CommonResponse.success();
+    }
+
+    @GetMapping("/syncUserDetail")
+    public CommonResponse<Void> syncUserDetail() {
+        weComUserDetailJob.syncUserDetail(null);
+        return CommonResponse.success();
+    }
+
+    @GetMapping("/syncRoomDetail")
+    public CommonResponse<Void> syncRoomDetail() {
+        weComUserDetailJob.syncRoomDetail(null);
+        return CommonResponse.success();
+    }
+
+    @GetMapping("/autoCreateRoom")
+    public CommonResponse<Void> autoCreateRoom() {
+        weComCreateRoomJob.autoCreateRoomJob(null);
+        return CommonResponse.success();
+    }
+
+    @GetMapping("/autoAddRoomUser")
+    public CommonResponse<Void> autoAddRoomUser() {
+        weComCreateRoomJob.autoAddRoomUserJob(null);
+        return CommonResponse.success();
+    }
+
+    @GetMapping("/syncThirdPartWeComVideoJob")
+    public CommonResponse<Void> syncThirdPartWeComVideoJob() {
+        weComVideoJob.syncThirdPartWeComVideoJob(null);
+        return CommonResponse.success();
+    }
+
+    @GetMapping("/checkThirdPartWeComVideoStatusJob")
+    public CommonResponse<Void> checkThirdPartWeComVideoStatusJob() {
+        weComVideoJob.checkThirdPartWeComVideoStatusJob(null);
+        return CommonResponse.success();
+    }
+
+}

+ 52 - 0
api-module/src/main/java/com/tzld/piaoquan/api/controller/wecom/thirdpart/WeComThirdPartyRoomController.java

@@ -0,0 +1,52 @@
+package com.tzld.piaoquan.api.controller.wecom.thirdpart;
+
+import com.tzld.piaoquan.api.model.param.wecom.thirdpart.ThirdPartyRoomConfigParam;
+import com.tzld.piaoquan.api.model.param.wecom.thirdpart.ThirdPartyConfigGetParam;
+import com.tzld.piaoquan.api.model.param.wecom.thirdpart.ThirdPartyRoomListParam;
+import com.tzld.piaoquan.api.model.vo.IdNameVO;
+import com.tzld.piaoquan.api.model.vo.wecom.thirdpart.ThirdPartyRoomConfigVO;
+import com.tzld.piaoquan.api.model.vo.wecom.thirdpart.ThirdPartyRoomVO;
+import com.tzld.piaoquan.api.service.wecom.thirdparty.WeComThirdPartyRoomService;
+import com.tzld.piaoquan.growth.common.common.base.CommonResponse;
+import com.tzld.piaoquan.growth.common.utils.page.Page;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@Slf4j
+@RestController
+@RequestMapping("/wecom/thirdparty/room")
+@CrossOrigin(origins = "*")
+public class WeComThirdPartyRoomController {
+
+    @Autowired
+    private WeComThirdPartyRoomService service;
+
+    @ApiOperation(value = "群列表")
+    @PostMapping("/list")
+    public CommonResponse<Page<ThirdPartyRoomVO>> list(@RequestBody ThirdPartyRoomListParam param) {
+        return CommonResponse.success(service.list(param));
+    }
+
+    @ApiOperation(value = "获取推送人员列表")
+    @GetMapping("/getPushAccountList")
+    public CommonResponse<List<IdNameVO<Long>>> getPushAccountList(@RequestParam Long roomId, @RequestParam(required = false) String name) {
+        return CommonResponse.success(service.getPushAccountList(roomId, name));
+    }
+
+    @ApiOperation(value = "获取群配置")
+    @PostMapping("/getRoomConfig")
+    public CommonResponse<ThirdPartyRoomConfigVO> getRoomConfig(@RequestBody ThirdPartyConfigGetParam param) {
+        return CommonResponse.success(service.getRoomConfig(param));
+    }
+
+    @ApiOperation(value = "保存群配置")
+    @PostMapping("/saveRoomConfig")
+    public CommonResponse<Void> saveRoomConfig(@RequestBody ThirdPartyRoomConfigParam param) {
+        service.saveRoomConfig(param, null);
+        return CommonResponse.success();
+    }
+}

+ 3 - 3
api-module/src/main/java/com/tzld/piaoquan/api/dao/generator/MybatisGeneratorMain.java

@@ -20,9 +20,9 @@ public class MybatisGeneratorMain {
             throws SQLException, IOException, InterruptedException, InvalidConfigurationException, XMLParserException {
             throws SQLException, IOException, InterruptedException, InvalidConfigurationException, XMLParserException {
         List<String> warnings = new ArrayList<>();
         List<String> warnings = new ArrayList<>();
 
 
-        //File configFile = new File(MybatisGeneratorMain.class.getResource("/mybatis-generator-config.xml").getFile());
-//        File configFile = new File(MybatisGeneratorMain.class.getResource("/mybatis-api-generator-config.xml").getFile());
-        File configFile = new File(MybatisGeneratorMain.class.getResource("/mybatis-api-contentPlatform-generator-config.xml").getFile());
+        File configFile = new File(MybatisGeneratorMain.class.getResource("/mybatis-generator-config.xml").getFile());
+        //File configFile = new File(MybatisGeneratorMain.class.getResource("/mybatis-api-generator-config.xml").getFile());
+        //File configFile = new File(MybatisGeneratorMain.class.getResource("/mybatis-api-contentPlatform-generator-config.xml").getFile());
 //        File configFile = new File(MybatisGeneratorMain.class.getResource("/mybatis-api-wecomThirdpart-generator-config.xml").getFile());
 //        File configFile = new File(MybatisGeneratorMain.class.getResource("/mybatis-api-wecomThirdpart-generator-config.xml").getFile());
         ConfigurationParser cp = new ConfigurationParser(warnings);
         ConfigurationParser cp = new ConfigurationParser(warnings);
         Configuration config = cp.parseConfiguration(configFile);
         Configuration config = cp.parseConfiguration(configFile);

+ 0 - 5
api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/GhDetailExtMapper.java

@@ -3,13 +3,8 @@ package com.tzld.piaoquan.api.dao.mapper;
 import com.tzld.piaoquan.api.model.po.GhDetailExt;
 import com.tzld.piaoquan.api.model.po.GhDetailExt;
 import com.tzld.piaoquan.api.model.po.GhDetailExtExample;
 import com.tzld.piaoquan.api.model.po.GhDetailExtExample;
 import java.util.List;
 import java.util.List;
-
-import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Param;
-import org.springframework.stereotype.Repository;
 
 
-@Mapper
-@Repository
 public interface GhDetailExtMapper {
 public interface GhDetailExtMapper {
     long countByExample(GhDetailExtExample example);
     long countByExample(GhDetailExtExample example);
 
 

+ 24 - 0
api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/GhDetailMapperExt.java

@@ -0,0 +1,24 @@
+package com.tzld.piaoquan.api.dao.mapper;
+
+import com.tzld.piaoquan.api.model.po.GhDetailExt;
+import com.tzld.piaoquan.api.model.po.GzhAutoreplyBehaviorUvTotal;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Mapper
+@Repository
+public interface GhDetailMapperExt {
+
+    void deleteOldGhDetailExt(@Param("ghId") String ghId, @Param("type") Integer type);
+
+    void batchInsertGhDetailExt(@Param("records") List<GhDetailExt> records);
+
+    List<GhDetailExt> getGhDetailExtList(@Param("ghId") String ghId, @Param("type") Integer type);
+
+    void deleteGzhAutoreplyBehaviorUvTotal(@Param("dt") String dt);
+
+    void batchInsertGzhAutoreplyBehaviorUvTotal(@Param("records") List<GzhAutoreplyBehaviorUvTotal> saveList);
+}

+ 30 - 0
api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/GzhAutoreplyBehaviorUvTotalMapper.java

@@ -0,0 +1,30 @@
+package com.tzld.piaoquan.api.dao.mapper;
+
+import com.tzld.piaoquan.api.model.po.GzhAutoreplyBehaviorUvTotal;
+import com.tzld.piaoquan.api.model.po.GzhAutoreplyBehaviorUvTotalExample;
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+
+public interface GzhAutoreplyBehaviorUvTotalMapper {
+    long countByExample(GzhAutoreplyBehaviorUvTotalExample example);
+
+    int deleteByExample(GzhAutoreplyBehaviorUvTotalExample example);
+
+    int deleteByPrimaryKey(Long id);
+
+    int insert(GzhAutoreplyBehaviorUvTotal record);
+
+    int insertSelective(GzhAutoreplyBehaviorUvTotal record);
+
+    List<GzhAutoreplyBehaviorUvTotal> selectByExample(GzhAutoreplyBehaviorUvTotalExample example);
+
+    GzhAutoreplyBehaviorUvTotal selectByPrimaryKey(Long id);
+
+    int updateByExampleSelective(@Param("record") GzhAutoreplyBehaviorUvTotal record, @Param("example") GzhAutoreplyBehaviorUvTotalExample example);
+
+    int updateByExample(@Param("record") GzhAutoreplyBehaviorUvTotal record, @Param("example") GzhAutoreplyBehaviorUvTotalExample example);
+
+    int updateByPrimaryKeySelective(GzhAutoreplyBehaviorUvTotal record);
+
+    int updateByPrimaryKey(GzhAutoreplyBehaviorUvTotal record);
+}

+ 30 - 0
api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/contentplatform/VideoGrowthMultiCoverMapper.java

@@ -0,0 +1,30 @@
+package com.tzld.piaoquan.api.dao.mapper.contentplatform;
+
+import com.tzld.piaoquan.api.model.po.contentplatform.VideoGrowthMultiCover;
+import com.tzld.piaoquan.api.model.po.contentplatform.VideoGrowthMultiCoverExample;
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+
+public interface VideoGrowthMultiCoverMapper {
+    long countByExample(VideoGrowthMultiCoverExample example);
+
+    int deleteByExample(VideoGrowthMultiCoverExample example);
+
+    int deleteByPrimaryKey(Long id);
+
+    int insert(VideoGrowthMultiCover record);
+
+    int insertSelective(VideoGrowthMultiCover record);
+
+    List<VideoGrowthMultiCover> selectByExample(VideoGrowthMultiCoverExample example);
+
+    VideoGrowthMultiCover selectByPrimaryKey(Long id);
+
+    int updateByExampleSelective(@Param("record") VideoGrowthMultiCover record, @Param("example") VideoGrowthMultiCoverExample example);
+
+    int updateByExample(@Param("record") VideoGrowthMultiCover record, @Param("example") VideoGrowthMultiCoverExample example);
+
+    int updateByPrimaryKeySelective(VideoGrowthMultiCover record);
+
+    int updateByPrimaryKey(VideoGrowthMultiCover record);
+}

+ 30 - 0
api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/contentplatform/VideoGrowthMultiTitleMapper.java

@@ -0,0 +1,30 @@
+package com.tzld.piaoquan.api.dao.mapper.contentplatform;
+
+import com.tzld.piaoquan.api.model.po.contentplatform.VideoGrowthMultiTitle;
+import com.tzld.piaoquan.api.model.po.contentplatform.VideoGrowthMultiTitleExample;
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+
+public interface VideoGrowthMultiTitleMapper {
+    long countByExample(VideoGrowthMultiTitleExample example);
+
+    int deleteByExample(VideoGrowthMultiTitleExample example);
+
+    int deleteByPrimaryKey(Long id);
+
+    int insert(VideoGrowthMultiTitle record);
+
+    int insertSelective(VideoGrowthMultiTitle record);
+
+    List<VideoGrowthMultiTitle> selectByExample(VideoGrowthMultiTitleExample example);
+
+    VideoGrowthMultiTitle selectByPrimaryKey(Long id);
+
+    int updateByExampleSelective(@Param("record") VideoGrowthMultiTitle record, @Param("example") VideoGrowthMultiTitleExample example);
+
+    int updateByExample(@Param("record") VideoGrowthMultiTitle record, @Param("example") VideoGrowthMultiTitleExample example);
+
+    int updateByPrimaryKeySelective(VideoGrowthMultiTitle record);
+
+    int updateByPrimaryKey(VideoGrowthMultiTitle record);
+}

+ 3 - 1
api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/contentplatform/ext/ContentPlatformPlanMapperExt.java

@@ -73,7 +73,7 @@ public interface ContentPlatformPlanMapperExt {
 
 
     List<ContentPlatformVideo> getVideoMinScoreList(@Param("dt") String dt,
     List<ContentPlatformVideo> getVideoMinScoreList(@Param("dt") String dt,
                                                     @Param("minScore") Double minScore,
                                                     @Param("minScore") Double minScore,
-                                                    @Param("excludeVideoIds") List<Long> excludeVideoIds,
+                                                    @Param("roomId") String roomId,
                                                     @Param("offset") int offset,
                                                     @Param("offset") int offset,
                                                     @Param("pageSize") Integer pageSize,
                                                     @Param("pageSize") Integer pageSize,
                                                     @Param("sort") String sort);
                                                     @Param("sort") String sort);
@@ -157,6 +157,8 @@ public interface ContentPlatformPlanMapperExt {
                                               @Param("status") Integer status,
                                               @Param("status") Integer status,
                                               @Param("now") Long now);
                                               @Param("now") Long now);
 
 
+    List<ContentPlatformGzhPlanVideo> getGzhPushPlanVideoByRootSourceId(@Param("rootSourceId") String rootSourceId, @Param("planType") Integer planType);
+
     void deleteContentPlatformVideoAccountRel(@Param("dt") String aggDt);
     void deleteContentPlatformVideoAccountRel(@Param("dt") String aggDt);
 
 
     void batchInsertContentPlatformVideoAccountRel(@Param("records") List<ContentPlatformVideoAccountRel> saveAccountRelList);
     void batchInsertContentPlatformVideoAccountRel(@Param("records") List<ContentPlatformVideoAccountRel> saveAccountRelList);

+ 13 - 0
api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/contentplatform/ext/VideoMultiMapperExt.java

@@ -0,0 +1,13 @@
+package com.tzld.piaoquan.api.dao.mapper.contentplatform.ext;
+
+import com.tzld.piaoquan.api.model.po.contentplatform.VideoGrowthMultiCover;
+import com.tzld.piaoquan.api.model.po.contentplatform.VideoGrowthMultiTitle;
+import org.apache.ibatis.annotations.Param;
+
+public interface VideoMultiMapperExt {
+
+    void insertVideoMultiTitleReturnId(@Param("record") VideoGrowthMultiTitle multiTitle);
+
+    void insertVideoMultiCoverReturnId(@Param("record") VideoGrowthMultiCover multiCover);
+
+}

+ 30 - 0
api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/wecom/thirdpart/ThirdPartWeComRoomConfigMapper.java

@@ -0,0 +1,30 @@
+package com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart;
+
+import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComRoomConfig;
+import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComRoomConfigExample;
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+
+public interface ThirdPartWeComRoomConfigMapper {
+    long countByExample(ThirdPartWeComRoomConfigExample example);
+
+    int deleteByExample(ThirdPartWeComRoomConfigExample example);
+
+    int deleteByPrimaryKey(String id);
+
+    int insert(ThirdPartWeComRoomConfig record);
+
+    int insertSelective(ThirdPartWeComRoomConfig record);
+
+    List<ThirdPartWeComRoomConfig> selectByExample(ThirdPartWeComRoomConfigExample example);
+
+    ThirdPartWeComRoomConfig selectByPrimaryKey(String id);
+
+    int updateByExampleSelective(@Param("record") ThirdPartWeComRoomConfig record, @Param("example") ThirdPartWeComRoomConfigExample example);
+
+    int updateByExample(@Param("record") ThirdPartWeComRoomConfig record, @Param("example") ThirdPartWeComRoomConfigExample example);
+
+    int updateByPrimaryKeySelective(ThirdPartWeComRoomConfig record);
+
+    int updateByPrimaryKey(ThirdPartWeComRoomConfig record);
+}

+ 30 - 0
api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/wecom/thirdpart/ThirdPartWeComRoomConfigTaskContentMapper.java

@@ -0,0 +1,30 @@
+package com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart;
+
+import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComRoomConfigTaskContent;
+import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComRoomConfigTaskContentExample;
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+
+public interface ThirdPartWeComRoomConfigTaskContentMapper {
+    long countByExample(ThirdPartWeComRoomConfigTaskContentExample example);
+
+    int deleteByExample(ThirdPartWeComRoomConfigTaskContentExample example);
+
+    int deleteByPrimaryKey(String id);
+
+    int insert(ThirdPartWeComRoomConfigTaskContent record);
+
+    int insertSelective(ThirdPartWeComRoomConfigTaskContent record);
+
+    List<ThirdPartWeComRoomConfigTaskContent> selectByExample(ThirdPartWeComRoomConfigTaskContentExample example);
+
+    ThirdPartWeComRoomConfigTaskContent selectByPrimaryKey(String id);
+
+    int updateByExampleSelective(@Param("record") ThirdPartWeComRoomConfigTaskContent record, @Param("example") ThirdPartWeComRoomConfigTaskContentExample example);
+
+    int updateByExample(@Param("record") ThirdPartWeComRoomConfigTaskContent record, @Param("example") ThirdPartWeComRoomConfigTaskContentExample example);
+
+    int updateByPrimaryKeySelective(ThirdPartWeComRoomConfigTaskContent record);
+
+    int updateByPrimaryKey(ThirdPartWeComRoomConfigTaskContent record);
+}

+ 30 - 0
api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/wecom/thirdpart/ThirdPartWeComRoomConfigTaskMapper.java

@@ -0,0 +1,30 @@
+package com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart;
+
+import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComRoomConfigTask;
+import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComRoomConfigTaskExample;
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+
+public interface ThirdPartWeComRoomConfigTaskMapper {
+    long countByExample(ThirdPartWeComRoomConfigTaskExample example);
+
+    int deleteByExample(ThirdPartWeComRoomConfigTaskExample example);
+
+    int deleteByPrimaryKey(String id);
+
+    int insert(ThirdPartWeComRoomConfigTask record);
+
+    int insertSelective(ThirdPartWeComRoomConfigTask record);
+
+    List<ThirdPartWeComRoomConfigTask> selectByExample(ThirdPartWeComRoomConfigTaskExample example);
+
+    ThirdPartWeComRoomConfigTask selectByPrimaryKey(String id);
+
+    int updateByExampleSelective(@Param("record") ThirdPartWeComRoomConfigTask record, @Param("example") ThirdPartWeComRoomConfigTaskExample example);
+
+    int updateByExample(@Param("record") ThirdPartWeComRoomConfigTask record, @Param("example") ThirdPartWeComRoomConfigTaskExample example);
+
+    int updateByPrimaryKeySelective(ThirdPartWeComRoomConfigTask record);
+
+    int updateByPrimaryKey(ThirdPartWeComRoomConfigTask record);
+}

+ 30 - 0
api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/wecom/thirdpart/ThirdPartWeComStaffConfigMapper.java

@@ -0,0 +1,30 @@
+package com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart;
+
+import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComStaffConfig;
+import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComStaffConfigExample;
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+
+public interface ThirdPartWeComStaffConfigMapper {
+    long countByExample(ThirdPartWeComStaffConfigExample example);
+
+    int deleteByExample(ThirdPartWeComStaffConfigExample example);
+
+    int deleteByPrimaryKey(String id);
+
+    int insert(ThirdPartWeComStaffConfig record);
+
+    int insertSelective(ThirdPartWeComStaffConfig record);
+
+    List<ThirdPartWeComStaffConfig> selectByExample(ThirdPartWeComStaffConfigExample example);
+
+    ThirdPartWeComStaffConfig selectByPrimaryKey(String id);
+
+    int updateByExampleSelective(@Param("record") ThirdPartWeComStaffConfig record, @Param("example") ThirdPartWeComStaffConfigExample example);
+
+    int updateByExample(@Param("record") ThirdPartWeComStaffConfig record, @Param("example") ThirdPartWeComStaffConfigExample example);
+
+    int updateByPrimaryKeySelective(ThirdPartWeComStaffConfig record);
+
+    int updateByPrimaryKey(ThirdPartWeComStaffConfig record);
+}

+ 30 - 0
api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/wecom/thirdpart/ThirdPartWeComStaffConfigTaskContentMapper.java

@@ -0,0 +1,30 @@
+package com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart;
+
+import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComStaffConfigTaskContent;
+import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComStaffConfigTaskContentExample;
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+
+public interface ThirdPartWeComStaffConfigTaskContentMapper {
+    long countByExample(ThirdPartWeComStaffConfigTaskContentExample example);
+
+    int deleteByExample(ThirdPartWeComStaffConfigTaskContentExample example);
+
+    int deleteByPrimaryKey(String id);
+
+    int insert(ThirdPartWeComStaffConfigTaskContent record);
+
+    int insertSelective(ThirdPartWeComStaffConfigTaskContent record);
+
+    List<ThirdPartWeComStaffConfigTaskContent> selectByExample(ThirdPartWeComStaffConfigTaskContentExample example);
+
+    ThirdPartWeComStaffConfigTaskContent selectByPrimaryKey(String id);
+
+    int updateByExampleSelective(@Param("record") ThirdPartWeComStaffConfigTaskContent record, @Param("example") ThirdPartWeComStaffConfigTaskContentExample example);
+
+    int updateByExample(@Param("record") ThirdPartWeComStaffConfigTaskContent record, @Param("example") ThirdPartWeComStaffConfigTaskContentExample example);
+
+    int updateByPrimaryKeySelective(ThirdPartWeComStaffConfigTaskContent record);
+
+    int updateByPrimaryKey(ThirdPartWeComStaffConfigTaskContent record);
+}

+ 30 - 0
api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/wecom/thirdpart/ThirdPartWeComStaffConfigTaskMapper.java

@@ -0,0 +1,30 @@
+package com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart;
+
+import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComStaffConfigTask;
+import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComStaffConfigTaskExample;
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+
+public interface ThirdPartWeComStaffConfigTaskMapper {
+    long countByExample(ThirdPartWeComStaffConfigTaskExample example);
+
+    int deleteByExample(ThirdPartWeComStaffConfigTaskExample example);
+
+    int deleteByPrimaryKey(String id);
+
+    int insert(ThirdPartWeComStaffConfigTask record);
+
+    int insertSelective(ThirdPartWeComStaffConfigTask record);
+
+    List<ThirdPartWeComStaffConfigTask> selectByExample(ThirdPartWeComStaffConfigTaskExample example);
+
+    ThirdPartWeComStaffConfigTask selectByPrimaryKey(String id);
+
+    int updateByExampleSelective(@Param("record") ThirdPartWeComStaffConfigTask record, @Param("example") ThirdPartWeComStaffConfigTaskExample example);
+
+    int updateByExample(@Param("record") ThirdPartWeComStaffConfigTask record, @Param("example") ThirdPartWeComStaffConfigTaskExample example);
+
+    int updateByPrimaryKeySelective(ThirdPartWeComStaffConfigTask record);
+
+    int updateByPrimaryKey(ThirdPartWeComStaffConfigTask record);
+}

+ 30 - 0
api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/wecom/thirdpart/ThirdPartWeComVideoMapper.java

@@ -0,0 +1,30 @@
+package com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart;
+
+import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComVideo;
+import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComVideoExample;
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+
+public interface ThirdPartWeComVideoMapper {
+    long countByExample(ThirdPartWeComVideoExample example);
+
+    int deleteByExample(ThirdPartWeComVideoExample example);
+
+    int deleteByPrimaryKey(Long id);
+
+    int insert(ThirdPartWeComVideo record);
+
+    int insertSelective(ThirdPartWeComVideo record);
+
+    List<ThirdPartWeComVideo> selectByExample(ThirdPartWeComVideoExample example);
+
+    ThirdPartWeComVideo selectByPrimaryKey(Long id);
+
+    int updateByExampleSelective(@Param("record") ThirdPartWeComVideo record, @Param("example") ThirdPartWeComVideoExample example);
+
+    int updateByExample(@Param("record") ThirdPartWeComVideo record, @Param("example") ThirdPartWeComVideoExample example);
+
+    int updateByPrimaryKeySelective(ThirdPartWeComVideo record);
+
+    int updateByPrimaryKey(ThirdPartWeComVideo record);
+}

+ 13 - 0
api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/wecom/thirdpart/ext/ThirdPartWeComMapperExt.java

@@ -1,5 +1,6 @@
 package com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ext;
 package com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ext;
 
 
+import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComRoom;
 import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComRoomUser;
 import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComRoomUser;
 import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComStaffUser;
 import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComStaffUser;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Param;
@@ -10,7 +11,19 @@ public interface ThirdPartWeComMapperExt {
 
 
     void batchInsertThirdPartWeComRoomUser(@Param("records") List<ThirdPartWeComRoomUser> records);
     void batchInsertThirdPartWeComRoomUser(@Param("records") List<ThirdPartWeComRoomUser> records);
 
 
+    void batchUpdateThirdPartWeComRoomUser(@Param("records") List<ThirdPartWeComRoomUser> records);
+
     void batchInsertThirdPartWeComStaffUser(@Param("records") List<ThirdPartWeComStaffUser> saveList);
     void batchInsertThirdPartWeComStaffUser(@Param("records") List<ThirdPartWeComStaffUser> saveList);
 
 
+    void batchUpdateThirdPartWeComStaffUser(@Param("records") List<ThirdPartWeComStaffUser> saveList);
+
     List<ThirdPartWeComStaffUser> getNoGroupStaffUserList(@Param("thirdStaffId") Long thirdStaffId);
     List<ThirdPartWeComStaffUser> getNoGroupStaffUserList(@Param("thirdStaffId") Long thirdStaffId);
+
+    void setRoomUserQuitTime(@Param("thirdRoomId") String thirdRoomId, @Param("deleteList") List<Long> deleteList, @Param("quitTime") Long quitTime);
+
+    void batchInsertThirdPartWeComRoom(@Param("records") List<ThirdPartWeComRoom> partition);
+
+    void batchUpdateThirdPartWeComRoom(@Param("records") List<ThirdPartWeComRoom> partition);
+
+    void updateStaffQrImageByUuid(@Param("uuid") String uuid, @Param("qrImage") String qrImage);
 }
 }

+ 20 - 0
api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/wecom/thirdpart/ext/ThirdPartWeComRoomMapperExt.java

@@ -0,0 +1,20 @@
+package com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ext;
+
+import com.tzld.piaoquan.api.model.param.wecom.thirdpart.ThirdPartyRoomListParam;
+import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComRoom;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface ThirdPartWeComRoomMapperExt {
+
+    int getRoomCount(@Param("param") ThirdPartyRoomListParam param,
+                     @Param("pushAccountIds") List<Long> pushAccountIds);
+
+    List<ThirdPartWeComRoom> getRoomList(@Param("param") ThirdPartyRoomListParam param,
+                                         @Param("pushAccountIds") List<Long> pushAccountIds,
+                                         @Param("offset") int offset, @Param("pageSize") Integer pageSize);
+
+    List<ThirdPartWeComRoom> getNoConfigRoomList(@Param("staffId") Long id);
+
+}

+ 21 - 0
api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/wecom/thirdpart/ext/ThirdPartWeComStaffMapperExt.java

@@ -0,0 +1,21 @@
+package com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ext;
+
+import com.tzld.piaoquan.api.model.param.wecom.thirdpart.ThirdPartyAccountListParam;
+import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComStaff;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface ThirdPartWeComStaffMapperExt {
+
+    int getAccountCount(@Param("param") ThirdPartyAccountListParam param);
+
+    List<ThirdPartWeComStaff> getAccountList(@Param("param") ThirdPartyAccountListParam param,
+                                             @Param("offset") int offset, @Param("pageSize") Integer pageSize);
+
+    List<ThirdPartWeComStaff> getPushStaffList(@Param("accountId") Long accountId,
+                                               @Param("roomId") Long roomId,
+                                               @Param("name") String name);
+
+    List<Long> getStaffIdByName(@Param("name") String name);
+}

+ 28 - 0
api-module/src/main/java/com/tzld/piaoquan/api/dao/mapper/wecom/thirdpart/ext/ThirdPartWeComVideoMapperExt.java

@@ -0,0 +1,28 @@
+package com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ext;
+
+import com.tzld.piaoquan.api.model.po.contentplatform.ContentPlatformVideo;
+import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComVideo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface ThirdPartWeComVideoMapperExt {
+
+    String getVideoMaxDt();
+
+    void updateOtherVideoStatus(@Param("dt") String dt, @Param("videoIdList") List<Long> videoIdList, @Param("now") Long now);
+
+    void batchInsertThirdPartWeComVideo(@Param("records") List<ThirdPartWeComVideo> saveList);
+
+    void updateVideoStatusWithOldStatus(@Param("videoId") Long videoId,
+                                        @Param("status") Integer status,
+                                        @Param("oldStatus") Integer oldStatus,
+                                        @Param("now") Long now);
+
+    List<ContentPlatformVideo> getVideoMinScoreList(@Param("dt") String dt,
+                                                    @Param("videoMinScore") Double videoMinScore,
+                                                    @Param("roomId") String roomId,
+                                                    @Param("offset") int offset,
+                                                    @Param("pageSize") int pageSize,
+                                                    @Param("sort") String sort);
+}

+ 412 - 0
api-module/src/main/java/com/tzld/piaoquan/api/job/GzhReplyVideoRefreshJob.java

@@ -0,0 +1,412 @@
+package com.tzld.piaoquan.api.job;
+
+import com.alibaba.fastjson.JSONObject;
+import com.aliyun.odps.data.Record;
+import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import com.tzld.piaoquan.api.component.AdApiService;
+import com.tzld.piaoquan.api.component.AigcApiService;
+import com.tzld.piaoquan.api.component.DeepSeekApiService;
+import com.tzld.piaoquan.api.dao.mapper.GhDetailMapperExt;
+import com.tzld.piaoquan.api.dao.mapper.GzhAutoreplyBehaviorUvTotalMapper;
+import com.tzld.piaoquan.api.model.bo.AdPutCreativeComponentCostData;
+import com.tzld.piaoquan.api.model.bo.GoogleLLMResult;
+import com.tzld.piaoquan.api.model.bo.VideoDetail;
+import com.tzld.piaoquan.api.model.dto.AIResult;
+import com.tzld.piaoquan.api.model.po.GzhAutoreplyBehaviorUvTotal;
+import com.tzld.piaoquan.api.model.po.GzhAutoreplyBehaviorUvTotalExample;
+import com.tzld.piaoquan.api.model.vo.GhDetailVo;
+import com.tzld.piaoquan.api.service.GhDetailService;
+import com.tzld.piaoquan.api.util.AliOssFileTool;
+import com.tzld.piaoquan.api.util.CdnUtil;
+import com.tzld.piaoquan.growth.common.model.po.GhDetail;
+import com.tzld.piaoquan.growth.common.utils.DateUtil;
+import com.tzld.piaoquan.growth.common.utils.OdpsUtil;
+import com.tzld.piaoquan.growth.common.utils.TitleSimilarCheckUtil;
+import com.xxl.job.core.biz.model.ReturnT;
+import com.xxl.job.core.handler.annotation.XxlJob;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Component
+public class GzhReplyVideoRefreshJob {
+
+    @Autowired
+    GhDetailService ghDetailService;
+    @Autowired
+    AdApiService adApiService;
+    @Autowired
+    AigcApiService aigcApiService;
+    @Autowired
+    DeepSeekApiService deepSeekApiService;
+    @Autowired
+    GhDetailMapperExt ghDetailMapperExt;
+    @Autowired
+    GzhAutoreplyBehaviorUvTotalMapper gzhAutoreplyBehaviorUvTotalMapper;
+
+    @ApolloJsonValue("${gzh.reply.video.refresh.job.filter.wxIds:[]}")
+    private List<String> filterWxIds;
+    @Value("${gzh.reply.video.refresh.job.topNum:2}")
+    private Integer topNum;
+
+    private final static ExecutorService pool = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.SECONDS,
+            new LinkedBlockingQueue<>(1000),
+            new ThreadFactoryBuilder().setNameFormat("GzhReplyVideoRefreshJob-%d").build(),
+            new ThreadPoolExecutor.AbortPolicy());
+
+    @XxlJob("gzhReplyVideoRefreshJob")
+    public ReturnT<String> gzhReplyVideoRefreshJob(String param) {
+        String dt =DateUtil.getBeforeDayDateString("yyyy-MM-dd");
+        if (StringUtils.isNotEmpty(param)) {
+            dt = param;
+        }
+        List<AdPutCreativeComponentCostData> list = adApiService.getCreativeComponentsCost(dt);
+        if (CollectionUtils.isEmpty(list)) {
+            return ReturnT.SUCCESS;
+        }
+        // 按公众号分组
+        Map<String, List<AdPutCreativeComponentCostData>> costDataMap = list.stream()
+                .filter(o ->CollectionUtils.isNotEmpty(o.getComponentIds()))
+                .collect(Collectors.groupingBy(AdPutCreativeComponentCostData::getWxId));
+        CountDownLatch cdl = new CountDownLatch(costDataMap.size());
+        // 获取所有投流账号信息
+        String accountMapSql = "SELECT account_id, account_name from loghubods.feishu_wechat_mp_account_base where account_status = '开';";
+        List<Record> accountList = OdpsUtil.getOdpsData(accountMapSql);
+        Map<String, String> accountMap = new HashMap<>();
+        if (CollectionUtils.isNotEmpty(accountList)) {
+            for (Record record : accountList) {
+                String accountId = record.getString(0);
+                String accountName = record.getString(1);
+                accountMap.put(accountId, accountName);
+            }
+        }
+        // 服务号投流账号
+        String fwhAccountMapSql = "SELECT account_id, account_name from loghubods.feishu_wechat_fwh_account_base where account_status = '开';";
+        List<Record> fwhAccountList = OdpsUtil.getOdpsData(fwhAccountMapSql);
+        if (CollectionUtils.isNotEmpty(fwhAccountList)) {
+            for (Record record : fwhAccountList) {
+                String accountId = record.getString(0);
+                String accountName = record.getString(1);
+                accountMap.put(accountId, accountName);
+            }
+        }
+
+        // 获取公众号信息
+        List<String> nameList = new ArrayList<>(accountMap.values());
+        List<GhDetail> ghDetailList = ghDetailService.getGhdetailByNames(nameList);
+        Map<String, GhDetail> ghDetailMap = ghDetailList.stream().collect(Collectors.toMap(GhDetail::getGhName, ghDetail -> ghDetail));
+        for (Map.Entry<String, List<AdPutCreativeComponentCostData>> entry : costDataMap.entrySet()) {
+            pool.submit(() -> {
+                try {
+                    replaceGZHReplyVideo(entry.getKey(), entry.getValue(), ghDetailMap, accountMap);
+                } finally {
+                    cdl.countDown();
+                }
+            });
+        }
+        try {
+            cdl.await();
+        } catch (InterruptedException e) {
+            log.error("GzhReplyVideoRefreshJob error", e);
+        }
+        return ReturnT.SUCCESS;
+    }
+
+    private void replaceGZHReplyVideo(String wxId, List<AdPutCreativeComponentCostData> costDataList,
+                                      Map<String, GhDetail> ghDetailMap,
+                                      Map<String, String> accountMap) {
+        if (filterWxIds.contains(wxId)) {
+            return;
+        }
+        String accountName = accountMap.get(wxId);
+        if (StringUtils.isEmpty(accountName)) {
+            return;
+        }
+        GhDetail ghDetail = ghDetailMap.get(accountName);
+        if (ghDetail == null) {
+            return;
+        }
+        Map<String, JSONObject> creativeIdTextMap = analysisImageText(costDataList);
+        log.info("GzhReplyVideoRefreshJob accountName:{} creativeIdTextMap:{}", accountName, JSONObject.toJSONString(creativeIdTextMap));
+        // 按cost排序 获取top2内容
+        List<JSONObject> sortedList = creativeIdTextMap.entrySet().stream()
+                .sorted((o1, o2) -> o2.getValue().getLong("cost").compareTo(o1.getValue().getLong("cost")))
+                .limit(topNum)
+                .map(Map.Entry::getValue)
+                .collect(Collectors.toList());
+        List<VideoDetail> searchVideos = new ArrayList<>();
+        List<String> existTitles = new ArrayList<>();
+        for (JSONObject obj : sortedList) {
+            String text = obj.getString("title");
+            String keywordPrompt = getKeyWordPrompt(text);
+            AIResult aiResult = deepSeekApiService.requestOfficialApi(keywordPrompt, null, null, false);
+            if (aiResult.isSuccess()) {
+                List<String> keywords = JSONObject.parseArray(aiResult.getResponse().getChoices().get(0).getMessage().getContent(), String.class);
+                log.info("GzhReplyVideoRefreshJob accountName:{} text:{} keywords:{}", accountName, text, keywords);
+                VideoDetail videoDetail = getVideoDetail(keywords, searchVideos, existTitles);
+                if (videoDetail != null) {
+                    existTitles.add(videoDetail.getTitle());
+                    existTitles.add(text);
+                    videoDetail.setTitle(text);
+                    videoDetail.setCover(obj.getString("coverImgUrl"));
+                    searchVideos.add(videoDetail);
+                }
+            }
+        }
+        if (searchVideos.size() == topNum) {
+            // 更新视频
+            updateVideoReply(ghDetail, searchVideos);
+        }
+    }
+
+    private String getKeyWordPrompt(String text) {
+        // 提取关键词
+        String keywordPrompt =
+                "# Role\n" +
+                        "你是一位世界顶级的短视频SEO专家。你擅长剥离标题中的修饰语和状态词,精准捕捉用户真正想搜索的“核心实体”或“核心话题”。\n" +
+                        "\n" +
+                        "# Task\n" +
+                        "分析给定的视频标题,提取 **1个 或 2个** 最具搜索价值的关键词。\n" +
+                        "\n" +
+                        "# Constraints (必须严格执行)\n" +
+                        "1. **字数限制**:每个关键词必须 **≤ 3个汉字**。\n" +
+                        "2. **数量限制**:输出 1 到 2 个关键词。如果只有一个核心词,不要强行凑数,只输出一个。\n" +
+                        "3. **选词优先级 (核心逻辑)**:\n" +
+                        "   - **最高优先级**:核心名词、实体(如:燕子、粮食、早餐)。\n" +
+                        "   - **次优先级**:具有明确分类属性的动词(如:剪辑、做菜)。\n" +
+                        "4. **负面清单 (严禁提取)**:\n" +
+                        "   - **剔除状态词/结果词**:如“过期”、“消失”、“变质”、“最好”、“几点”等描述物体状态或程度的词。\n" +
+                        "   - **剔除虚词**:如“的”、“了”、“吗”。\n" +
+                        "   - **剔除泛词**:如“今天”、“才知道”、“告诉”。\n" +
+                        "5. **输出格式**:仅输出JSON数组,无其他字符。\n" +
+                        "\n" +
+                        "# Few-Shot Examples (学习选词逻辑)\n" +
+                        "Input: 今天才知道5种粮食不怕过期!放越久越好!\n" +
+                        "Output: [\"粮食\"]\n" +
+                        "(解释:剔除“过期”,因为它只是粮食的一个状态,用户搜的是粮食)\n" +
+                        "\n" +
+                        "Input: 今年燕子消失了 你知道怎么回事吗?\n" +
+                        "Output: [\"燕子\"]\n" +
+                        "(解释:剔除“消失”,保留核心生物实体)\n" +
+                        "\n" +
+                        "Input: 新手如何快速学会剪映剪辑\n" +
+                        "Output: [\"剪映\",\"剪辑\"]\n" +
+                        "(解释:两个词都是核心技能点,且都在3字内)\n" +
+                        "\n" +
+                        "Input: 冰箱总是结冰怎么办\n" +
+                        "Output: [\"冰箱\",\"结冰\"]\n" +
+                        "(解释:“结冰”虽是状态,但“冰箱结冰”是常见故障搜索词,故保留;若无法判断,优先保实体)\n" +
+                        "\n" +
+                        "# Input\n" +
+                        "内容是: {{text}} \n" +
+                        "\n" +
+                        "# Output\n" +
+                        "请基于上述规则,输出最终的JSON:";
+        keywordPrompt = keywordPrompt.replace("text", text);
+        return keywordPrompt;
+    }
+
+    private Map<String, JSONObject> analysisImageText(List<AdPutCreativeComponentCostData> costDataList) {
+        Map<String, JSONObject> creativeIdTextMap = new HashMap<>();
+        for (AdPutCreativeComponentCostData costData : costDataList) {
+            for (AdPutCreativeComponentCostData.AdPutTencentComponent component : costData.getComponentList()) {
+                String imageUrl = component.getImageUrl();
+                try {
+                    // download & upload to oss
+                    String fileName = String.format("growth/image/%s_%d.jpg", costData.getCreativeId(), System.currentTimeMillis());
+                    String ossImageUrl = AliOssFileTool.downloadAndSaveInOSS(fileName, imageUrl, "image/jpeg");
+                    // 调用gemini-3-pro模型提取图片中的文字
+                    String prompt = "识别图片里的文字,直接输出图片里的文字标题,但是不要输出图片里右下角的字,比如“点开看看”“看这里”等,仅输出标题,不要有多余的文字输出";
+                    GoogleLLMResult result = aigcApiService.gemini("gemini-2.0-flash", prompt, Arrays.asList(ossImageUrl));
+                    String text = result.getResult();
+                    text = text.replaceAll("\\n", "");
+                    for (String existText : creativeIdTextMap.keySet()) {
+                        if (TitleSimilarCheckUtil.isSimilar(text, existText, TitleSimilarCheckUtil.SIMILARITY_THRESHOLD)) {
+                            text = existText;
+                            break;
+                        }
+                    }
+                    JSONObject obj = creativeIdTextMap.getOrDefault(text, new JSONObject());
+                    Long cost = obj.getLong("cost");
+                    if (Objects.isNull(cost)) {
+                        cost = costData.getCost();
+                        obj.put("cost", cost);
+                        obj.put("title", text);
+                        obj.put("coverImgUrl", ossImageUrl);
+                    } else {
+                        cost += costData.getCost();
+                        obj.put("cost", cost);
+                    }
+                    creativeIdTextMap.put(text, obj);
+                    break;
+                } catch (Exception e) {
+                    log.error("GzhReplyVideoRefreshJob analysisImageText error, imageUrl:{}", imageUrl, e);
+                }
+            }
+        }
+        return creativeIdTextMap;
+    }
+
+    private VideoDetail getVideoDetail(List<String> keywords, List<VideoDetail> searchVideos, List<String> existTitles) {
+        VideoDetail videoDetail = null;
+        int maxRetries = 3;
+        int retryCount = 0;
+        while (retryCount < maxRetries) {
+            try {
+                videoDetail = searchVideoByKeyword(keywords, searchVideos, existTitles);
+                break;
+            } catch (Exception e) {
+                retryCount++;
+                log.error("GzhReplyVideoRefreshJob searchVideoByKeyword error, retry count: {}/{}", retryCount, maxRetries, e);
+                if (retryCount >= maxRetries) {
+                    break;
+                }
+            }
+        }
+        return videoDetail;
+    }
+
+    private VideoDetail searchVideoByKeyword(List<String> keywords, List<VideoDetail> searchVideos, List<String> existTitles) {
+        if (CollectionUtils.isNotEmpty(keywords)) {
+            String searchVideoSql = "SELECT v.id, v.title, v.cover_img_path\n" +
+                    "FROM videoods.wx_video v\n" +
+                    "join videoods.wx_video_status vs on v.id = vs.video_id\n" +
+                    "where (v.title like '%" + String.join("%' or v.title like '%", keywords) + "%') and v.status = 1 and vs.audit_status = 5\n" +
+                    "order by v.play_count_total desc limit 10;";
+            List<Record> videoList = OdpsUtil.getOdpsData(searchVideoSql);
+            if (CollectionUtils.isNotEmpty(videoList)) {
+                for (Record record : videoList) {
+                    Long videoId = Long.parseLong(record.getString(0));
+                    String title = record.getString(1);
+                    // 过滤重复视频
+                    boolean filter = false;
+                    for (VideoDetail searchVideo : searchVideos) {
+                        if (searchVideo.getId().equals(videoId)) {
+                            filter = true;
+                            break;
+                        }
+                    }
+                    // 过滤重复标题
+                    if (!filter && CollectionUtils.isNotEmpty(existTitles)) {
+                        for (String existTitle : existTitles) {
+                            if (TitleSimilarCheckUtil.isSimilar(title, existTitle, TitleSimilarCheckUtil.SIMILARITY_THRESHOLD)) {
+                                filter = true;
+                                break;
+                            }
+                        }
+                    }
+                    if (filter) {
+                        continue;
+                    }
+                    String cover = record.getString(2);
+                    VideoDetail videoDetail = new VideoDetail();
+                    videoDetail.setId(videoId);
+                    videoDetail.setCover(CdnUtil.getOssHttpUrl(cover));
+                    videoDetail.setTitle(title);
+                    return videoDetail;
+                }
+            }
+        }
+        return null;
+    }
+
+    private void updateVideoReply(GhDetail ghDetail, List<VideoDetail> searchVideos) {
+        log.info("GzhReplyVideoRefreshJob accountName:{} updateVideoReply, oldVideoIds: {}, replaceVideos: {}",
+                ghDetail.getGhName(), ghDetail.getVideoIds(), JSONObject.toJSONString(searchVideos));
+        GhDetailVo ghDetailVo = new GhDetailVo();
+        ghDetailVo.setId(ghDetail.getId());
+        ghDetailVo.setAccountId(ghDetail.getGhId());
+        ghDetailVo.setAccountName(ghDetail.getGhName());
+        ghDetailVo.setCategory1(ghDetail.getCategory1());
+        ghDetailVo.setStrategyStatus(ghDetail.getStrategyStatus());
+        ghDetailVo.setType(ghDetail.getType());
+        ghDetailVo.setAutoreplySendMinigramNum(topNum);
+        ghDetailVo.setVideoIds(searchVideos.stream().map(VideoDetail::getId).collect(Collectors.toList()));
+        List<GhDetailVo.VideoDetail> videoDetailList = new ArrayList<>();
+        for (int i = 0; i < searchVideos.size(); i++) {
+            VideoDetail videoDetail = searchVideos.get(i);
+            GhDetailVo.VideoDetail videoDetailVo = new GhDetailVo.VideoDetail();
+            videoDetailVo.setVideoId(videoDetail.getId());
+            videoDetailVo.setSort(i + 1);
+            videoDetailVo.setTitle(dealTitleLength(videoDetail.getTitle()));
+            videoDetailVo.setCover(videoDetail.getCover());
+            videoDetailList.add(videoDetailVo);
+        }
+        ghDetailVo.setVideoList(videoDetailList);
+        ghDetailService.updateDetail(ghDetailVo);
+    }
+
+    private String dealTitleLength(String title) {
+        if (StringUtils.isBlank(title)) {
+            return title;
+        }
+        if (title.length() > 20) {
+            title = title.substring(0, 19) + "…";
+        }
+        return title;
+    }
+
+    @XxlJob("syncGzhAutoreplyBehaviorUvTotalJob")
+    public ReturnT<String> syncGzhAutoreplyBehaviorUvTotalJob(String param) {
+        String dt = DateUtil.getBeforeDayDateString("yyyyMMdd");
+        if (StringUtils.isNotEmpty(param)) {
+            dt = param;
+        }
+        Long now = System.currentTimeMillis();
+        GzhAutoreplyBehaviorUvTotalExample example = new GzhAutoreplyBehaviorUvTotalExample();
+        example.createCriteria().andDtEqualTo(dt);
+        List<GzhAutoreplyBehaviorUvTotal> list = gzhAutoreplyBehaviorUvTotalMapper.selectByExample(example);
+        if (CollectionUtils.isNotEmpty(list)) {
+            return ReturnT.SUCCESS;
+        }
+        // 公众号自动回复数据统计
+        String sql = String.format(
+                "SELECT 合作方\n" +
+                        ",公众号id\n" +
+                        ",访问人数\n" +
+                        ",首层访问人数\n" +
+                        ",dt\n" +
+                        "FROM loghubods.gzh_autoreply_behavior_uv_total\n" +
+                        "WHERE dt = %s ;", dt);
+        List<Record> dataList = OdpsUtil.getOdpsData(sql);
+        if (CollectionUtils.isNotEmpty(dataList)) {
+            List<GzhAutoreplyBehaviorUvTotal> saveList = new ArrayList<>();
+            for (Record record : dataList) {
+                String channel = (String) record.get(0);
+                String ghId = (String) record.get(1);
+                Integer uv = parseInteger(record.get(2));
+                Integer firstLevel = parseInteger(record.get(3));
+                GzhAutoreplyBehaviorUvTotal item = new GzhAutoreplyBehaviorUvTotal();
+                item.setDt(dt);
+                item.setChannel(channel);
+                item.setUv(uv);
+                item.setFirstLevel(firstLevel);
+                item.setGhId(ghId);
+                item.setCreateTimestamp(now);
+                saveList.add(item);
+            }
+            if (CollectionUtils.isNotEmpty(saveList)) {
+                ghDetailMapperExt.deleteGzhAutoreplyBehaviorUvTotal(dt);
+                ghDetailMapperExt.batchInsertGzhAutoreplyBehaviorUvTotal(saveList);
+            }
+        }
+        return ReturnT.SUCCESS;
+    }
+
+    private Integer parseInteger(Object value) {
+        try {
+            return Integer.parseInt((String) value);
+        } catch (NumberFormatException e) {
+            return 0;
+        }
+    }
+}

+ 193 - 99
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.aliyun.odps.data.Record;
 import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
 import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
 import com.tzld.piaoquan.api.common.enums.contentplatform.AccountStatusEnum;
 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.common.enums.contentplatform.BussinessTypeEnum;
 import com.tzld.piaoquan.api.component.AigcApiService;
 import com.tzld.piaoquan.api.component.AigcApiService;
 import com.tzld.piaoquan.api.dao.mapper.contentplatform.*;
 import com.tzld.piaoquan.api.dao.mapper.contentplatform.*;
@@ -73,19 +74,22 @@ public class ContentPlatformDatastatJob {
         Long now = System.currentTimeMillis();
         Long now = System.currentTimeMillis();
         // 公众号自动回复数据统计
         // 公众号自动回复数据统计
         String sql = String.format(
         String sql = String.format(
-                "SELECT first_level.channel_shortname, first_level.subchannel, first_level.first_uv, fission.split_uv " +
-                "FROM loghubods.out_channel_mid_first_total first_level " +
-                "left join loghubods.out_channel_mid_split_total fission " +
-                "on first_level.channel_shortname = fission.channel_shortname and first_level.subchannel = fission.subchannel " +
-                "and first_level.dt = fission.dt and first_level.type = fission.type and first_level.tag = fission.tag " +
-                "WHERE first_level.dt = %s and first_level.type = '公众号即时回复' and first_level.tag = '分投放渠道客户分账号去重';", dt);
+                "SELECT distinct first_level.channel_shortname, first_level.subchannel, first_level.first_uv, fission.split_uv, fission.裂变arpu " +
+                        "FROM loghubods.out_channel_mid_first_total first_level " +
+                        "left join loghubods.out_channel_mid_split_total fission " +
+                        "on first_level.channel_shortname = fission.channel_shortname and first_level.subchannel = fission.subchannel " +
+                        "and first_level.dt = fission.dt and first_level.type = fission.type and first_level.tag = fission.tag " +
+                        "WHERE first_level.dt = %s and first_level.type = '公众号即时回复' and first_level.tag = '分投放渠道客户分账号去重';", dt);
         List<Record> dataList = OdpsUtil.getOdpsData(sql);
         List<Record> dataList = OdpsUtil.getOdpsData(sql);
+        List<ContentPlatformAccount> accountList = getAllAccount();
+        Map<String, ContentPlatformAccount> accountMap = accountList.stream()
+                .collect(Collectors.toMap(ContentPlatformAccount::getChannel, account -> account));
         // 所有公众号
         // 所有公众号
-        List<ContentPlatformGzhAccount> accountList = getAllGzhAccount();
-        Map<String, ContentPlatformGzhAccount> accountMap = accountList.stream()
-                .collect(Collectors.toMap(ContentPlatformGzhAccount::getGhId, account -> account));
-        List<String> ghIds = accountList.stream().map(ContentPlatformGzhAccount::getGhId).collect(Collectors.toList());
-        List<String> accountExternalIds = accountList.stream().map(ContentPlatformGzhAccount::getExternalId)
+        List<ContentPlatformGzhAccount> gzhAccountList = getAllGzhAccount();
+        Map<Long, Map<String, ContentPlatformGzhAccount>> gzhAccountMap = gzhAccountList.stream()
+                .collect(Collectors.groupingBy(ContentPlatformGzhAccount::getCreateAccountId,
+                        Collectors.toMap(ContentPlatformGzhAccount::getGhId, account -> account)));
+        List<String> accountExternalIds = gzhAccountList.stream().map(ContentPlatformGzhAccount::getExternalId)
                 .collect(Collectors.toList());
                 .collect(Collectors.toList());
         String dateStr = dt.substring(0, 4) + "-" + dt.substring(4, 6) + "-" + dt.substring(6, 8);
         String dateStr = dt.substring(0, 4) + "-" + dt.substring(4, 6) + "-" + dt.substring(6, 8);
         List<WxAccountDatastatVO> wxAccountDatastatVOList = aigcApiService.getWxAccountDatastat(dateStr, accountExternalIds);
         List<WxAccountDatastatVO> wxAccountDatastatVOList = aigcApiService.getWxAccountDatastat(dateStr, accountExternalIds);
@@ -93,16 +97,38 @@ public class ContentPlatformDatastatJob {
                 .collect(Collectors.toMap(WxAccountDatastatVO::getAccountId, wxAccountDatastatVO -> wxAccountDatastatVO));
                 .collect(Collectors.toMap(WxAccountDatastatVO::getAccountId, wxAccountDatastatVO -> wxAccountDatastatVO));
         if (CollectionUtils.isNotEmpty(dataList)) {
         if (CollectionUtils.isNotEmpty(dataList)) {
             List<ContentPlatformGzhDataStat> saveList = new ArrayList<>();
             List<ContentPlatformGzhDataStat> saveList = new ArrayList<>();
+            BigDecimal sumScore = BigDecimal.ZERO;
             for (Record record : dataList) {
             for (Record record : dataList) {
-                ContentPlatformGzhDataStat item = new ContentPlatformGzhDataStat();
+                String channel = (String) record.get(0);
                 String ghId = (String) record.get(1);
                 String ghId = (String) record.get(1);
-                int firstLevelCount = Integer.parseInt((String) record.get(2));
+                Integer firstLevelCount = parseInteger(record.get(2));
                 Integer fissionCount = parseInteger(record.get(3));
                 Integer fissionCount = parseInteger(record.get(3));
-                item.setDateStr(dt);
-                if (!ghIds.contains(ghId)) {
+                Double fissionArpu = parseDouble(record.get(4));
+                if (fissionArpu > 0.3) {
+                    fissionArpu = 0.3;
+                }
+                if ("SUM".equals(channel)) {
+                    BigDecimal fissionRate = BigDecimal.valueOf(fissionCount.doubleValue() * 10 / firstLevelCount)
+                            .setScale(2, RoundingMode.HALF_UP);
+                    fissionArpu = BigDecimal.valueOf(fissionArpu).setScale(2, RoundingMode.HALF_UP).doubleValue();
+                    sumScore = fissionRate.add(new BigDecimal(fissionArpu));
                     continue;
                     continue;
                 }
                 }
-                ContentPlatformGzhAccount gzhAccount = accountMap.get(ghId);
+                ContentPlatformAccount account = accountMap.get(channel);
+                if (Objects.isNull(account)) {
+                    continue;
+                }
+                Map<String, ContentPlatformGzhAccount> gzhAccounts = gzhAccountMap.get(account.getId());
+                if (Objects.isNull(gzhAccounts)) {
+                    continue;
+                }
+
+                ContentPlatformGzhAccount gzhAccount = gzhAccounts.get(ghId);
+                if (Objects.isNull(gzhAccount)) {
+                    continue;
+                }
+                ContentPlatformGzhDataStat item = new ContentPlatformGzhDataStat();
+                item.setDateStr(dt);
                 item.setAccountId(gzhAccount.getId());
                 item.setAccountId(gzhAccount.getId());
                 item.setFirstLevelCount(firstLevelCount);
                 item.setFirstLevelCount(firstLevelCount);
                 WxAccountDatastatVO wxAccountDatastatVO = wxAccountDatastatMap.get(gzhAccount.getExternalId());
                 WxAccountDatastatVO wxAccountDatastatVO = wxAccountDatastatMap.get(gzhAccount.getExternalId());
@@ -111,13 +137,25 @@ public class ContentPlatformDatastatJob {
                 }
                 }
 
 
                 if (fissionCount > 0 && firstLevelCount > 0) {
                 if (fissionCount > 0 && firstLevelCount > 0) {
-                    BigDecimal num = BigDecimal.valueOf(fissionCount.doubleValue() * 10 / firstLevelCount);
-                    BigDecimal rounded = num.setScale(2, RoundingMode.HALF_UP);
-                    item.setScore(rounded.doubleValue());
+                    BigDecimal fissionRate = BigDecimal.valueOf(fissionCount.doubleValue() * 10 / firstLevelCount)
+                            .setScale(2, RoundingMode.HALF_UP);
+                    fissionArpu = BigDecimal.valueOf(fissionArpu).setScale(2, RoundingMode.HALF_UP).doubleValue();
+                    BigDecimal totalScore = fissionRate.add(new BigDecimal(fissionArpu));
+                    item.setScore(totalScore.doubleValue());
                 }
                 }
                 item.setCreateTimestamp(now);
                 item.setCreateTimestamp(now);
                 saveList.add(item);
                 saveList.add(item);
             }
             }
+            for (ContentPlatformGzhDataStat item : saveList) {
+                if (item.getFirstLevelCount() < 10) {
+                    item.setScore(0.0);
+                    continue;
+                }
+                if (Objects.nonNull(item.getScore())) {
+                    BigDecimal score = BigDecimal.valueOf(item.getScore());
+                    item.setScore(score.divide(sumScore, 3, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(10)).doubleValue());
+                }
+            }
             if (CollectionUtils.isNotEmpty(saveList)) {
             if (CollectionUtils.isNotEmpty(saveList)) {
                 dataStatMapperExt.deleteGzhDatastat(dt);
                 dataStatMapperExt.deleteGzhDatastat(dt);
                 dataStatMapperExt.batchInsertGzhDatastat(saveList);
                 dataStatMapperExt.batchInsertGzhDatastat(saveList);
@@ -186,15 +224,15 @@ public class ContentPlatformDatastatJob {
         Long now = System.currentTimeMillis();
         Long now = System.currentTimeMillis();
         // 公众号自动回复数据统计
         // 公众号自动回复数据统计
         String sql = String.format(
         String sql = String.format(
-                "SELECT first_level.channel_shortname, first_level.first_uv, fission.split_uv, price.arpu " +
-                "FROM loghubods.out_channel_mid_first_total first_level " +
-                "left join loghubods.out_channel_mid_split_total fission " +
-                "on first_level.channel_shortname = fission.channel_shortname and first_level.dt = fission.dt " +
-                "and first_level.type = fission.type and first_level.tag = fission.tag " +
-                "left join loghubods.wecom_cooperation_dynamic_unit_price price " +
-                "on first_level.channel_shortname = price.channel_shortname and first_level.dt = price.dt " +
-                "and first_level.type = price.type and first_level.tag = price.tag " +
-                "WHERE first_level.dt = %s and first_level.type = '公众号即时回复' and first_level.tag = '投放渠道内去重' ;", dt);
+                "SELECT distinct first_level.channel_shortname, first_level.first_uv, fission.split_uv, fission.裂变arpu, price.arpu " +
+                        "FROM loghubods.out_channel_mid_first_total first_level " +
+                        "left join loghubods.out_channel_mid_split_total fission " +
+                        "on first_level.channel_shortname = fission.channel_shortname and first_level.dt = fission.dt " +
+                        "and first_level.type = fission.type and first_level.tag = fission.tag " +
+                        "left join loghubods.wecom_cooperation_dynamic_unit_price price " +
+                        "on first_level.channel_shortname = price.channel_shortname and first_level.dt = price.dt " +
+                        "and first_level.type = price.type and first_level.tag = price.tag " +
+                        "WHERE first_level.dt = %s and first_level.type = '公众号即时回复' and first_level.tag = '投放渠道内去重' ;", dt);
         List<Record> dataList = OdpsUtil.getOdpsData(sql);
         List<Record> dataList = OdpsUtil.getOdpsData(sql);
         // 所有公众号
         // 所有公众号
         List<ContentPlatformAccount> accountList = getAllAccount();
         List<ContentPlatformAccount> accountList = getAllAccount();
@@ -210,16 +248,24 @@ public class ContentPlatformDatastatJob {
         Map<String, WxAccountDatastatVO> wxAccountDatastatMap = wxAccountDatastatVOList.stream()
         Map<String, WxAccountDatastatVO> wxAccountDatastatMap = wxAccountDatastatVOList.stream()
                 .collect(Collectors.toMap(WxAccountDatastatVO::getAccountId, wxAccountDatastatVO -> wxAccountDatastatVO));
                 .collect(Collectors.toMap(WxAccountDatastatVO::getAccountId, wxAccountDatastatVO -> wxAccountDatastatVO));
         if (CollectionUtils.isNotEmpty(dataList)) {
         if (CollectionUtils.isNotEmpty(dataList)) {
+            BigDecimal sumScore = BigDecimal.ZERO;
             List<ContentPlatformGzhDataStatTotal> saveList = new ArrayList<>();
             List<ContentPlatformGzhDataStatTotal> saveList = new ArrayList<>();
             for (Record record : dataList) {
             for (Record record : dataList) {
-                ContentPlatformGzhDataStatTotal item = new ContentPlatformGzhDataStatTotal();
                 String channel = record.getString(0);
                 String channel = record.getString(0);
-                int firstLevelCount = Integer.parseInt((String) record.get(1));
+                Integer firstLevelCount = parseInteger(record.get(1));
                 Integer fissionCount = parseInteger(record.get(2));
                 Integer fissionCount = parseInteger(record.get(2));
-                Double arpu = parseDouble(record.get(3));
-                item.setDateStr(dt);
-                item.setChannel(channel);
-                item.setFirstLevelCount(firstLevelCount);
+                Double fissionArpu = parseDouble(record.get(3));
+                if (fissionArpu > 0.3) {
+                    fissionArpu = 0.3;
+                }
+                Double arpu = parseDouble(record.get(4));
+                if ("SUM".equals(channel)) {
+                    BigDecimal fissionRate = BigDecimal.valueOf(fissionCount.doubleValue() * 10 / firstLevelCount)
+                            .setScale(2, RoundingMode.HALF_UP);
+                    fissionArpu = BigDecimal.valueOf(fissionArpu).setScale(2, RoundingMode.HALF_UP).doubleValue();
+                    sumScore = fissionRate.add(new BigDecimal(fissionArpu));
+                    continue;
+                }
                 ContentPlatformAccount account = accountMap.get(channel);
                 ContentPlatformAccount account = accountMap.get(channel);
                 if (Objects.isNull(account)) {
                 if (Objects.isNull(account)) {
                     continue;
                     continue;
@@ -234,12 +280,19 @@ public class ContentPlatformDatastatJob {
                         }
                         }
                     }
                     }
                 }
                 }
+                ContentPlatformGzhDataStatTotal item = new ContentPlatformGzhDataStatTotal();
+                item.setDateStr(dt);
+                item.setChannel(channel);
+                item.setFirstLevelCount(firstLevelCount);
                 item.setFansIncreaseCount(fansIncreaseCount);
                 item.setFansIncreaseCount(fansIncreaseCount);
 
 
                 if (fissionCount > 0 && firstLevelCount > 0) {
                 if (fissionCount > 0 && firstLevelCount > 0) {
-                    BigDecimal fissionRate = BigDecimal.valueOf(fissionCount.doubleValue() / firstLevelCount);
-                    BigDecimal rounded = fissionRate.multiply(new BigDecimal(10)).setScale(2, RoundingMode.HALF_UP);
-                    item.setScore(rounded.doubleValue());
+                    BigDecimal fissionRate = BigDecimal.valueOf(fissionCount.doubleValue() * 10 / firstLevelCount)
+                            .setScale(2, RoundingMode.HALF_UP);
+                    fissionArpu = BigDecimal.valueOf(fissionArpu).setScale(2, RoundingMode.HALF_UP).doubleValue();
+                    BigDecimal totalScore = fissionRate.add(new BigDecimal(fissionArpu));
+                    item.setScore(totalScore.doubleValue());
+
                     BigDecimal unitPrice = getUnitPrice(account.getPrice(), fissionRate, arpu, BussinessTypeEnum.GZH_AUTO_REPLY);
                     BigDecimal unitPrice = getUnitPrice(account.getPrice(), fissionRate, arpu, BussinessTypeEnum.GZH_AUTO_REPLY);
                     if (Objects.nonNull(unitPrice)) {
                     if (Objects.nonNull(unitPrice)) {
                         item.setUnitPrice(unitPrice.doubleValue());
                         item.setUnitPrice(unitPrice.doubleValue());
@@ -254,6 +307,16 @@ public class ContentPlatformDatastatJob {
                 item.setCreateTimestamp(now);
                 item.setCreateTimestamp(now);
                 saveList.add(item);
                 saveList.add(item);
             }
             }
+            for (ContentPlatformGzhDataStatTotal item : saveList) {
+                if (item.getFirstLevelCount() < 25) {
+                    item.setScore(0.0);
+                    continue;
+                }
+                if (Objects.nonNull(item.getScore())) {
+                    BigDecimal score = BigDecimal.valueOf(item.getScore());
+                    item.setScore(score.divide(sumScore, 3, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(10)).doubleValue());
+                }
+            }
             if (CollectionUtils.isNotEmpty(saveList)) {
             if (CollectionUtils.isNotEmpty(saveList)) {
                 dataStatMapperExt.deleteGzhDatastatTotal(dt);
                 dataStatMapperExt.deleteGzhDatastatTotal(dt);
                 dataStatMapperExt.batchInsertGzhDatastatTotal(saveList);
                 dataStatMapperExt.batchInsertGzhDatastatTotal(saveList);
@@ -271,12 +334,12 @@ public class ContentPlatformDatastatJob {
         Long now = System.currentTimeMillis();
         Long now = System.currentTimeMillis();
         // 公众号自动回复数据统计
         // 公众号自动回复数据统计
         String sql = String.format(
         String sql = String.format(
-                "SELECT first_level.subchannel, first_level.first_uv, fission.split_uv " +
-                "FROM loghubods.out_channel_mid_first_total first_level " +
-                "left join loghubods.out_channel_mid_split_total fission " +
-                "on first_level.subchannel = fission.subchannel and first_level.dt = fission.dt " +
-                "and first_level.type = fission.type and first_level.tag = fission.tag " +
-                "WHERE first_level.dt = %s and first_level.type = '服务号代运营' and first_level.tag = '分投放渠道客户分账号去重' ;", dt);
+                "SELECT distinct first_level.subchannel, first_level.first_uv, fission.split_uv " +
+                        "FROM loghubods.out_channel_mid_first_total first_level " +
+                        "left join loghubods.out_channel_mid_split_total fission " +
+                        "on first_level.subchannel = fission.subchannel and first_level.dt = fission.dt " +
+                        "and first_level.type = fission.type and first_level.tag = fission.tag " +
+                        "WHERE first_level.dt = %s and first_level.type = '服务号代运营' and first_level.tag = '分投放渠道客户分账号去重' ;", dt);
         List<Record> dataList = OdpsUtil.getOdpsData(sql);
         List<Record> dataList = OdpsUtil.getOdpsData(sql);
         // 所有公众号
         // 所有公众号
         List<ContentPlatformGzhAccount> accountList = getAllGzhAccount();
         List<ContentPlatformGzhAccount> accountList = getAllGzhAccount();
@@ -333,15 +396,15 @@ public class ContentPlatformDatastatJob {
         Long now = System.currentTimeMillis();
         Long now = System.currentTimeMillis();
         // 公众号自动回复数据统计
         // 公众号自动回复数据统计
         String sql = String.format(
         String sql = String.format(
-                "SELECT first_level.channel_shortname, first_level.first_uv, fission.split_uv, price.arpu " +
-                "FROM loghubods.out_channel_mid_first_total first_level " +
-                "left join loghubods.out_channel_mid_split_total fission " +
-                "on first_level.channel_shortname = fission.channel_shortname and first_level.dt = fission.dt " +
-                "and first_level.type = fission.type and first_level.tag = fission.tag " +
-                "left join loghubods.wecom_cooperation_dynamic_unit_price price " +
-                "on first_level.channel_shortname = price.channel_shortname and first_level.dt = price.dt " +
-                "and first_level.type = price.type and first_level.tag = price.tag " +
-                "WHERE first_level.dt = %s and first_level.type = '服务号代运营' and first_level.tag = '投放渠道内去重' ;", dt);
+                "SELECT distinct first_level.channel_shortname, first_level.first_uv, fission.split_uv, price.arpu " +
+                        "FROM loghubods.out_channel_mid_first_total first_level " +
+                        "left join loghubods.out_channel_mid_split_total fission " +
+                        "on first_level.channel_shortname = fission.channel_shortname and first_level.dt = fission.dt " +
+                        "and first_level.type = fission.type and first_level.tag = fission.tag " +
+                        "left join loghubods.wecom_cooperation_dynamic_unit_price price " +
+                        "on first_level.channel_shortname = price.channel_shortname and first_level.dt = price.dt " +
+                        "and first_level.type = price.type and first_level.tag = price.tag " +
+                        "WHERE first_level.dt = %s and first_level.type = '服务号代运营' and first_level.tag = '投放渠道内去重' ;", dt);
         List<Record> dataList = OdpsUtil.getOdpsData(sql);
         List<Record> dataList = OdpsUtil.getOdpsData(sql);
         // 所有公众号
         // 所有公众号
         List<ContentPlatformAccount> accountList = getAllAccount();
         List<ContentPlatformAccount> accountList = getAllAccount();
@@ -418,12 +481,12 @@ public class ContentPlatformDatastatJob {
         Long now = System.currentTimeMillis();
         Long now = System.currentTimeMillis();
         // 公众号自动回复数据统计
         // 公众号自动回复数据统计
         String sql = String.format(
         String sql = String.format(
-                "SELECT first_level.subchannel, first_level.first_uv, fission.split_uv " +
-                "FROM loghubods.out_channel_mid_first_total first_level " +
-                "left join loghubods.out_channel_mid_split_total fission " +
-                "on first_level.subchannel = fission.subchannel and first_level.dt = fission.dt " +
-                "and first_level.type = fission.type and first_level.tag = fission.tag " +
-                "WHERE first_level.dt = %s and first_level.type = '公众号推送' and first_level.tag = '分投放渠道客户分账号去重' ;", dt);
+                "SELECT distinct first_level.subchannel, first_level.first_uv, fission.split_uv " +
+                        "FROM loghubods.out_channel_mid_first_total first_level " +
+                        "left join loghubods.out_channel_mid_split_total fission " +
+                        "on first_level.subchannel = fission.subchannel and first_level.dt = fission.dt " +
+                        "and first_level.type = fission.type and first_level.tag = fission.tag " +
+                        "WHERE first_level.dt = %s and first_level.type = '公众号推送' and first_level.tag = '分投放渠道客户分账号去重' ;", dt);
         List<Record> dataList = OdpsUtil.getOdpsData(sql);
         List<Record> dataList = OdpsUtil.getOdpsData(sql);
         // 所有公众号
         // 所有公众号
         List<ContentPlatformGzhAccount> accountList = getAllGzhAccount();
         List<ContentPlatformGzhAccount> accountList = getAllGzhAccount();
@@ -480,15 +543,15 @@ public class ContentPlatformDatastatJob {
         Long now = System.currentTimeMillis();
         Long now = System.currentTimeMillis();
         // 公众号自动回复数据统计
         // 公众号自动回复数据统计
         String sql = String.format(
         String sql = String.format(
-                "SELECT first_level.channel_shortname, first_level.first_uv, fission.split_uv, price.arpu " +
-                "FROM loghubods.out_channel_mid_first_total first_level " +
-                "left join loghubods.out_channel_mid_split_total fission " +
-                "on first_level.channel_shortname = fission.channel_shortname and first_level.dt = fission.dt " +
-                "and first_level.type = fission.type and first_level.tag = fission.tag " +
-                "left join loghubods.wecom_cooperation_dynamic_unit_price price " +
-                "on first_level.channel_shortname = price.channel_shortname and first_level.dt = price.dt " +
-                "and first_level.type = price.type and first_level.tag = price.tag " +
-                "WHERE first_level.dt = %s and first_level.type = '公众号推送' and first_level.tag = '投放渠道内去重' ;", dt);
+                "SELECT distinct first_level.channel_shortname, first_level.first_uv, fission.split_uv, price.arpu " +
+                        "FROM loghubods.out_channel_mid_first_total first_level " +
+                        "left join loghubods.out_channel_mid_split_total fission " +
+                        "on first_level.channel_shortname = fission.channel_shortname and first_level.dt = fission.dt " +
+                        "and first_level.type = fission.type and first_level.tag = fission.tag " +
+                        "left join loghubods.wecom_cooperation_dynamic_unit_price price " +
+                        "on first_level.channel_shortname = price.channel_shortname and first_level.dt = price.dt " +
+                        "and first_level.type = price.type and first_level.tag = price.tag " +
+                        "WHERE first_level.dt = %s and first_level.type = '公众号推送' and first_level.tag = '投放渠道内去重' ;", dt);
         List<Record> dataList = OdpsUtil.getOdpsData(sql);
         List<Record> dataList = OdpsUtil.getOdpsData(sql);
         // 所有公众号
         // 所有公众号
         List<ContentPlatformAccount> accountList = getAllAccount();
         List<ContentPlatformAccount> accountList = getAllAccount();
@@ -586,25 +649,39 @@ public class ContentPlatformDatastatJob {
         }
         }
         Map<Long, ContentPlatformQwPlan> planMap = qwPlanList.stream()
         Map<Long, ContentPlatformQwPlan> planMap = qwPlanList.stream()
                 .collect(Collectors.toMap(ContentPlatformQwPlan::getId, plan -> plan));
                 .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()
         Map<String, Long> rootSourceIdMap = qwPlanList.stream()
                 .collect(Collectors.toMap(ContentPlatformQwPlan::getRootSourceId, ContentPlatformQwPlan::getId));
                 .collect(Collectors.toMap(ContentPlatformQwPlan::getRootSourceId, ContentPlatformQwPlan::getId));
         List<Long> planIds = qwPlanList.stream().map(ContentPlatformQwPlan::getId).collect(Collectors.toList());
         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()
         Map<Long, Long> planVideoMap = planVideoList.stream()
                 .collect(Collectors.toMap(ContentPlatformQwPlanVideo::getPlanId, ContentPlatformQwPlanVideo::getVideoId));
                 .collect(Collectors.toMap(ContentPlatformQwPlanVideo::getPlanId, ContentPlatformQwPlanVideo::getVideoId));
         List<Long> videoIds = planVideoList.stream().map(ContentPlatformQwPlanVideo::getVideoId).collect(Collectors.toList());
         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()
         Map<Long, Double> videoScoreMap = videoList.stream()
                 .collect(Collectors.toMap(ContentPlatformVideoAgg::getVideoId, ContentPlatformVideoAgg::getScore, (a, b) -> a));
                 .collect(Collectors.toMap(ContentPlatformVideoAgg::getVideoId, ContentPlatformVideoAgg::getScore, (a, b) -> a));
         List<ContentPlatformQwDataStat> saveList = new ArrayList<>();
         List<ContentPlatformQwDataStat> saveList = new ArrayList<>();
         List<String> rootSourceIds = qwPlanList.stream().map(ContentPlatformQwPlan::getRootSourceId).collect(Collectors.toList());
         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();
         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) {
             for (Record record : outDataList) {
                 ContentPlatformQwDataStat item = new ContentPlatformQwDataStat();
                 ContentPlatformQwDataStat item = new ContentPlatformQwDataStat();
                 String rootSourceId = (String) record.get(0);
                 String rootSourceId = (String) record.get(0);
@@ -614,7 +691,7 @@ public class ContentPlatformDatastatJob {
                 if (existRootSourceIds.contains(rootSourceId)) {
                 if (existRootSourceIds.contains(rootSourceId)) {
                     continue;
                     continue;
                 }
                 }
-                int firstLevelCount = Integer.parseInt((String) record.get(8));
+                int firstLevelCount = Integer.parseInt((String) record.get(1));
                 if (firstLevelCount == 0) {
                 if (firstLevelCount == 0) {
                     continue;
                     continue;
                 }
                 }
@@ -633,12 +710,24 @@ public class ContentPlatformDatastatJob {
                 item.setFirstLevelCount(firstLevelCount);
                 item.setFirstLevelCount(firstLevelCount);
                 item.setCreateTimestamp(now);
                 item.setCreateTimestamp(now);
                 saveList.add(item);
                 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();
                 ContentPlatformQwDataStat item = new ContentPlatformQwDataStat();
                 String rootSourceId = (String) record.get(0);
                 String rootSourceId = (String) record.get(0);
                 if (!rootSourceIds.contains(rootSourceId)) {
                 if (!rootSourceIds.contains(rootSourceId)) {
@@ -647,7 +736,7 @@ public class ContentPlatformDatastatJob {
                 if (existRootSourceIds.contains(rootSourceId)) {
                 if (existRootSourceIds.contains(rootSourceId)) {
                     continue;
                     continue;
                 }
                 }
-                int firstLevelCount = Integer.parseInt((String) record.get(8));
+                int firstLevelCount = Integer.parseInt((String) record.get(1));
                 if (firstLevelCount == 0) {
                 if (firstLevelCount == 0) {
                     continue;
                     continue;
                 }
                 }
@@ -664,7 +753,12 @@ public class ContentPlatformDatastatJob {
                 item.setFirstLevelCount(firstLevelCount);
                 item.setFirstLevelCount(firstLevelCount);
                 item.setCreateTimestamp(now);
                 item.setCreateTimestamp(now);
                 saveList.add(item);
                 saveList.add(item);
+                existRootSourceIds.add(rootSourceId);
+            }
+            if (outDataList.size() < pageSize) {
+                break;
             }
             }
+            pageNum++;
         }
         }
         if (CollectionUtils.isNotEmpty(saveList)) {
         if (CollectionUtils.isNotEmpty(saveList)) {
             dataStatMapperExt.deleteQwDatastat(dt);
             dataStatMapperExt.deleteQwDatastat(dt);
@@ -686,15 +780,15 @@ public class ContentPlatformDatastatJob {
         }
         }
         Map<String, ContentPlatformQwDataStatTotal> saveMap = new HashMap<>();
         Map<String, ContentPlatformQwDataStatTotal> saveMap = new HashMap<>();
         String outSql = String.format(
         String outSql = String.format(
-                "SELECT first_level.channel_shortname, first_level.first_uv, fission.split_uv, price.arpu " +
-                "FROM loghubods.out_channel_mid_first_total first_level " +
-                "left join loghubods.out_channel_mid_split_total fission " +
-                "on first_level.channel_shortname = fission.channel_shortname and first_level.dt = fission.dt " +
-                "and first_level.type = fission.type and first_level.tag = fission.tag " +
-                "left join loghubods.wecom_cooperation_dynamic_unit_price price " +
-                "on first_level.channel_shortname = price.channel_shortname and first_level.dt = price.dt " +
-                "and first_level.type = price.type and first_level.tag = price.tag " +
-                "WHERE first_level.dt = %s and first_level.type = '企微外部' and first_level.tag = '投放渠道内去重' ;", dt);
+                "SELECT distinct first_level.channel_shortname, first_level.first_uv, fission.split_uv, price.arpu " +
+                        "FROM loghubods.out_channel_mid_first_total first_level " +
+                        "left join loghubods.out_channel_mid_split_total fission " +
+                        "on first_level.channel_shortname = fission.channel_shortname and first_level.dt = fission.dt " +
+                        "and first_level.type = fission.type and first_level.tag = fission.tag " +
+                        "left join loghubods.wecom_cooperation_dynamic_unit_price price " +
+                        "on first_level.channel_shortname = price.channel_shortname and first_level.dt = price.dt " +
+                        "and first_level.type = price.type and first_level.tag = price.tag " +
+                        "WHERE first_level.dt = %s and first_level.type = '企微外部' and first_level.tag = '投放渠道内去重' ;", dt);
         List<Record> outDataList = OdpsUtil.getOdpsData(outSql);
         List<Record> outDataList = OdpsUtil.getOdpsData(outSql);
         List<ContentPlatformAccount> accountList = getAllAccount();
         List<ContentPlatformAccount> accountList = getAllAccount();
         Map<String, ContentPlatformAccount> accountMap = accountList.stream()
         Map<String, ContentPlatformAccount> accountMap = accountList.stream()
@@ -838,15 +932,15 @@ public class ContentPlatformDatastatJob {
         }
         }
         List<ContentPlatformQwDataStatSubChannel> saveList = new ArrayList<>();
         List<ContentPlatformQwDataStatSubChannel> saveList = new ArrayList<>();
         String outSql = String.format(
         String outSql = String.format(
-                "SELECT first_level.channel_shortname, first_level.subchannel, first_level.first_uv, fission.split_uv, price.arpu " +
-                "FROM loghubods.out_channel_mid_first_total first_level " +
-                "left join loghubods.out_channel_mid_split_total fission " +
-                "on first_level.channel_shortname = fission.channel_shortname and first_level.subchannel = fission.subchannel " +
-                "and first_level.dt = fission.dt and first_level.type = fission.type and first_level.tag = fission.tag " +
-                "left join loghubods.wecom_cooperation_dynamic_unit_price price " +
-                "on first_level.channel_shortname = price.channel_shortname and first_level.subchannel = price.subchannel " +
-                "and first_level.dt = price.dt and first_level.type = price.type and first_level.tag = price.tag " +
-                "WHERE first_level.dt = %s and first_level.type = '企微外部' and first_level.tag = '分投放渠道客户分账号去重' ;", dt);
+                "SELECT distinct first_level.channel_shortname, first_level.subchannel, first_level.first_uv, fission.split_uv, price.arpu " +
+                        "FROM loghubods.out_channel_mid_first_total first_level " +
+                        "left join loghubods.out_channel_mid_split_total fission " +
+                        "on first_level.channel_shortname = fission.channel_shortname and first_level.subchannel = fission.subchannel " +
+                        "and first_level.dt = fission.dt and first_level.type = fission.type and first_level.tag = fission.tag " +
+                        "left join loghubods.wecom_cooperation_dynamic_unit_price price " +
+                        "on first_level.channel_shortname = price.channel_shortname and first_level.subchannel = price.subchannel " +
+                        "and first_level.dt = price.dt and first_level.type = price.type and first_level.tag = price.tag " +
+                        "WHERE first_level.dt = %s and first_level.type = '企微外部' and first_level.tag = '分投放渠道客户分账号去重' ;", dt);
         List<Record> outDataList = OdpsUtil.getOdpsData(outSql);
         List<Record> outDataList = OdpsUtil.getOdpsData(outSql);
         List<ContentPlatformAccount> accountList = getAllAccount();
         List<ContentPlatformAccount> accountList = getAllAccount();
         Map<String, ContentPlatformAccount> accountMap = accountList.stream()
         Map<String, ContentPlatformAccount> accountMap = accountList.stream()

+ 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() {
     private List<ContentPlatformGzhAccount> getNeedSyncAccountInfo() {
         ContentPlatformGzhAccountExample example = new ContentPlatformGzhAccountExample();
         ContentPlatformGzhAccountExample example = new ContentPlatformGzhAccountExample();
-        example.createCriteria().andExternalIdIsNotNull();
+        example.createCriteria().andExternalIdIsNotNull().andStatusEqualTo(1);
         return gzhAccountMapper.selectByExample(example);
         return gzhAccountMapper.selectByExample(example);
     }
     }
 }
 }

+ 7 - 0
api-module/src/main/java/com/tzld/piaoquan/api/job/contentplatform/ContentPlatformIllegalVideoJob.java

@@ -130,6 +130,13 @@ public class ContentPlatformIllegalVideoJob {
         illegalMsg.setVideoId(videoId);
         illegalMsg.setVideoId(videoId);
         illegalMsg.setTitle(planList.get(0).getTitle());
         illegalMsg.setTitle(planList.get(0).getTitle());
         illegalMsg.setBusinessType(businessType);
         illegalMsg.setBusinessType(businessType);
+        String videoTitle = illegalMsg.getTitle();
+        if (videoTitle.length() >= 20) {
+            videoTitle = videoTitle.substring(0, 19) + "...";
+        }
+        illegalMsg.setIllegalTitle("视频“" + videoTitle + "”被封禁,请及时替换");
+        illegalMsg.setIllegalContent("您在" + illegalMsg.getBusinessType() + "栏目中使用的视频“" +
+                videoTitle + "”(视频ID:" + illegalMsg.getVideoId() + ")被微信封禁,请及时替换为其他视频。");
         illegalMsg.setStatus(0);
         illegalMsg.setStatus(0);
         illegalMsg.setCreateTimestamp(now);
         illegalMsg.setCreateTimestamp(now);
         illegalMsg.setUpdateTimestamp(now);
         illegalMsg.setUpdateTimestamp(now);

+ 2 - 0
api-module/src/main/java/com/tzld/piaoquan/api/job/contentplatform/ContentPlatformVideoJob.java

@@ -451,6 +451,8 @@ public class ContentPlatformVideoJob {
         List<ContentPlatformVideoDataStatAgg> saveAggList = buildVideoDataStatAggList(aggDt, dtList);
         List<ContentPlatformVideoDataStatAgg> saveAggList = buildVideoDataStatAggList(aggDt, dtList);
         if (CollectionUtils.isNotEmpty(saveAggList)) {
         if (CollectionUtils.isNotEmpty(saveAggList)) {
             planMapperExt.deleteContentPlatformVideoDatastatAgg(aggDt, null);
             planMapperExt.deleteContentPlatformVideoDatastatAgg(aggDt, null);
+            String delDt = DateUtil.getBeforeDayDateString(31, "yyyyMMdd");
+            planMapperExt.deleteContentPlatformVideoDatastatAgg(delDt, null);
             planMapperExt.batchInsertContentPlatformVideoDatastatAgg(saveAggList);
             planMapperExt.batchInsertContentPlatformVideoDatastatAgg(saveAggList);
         }
         }
         calContentPlatformVideoDatastatAggRecommendRateJob(param);
         calContentPlatformVideoDatastatAggRecommendRateJob(param);

+ 101 - 6
offline-module/src/main/java/com/tzld/piaoquan/offline/job/WeComMessageDataJob.java → api-module/src/main/java/com/tzld/piaoquan/api/job/wecom/WeComMessageDataJob.java

@@ -1,13 +1,13 @@
-package com.tzld.piaoquan.offline.job;
+package com.tzld.piaoquan.api.job.wecom;
 
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.JSONObject;
 import com.aliyun.odps.data.Record;
 import com.aliyun.odps.data.Record;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Lists;
+import com.tzld.piaoquan.api.service.VideoMultiService;
+import com.tzld.piaoquan.growth.common.common.base.CommonResponse;
 import com.tzld.piaoquan.growth.common.common.constant.MessageConstant;
 import com.tzld.piaoquan.growth.common.common.constant.MessageConstant;
-import com.tzld.piaoquan.growth.common.common.enums.ExceptionCodeEnum;
-import com.tzld.piaoquan.growth.common.common.exception.CustomizeException;
 import com.tzld.piaoquan.growth.common.dao.mapper.*;
 import com.tzld.piaoquan.growth.common.dao.mapper.*;
 import com.tzld.piaoquan.growth.common.model.bo.*;
 import com.tzld.piaoquan.growth.common.model.bo.*;
 import com.tzld.piaoquan.growth.common.model.po.*;
 import com.tzld.piaoquan.growth.common.model.po.*;
@@ -19,6 +19,7 @@ import com.tzld.piaoquan.growth.common.utils.*;
 import com.tzld.piaoquan.growth.common.utils.page.Page;
 import com.tzld.piaoquan.growth.common.utils.page.Page;
 import com.xxl.job.core.biz.model.ReturnT;
 import com.xxl.job.core.biz.model.ReturnT;
 import com.xxl.job.core.handler.annotation.XxlJob;
 import com.xxl.job.core.handler.annotation.XxlJob;
+import com.xxl.job.core.log.XxlJobLogger;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -67,6 +68,9 @@ public class WeComMessageDataJob {
     @Autowired
     @Autowired
     private WeComUserService weComUserService;
     private WeComUserService weComUserService;
 
 
+    @Autowired
+    private VideoMultiService videoMultiService;
+
     //发送小程序标题限制字节数
     //发送小程序标题限制字节数
     private static final int MAX_BYTES = 64;
     private static final int MAX_BYTES = 64;
 
 
@@ -481,7 +485,7 @@ public class WeComMessageDataJob {
         example.createCriteria().andIsSendEqualTo(0).andCreateTimeGreaterThan(DateUtil.getThatDayDate());
         example.createCriteria().andIsSendEqualTo(0).andCreateTimeGreaterThan(DateUtil.getThatDayDate());
         long l = sendMessageMapper.countByExample(example);
         long l = sendMessageMapper.countByExample(example);
         if (l > 0) {
         if (l > 0) {
-            LarkRobotUtil.sendMessage("存在发送失败消息,请检查@薛一鸣");
+            LarkRobotUtil.sendMessage("存在发送失败消息,请检查<at user_id=\"g6732afb\">王云鹏</at>");
         }
         }
         return ReturnT.SUCCESS;
         return ReturnT.SUCCESS;
     }
     }
@@ -551,8 +555,10 @@ public class WeComMessageDataJob {
             String key = staff.getCarrierId() + "_" + videoId;
             String key = staff.getCarrierId() + "_" + videoId;
             if (pageMap.containsKey(key)) {
             if (pageMap.containsKey(key)) {
                 page = pageMap.get(key);
                 page = pageMap.get(key);
+                page = videoMultiService.setVideoMultiTitleCoverPagePath(videoId, page, title, messageAttachment.getCover());
             } else {
             } else {
-                page = messageAttachmentService.getPage(staff, videoId, "企微", "日常推送");
+                page = messageAttachmentService.getPage("touliu", "tencentqw", staff, videoId, "企微", "日常推送");
+                page = videoMultiService.setVideoMultiTitleCoverPagePath(videoId, page, title, messageAttachment.getCover());
                 pageMap.put(key, page);
                 pageMap.put(key, page);
             }
             }
             if (StringUtils.isEmpty(page)) {
             if (StringUtils.isEmpty(page)) {
@@ -592,10 +598,99 @@ public class WeComMessageDataJob {
         GuaranteedParam guaranteedParam = messageAttachmentService.getGuaranteedVideo(DateUtil.getNextDayDateString());
         GuaranteedParam guaranteedParam = messageAttachmentService.getGuaranteedVideo(DateUtil.getNextDayDateString());
         if (guaranteedParam == null
         if (guaranteedParam == null
                 || CollectionUtils.isEmpty(guaranteedParam.getVideoParamList())) {
                 || CollectionUtils.isEmpty(guaranteedParam.getVideoParamList())) {
-            LarkRobotUtil.sendMessage("@薛一鸣 保底视频异常,请检查" + DateUtil.getNextDayDateString());
+            LarkRobotUtil.sendMessage("<at user_id=\"g6732afb\">王云鹏</at> 保底视频异常,请检查" + DateUtil.getNextDayDateString());
         }
         }
         return ReturnT.SUCCESS;
         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;
+    }
 }
 }

+ 18 - 3
api-module/src/main/java/com/tzld/piaoquan/api/job/wecom/thirdpart/WeComAccountJob.java

@@ -2,12 +2,14 @@ package com.tzld.piaoquan.api.job.wecom.thirdpart;
 
 
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.TypeReference;
 import com.alibaba.fastjson.TypeReference;
+import com.tzld.piaoquan.api.common.enums.wecom.ThirdPartWeComStaffStatusEnum;
 import com.tzld.piaoquan.api.component.WeComThirdPartyApiClient;
 import com.tzld.piaoquan.api.component.WeComThirdPartyApiClient;
+import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ThirdPartWeComStaffMapper;
 import com.tzld.piaoquan.api.model.param.wecom.thirdpart.CommonResponse;
 import com.tzld.piaoquan.api.model.param.wecom.thirdpart.CommonResponse;
 import com.tzld.piaoquan.api.model.param.wecom.thirdpart.LoginInfo;
 import com.tzld.piaoquan.api.model.param.wecom.thirdpart.LoginInfo;
 import com.tzld.piaoquan.api.model.param.wecom.thirdpart.UuidRequest;
 import com.tzld.piaoquan.api.model.param.wecom.thirdpart.UuidRequest;
 import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComStaff;
 import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComStaff;
-import com.tzld.piaoquan.api.service.WeComThirdPartyService;
+import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComStaffExample;
 import com.tzld.piaoquan.growth.common.utils.LarkRobotUtil;
 import com.tzld.piaoquan.growth.common.utils.LarkRobotUtil;
 import com.tzld.piaoquan.growth.common.utils.RedisUtils;
 import com.tzld.piaoquan.growth.common.utils.RedisUtils;
 import com.xxl.job.core.biz.model.ReturnT;
 import com.xxl.job.core.biz.model.ReturnT;
@@ -16,6 +18,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Component;
 
 
+import java.util.Arrays;
 import java.util.List;
 import java.util.List;
 import java.util.Objects;
 import java.util.Objects;
 
 
@@ -24,7 +27,7 @@ import java.util.Objects;
 public class WeComAccountJob {
 public class WeComAccountJob {
 
 
     @Autowired
     @Autowired
-    WeComThirdPartyService weComThirdPartyService;
+    ThirdPartWeComStaffMapper thirdPartWeComStaffMapper;
     @Autowired
     @Autowired
     WeComThirdPartyApiClient apiClient;
     WeComThirdPartyApiClient apiClient;
 
 
@@ -33,7 +36,7 @@ public class WeComAccountJob {
 
 
     @XxlJob("checkAccountOnline")
     @XxlJob("checkAccountOnline")
     public ReturnT<String> checkAccountOnline(String param) {
     public ReturnT<String> checkAccountOnline(String param) {
-        List<ThirdPartWeComStaff> activeStaffList = weComThirdPartyService.getActiveStaffList();
+        List<ThirdPartWeComStaff> activeStaffList = getCheckOnlineStaffList();
         for (ThirdPartWeComStaff staff : activeStaffList) {
         for (ThirdPartWeComStaff staff : activeStaffList) {
             String uuid = staff.getThirdUuid();
             String uuid = staff.getThirdUuid();
             String offLineKey = "wecom:thirdpart:offline:" + uuid;
             String offLineKey = "wecom:thirdpart:offline:" + uuid;
@@ -53,8 +56,20 @@ public class WeComAccountJob {
                                 "账号VID:" + staff.getThirdStaffId() + "\n" +
                                 "账号VID:" + staff.getThirdStaffId() + "\n" +
                                 "账号UUID:" + uuid + "\n" +
                                 "账号UUID:" + uuid + "\n" +
                                 "账号状态:已下线");
                                 "账号状态:已下线");
+                if (staff.getStatus() == ThirdPartWeComStaffStatusEnum.NORMAL.getVal()) {
+                    staff.setStatus(ThirdPartWeComStaffStatusEnum.OFFLINE.getVal());
+                    thirdPartWeComStaffMapper.updateByPrimaryKeySelective(staff);
+                }
             }
             }
         }
         }
         return ReturnT.SUCCESS;
         return ReturnT.SUCCESS;
     }
     }
+
+    private List<ThirdPartWeComStaff> getCheckOnlineStaffList() {
+        List<Integer> statusList = Arrays.asList(ThirdPartWeComStaffStatusEnum.NORMAL.getVal(),
+                ThirdPartWeComStaffStatusEnum.OFFLINE.getVal());
+        ThirdPartWeComStaffExample example = new ThirdPartWeComStaffExample();
+        example.createCriteria().andStatusIn(statusList);
+        return thirdPartWeComStaffMapper.selectByExample(example);
+    }
 }
 }

+ 1 - 1
api-module/src/main/java/com/tzld/piaoquan/api/job/wecom/thirdpart/WeComCreateRoomJob.java

@@ -9,7 +9,7 @@ import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComRoom;
 import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComRoomUser;
 import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComRoomUser;
 import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComStaff;
 import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComStaff;
 import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComStaffUser;
 import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComStaffUser;
-import com.tzld.piaoquan.api.service.WeComThirdPartyService;
+import com.tzld.piaoquan.api.service.wecom.thirdparty.WeComThirdPartyService;
 import com.tzld.piaoquan.growth.common.utils.DateUtil;
 import com.tzld.piaoquan.growth.common.utils.DateUtil;
 import com.tzld.piaoquan.growth.common.utils.RedisUtils;
 import com.tzld.piaoquan.growth.common.utils.RedisUtils;
 import com.xxl.job.core.biz.model.ReturnT;
 import com.xxl.job.core.biz.model.ReturnT;

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

@@ -1,22 +1,23 @@
 package com.tzld.piaoquan.api.job.wecom.thirdpart;
 package com.tzld.piaoquan.api.job.wecom.thirdpart;
 
 
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.JSONObject;
-import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
 import com.google.common.util.concurrent.ThreadFactoryBuilder;
 import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import com.tzld.piaoquan.api.common.enums.wecom.ConfigTaskContentTypeEnum;
+import com.tzld.piaoquan.api.common.enums.wecom.MsgSendStatusEnum;
+import com.tzld.piaoquan.api.common.enums.wecom.ThirdPartWeComStaffStatusEnum;
 import com.tzld.piaoquan.api.component.VideoApiService;
 import com.tzld.piaoquan.api.component.VideoApiService;
 import com.tzld.piaoquan.api.dao.mapper.contentplatform.ext.ContentPlatformPlanMapperExt;
 import com.tzld.piaoquan.api.dao.mapper.contentplatform.ext.ContentPlatformPlanMapperExt;
 import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ThirdPartWeComMsgMapper;
 import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ThirdPartWeComMsgMapper;
 import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ThirdPartWeComRoomMapper;
 import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ThirdPartWeComRoomMapper;
-import com.tzld.piaoquan.api.model.param.wecom.thirdpart.CdnUploadImgLinkRequest;
-import com.tzld.piaoquan.api.model.param.wecom.thirdpart.CdnUploadImgLinkResponse;
-import com.tzld.piaoquan.api.model.param.wecom.thirdpart.SendAppMsgRequest;
+import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ext.ThirdPartWeComVideoMapperExt;
+import com.tzld.piaoquan.api.model.param.wecom.thirdpart.*;
 import com.tzld.piaoquan.api.model.po.contentplatform.ContentPlatformVideo;
 import com.tzld.piaoquan.api.model.po.contentplatform.ContentPlatformVideo;
-import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComMsg;
-import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComMsgExample;
-import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComRoom;
-import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComStaff;
+import com.tzld.piaoquan.api.model.po.wecom.thirdpart.*;
 import com.tzld.piaoquan.api.model.vo.contentplatform.WxVideoV2VO;
 import com.tzld.piaoquan.api.model.vo.contentplatform.WxVideoV2VO;
-import com.tzld.piaoquan.api.service.WeComThirdPartyService;
+import com.tzld.piaoquan.api.service.VideoMultiService;
+import com.tzld.piaoquan.api.service.wecom.thirdparty.WeComThirdPartyAccountService;
+import com.tzld.piaoquan.api.service.wecom.thirdparty.WeComThirdPartyRoomService;
+import com.tzld.piaoquan.api.service.wecom.thirdparty.WeComThirdPartyService;
 import com.tzld.piaoquan.api.util.CdnUtil;
 import com.tzld.piaoquan.api.util.CdnUtil;
 import com.tzld.piaoquan.growth.common.model.po.CgiReplyBucketData;
 import com.tzld.piaoquan.growth.common.model.po.CgiReplyBucketData;
 import com.tzld.piaoquan.growth.common.model.po.Staff;
 import com.tzld.piaoquan.growth.common.model.po.Staff;
@@ -24,22 +25,22 @@ import com.tzld.piaoquan.growth.common.service.MessageAttachmentService;
 import com.tzld.piaoquan.growth.common.utils.DateUtil;
 import com.tzld.piaoquan.growth.common.utils.DateUtil;
 import com.tzld.piaoquan.growth.common.utils.LarkRobotUtil;
 import com.tzld.piaoquan.growth.common.utils.LarkRobotUtil;
 import com.tzld.piaoquan.growth.common.utils.MessageUtil;
 import com.tzld.piaoquan.growth.common.utils.MessageUtil;
+import com.tzld.piaoquan.growth.common.utils.RedisUtils;
 import com.xxl.job.core.biz.model.ReturnT;
 import com.xxl.job.core.biz.model.ReturnT;
 import com.xxl.job.core.handler.annotation.XxlJob;
 import com.xxl.job.core.handler.annotation.XxlJob;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Component;
 
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 
 
 @Slf4j
 @Slf4j
@@ -49,30 +50,31 @@ public class WeComSendMsgJob {
     @Autowired
     @Autowired
     WeComThirdPartyService weComThirdPartyService;
     WeComThirdPartyService weComThirdPartyService;
     @Autowired
     @Autowired
+    WeComThirdPartyAccountService weComThirdPartyAccountService;
+    @Autowired
+    WeComThirdPartyRoomService weComThirdPartyRoomService;
+    @Autowired
     MessageAttachmentService messageAttachmentService;
     MessageAttachmentService messageAttachmentService;
     @Autowired
     @Autowired
     VideoApiService videoApiService;
     VideoApiService videoApiService;
     @Autowired
     @Autowired
     ContentPlatformPlanMapperExt planMapperExt;
     ContentPlatformPlanMapperExt planMapperExt;
     @Autowired
     @Autowired
+    ThirdPartWeComVideoMapperExt videoMapperExt;
+    @Autowired
     ThirdPartWeComRoomMapper roomMapper;
     ThirdPartWeComRoomMapper roomMapper;
     @Autowired
     @Autowired
     ThirdPartWeComMsgMapper msgMapper;
     ThirdPartWeComMsgMapper msgMapper;
+    @Autowired
+    private VideoMultiService videoMultiService;
+
+    @Autowired
+    RedisUtils redisUtils;
 
 
-    @Value("${send.room.msg.video.min.score:3}")
+    @Value("${send.room.msg.video.min.score:1}")
     private Double videoMinScore;
     private Double videoMinScore;
-    @Value("${send.room.msg.duplicate.days:7}")
+    @Value("${send.room.msg.duplicate.days:30}")
     private Integer duplicateDays;
     private Integer duplicateDays;
-    @Value("${send.room.msg.video.num:2}")
-    private Integer videoNum;
-    @ApolloJsonValue("${send.room.msg.test.roomList:[]}")
-    private List<String> testRoomList;
-    @ApolloJsonValue("${send.room.msg.video.source.staff.config:{}}")
-    private Map<Long, JSONObject> videoSourceStaffConfig;
-    @ApolloJsonValue("${send.room.msg.staff.put.scene.config:{}}")
-    private Map<Long, String> staffPutSceneConfig;
-    @ApolloJsonValue("${send.room.msg.auto.open.staff:[]}")
-    private List<Long> autoOpenStaffList;
 
 
     private final static ExecutorService pool = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.SECONDS,
     private final static ExecutorService pool = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.SECONDS,
             new LinkedBlockingQueue<>(),
             new LinkedBlockingQueue<>(),
@@ -83,30 +85,160 @@ public class WeComSendMsgJob {
     public ReturnT<String> autoSendAppMsg(String param) {
     public ReturnT<String> autoSendAppMsg(String param) {
         List<ThirdPartWeComStaff> activeStaffList = weComThirdPartyService.getActiveStaffList();
         List<ThirdPartWeComStaff> activeStaffList = weComThirdPartyService.getActiveStaffList();
         String time = DateUtil.getCurrentDateStr("HH:mm");
         String time = DateUtil.getCurrentDateStr("HH:mm");
+        List<Long> staffIdList = activeStaffList.stream().map(ThirdPartWeComStaff::getId).collect(Collectors.toList());
+        List<ThirdPartWeComStaffConfig> staffConfigList = weComThirdPartyAccountService.getStaffConfigListByStaffIds(staffIdList);
+        Map<Long, ThirdPartWeComStaffConfig> staffConfigMap = staffConfigList.stream().collect(Collectors.toMap(ThirdPartWeComStaffConfig::getStaffId, a -> a));
         for (ThirdPartWeComStaff staff : activeStaffList) {
         for (ThirdPartWeComStaff staff : activeStaffList) {
+            ThirdPartWeComStaffConfig staffConfig = staffConfigMap.get(staff.getId());
+            if (Objects.isNull(staffConfig) || staffConfig.getSwitchFlag() != 1) {
+                continue;
+            }
             List<ThirdPartWeComRoom> roomList = weComThirdPartyService.getStaffRoomList(staff.getId());
             List<ThirdPartWeComRoom> roomList = weComThirdPartyService.getStaffRoomList(staff.getId());
-            for (ThirdPartWeComRoom room : roomList) {
-                if (room.getSendStatus() != 1) {
+            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));
+            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;
                     continue;
                 }
                 }
-                pool.execute(() -> {
-                    List<String> timeList = JSONObject.parseArray(room.getSendTime()).toJavaList(String.class);
-                    if (timeList.contains(time)) {
-                        // 选取视频
-                        List<CgiReplyBucketData> cgiReplyBucketDataList = getCgiReplyBucketData(room.getThirdRoomId(), staff);
+                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) {
                         for (CgiReplyBucketData cgiReplyBucketData : cgiReplyBucketDataList) {
                             // build发送体
                             // build发送体
-                            SendAppMsgRequest request = buildSendAppMsgRequest(cgiReplyBucketData, staff, room);
-                            // 发送消息
-                            weComThirdPartyService.sendAppMsg(request);
-                            // 存储消息
-                            saveWeComMsg(staff.getId(), cgiReplyBucketData.getMiniVideoId(), request);
+                            SendAppMsgRequest request = buildSendAppMsgRequest(cgiReplyBucketData, pushStaff, room);
+                            try {
+                                // 发送消息
+                                CommonResponse<SendAppMsgResponse> response = weComThirdPartyService.sendAppMsg(pushStaff, room, request);
+                                // 存储消息
+                                saveAppWeComMsg(pushStaff.getId(), cgiReplyBucketData.getMiniVideoId(), request, response);
+                            } catch (Exception e) {
+                                log.error("发送群消息失败,账号名称:{},账号VID:{},群名称:{},视频ID:{},request:{},异常信息:{}",
+                                        staff.getName(), staff.getThirdStaffId(), room.getName(),
+                                        cgiReplyBucketData.getMiniVideoId(), JSONObject.toJSONString(request), e.getMessage(), e);
+                            }
                         }
                         }
                     }
                     }
-                });
+                }
             }
             }
         }
         }
-        return ReturnT.SUCCESS;
+    }
+
+    private ThirdPartWeComStaff getSendStaff(ThirdPartWeComRoomConfig roomConfig) {
+        List<ThirdPartWeComStaff> pushStaffList = weComThirdPartyRoomService.getRoomConfigPushList(Collections.singletonList(roomConfig));
+        Map<Long, ThirdPartWeComStaff> pushStaffMap = pushStaffList.stream()
+                .collect(Collectors.toMap(ThirdPartWeComStaff::getThirdStaffId, Function.identity()));
+        ThirdPartWeComStaff pushStaff = pushStaffMap.get(roomConfig.getPrimaryThirdStaffId());
+        if (Objects.isNull(pushStaff) || pushStaff.getStatus() != ThirdPartWeComStaffStatusEnum.NORMAL.getVal()) {
+            if (Objects.nonNull(roomConfig.getSecondThirdStaffId())) {
+                pushStaff = pushStaffMap.get(roomConfig.getSecondThirdStaffId());
+                if (Objects.isNull(pushStaff) || pushStaff.getStatus() != ThirdPartWeComStaffStatusEnum.NORMAL.getVal()) {
+                    pushStaff = null;
+                }
+            } else {
+                pushStaff = null;
+            }
+        }
+        return pushStaff;
+    }
+
+    private List<String> getRoomSendTime(ThirdPartWeComRoom room,
+                                         ThirdPartWeComRoomConfig roomConfig,
+                                         ThirdPartWeComRoomConfigTask configTask) {
+        String key = "wecom:room:send:time:" + room.getThirdRoomId() + ":" + roomConfig.getId() + ":" + configTask.getId();
+        String timeStr = redisUtils.get(key);
+        if (StringUtils.isBlank(timeStr)) {
+            return JSONObject.parseArray(room.getSendTime()).toJavaList(String.class);
+        }
+        return JSONObject.parseArray(timeStr).toJavaList(String.class);
+    }
+
+    private SendTextMsgRequest buildSendTextMsgRequest(String content,
+                                                       ThirdPartWeComStaff staff,
+                                                       ThirdPartWeComRoom room) {
+        String thirdRoomId = room.getThirdRoomId();
+        SendTextMsgRequest request = new SendTextMsgRequest();
+        request.setUuid(staff.getThirdUuid());
+        request.setSend_userid(Long.valueOf(thirdRoomId));
+        request.setIsRoom(true);
+        request.setContent(content);
+        return request;
     }
     }
 
 
     private SendAppMsgRequest buildSendAppMsgRequest(CgiReplyBucketData cgiReplyBucketData,
     private SendAppMsgRequest buildSendAppMsgRequest(CgiReplyBucketData cgiReplyBucketData,
@@ -123,11 +255,8 @@ public class WeComSendMsgJob {
         request.setTitle(cgiReplyBucketData.getTitle());
         request.setTitle(cgiReplyBucketData.getTitle());
         request.setWeappIconUrl("http://rescdn.yishihui.com/temp/1755515422185_%E7%A5%A8%E5%9C%88Vlog_logo.jpg");
         request.setWeappIconUrl("http://rescdn.yishihui.com/temp/1755515422185_%E7%A5%A8%E5%9C%88Vlog_logo.jpg");
         // 填充视频信息
         // 填充视频信息
-        String coverUrl = cgiReplyBucketData.getCoverUrl();
-        // 实验 封面添加播放按钮水印
-        if (!testRoomList.contains(thirdRoomId)) {
-            coverUrl = addPlayWatermark(cgiReplyBucketData.getCoverUrl());
-        }
+        // 封面添加播放按钮水印
+        String coverUrl = addPlayWatermark(cgiReplyBucketData.getCoverUrl());
         request.setDesc(cgiReplyBucketData.getTitle());
         request.setDesc(cgiReplyBucketData.getTitle());
         request.setPagepath(cgiReplyBucketData.getMiniPagePath());
         request.setPagepath(cgiReplyBucketData.getMiniPagePath());
         CdnUploadImgLinkRequest cdnUploadImgLinkRequest = new CdnUploadImgLinkRequest();
         CdnUploadImgLinkRequest cdnUploadImgLinkRequest = new CdnUploadImgLinkRequest();
@@ -152,66 +281,54 @@ public class WeComSendMsgJob {
         return coverUrl + waterMark;
         return coverUrl + waterMark;
     }
     }
 
 
-    private List<CgiReplyBucketData> getCgiReplyBucketData(String roomId, ThirdPartWeComStaff thirdPartWeComStaff) {
-        String dt = planMapperExt.getVideoMaxDt();
-        String datastatDt = planMapperExt.getVideoDatastatMaxDt();
+    private List<CgiReplyBucketData> getCgiReplyBucketData(String roomId,
+                                                           ThirdPartWeComStaff thirdPartWeComStaff,
+                                                           ThirdPartWeComRoomConfig roomConfig,
+                                                           ThirdPartWeComRoomConfigTaskContent configTaskContent) {
         // 排除最近发送过的视频
         // 排除最近发送过的视频
         List<Long> sentVideoIds = getSentVideoIds(Long.valueOf(roomId));
         List<Long> sentVideoIds = getSentVideoIds(Long.valueOf(roomId));
-        // 按行业获取视频
-        String sort = "datastat.fission_rate desc, video.score desc";
-        String type = "企微-社群";
-        String channel = "sum";
-        List<ContentPlatformVideo> videoList = getVideoByStrategy(thirdPartWeComStaff.getThirdStaffId(), roomId, dt, datastatDt, type, channel, videoMinScore,
-                sentVideoIds, 1, 100, sort);
+        List<ContentPlatformVideo> videoList = getVideoByStrategy(roomId, videoMinScore, sentVideoIds,
+                configTaskContent, 1, 100);
         if (CollectionUtils.isEmpty(videoList)) {
         if (CollectionUtils.isEmpty(videoList)) {
             LarkRobotUtil.sendWeComThirdPartMessage(
             LarkRobotUtil.sendWeComThirdPartMessage(
                     "【账号发送群消息,视频数量不足通知】\n" +
                     "【账号发送群消息,视频数量不足通知】\n" +
                             "账号名称:" + thirdPartWeComStaff.getName() + "\n" +
                             "账号名称:" + thirdPartWeComStaff.getName() + "\n" +
                             "账号VID:" + thirdPartWeComStaff.getThirdStaffId() + "\n" +
                             "账号VID:" + thirdPartWeComStaff.getThirdStaffId() + "\n" +
                             "群ID:" + roomId + "\n" +
                             "群ID:" + roomId + "\n" +
-                            "账号配置:" + videoSourceStaffConfig.get(thirdPartWeComStaff.getId()));
+                            "账号配置:" + JSONObject.toJSONString(configTaskContent));
             return Collections.emptyList();
             return Collections.emptyList();
         }
         }
         List<CgiReplyBucketData> result = new ArrayList<>();
         List<CgiReplyBucketData> result = new ArrayList<>();
-        for (int i = 0; i < videoNum; i++) {
-            ContentPlatformVideo video = videoList.get(i);
-            Staff staff = new Staff();
-            staff.setCarrierId(String.valueOf(thirdPartWeComStaff.getThirdStaffId()));
-            staff.setRemark(thirdPartWeComStaff.getName());
-            String putScene = staffPutSceneConfig.getOrDefault(thirdPartWeComStaff.getThirdStaffId(), "touliu");
-            String page = messageAttachmentService.getPageNoCache(putScene, staff, video.getVideoId(), "企微", "社群");
+        ContentPlatformVideo video = videoList.get(0);
+        Staff staff = new Staff();
+        staff.setCarrierId(String.valueOf(thirdPartWeComStaff.getThirdStaffId()));
+        staff.setRemark(thirdPartWeComStaff.getName());
+        String putScene = StringUtils.isNotBlank(roomConfig.getPutScene()) ? roomConfig.getPutScene() : "touliu";
+        String pageChannel = StringUtils.isNotBlank(roomConfig.getChannel()) ? roomConfig.getChannel() : "tencentqw";
+        String page = messageAttachmentService.getPageNoCache(putScene, pageChannel, staff, video.getVideoId(), "企微", "社群");
+        page = videoMultiService.setVideoMultiTitleCoverPagePath(video.getVideoId(), page, video.getTitle(), video.getCover());
 
 
-            CgiReplyBucketData cgiReplyBucketData = new CgiReplyBucketData();
-            cgiReplyBucketData.setMiniVideoId(video.getVideoId());
-            cgiReplyBucketData.setTitle(video.getTitle());
-            cgiReplyBucketData.setCoverUrl(video.getCover());
-            cgiReplyBucketData.setMiniPagePath(page);
-            result.add(cgiReplyBucketData);
-        }
+        CgiReplyBucketData cgiReplyBucketData = new CgiReplyBucketData();
+        cgiReplyBucketData.setMiniVideoId(video.getVideoId());
+        cgiReplyBucketData.setTitle(video.getTitle());
+        cgiReplyBucketData.setCoverUrl(video.getCover());
+        cgiReplyBucketData.setMiniPagePath(page);
+        result.add(cgiReplyBucketData);
         return result;
         return result;
     }
     }
 
 
-    private List<ContentPlatformVideo> getVideoByStrategy(Long staffId,
-                                                          String roomId,
-                                                          String dt,
-                                                          String datastatDt,
-                                                          String type,
-                                                          String channel,
+    private List<ContentPlatformVideo> getVideoByStrategy(String roomId,
                                                           Double videoMinScore,
                                                           Double videoMinScore,
                                                           List<Long> sentVideoIds,
                                                           List<Long> sentVideoIds,
+                                                          ThirdPartWeComRoomConfigTaskContent configTaskContent,
                                                           int pageNum,
                                                           int pageNum,
-                                                          int pageSize,
-                                                          String sort) {
+                                                          int pageSize) {
         List<ContentPlatformVideo> result = new ArrayList<>();
         List<ContentPlatformVideo> result = new ArrayList<>();
-        JSONObject staffConfig = videoSourceStaffConfig.get(staffId);
-        if (staffConfig == null) {
-            staffConfig = new JSONObject();
-        }
         List<ContentPlatformVideo> videoList;
         List<ContentPlatformVideo> videoList;
-        String source = (String) staffConfig.getOrDefault("source", "");
-        switch (source) {
-            case "user":
-                Long uid = staffConfig.getLong("uid");
+        // 0-热榜 1-标签 2-账号
+        switch (configTaskContent.getSource()) {
+            case 2:
+                Long uid = Long.valueOf(configTaskContent.getSourceContent());
                 List<WxVideoV2VO> list = videoApiService.getUserVideoList(uid, sentVideoIds, pageNum, pageSize);
                 List<WxVideoV2VO> list = videoApiService.getUserVideoList(uid, sentVideoIds, pageNum, pageSize);
                 if (CollectionUtils.isEmpty(list)) {
                 if (CollectionUtils.isEmpty(list)) {
                     break;
                     break;
@@ -219,8 +336,8 @@ public class WeComSendMsgJob {
                 videoList = convertWxVideoV2VOToVideo(list);
                 videoList = convertWxVideoV2VOToVideo(list);
                 result.addAll(videoList);
                 result.addAll(videoList);
                 break;
                 break;
-            case "tag":
-                String tagName = staffConfig.getString("tagName");
+            case 1:
+                String tagName = configTaskContent.getSourceContent();
                 list = videoApiService.getTagVideoList(tagName, roomId, sentVideoIds, pageNum, pageSize);
                 list = videoApiService.getTagVideoList(tagName, roomId, sentVideoIds, pageNum, pageSize);
                 if (CollectionUtils.isEmpty(list)) {
                 if (CollectionUtils.isEmpty(list)) {
                     break;
                     break;
@@ -229,11 +346,9 @@ public class WeComSendMsgJob {
                 result.addAll(videoList);
                 result.addAll(videoList);
                 break;
                 break;
             default:
             default:
-                result = planMapperExt.getVideoMinDatastatScoreList(dt, datastatDt,
-                        type, channel, "normal", videoMinScore, sentVideoIds, 0, 100, sort);
-                // 行业数量不足,按平台推荐top选取视频
-                sort = "video.score desc";
-                result.addAll(planMapperExt.getVideoMinScoreList(dt, videoMinScore, sentVideoIds, 0, 100, sort));
+                // 按平台推荐top选取视频
+                String dt = videoMapperExt.getVideoMaxDt();
+                result.addAll(videoMapperExt.getVideoMinScoreList(dt, videoMinScore, roomId, 0, 100, "video.score desc"));
         }
         }
         return result;
         return result;
     }
     }
@@ -253,17 +368,19 @@ public class WeComSendMsgJob {
     private List<Long> getSentVideoIds(Long roomId) {
     private List<Long> getSentVideoIds(Long roomId) {
         ThirdPartWeComMsgExample msgExample = new ThirdPartWeComMsgExample();
         ThirdPartWeComMsgExample msgExample = new ThirdPartWeComMsgExample();
         msgExample.createCriteria().andSendUseridEqualTo(roomId)
         msgExample.createCriteria().andSendUseridEqualTo(roomId)
-                .andCreateTimeGreaterThan(DateUtil.getDaysAgoDate(duplicateDays));
+                .andCreateTimeGreaterThan(DateUtil.getDaysAgoDate(duplicateDays))
+                .andVideoIdIsNotNull();
         List<ThirdPartWeComMsg> msgList = msgMapper.selectByExample(msgExample);
         List<ThirdPartWeComMsg> msgList = msgMapper.selectByExample(msgExample);
         return msgList.stream().map(ThirdPartWeComMsg::getVideoId).collect(Collectors.toList());
         return msgList.stream().map(ThirdPartWeComMsg::getVideoId).collect(Collectors.toList());
     }
     }
 
 
-    private void saveWeComMsg(Long staffId, Long videoId, SendAppMsgRequest request) {
+    private void saveAppWeComMsg(Long staffId, Long videoId, SendAppMsgRequest request, CommonResponse<SendAppMsgResponse> response) {
         ThirdPartWeComMsg msg = new ThirdPartWeComMsg();
         ThirdPartWeComMsg msg = new ThirdPartWeComMsg();
         msg.setStaffId(staffId);
         msg.setStaffId(staffId);
         msg.setVideoId(videoId);
         msg.setVideoId(videoId);
         msg.setUuid(request.getUuid());
         msg.setUuid(request.getUuid());
         msg.setSendUserid(request.getSend_userid());
         msg.setSendUserid(request.getSend_userid());
+        msg.setSendType(ConfigTaskContentTypeEnum.MINI_PROGRAM.getVal());
         msg.setIsroom(request.getIsRoom());
         msg.setIsroom(request.getIsRoom());
         msg.setAppid(request.getAppid());
         msg.setAppid(request.getAppid());
         msg.setUsername(request.getUsername());
         msg.setUsername(request.getUsername());
@@ -277,15 +394,39 @@ public class WeComSendMsgJob {
         msg.setMd5(request.getMd5());
         msg.setMd5(request.getMd5());
         msg.setAeskey(request.getAeskey());
         msg.setAeskey(request.getAeskey());
         msg.setFilesize(request.getFileSize());
         msg.setFilesize(request.getFileSize());
+        if (response.getErrcode() == 0) {
+            msg.setStatus(MsgSendStatusEnum.NORMAL.getVal());
+        } else {
+            msg.setStatus(MsgSendStatusEnum.FAIL.getVal());
+        }
         msgMapper.insertSelective(msg);
         msgMapper.insertSelective(msg);
     }
     }
 
 
+    private void saveTextWeComMsg(Long staffId, String content, SendTextMsgRequest request, CommonResponse<SendTextMsgResponse> response) {
+        ThirdPartWeComMsg msg = new ThirdPartWeComMsg();
+        msg.setStaffId(staffId);
+        msg.setUuid(request.getUuid());
+        msg.setSendUserid(request.getSend_userid());
+        msg.setSendType(ConfigTaskContentTypeEnum.TEXT.getVal());
+        msg.setContent(content);
+        msg.setIsroom(request.getIsRoom());
+        if (response.getErrcode() == 0) {
+            msg.setStatus(MsgSendStatusEnum.NORMAL.getVal());
+        } else {
+            msg.setStatus(MsgSendStatusEnum.FAIL.getVal());
+        }
+        msgMapper.insertSelective(msg);
+    }
 
 
     @XxlJob("autoOpenSendStatusJob")
     @XxlJob("autoOpenSendStatusJob")
     public ReturnT<String> autoOpenSendStatusJob(String param) {
     public ReturnT<String> autoOpenSendStatusJob(String param) {
         List<ThirdPartWeComStaff> activeStaffList = weComThirdPartyService.getActiveStaffList();
         List<ThirdPartWeComStaff> activeStaffList = weComThirdPartyService.getActiveStaffList();
+        List<Long> staffIdList = activeStaffList.stream().map(ThirdPartWeComStaff::getId).collect(Collectors.toList());
+        List<ThirdPartWeComStaffConfig> staffConfigList = weComThirdPartyAccountService.getStaffConfigListByStaffIds(staffIdList);
+        Map<Long, ThirdPartWeComStaffConfig> staffConfigMap = staffConfigList.stream().collect(Collectors.toMap(ThirdPartWeComStaffConfig::getStaffId, a -> a));
         for (ThirdPartWeComStaff staff : activeStaffList) {
         for (ThirdPartWeComStaff staff : activeStaffList) {
-            if (!autoOpenStaffList.contains(staff.getThirdStaffId())) {
+            ThirdPartWeComStaffConfig staffConfig = staffConfigMap.get(staff.getId());
+            if (Objects.isNull(staffConfig) || staffConfig.getSwitchFlag() != 1 || Objects.isNull(staffConfig.getOpenRoomSendSwitchNum())) {
                 continue;
                 continue;
             }
             }
             List<ThirdPartWeComRoom> roomList = weComThirdPartyService.getStaffRoomList(staff.getId());
             List<ThirdPartWeComRoom> roomList = weComThirdPartyService.getStaffRoomList(staff.getId());
@@ -293,7 +434,7 @@ public class WeComSendMsgJob {
                 if (room.getSendStatus() == 1) {
                 if (room.getSendStatus() == 1) {
                     continue;
                     continue;
                 }
                 }
-                if (room.getMemberCount() > 20) {
+                if (room.getMemberCount() > staffConfig.getOpenRoomSendSwitchNum()) {
                     room.setSendStatus(1);
                     room.setSendStatus(1);
                     roomMapper.updateByPrimaryKeySelective(room);
                     roomMapper.updateByPrimaryKeySelective(room);
                 }
                 }
@@ -301,4 +442,74 @@ public class WeComSendMsgJob {
         }
         }
         return ReturnT.SUCCESS;
         return ReturnT.SUCCESS;
     }
     }
+
+    @XxlJob("randomRoomSendTimeJob")
+    public ReturnT<String> randomRoomSendTimeJob(String param) {
+        List<ThirdPartWeComStaff> activeStaffList = weComThirdPartyService.getActiveStaffList();
+        String now = DateUtil.getCurrentDateStr("HH:mm");
+        for (ThirdPartWeComStaff staff : activeStaffList) {
+            List<ThirdPartWeComRoom> roomList = weComThirdPartyService.getStaffRoomList(staff.getId());
+            List<ThirdPartWeComRoomConfig> roomConfigList = weComThirdPartyRoomService.getRoomConfigListByRoomIds(roomList.stream().map(ThirdPartWeComRoom::getId).collect(Collectors.toList()));
+            Map<Long, ThirdPartWeComRoomConfig> roomConfigMap = roomConfigList.stream().collect(Collectors.toMap(ThirdPartWeComRoomConfig::getRoomId, Function.identity()));
+            List<String> configIds = roomConfigList.stream().map(ThirdPartWeComRoomConfig::getId).map(String::valueOf).collect(Collectors.toList());
+            List<ThirdPartWeComRoomConfigTask> roomConfigTaskList = weComThirdPartyRoomService.getRoomConfigTasks(configIds);
+            Map<String, List<ThirdPartWeComRoomConfigTask>> roomConfigTaskMap = roomConfigTaskList.stream().collect(Collectors.groupingBy(ThirdPartWeComRoomConfigTask::getConfigId));
+            for (ThirdPartWeComRoom room : roomList) {
+                ThirdPartWeComRoomConfig roomConfig = roomConfigMap.get(room.getId());
+                if (roomConfig == null) {
+                    continue;
+                }
+                List<ThirdPartWeComRoomConfigTask> taskList = roomConfigTaskMap.getOrDefault(roomConfig.getId(), new ArrayList<>());
+                if (taskList.isEmpty()) {
+                    continue;
+                }
+                randomRoomSendTime(room, roomConfig, taskList, now);
+            }
+        }
+        return ReturnT.SUCCESS;
+    }
+
+    public void randomRoomSendTime(ThirdPartWeComRoom room,
+                                   ThirdPartWeComRoomConfig roomConfig,
+                                   List<ThirdPartWeComRoomConfigTask> taskList,
+                                   String now) {
+        for (ThirdPartWeComRoomConfigTask configTask : taskList) {
+            String key = "wecom:room:send:time:" + room.getThirdRoomId() + ":" + roomConfig.getId() + ":" + configTask.getId();
+            if (redisUtils.containsKey(key)) {
+                continue;
+            }
+            List<String> timeList = JSONObject.parseArray(room.getSendTime()).toJavaList(String.class);
+            // 判断timeList中在now之后的时间,随机增加或减少20以内的分钟数
+            List<String> newTimeList = new ArrayList<>();
+            for (String time : timeList) {
+                // time与now比较,判断是否在now之后
+                int hour = Integer.parseInt(time.substring(0, 2));
+                int minute = Integer.parseInt(time.substring(3, 5));
+                int nowHour = Integer.parseInt(now.substring(0, 2));
+                int nowMinute = Integer.parseInt(now.substring(3, 5));
+                if (hour < nowHour || (hour == nowHour && minute <= nowMinute)) {
+                    newTimeList.add(time);
+                    continue;
+                }
+                // 增加或减少20以内的分钟数 -20~20
+                int randomTimeRange = Objects.isNull(configTask.getRandomMin()) ? 0 : configTask.getRandomMin();
+                int randomMinute = randomTimeRange == 0 ? 0 : new Random().nextInt(randomTimeRange * 2) - randomTimeRange;
+                minute += randomMinute;
+                if (minute < 0) {
+                    hour--;
+                    minute += 60;
+                } else if (minute >= 60) {
+                    hour++;
+                    minute -= 60;
+                }
+                // 确保时间在now之后
+                if (hour < nowHour || (hour == nowHour && minute <= nowMinute)) {
+                    newTimeList.add(time);
+                    continue;
+                }
+                newTimeList.add(String.format("%02d:%02d", hour, minute));
+            }
+            redisUtils.set(key, JSONObject.toJSONString(newTimeList), 18 * 60 * 60);
+        }
+    }
 }
 }

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

@@ -2,17 +2,21 @@ package com.tzld.piaoquan.api.job.wecom.thirdpart;
 
 
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.TypeReference;
 import com.alibaba.fastjson.TypeReference;
+import com.google.common.collect.Lists;
 import com.google.common.util.concurrent.ThreadFactoryBuilder;
 import com.google.common.util.concurrent.ThreadFactoryBuilder;
 import com.tzld.piaoquan.api.component.WeComThirdPartyApiClient;
 import com.tzld.piaoquan.api.component.WeComThirdPartyApiClient;
-import com.tzld.piaoquan.api.controller.GetRoomUserListResponse;
 import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ThirdPartWeComRoomMapper;
 import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ThirdPartWeComRoomMapper;
 import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ThirdPartWeComRoomUserMapper;
 import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ThirdPartWeComRoomUserMapper;
 import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ThirdPartWeComStaffMapper;
 import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ThirdPartWeComStaffMapper;
 import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ThirdPartWeComStaffUserMapper;
 import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ThirdPartWeComStaffUserMapper;
 import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ext.ThirdPartWeComMapperExt;
 import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ext.ThirdPartWeComMapperExt;
+import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ext.ThirdPartWeComRoomMapperExt;
 import com.tzld.piaoquan.api.model.param.wecom.thirdpart.*;
 import com.tzld.piaoquan.api.model.param.wecom.thirdpart.*;
 import com.tzld.piaoquan.api.model.po.wecom.thirdpart.*;
 import com.tzld.piaoquan.api.model.po.wecom.thirdpart.*;
-import com.tzld.piaoquan.api.service.WeComThirdPartyService;
+import com.tzld.piaoquan.api.model.vo.wecom.thirdpart.ThirdPartyAccountConfigVO;
+import com.tzld.piaoquan.api.service.wecom.thirdparty.WeComThirdPartyAccountService;
+import com.tzld.piaoquan.api.service.wecom.thirdparty.WeComThirdPartyRoomService;
+import com.tzld.piaoquan.api.service.wecom.thirdparty.WeComThirdPartyService;
 import com.tzld.piaoquan.growth.common.utils.RedisUtils;
 import com.tzld.piaoquan.growth.common.utils.RedisUtils;
 import com.xxl.job.core.biz.model.ReturnT;
 import com.xxl.job.core.biz.model.ReturnT;
 import com.xxl.job.core.handler.annotation.XxlJob;
 import com.xxl.job.core.handler.annotation.XxlJob;
@@ -33,6 +37,10 @@ public class WeComUserDetailJob {
     @Autowired
     @Autowired
     WeComThirdPartyService thirdPartyService;
     WeComThirdPartyService thirdPartyService;
     @Autowired
     @Autowired
+    WeComThirdPartyAccountService thirdPartyAccountService;
+    @Autowired
+    WeComThirdPartyRoomService thirdPartyRoomService;
+    @Autowired
     WeComThirdPartyApiClient apiClient;
     WeComThirdPartyApiClient apiClient;
     @Autowired
     @Autowired
     ThirdPartWeComStaffMapper staffMapper;
     ThirdPartWeComStaffMapper staffMapper;
@@ -44,6 +52,8 @@ public class WeComUserDetailJob {
     ThirdPartWeComRoomUserMapper roomUserMapper;
     ThirdPartWeComRoomUserMapper roomUserMapper;
     @Autowired
     @Autowired
     ThirdPartWeComMapperExt thirdPartWeComMapperExt;
     ThirdPartWeComMapperExt thirdPartWeComMapperExt;
+    @Autowired
+    ThirdPartWeComRoomMapperExt thirdPartWeComRoomMapperExt;
 
 
     @Autowired
     @Autowired
     private RedisUtils redisUtils;
     private RedisUtils redisUtils;
@@ -58,7 +68,7 @@ public class WeComUserDetailJob {
     private Boolean autoSendMsg;
     private Boolean autoSendMsg;
 
 
     private final static ExecutorService pool = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.SECONDS,
     private final static ExecutorService pool = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.SECONDS,
-            new LinkedBlockingQueue<>(1000),
+            new LinkedBlockingQueue<>(10000),
             new ThreadFactoryBuilder().setNameFormat("SyncUserDetailJob-%d").build(),
             new ThreadFactoryBuilder().setNameFormat("SyncUserDetailJob-%d").build(),
             new ThreadPoolExecutor.AbortPolicy());
             new ThreadPoolExecutor.AbortPolicy());
 
 
@@ -69,23 +79,7 @@ public class WeComUserDetailJob {
         for (ThirdPartWeComStaff staff : activeStaffList) {
         for (ThirdPartWeComStaff staff : activeStaffList) {
             pool.execute(() -> {
             pool.execute(() -> {
                 try {
                 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.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) {
                 } catch (Exception e) {
                     log.error("syncUserDetail error", e);
                     log.error("syncUserDetail error", e);
                 } finally {
                 } finally {
@@ -101,6 +95,37 @@ public class WeComUserDetailJob {
         return ReturnT.SUCCESS;
         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) {
     private void syncStaffUserList(ThirdPartWeComStaff staff) {
         List<ExternalContactsResponse.ContactItem> contactItemList = thirdPartyService.getExternalContacts(
         List<ExternalContactsResponse.ContactItem> contactItemList = thirdPartyService.getExternalContacts(
                 new GetExternalContactsRequest(staff.getThirdUuid(), 100, 0));
                 new GetExternalContactsRequest(staff.getThirdUuid(), 100, 0));
@@ -111,13 +136,33 @@ public class WeComUserDetailJob {
         List<ThirdPartWeComStaffUser> existUserList = getThirdPartWeComStaffUserListByStaffId(thirdStaffId);
         List<ThirdPartWeComStaffUser> existUserList = getThirdPartWeComStaffUserListByStaffId(thirdStaffId);
         List<Long> existUserIdList = existUserList.stream().map(ThirdPartWeComStaffUser::getUserId).collect(Collectors.toList());
         List<Long> existUserIdList = existUserList.stream().map(ThirdPartWeComStaffUser::getUserId).collect(Collectors.toList());
         Map<Long, ThirdPartWeComStaffUser> existUserMap = existUserList.stream()
         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> saveList = new ArrayList<>();
+        List<ThirdPartWeComStaffUser> updateList = new ArrayList<>();
         for (ExternalContactsResponse.ContactItem contactItem : contactItemList) {
         for (ExternalContactsResponse.ContactItem contactItem : contactItemList) {
             if (existUserIdList.contains(contactItem.getUser_id())) {
             if (existUserIdList.contains(contactItem.getUser_id())) {
+                //0 互相删除 8主动删除拉黑  2049被删除  其他的都是好友
+                List<Integer> deleteStatusList = Arrays.asList(0, 8, 2049);
                 ThirdPartWeComStaffUser existUser = existUserMap.get(contactItem.getUser_id());
                 ThirdPartWeComStaffUser existUser = existUserMap.get(contactItem.getUser_id());
                 existUser.setUpdateTime(new Date());
                 existUser.setUpdateTime(new Date());
-
+                if (Objects.isNull(existUser.getRemoveCustomerTime()) && deleteStatusList.contains(contactItem.getStatus())) {
+                    if (!deleteStatusList.contains(existUser.getStatus())) {
+                        existUser.setRemoveCustomerTime(System.currentTimeMillis() / 1000);
+                    } else {
+                        // 历史已删除,设为前一天
+                        existUser.setRemoveCustomerTime((System.currentTimeMillis() / 1000) - 86400);
+                    }
+                }
+                existUser.setAddCustomerTime(contactItem.getAdd_customer_time());
                 existUser.setUnionid(contactItem.getUnionid());
                 existUser.setUnionid(contactItem.getUnionid());
                 existUser.setSex(contactItem.getSex());
                 existUser.setSex(contactItem.getSex());
                 existUser.setMobile(contactItem.getMobile());
                 existUser.setMobile(contactItem.getMobile());
@@ -137,7 +182,8 @@ public class WeComUserDetailJob {
                 existUser.setSeq(contactItem.getSeq());
                 existUser.setSeq(contactItem.getSeq());
                 existUser.setStatus(contactItem.getStatus());
                 existUser.setStatus(contactItem.getStatus());
 
 
-                staffUserMapper.updateByPrimaryKeySelective(existUser);
+                //staffUserMapper.updateByPrimaryKeySelective(existUser);
+                updateList.add(existUser);
             } else {
             } else {
                 ThirdPartWeComStaffUser staffUser = new ThirdPartWeComStaffUser();
                 ThirdPartWeComStaffUser staffUser = new ThirdPartWeComStaffUser();
                 staffUser.setThirdStaffId(thirdStaffId);
                 staffUser.setThirdStaffId(thirdStaffId);
@@ -145,6 +191,7 @@ public class WeComUserDetailJob {
                 staffUser.setUpdateTime(new Date());
                 staffUser.setUpdateTime(new Date());
 
 
                 // 从ContactItem对象复制所有字段值
                 // 从ContactItem对象复制所有字段值
+                staffUser.setAddCustomerTime(contactItem.getAdd_customer_time());
                 staffUser.setUnionid(contactItem.getUnionid());
                 staffUser.setUnionid(contactItem.getUnionid());
                 staffUser.setSex(contactItem.getSex());
                 staffUser.setSex(contactItem.getSex());
                 staffUser.setMobile(contactItem.getMobile());
                 staffUser.setMobile(contactItem.getMobile());
@@ -168,7 +215,16 @@ public class WeComUserDetailJob {
             }
             }
         }
         }
         if (CollectionUtils.isNotEmpty(saveList)) {
         if (CollectionUtils.isNotEmpty(saveList)) {
-            thirdPartWeComMapperExt.batchInsertThirdPartWeComStaffUser(saveList);
+            List<List<ThirdPartWeComStaffUser>> partitionList = Lists.partition(saveList, 500);
+            for (List<ThirdPartWeComStaffUser> partition : partitionList) {
+                thirdPartWeComMapperExt.batchInsertThirdPartWeComStaffUser(partition);
+            }
+        }
+        if (CollectionUtils.isNotEmpty(updateList)) {
+            List<List<ThirdPartWeComStaffUser>> partitionList = Lists.partition(updateList, 200);
+            for (List<ThirdPartWeComStaffUser> partition : partitionList) {
+                thirdPartWeComMapperExt.batchUpdateThirdPartWeComStaffUser(partition);
+            }
         }
         }
     }
     }
 
 
@@ -206,6 +262,8 @@ public class WeComUserDetailJob {
         List<ThirdPartWeComRoom> roomList = thirdPartyService.getStaffRoomList(staff.getId());
         List<ThirdPartWeComRoom> roomList = thirdPartyService.getStaffRoomList(staff.getId());
         Map<String, ThirdPartWeComRoom> roomMap = roomList.stream()
         Map<String, ThirdPartWeComRoom> roomMap = roomList.stream()
                 .collect(Collectors.toMap(ThirdPartWeComRoom::getThirdRoomId, room -> room));
                 .collect(Collectors.toMap(ThirdPartWeComRoom::getThirdRoomId, room -> room));
+        List<ThirdPartWeComRoom> saveList = new ArrayList<>();
+        List<ThirdPartWeComRoom> updateList = new ArrayList<>();
         for (GetChatroomMembersResponse.RoomInfo roomInfo : roomInfoList) {
         for (GetChatroomMembersResponse.RoomInfo roomInfo : roomInfoList) {
             String roomId = roomInfo.getRoom_id();
             String roomId = roomInfo.getRoom_id();
             ThirdPartWeComRoom roomDetail = roomMap.get(roomId);
             ThirdPartWeComRoom roomDetail = roomMap.get(roomId);
@@ -220,27 +278,43 @@ public class WeComUserDetailJob {
                 roomDetail.setName(roomInfo.getNickname());
                 roomDetail.setName(roomInfo.getNickname());
                 roomDetail.setAddUserStatus(0);
                 roomDetail.setAddUserStatus(0);
                 roomDetail.setSendStatus(0);
                 roomDetail.setSendStatus(0);
+                roomDetail.setRoomCreateTime(roomInfo.getCreate_time());
                 roomDetail.setCreateTime(new Date());
                 roomDetail.setCreateTime(new Date());
                 roomDetail.setUpdateTime(new Date());
                 roomDetail.setUpdateTime(new Date());
-                roomMapper.insertSelective(roomDetail);
+                //roomMapper.insertSelective(roomDetail);
+                saveList.add(roomDetail);
             } else {
             } else {
                 roomDetail.setRoomUrl(roomInfo.getRoomurl());
                 roomDetail.setRoomUrl(roomInfo.getRoomurl());
                 roomDetail.setThirdRoomId(roomInfo.getRoom_id());
                 roomDetail.setThirdRoomId(roomInfo.getRoom_id());
                 roomDetail.setThirdCreateUserId(roomInfo.getCreate_user_id());
                 roomDetail.setThirdCreateUserId(roomInfo.getCreate_user_id());
                 roomDetail.setMemberCount(roomInfo.getTotal());
                 roomDetail.setMemberCount(roomInfo.getTotal());
                 roomDetail.setName(roomInfo.getNickname());
                 roomDetail.setName(roomInfo.getNickname());
+                roomDetail.setRoomCreateTime(roomInfo.getCreate_time());
                 roomDetail.setUpdateTime(new Date());
                 roomDetail.setUpdateTime(new Date());
                 if (staff.getAutoCreateRoom() == 1) {
                 if (staff.getAutoCreateRoom() == 1) {
                     if (roomDetail.getMemberCount() >= memberMaxNums) {
                     if (roomDetail.getMemberCount() >= memberMaxNums) {
                         roomDetail.setAddUserStatus(0);
                         roomDetail.setAddUserStatus(0);
                     }
                     }
-                    if (roomDetail.getMemberCount() >= sendMsgStatusNums && autoSendMsg) {
-                        roomDetail.setSendStatus(1);
-                    }
                 }
                 }
-                roomMapper.updateByPrimaryKeySelective(roomDetail);
+                //roomMapper.updateByPrimaryKeySelective(roomDetail);
+                updateList.add(roomDetail);
+            }
+        }
+        if (CollectionUtils.isNotEmpty(saveList)) {
+            List<List<ThirdPartWeComRoom>> partitionList = Lists.partition(saveList, 500);
+            for (List<ThirdPartWeComRoom> partition : partitionList) {
+                thirdPartWeComMapperExt.batchInsertThirdPartWeComRoom(partition);
             }
             }
-            syncRoomUserList(staff.getThirdUuid(), roomDetail.getThirdRoomId());
+            new Thread(() -> batchSaveRoomConfig(staff)).start();
+        }
+        if (CollectionUtils.isNotEmpty(updateList)) {
+            List<List<ThirdPartWeComRoom>> partitionList = Lists.partition(updateList, 200);
+            for (List<ThirdPartWeComRoom> partition : partitionList) {
+                thirdPartWeComMapperExt.batchUpdateThirdPartWeComRoom(partition);
+            }
+        }
+        for (GetChatroomMembersResponse.RoomInfo roomInfo : roomInfoList) {
+            syncRoomUserList(staff.getThirdUuid(), roomInfo.getRoom_id());
         }
         }
         List<String> roomIds = roomInfoList.stream().map(GetChatroomMembersResponse.RoomInfo::getRoom_id).collect(Collectors.toList());
         List<String> roomIds = roomInfoList.stream().map(GetChatroomMembersResponse.RoomInfo::getRoom_id).collect(Collectors.toList());
         roomList.removeIf(room -> roomIds.contains(room.getThirdRoomId()));
         roomList.removeIf(room -> roomIds.contains(room.getThirdRoomId()));
@@ -253,15 +327,30 @@ public class WeComUserDetailJob {
         }
         }
     }
     }
 
 
+    private void batchSaveRoomConfig(ThirdPartWeComStaff staff) {
+        ThirdPartyAccountConfigVO accountConfig = thirdPartyAccountService.getAccountConfig(new ThirdPartyConfigGetParam(staff.getId()));
+        if (Objects.isNull(accountConfig)) {
+            return;
+        }
+        List<ThirdPartWeComRoom> noConfigRoomList = thirdPartWeComRoomMapperExt.getNoConfigRoomList(staff.getId());
+        if (CollectionUtils.isNotEmpty(noConfigRoomList)) {
+            for (ThirdPartWeComRoom room : noConfigRoomList) {
+                thirdPartyRoomService.saveRoomConfig(room, accountConfig.getId(), accountConfig);
+            }
+        }
+    }
+
     public void syncRoomUserList(String uuid, String thirdRoomId) {
     public void syncRoomUserList(String uuid, String thirdRoomId) {
         GetRoomUserListRequest request = new GetRoomUserListRequest(uuid, Long.valueOf(thirdRoomId));
         GetRoomUserListRequest request = new GetRoomUserListRequest(uuid, Long.valueOf(thirdRoomId));
         List<GetRoomUserListResponse.Member> userList = thirdPartyService.getRoomUserList(request);
         List<GetRoomUserListResponse.Member> userList = thirdPartyService.getRoomUserList(request);
+        List<Long> currentUniList = userList.stream().map(GetRoomUserListResponse.Member::getUin).collect(Collectors.toList());
         List<ThirdPartWeComRoomUser> existUserList = getThirdPartWeComRoomUserListByRoomId(thirdRoomId);
         List<ThirdPartWeComRoomUser> existUserList = getThirdPartWeComRoomUserListByRoomId(thirdRoomId);
         List<Long> existUserIdList = existUserList.stream().map(ThirdPartWeComRoomUser::getUin).collect(Collectors.toList());
         List<Long> existUserIdList = existUserList.stream().map(ThirdPartWeComRoomUser::getUin).collect(Collectors.toList());
         Map<Long, ThirdPartWeComRoomUser> existUserMap = existUserList.stream()
         Map<Long, ThirdPartWeComRoomUser> existUserMap = existUserList.stream()
                 .collect(Collectors.toMap(ThirdPartWeComRoomUser::getUin, roomUser -> roomUser, (a, b) -> a));
                 .collect(Collectors.toMap(ThirdPartWeComRoomUser::getUin, roomUser -> roomUser, (a, b) -> a));
 
 
         List<ThirdPartWeComRoomUser> saveList = new ArrayList<>();
         List<ThirdPartWeComRoomUser> saveList = new ArrayList<>();
+        List<ThirdPartWeComRoomUser> updateList = new ArrayList<>();
         for (GetRoomUserListResponse.Member user : userList) {
         for (GetRoomUserListResponse.Member user : userList) {
             if (existUserIdList.contains(user.getUin())) {
             if (existUserIdList.contains(user.getUin())) {
                 ThirdPartWeComRoomUser existUser = existUserMap.get(user.getUin());
                 ThirdPartWeComRoomUser existUser = existUserMap.get(user.getUin());
@@ -284,7 +373,8 @@ public class WeComUserDetailJob {
                 existUser.setInviteUserId(user.getInvite_user_id());
                 existUser.setInviteUserId(user.getInvite_user_id());
                 existUser.setCorpId(user.getCorp_id());
                 existUser.setCorpId(user.getCorp_id());
 
 
-                roomUserMapper.updateByPrimaryKeySelective(existUser);
+                //roomUserMapper.updateByPrimaryKeySelective(existUser);
+                updateList.add(existUser);
             } else {
             } else {
                 ThirdPartWeComRoomUser roomUser = new ThirdPartWeComRoomUser();
                 ThirdPartWeComRoomUser roomUser = new ThirdPartWeComRoomUser();
                 roomUser.setThirdRoomId(thirdRoomId);
                 roomUser.setThirdRoomId(thirdRoomId);
@@ -313,7 +403,26 @@ public class WeComUserDetailJob {
             }
             }
         }
         }
         if (CollectionUtils.isNotEmpty(saveList)) {
         if (CollectionUtils.isNotEmpty(saveList)) {
-            thirdPartWeComMapperExt.batchInsertThirdPartWeComRoomUser(saveList);
+            List<List<ThirdPartWeComRoomUser>> partitionList = Lists.partition(saveList, 500);
+            for (List<ThirdPartWeComRoomUser> partition : partitionList) {
+                thirdPartWeComMapperExt.batchInsertThirdPartWeComRoomUser(partition);
+            }
+        }
+        if (CollectionUtils.isNotEmpty(updateList)) {
+            List<List<ThirdPartWeComRoomUser>> partitionList = Lists.partition(updateList, 200);
+            for (List<ThirdPartWeComRoomUser> partition : partitionList) {
+                thirdPartWeComMapperExt.batchUpdateThirdPartWeComRoomUser(partition);
+            }
+        }
+        // 删除不存在的用户
+        List<Long> deleteList = existUserList.stream()
+                .filter(user -> Objects.isNull(user.getQuitTime()))
+                .map(ThirdPartWeComRoomUser::getUin)
+                .filter(uin -> !currentUniList.contains(uin))
+                .collect(Collectors.toList());
+        if (CollectionUtils.isNotEmpty(deleteList)) {
+            Long quitTime = System.currentTimeMillis() / 1000;
+            thirdPartWeComMapperExt.setRoomUserQuitTime(thirdRoomId, deleteList, quitTime);
         }
         }
     }
     }
 
 

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

@@ -0,0 +1,215 @@
+package com.tzld.piaoquan.api.job.wecom.thirdpart;
+
+import com.aliyun.odps.data.Record;
+import com.google.common.collect.Lists;
+import com.tzld.piaoquan.api.dao.mapper.contentplatform.ContentPlatformIllegalVideoMapper;
+import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ThirdPartWeComVideoMapper;
+import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ext.ThirdPartWeComVideoMapperExt;
+import com.tzld.piaoquan.api.model.po.contentplatform.ContentPlatformIllegalVideo;
+import com.tzld.piaoquan.api.model.po.contentplatform.ContentPlatformIllegalVideoExample;
+import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComVideo;
+import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComVideoExample;
+import com.tzld.piaoquan.api.util.CdnUtil;
+import com.tzld.piaoquan.growth.common.model.bo.VideoDetail;
+import com.tzld.piaoquan.growth.common.service.MessageAttachmentService;
+import com.tzld.piaoquan.growth.common.utils.DateUtil;
+import com.tzld.piaoquan.growth.common.utils.OdpsUtil;
+import com.xxl.job.core.biz.model.ReturnT;
+import com.xxl.job.core.handler.annotation.XxlJob;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Component
+public class WeComVideoJob {
+
+    @Autowired
+    private ThirdPartWeComVideoMapperExt videoMapperExt;
+    @Autowired
+    private ThirdPartWeComVideoMapper videoMapper;
+    @Autowired
+    private ContentPlatformIllegalVideoMapper illegalVideoMapper;
+    @Autowired
+    private MessageAttachmentService messageAttachmentService;
+
+
+    @XxlJob("syncThirdPartWeComVideoJob")
+    public ReturnT<String> syncThirdPartWeComVideoJob(String param) {
+        String dt = DateUtil.getBeforeDayDateString("yyyyMMdd");
+        if (StringUtils.hasText(param)) {
+            dt = param;
+        }
+
+        String maxDt = videoMapperExt.getVideoMaxDt();
+        if (StringUtils.hasText(maxDt) && maxDt.equals(dt)) {
+            return ReturnT.SUCCESS;
+        }
+        String sql = String.format("SELECT 视频id, 视频品类, 视频标题, 视频播放地址, 分数 " +
+                "FROM loghubods.wecom_cooperation_video_candidate_pool_20251125 WHERE dt=%s;", dt);
+        List<Record> dataList = OdpsUtil.getOdpsData(sql);
+        Long now = System.currentTimeMillis();
+        if (CollectionUtils.isNotEmpty(dataList)) {
+            List<ThirdPartWeComVideo> saveList = new ArrayList<>();
+            List<Long> existVideoIds = new ArrayList<>();
+            for (Record record : dataList) {
+                ThirdPartWeComVideo item = new ThirdPartWeComVideo();
+                Long videoId = Long.parseLong((String) record.get(0));
+                if (existVideoIds.contains(videoId)) {
+                    continue;
+                }
+                existVideoIds.add(videoId);
+                String category = (String) record.get(1);
+                String title = (String) record.get(2);
+                String videoUrl = (String) record.get(3);
+                Double score = Double.parseDouble((String) record.get(4));
+                item.setDt(dt);
+                item.setVideoId(videoId);
+                item.setCategory(category);
+                item.setTitle(title);
+                item.setVideo(videoUrl);
+                item.setScore(score);
+                item.setCreateTimestamp(now);
+                saveList.add(item);
+            }
+            // 获取视频封面
+            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);
+                    }
+                }
+            }
+        }
+    }
+
+    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)) {
+                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.isNull(detail)) {
+                        continue;
+                    }
+                    String cover = detail.getCover().substring(0, detail.getCover().indexOf("/watermark"));
+                    if (!cover.startsWith(CdnUtil.VIDEO_CDN_URL_HOST)
+                            && StringUtils.hasText(detail.getVideoCoverSnapshotPath())
+                            && detail.getVideoCoverSnapshotPath().startsWith(CdnUtil.VIDEO_CDN_URL_HOST)) {
+                        cover = detail.getVideoCoverSnapshotPath() + cover.substring(cover.indexOf("?"));
+                    }
+                    item.setCover(cover);
+                    if (detail.getAuditStatus() != 5) {
+                        item.setStatus(0);
+                    }
+                    videoMapper.updateByPrimaryKeySelective(item);
+                }
+            }
+        }
+    }
+
+    private List<ContentPlatformIllegalVideo> getAllIllegalVideoList() {
+        ContentPlatformIllegalVideoExample example = new ContentPlatformIllegalVideoExample();
+        return illegalVideoMapper.selectByExample(example);
+    }
+
+    private List<ThirdPartWeComVideo> getVideoNullCover() {
+        ThirdPartWeComVideoExample example = new ThirdPartWeComVideoExample();
+        example.createCriteria().andCoverIsNull();
+        return videoMapper.selectByExample(example);
+    }
+
+    private List<ThirdPartWeComVideo> getVideoList(String dt) {
+        ThirdPartWeComVideoExample example = new ThirdPartWeComVideoExample();
+        example.createCriteria().andDtEqualTo(dt);
+        return videoMapper.selectByExample(example);
+    }
+
+    private List<ThirdPartWeComVideo> getVideoListByDt(String dt) {
+        ThirdPartWeComVideoExample example = new ThirdPartWeComVideoExample();
+        example.createCriteria().andDtEqualTo(dt);
+        return videoMapper.selectByExample(example);
+    }
+
+    @XxlJob("checkThirdPartWeComVideoStatusJob")
+    public ReturnT<String> checkThirdPartWeComVideoStatusJob(String param) {
+        String dt = videoMapperExt.getVideoMaxDt();
+        if (StringUtils.hasText(param)) {
+            dt = param;
+        }
+        List<ThirdPartWeComVideo> videoList = getVideoListByDt(dt);
+        Long now = System.currentTimeMillis();
+        for (List<ThirdPartWeComVideo> partition : Lists.partition(videoList, 20)) {
+            List<Long> videoIds = partition.stream().map(ThirdPartWeComVideo::getVideoId).collect(Collectors.toList());
+            Map<Long, VideoDetail> videoDetailMap = messageAttachmentService.getVideoDetail(new HashSet<>(videoIds));
+            for (ThirdPartWeComVideo video : partition) {
+                VideoDetail videoDetail = videoDetailMap.get(video.getVideoId());
+                if (videoDetail == null
+                        || videoDetail.getAuditStatus() != 5) {
+                    updateVideoStatusWithOldStatus(video.getVideoId(), 0, 1, now);
+                } else if (videoDetail.getRecommendStatus() == -6 && video.getStatus() == 0) {
+                    updateVideoStatusWithOldStatus(video.getVideoId(), 1, 0, now);
+                }
+            }
+        }
+        // 检查视频是否违规
+        List<ContentPlatformIllegalVideo> illegalVideoList = getAllIllegalVideoList();
+        List<Long> illegalVideoIds = illegalVideoList.stream().map(ContentPlatformIllegalVideo::getVideoId).collect(Collectors.toList());
+        if (CollectionUtils.isNotEmpty(illegalVideoIds)) {
+            for (Long illegalVideoId : illegalVideoIds) {
+                updateVideoStatusWithOldStatus(illegalVideoId, 0, 1, now);
+            }
+        }
+        return ReturnT.SUCCESS;
+    }
+
+    private void updateVideoStatusWithOldStatus(Long videoId, Integer status, Integer oldStatus, Long now) {
+        videoMapperExt.updateVideoStatusWithOldStatus(videoId, status, oldStatus, now);
+    }
+
+}

+ 36 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/bo/AdPutCreativeComponentCostData.java

@@ -0,0 +1,36 @@
+package com.tzld.piaoquan.api.model.bo;
+
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+@Data
+public class AdPutCreativeComponentCostData {
+    private Long accountId;
+    private Long adId;
+    private Long creativeId;
+    private String creativeName;
+    private Long cost;
+    private String wxId;
+    private List<Long> componentIds;
+    private List<AdPutTencentComponent> componentList;
+
+    @Data
+    public static class AdPutTencentComponent {
+        private Long id;
+        private Long accountId;
+        private Long componentId;
+        private String componentCustomName;
+        private String componentSubType;
+        private String generationType;
+        private Byte isDeleted;
+        private Long imageId;
+        private String imageUrl;
+        private Long videoId;
+        private Date createTime;
+        private Date updateTime;
+        private String videoCoverUrl;
+        private String videoUrl;
+    }
+}

+ 0 - 1
api-module/src/main/java/com/tzld/piaoquan/api/model/bo/BucketDataParam.java

@@ -1,6 +1,5 @@
 package com.tzld.piaoquan.api.model.bo;
 package com.tzld.piaoquan.api.model.bo;
 
 
-import com.tzld.piaoquan.api.model.po.GhDetailExt;
 import lombok.Data;
 import lombok.Data;
 
 
 import java.util.List;
 import java.util.List;

+ 28 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/bo/GoogleLLMResult.java

@@ -0,0 +1,28 @@
+package com.tzld.piaoquan.api.model.bo;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+@Data
+@Accessors(chain = true)
+public class GoogleLLMResult {
+
+    /**
+     * 生成结果
+     */
+    private String result;
+    /**
+     * 是否成功
+     */
+    private Boolean success;
+    /**
+     * 错误信息
+     */
+    private String errorMessage;
+    /**
+     * 是否可以重试
+     */
+    private Boolean enableRetry;
+    private String respBodyString;
+
+}

+ 13 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/bo/bucketDataGenerateParam.java

@@ -0,0 +1,13 @@
+package com.tzld.piaoquan.api.model.bo;
+
+import lombok.Data;
+
+@Data
+public class bucketDataGenerateParam {
+    private String ghId;
+    private Long videoId;
+    private String title;
+    private String coverUrl;
+    private String putScene;
+    private String channel;
+}

+ 39 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/dto/AIOfficialApiResponse.java

@@ -0,0 +1,39 @@
+package com.tzld.piaoquan.api.model.dto;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class AIOfficialApiResponse {
+
+    private String id;
+    private String object;
+    private long created;
+    private String model;
+    private List<Choice> choices;
+    private Usage usage;
+
+
+    @Data
+    public static class Choice {
+        private long index;
+        private Message message;
+        private String finishReason;
+    }
+
+
+    @Data
+    public static class Message {
+        private String role;
+        private String content;
+    }
+
+    @Data
+    public static class Usage {
+        private long promptTokens;
+        private long completionTokens;
+        private long totalTokens;
+    }
+
+}

+ 11 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/dto/AIResult.java

@@ -0,0 +1,11 @@
+package com.tzld.piaoquan.api.model.dto;
+
+import lombok.Data;
+
+@Data
+public class AIResult {
+    private boolean success;
+    private AIOfficialApiResponse response;
+    private String failReason;
+    private String responseStr;
+}

+ 11 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/dto/PageUrlExtData.java

@@ -0,0 +1,11 @@
+package com.tzld.piaoquan.api.model.dto;
+
+import lombok.Data;
+
+@Data
+public class PageUrlExtData {
+    private Long growthTitleId;
+    private String growthTitleSource;
+    private Long growthCoverId;
+    private String growthCoverSource;
+}

+ 1 - 1
api-module/src/main/java/com/tzld/piaoquan/api/model/vo/AccessTokenParam.java → api-module/src/main/java/com/tzld/piaoquan/api/model/param/AccessTokenParam.java

@@ -1,4 +1,4 @@
-package com.tzld.piaoquan.api.model.vo;
+package com.tzld.piaoquan.api.model.param;
 
 
 import lombok.Data;
 import lombok.Data;
 
 

+ 1 - 1
api-module/src/main/java/com/tzld/piaoquan/api/model/vo/CallbackParam.java → api-module/src/main/java/com/tzld/piaoquan/api/model/param/CallbackParam.java

@@ -1,4 +1,4 @@
-package com.tzld.piaoquan.api.model.vo;
+package com.tzld.piaoquan.api.model.param;
 
 
 import com.tzld.piaoquan.api.model.bo.ReplyInfo;
 import com.tzld.piaoquan.api.model.bo.ReplyInfo;
 import lombok.Data;
 import lombok.Data;

+ 1 - 1
api-module/src/main/java/com/tzld/piaoquan/api/model/vo/PushMessageParam.java → api-module/src/main/java/com/tzld/piaoquan/api/model/param/PushMessageParam.java

@@ -1,4 +1,4 @@
-package com.tzld.piaoquan.api.model.vo;
+package com.tzld.piaoquan.api.model.param;
 
 
 import lombok.Data;
 import lombok.Data;
 import lombok.ToString;
 import lombok.ToString;

+ 1 - 1
api-module/src/main/java/com/tzld/piaoquan/api/model/vo/WeComPushMessageParam.java → api-module/src/main/java/com/tzld/piaoquan/api/model/param/WeComPushMessageParam.java

@@ -1,4 +1,4 @@
-package com.tzld.piaoquan.api.model.vo;
+package com.tzld.piaoquan.api.model.param;
 
 
 import lombok.Data;
 import lombok.Data;
 import lombok.ToString;
 import lombok.ToString;

+ 1 - 1
api-module/src/main/java/com/tzld/piaoquan/api/model/vo/WeComUserNameAvatarParam.java → api-module/src/main/java/com/tzld/piaoquan/api/model/param/WeComUserNameAvatarParam.java

@@ -1,4 +1,4 @@
-package com.tzld.piaoquan.api.model.vo;
+package com.tzld.piaoquan.api.model.param;
 
 
 import lombok.Data;
 import lombok.Data;
 import lombok.ToString;
 import lombok.ToString;

+ 2 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/param/contentplatform/AccountSaveParam.java

@@ -22,6 +22,8 @@ public class AccountSaveParam {
     private String price;
     private String price;
     @ApiModelProperty(value = "密码")
     @ApiModelProperty(value = "密码")
     private String password;
     private String password;
+    @ApiModelProperty(value = "层级类型:特殊首层/非特殊首层")
+    private String layerType;
 
 
     @ApiModelProperty(value = "操作人")
     @ApiModelProperty(value = "操作人")
     private String operator;
     private String operator;

+ 8 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/ExternalBusinessCardResponse.java

@@ -0,0 +1,8 @@
+package com.tzld.piaoquan.api.model.param.wecom.thirdpart;
+
+import lombok.Data;
+
+@Data
+public class ExternalBusinessCardResponse {
+    private String qr_image;
+}

+ 1 - 1
api-module/src/main/java/com/tzld/piaoquan/api/controller/GetRoomUserListResponse.java → api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/GetRoomUserListResponse.java

@@ -1,4 +1,4 @@
-package com.tzld.piaoquan.api.controller;
+package com.tzld.piaoquan.api.model.param.wecom.thirdpart;
 
 
 import lombok.Data;
 import lombok.Data;
 
 

+ 10 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/LoginOutResponse.java

@@ -0,0 +1,10 @@
+package com.tzld.piaoquan.api.model.param.wecom.thirdpart;
+
+import lombok.Data;
+
+@Data
+public class LoginOutResponse {
+    private Integer errcode;
+    private String errmsg;
+    private Object data;
+}

+ 21 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/SendTextMsgResponse.java

@@ -0,0 +1,21 @@
+package com.tzld.piaoquan.api.model.param.wecom.thirdpart;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class SendTextMsgResponse {
+    private Long receiver;
+    private Long sender;
+    private List<Long> atList;
+    private String senderName;
+    private String app_info;
+    private Integer isRoom;
+    private Long sendtime;
+    private Long msgId;
+    private Long serverId;
+    private Integer msgtype;
+    private String content;
+
+}

+ 4 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/SetCallbackUrlRequest.java

@@ -1,8 +1,12 @@
 package com.tzld.piaoquan.api.model.param.wecom.thirdpart;
 package com.tzld.piaoquan.api.model.param.wecom.thirdpart;
 
 
+import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 
 
 @Data
 @Data
+@AllArgsConstructor
+@NoArgsConstructor
 public class SetCallbackUrlRequest {
 public class SetCallbackUrlRequest {
     private String uuid;
     private String uuid;
     private String url;
     private String url;

+ 37 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/ThirdPartyAccountConfigParam.java

@@ -0,0 +1,37 @@
+package com.tzld.piaoquan.api.model.param.wecom.thirdpart;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class ThirdPartyAccountConfigParam {
+
+    @ApiModelProperty(value = "账号id")
+    private Long accountId;
+
+    @ApiModelProperty(value = "投放场景")
+    private String putScene;
+    @ApiModelProperty(value = "渠道")
+    private String channel;
+    @ApiModelProperty(value = "是否开启(0否,1是)")
+    private Integer switchFlag;
+    @ApiModelProperty(value = "推送触发人数")
+    private Integer openRoomSendSwitchNum;
+    @ApiModelProperty(value = "主推送人员")
+    private Long primaryThirdStaffId;
+    @ApiModelProperty(value = "主推送人员名称")
+    private String primaryThirdStaffName;
+    @ApiModelProperty(value = "次推送人员")
+    private Long secondThirdStaffId;
+    @ApiModelProperty(value = "次推送人员名称")
+    private String secondThirdStaffName;
+    @ApiModelProperty(value = "任务列表")
+    private List<ThirdPartyAccountConfigTaskParam> taskList;
+    @ApiModelProperty(value = "配置同步 0-仅对新建群生效 1-所有群 2-指定群生效")
+    private Integer configSync;
+    @ApiModelProperty(value = "指定群生效列表")
+    private List<Long> configSyncRoomIdList;
+
+}

+ 19 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/ThirdPartyAccountConfigTaskContentParam.java

@@ -0,0 +1,19 @@
+package com.tzld.piaoquan.api.model.param.wecom.thirdpart;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class ThirdPartyAccountConfigTaskContentParam {
+
+    @ApiModelProperty(value = "类型 0-文案 1-小程序")
+    private Integer type;
+    @ApiModelProperty(value = "文案内容")
+    private String content;
+    @ApiModelProperty(value = "小程序来源 0-热榜 1-标签 2-账号")
+    private Integer source;
+    @ApiModelProperty(value = "小程序来源内容 (标签/账号id)")
+    private String sourceContent;
+    @ApiModelProperty(value = "顺序")
+    private Integer seq;
+}

+ 21 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/ThirdPartyAccountConfigTaskParam.java

@@ -0,0 +1,21 @@
+package com.tzld.piaoquan.api.model.param.wecom.thirdpart;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class ThirdPartyAccountConfigTaskParam {
+
+    @ApiModelProperty(value = "是否开启(0否,1是)")
+    private Integer switchFlag;
+    @ApiModelProperty(value = "发送时间")
+    private List<String> sendTime;
+    @ApiModelProperty(value = "随机浮动分钟")
+    private Integer randomMin;
+    @ApiModelProperty(value = "顺序")
+    private Integer seq;
+    @ApiModelProperty(value = "发送内容列表")
+    private List<ThirdPartyAccountConfigTaskContentParam> contentList;
+}

+ 16 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/ThirdPartyAccountListParam.java

@@ -0,0 +1,16 @@
+package com.tzld.piaoquan.api.model.param.wecom.thirdpart;
+
+import com.tzld.piaoquan.api.model.param.PageParam;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class ThirdPartyAccountListParam extends PageParam {
+
+    @ApiModelProperty(value = "企微主体名称")
+    private String corpName;
+    @ApiModelProperty(value = "账号名称")
+    private String accountName;
+    @ApiModelProperty(value = "手机号")
+    private String mobile;
+}

+ 10 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/ThirdPartyAccountLogOutParam.java

@@ -0,0 +1,10 @@
+package com.tzld.piaoquan.api.model.param.wecom.thirdpart;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class ThirdPartyAccountLogOutParam {
+    @ApiModelProperty(value = "账号id")
+    private Long id;
+}

+ 14 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/ThirdPartyConfigGetParam.java

@@ -0,0 +1,14 @@
+package com.tzld.piaoquan.api.model.param.wecom.thirdpart;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class ThirdPartyConfigGetParam {
+    @ApiModelProperty(value = "id")
+    private Long id;
+}

+ 31 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/ThirdPartyRoomConfigParam.java

@@ -0,0 +1,31 @@
+package com.tzld.piaoquan.api.model.param.wecom.thirdpart;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class ThirdPartyRoomConfigParam {
+
+    @ApiModelProperty(value = "群id")
+    private Long roomId;
+
+    @ApiModelProperty(value = "投放场景")
+    private String putScene;
+    @ApiModelProperty(value = "渠道")
+    private String channel;
+    @ApiModelProperty(value = "推送触发人数")
+    private Integer openRoomSendSwitchNum;
+    @ApiModelProperty(value = "主推送人员")
+    private Long primaryThirdStaffId;
+    @ApiModelProperty(value = "主推送人员名称")
+    private String primaryThirdStaffName;
+    @ApiModelProperty(value = "次推送人员")
+    private Long secondThirdStaffId;
+    @ApiModelProperty(value = "次推送人员名称")
+    private String secondThirdStaffName;
+    @ApiModelProperty(value = "任务列表")
+    private List<ThirdPartyRoomConfigTaskParam> taskList;
+
+}

+ 19 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/ThirdPartyRoomConfigTaskContentParam.java

@@ -0,0 +1,19 @@
+package com.tzld.piaoquan.api.model.param.wecom.thirdpart;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class ThirdPartyRoomConfigTaskContentParam {
+
+    @ApiModelProperty(value = "类型 0-文案 1-小程序")
+    private Integer type;
+    @ApiModelProperty(value = "文案内容")
+    private String content;
+    @ApiModelProperty(value = "小程序来源 0-热榜 1-标签 2-账号")
+    private Integer source;
+    @ApiModelProperty(value = "小程序来源内容 (标签/账号id)")
+    private String sourceContent;
+    @ApiModelProperty(value = "顺序")
+    private Integer seq;
+}

+ 21 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/ThirdPartyRoomConfigTaskParam.java

@@ -0,0 +1,21 @@
+package com.tzld.piaoquan.api.model.param.wecom.thirdpart;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class ThirdPartyRoomConfigTaskParam {
+
+    @ApiModelProperty(value = "是否开启(0否,1是)")
+    private Integer switchFlag;
+    @ApiModelProperty(value = "发送时间")
+    private List<String> sendTime;
+    @ApiModelProperty(value = "随机浮动分钟")
+    private Integer randomMin;
+    @ApiModelProperty(value = "顺序")
+    private Integer seq;
+    @ApiModelProperty(value = "发送内容列表")
+    private List<ThirdPartyRoomConfigTaskContentParam> contentList;
+}

+ 18 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/ThirdPartyRoomListParam.java

@@ -0,0 +1,18 @@
+package com.tzld.piaoquan.api.model.param.wecom.thirdpart;
+
+import com.tzld.piaoquan.api.model.param.PageParam;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class ThirdPartyRoomListParam extends PageParam {
+
+    @ApiModelProperty(value = "企微主体名称")
+    private String corpName;
+    @ApiModelProperty(value = "群主")
+    private String groupLeaderName;
+    @ApiModelProperty(value = "群名称")
+    private String roomName;
+    @ApiModelProperty(value = "推送人员")
+    private String pushAccountName;
+}

+ 10 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/WeComThirdPartyCallBackParam.java

@@ -0,0 +1,10 @@
+package com.tzld.piaoquan.api.model.param.wecom.thirdpart;
+
+import lombok.Data;
+
+@Data
+public class WeComThirdPartyCallBackParam {
+    private String uuid;
+    private Integer type;
+    private String json;
+}

+ 33 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/po/GhDetailExt.java

@@ -7,10 +7,16 @@ public class GhDetailExt {
 
 
     private Long ghDetailId;
     private Long ghDetailId;
 
 
+    private Long videoId;
+
     private String page;
     private String page;
 
 
+    private Long titleId;
+
     private String title;
     private String title;
 
 
+    private Long coverId;
+
     private String cover;
     private String cover;
 
 
     private Integer sort;
     private Integer sort;
@@ -37,6 +43,14 @@ public class GhDetailExt {
         this.ghDetailId = ghDetailId;
         this.ghDetailId = ghDetailId;
     }
     }
 
 
+    public Long getVideoId() {
+        return videoId;
+    }
+
+    public void setVideoId(Long videoId) {
+        this.videoId = videoId;
+    }
+
     public String getPage() {
     public String getPage() {
         return page;
         return page;
     }
     }
@@ -45,6 +59,14 @@ public class GhDetailExt {
         this.page = page;
         this.page = page;
     }
     }
 
 
+    public Long getTitleId() {
+        return titleId;
+    }
+
+    public void setTitleId(Long titleId) {
+        this.titleId = titleId;
+    }
+
     public String getTitle() {
     public String getTitle() {
         return title;
         return title;
     }
     }
@@ -53,6 +75,14 @@ public class GhDetailExt {
         this.title = title;
         this.title = title;
     }
     }
 
 
+    public Long getCoverId() {
+        return coverId;
+    }
+
+    public void setCoverId(Long coverId) {
+        this.coverId = coverId;
+    }
+
     public String getCover() {
     public String getCover() {
         return cover;
         return cover;
     }
     }
@@ -101,8 +131,11 @@ public class GhDetailExt {
         sb.append("Hash = ").append(hashCode());
         sb.append("Hash = ").append(hashCode());
         sb.append(", id=").append(id);
         sb.append(", id=").append(id);
         sb.append(", ghDetailId=").append(ghDetailId);
         sb.append(", ghDetailId=").append(ghDetailId);
+        sb.append(", videoId=").append(videoId);
         sb.append(", page=").append(page);
         sb.append(", page=").append(page);
+        sb.append(", titleId=").append(titleId);
         sb.append(", title=").append(title);
         sb.append(", title=").append(title);
+        sb.append(", coverId=").append(coverId);
         sb.append(", cover=").append(cover);
         sb.append(", cover=").append(cover);
         sb.append(", sort=").append(sort);
         sb.append(", sort=").append(sort);
         sb.append(", isDelete=").append(isDelete);
         sb.append(", isDelete=").append(isDelete);

+ 180 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/po/GhDetailExtExample.java

@@ -236,6 +236,66 @@ public class GhDetailExtExample {
             return (Criteria) this;
             return (Criteria) this;
         }
         }
 
 
+        public Criteria andVideoIdIsNull() {
+            addCriterion("video_id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andVideoIdIsNotNull() {
+            addCriterion("video_id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andVideoIdEqualTo(Long value) {
+            addCriterion("video_id =", value, "videoId");
+            return (Criteria) this;
+        }
+
+        public Criteria andVideoIdNotEqualTo(Long value) {
+            addCriterion("video_id <>", value, "videoId");
+            return (Criteria) this;
+        }
+
+        public Criteria andVideoIdGreaterThan(Long value) {
+            addCriterion("video_id >", value, "videoId");
+            return (Criteria) this;
+        }
+
+        public Criteria andVideoIdGreaterThanOrEqualTo(Long value) {
+            addCriterion("video_id >=", value, "videoId");
+            return (Criteria) this;
+        }
+
+        public Criteria andVideoIdLessThan(Long value) {
+            addCriterion("video_id <", value, "videoId");
+            return (Criteria) this;
+        }
+
+        public Criteria andVideoIdLessThanOrEqualTo(Long value) {
+            addCriterion("video_id <=", value, "videoId");
+            return (Criteria) this;
+        }
+
+        public Criteria andVideoIdIn(List<Long> values) {
+            addCriterion("video_id in", values, "videoId");
+            return (Criteria) this;
+        }
+
+        public Criteria andVideoIdNotIn(List<Long> values) {
+            addCriterion("video_id not in", values, "videoId");
+            return (Criteria) this;
+        }
+
+        public Criteria andVideoIdBetween(Long value1, Long value2) {
+            addCriterion("video_id between", value1, value2, "videoId");
+            return (Criteria) this;
+        }
+
+        public Criteria andVideoIdNotBetween(Long value1, Long value2) {
+            addCriterion("video_id not between", value1, value2, "videoId");
+            return (Criteria) this;
+        }
+
         public Criteria andPageIsNull() {
         public Criteria andPageIsNull() {
             addCriterion("page is null");
             addCriterion("page is null");
             return (Criteria) this;
             return (Criteria) this;
@@ -306,6 +366,66 @@ public class GhDetailExtExample {
             return (Criteria) this;
             return (Criteria) this;
         }
         }
 
 
+        public Criteria andTitleIdIsNull() {
+            addCriterion("title_id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleIdIsNotNull() {
+            addCriterion("title_id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleIdEqualTo(Long value) {
+            addCriterion("title_id =", value, "titleId");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleIdNotEqualTo(Long value) {
+            addCriterion("title_id <>", value, "titleId");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleIdGreaterThan(Long value) {
+            addCriterion("title_id >", value, "titleId");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleIdGreaterThanOrEqualTo(Long value) {
+            addCriterion("title_id >=", value, "titleId");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleIdLessThan(Long value) {
+            addCriterion("title_id <", value, "titleId");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleIdLessThanOrEqualTo(Long value) {
+            addCriterion("title_id <=", value, "titleId");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleIdIn(List<Long> values) {
+            addCriterion("title_id in", values, "titleId");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleIdNotIn(List<Long> values) {
+            addCriterion("title_id not in", values, "titleId");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleIdBetween(Long value1, Long value2) {
+            addCriterion("title_id between", value1, value2, "titleId");
+            return (Criteria) this;
+        }
+
+        public Criteria andTitleIdNotBetween(Long value1, Long value2) {
+            addCriterion("title_id not between", value1, value2, "titleId");
+            return (Criteria) this;
+        }
+
         public Criteria andTitleIsNull() {
         public Criteria andTitleIsNull() {
             addCriterion("title is null");
             addCriterion("title is null");
             return (Criteria) this;
             return (Criteria) this;
@@ -376,6 +496,66 @@ public class GhDetailExtExample {
             return (Criteria) this;
             return (Criteria) this;
         }
         }
 
 
+        public Criteria andCoverIdIsNull() {
+            addCriterion("cover_id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverIdIsNotNull() {
+            addCriterion("cover_id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverIdEqualTo(Long value) {
+            addCriterion("cover_id =", value, "coverId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverIdNotEqualTo(Long value) {
+            addCriterion("cover_id <>", value, "coverId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverIdGreaterThan(Long value) {
+            addCriterion("cover_id >", value, "coverId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverIdGreaterThanOrEqualTo(Long value) {
+            addCriterion("cover_id >=", value, "coverId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverIdLessThan(Long value) {
+            addCriterion("cover_id <", value, "coverId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverIdLessThanOrEqualTo(Long value) {
+            addCriterion("cover_id <=", value, "coverId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverIdIn(List<Long> values) {
+            addCriterion("cover_id in", values, "coverId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverIdNotIn(List<Long> values) {
+            addCriterion("cover_id not in", values, "coverId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverIdBetween(Long value1, Long value2) {
+            addCriterion("cover_id between", value1, value2, "coverId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverIdNotBetween(Long value1, Long value2) {
+            addCriterion("cover_id not between", value1, value2, "coverId");
+            return (Criteria) this;
+        }
+
         public Criteria andCoverIsNull() {
         public Criteria andCoverIsNull() {
             addCriterion("cover is null");
             addCriterion("cover is null");
             return (Criteria) this;
             return (Criteria) this;

+ 90 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/po/GzhAutoreplyBehaviorUvTotal.java

@@ -0,0 +1,90 @@
+package com.tzld.piaoquan.api.model.po;
+
+public class GzhAutoreplyBehaviorUvTotal {
+    private Long id;
+
+    private String dt;
+
+    private String channel;
+
+    private String ghId;
+
+    private Integer uv;
+
+    private Integer firstLevel;
+
+    private Long createTimestamp;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getDt() {
+        return dt;
+    }
+
+    public void setDt(String dt) {
+        this.dt = dt;
+    }
+
+    public String getChannel() {
+        return channel;
+    }
+
+    public void setChannel(String channel) {
+        this.channel = channel;
+    }
+
+    public String getGhId() {
+        return ghId;
+    }
+
+    public void setGhId(String ghId) {
+        this.ghId = ghId;
+    }
+
+    public Integer getUv() {
+        return uv;
+    }
+
+    public void setUv(Integer uv) {
+        this.uv = uv;
+    }
+
+    public Integer getFirstLevel() {
+        return firstLevel;
+    }
+
+    public void setFirstLevel(Integer firstLevel) {
+        this.firstLevel = firstLevel;
+    }
+
+    public Long getCreateTimestamp() {
+        return createTimestamp;
+    }
+
+    public void setCreateTimestamp(Long createTimestamp) {
+        this.createTimestamp = createTimestamp;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(getClass().getSimpleName());
+        sb.append(" [");
+        sb.append("Hash = ").append(hashCode());
+        sb.append(", id=").append(id);
+        sb.append(", dt=").append(dt);
+        sb.append(", channel=").append(channel);
+        sb.append(", ghId=").append(ghId);
+        sb.append(", uv=").append(uv);
+        sb.append(", firstLevel=").append(firstLevel);
+        sb.append(", createTimestamp=").append(createTimestamp);
+        sb.append("]");
+        return sb.toString();
+    }
+}

+ 661 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/po/GzhAutoreplyBehaviorUvTotalExample.java

@@ -0,0 +1,661 @@
+package com.tzld.piaoquan.api.model.po;
+
+import com.tzld.piaoquan.growth.common.utils.page.Page;
+import java.util.ArrayList;
+import java.util.List;
+
+public class GzhAutoreplyBehaviorUvTotalExample {
+    protected String orderByClause;
+
+    protected boolean distinct;
+
+    protected List<Criteria> oredCriteria;
+
+    protected Page page;
+
+    public GzhAutoreplyBehaviorUvTotalExample() {
+        oredCriteria = new ArrayList<Criteria>();
+    }
+
+    public void setOrderByClause(String orderByClause) {
+        this.orderByClause = orderByClause;
+    }
+
+    public String getOrderByClause() {
+        return orderByClause;
+    }
+
+    public void setDistinct(boolean distinct) {
+        this.distinct = distinct;
+    }
+
+    public boolean isDistinct() {
+        return distinct;
+    }
+
+    public List<Criteria> getOredCriteria() {
+        return oredCriteria;
+    }
+
+    public void or(Criteria criteria) {
+        oredCriteria.add(criteria);
+    }
+
+    public Criteria or() {
+        Criteria criteria = createCriteriaInternal();
+        oredCriteria.add(criteria);
+        return criteria;
+    }
+
+    public Criteria createCriteria() {
+        Criteria criteria = createCriteriaInternal();
+        if (oredCriteria.size() == 0) {
+            oredCriteria.add(criteria);
+        }
+        return criteria;
+    }
+
+    protected Criteria createCriteriaInternal() {
+        Criteria criteria = new Criteria();
+        return criteria;
+    }
+
+    public void clear() {
+        oredCriteria.clear();
+        orderByClause = null;
+        distinct = false;
+    }
+
+    public void setPage(Page page) {
+        this.page=page;
+    }
+
+    public Page getPage() {
+        return page;
+    }
+
+    protected abstract static class GeneratedCriteria {
+        protected List<Criterion> criteria;
+
+        protected GeneratedCriteria() {
+            super();
+            criteria = new ArrayList<Criterion>();
+        }
+
+        public boolean isValid() {
+            return criteria.size() > 0;
+        }
+
+        public List<Criterion> getAllCriteria() {
+            return criteria;
+        }
+
+        public List<Criterion> getCriteria() {
+            return criteria;
+        }
+
+        protected void addCriterion(String condition) {
+            if (condition == null) {
+                throw new RuntimeException("Value for condition cannot be null");
+            }
+            criteria.add(new Criterion(condition));
+        }
+
+        protected void addCriterion(String condition, Object value, String property) {
+            if (value == null) {
+                throw new RuntimeException("Value for " + property + " cannot be null");
+            }
+            criteria.add(new Criterion(condition, value));
+        }
+
+        protected void addCriterion(String condition, Object value1, Object value2, String property) {
+            if (value1 == null || value2 == null) {
+                throw new RuntimeException("Between values for " + property + " cannot be null");
+            }
+            criteria.add(new Criterion(condition, value1, value2));
+        }
+
+        public Criteria andIdIsNull() {
+            addCriterion("id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdIsNotNull() {
+            addCriterion("id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdEqualTo(Long value) {
+            addCriterion("id =", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdNotEqualTo(Long value) {
+            addCriterion("id <>", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdGreaterThan(Long value) {
+            addCriterion("id >", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdGreaterThanOrEqualTo(Long value) {
+            addCriterion("id >=", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdLessThan(Long value) {
+            addCriterion("id <", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdLessThanOrEqualTo(Long value) {
+            addCriterion("id <=", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdIn(List<Long> values) {
+            addCriterion("id in", values, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdNotIn(List<Long> values) {
+            addCriterion("id not in", values, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdBetween(Long value1, Long value2) {
+            addCriterion("id between", value1, value2, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdNotBetween(Long value1, Long value2) {
+            addCriterion("id not between", value1, value2, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andDtIsNull() {
+            addCriterion("dt is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andDtIsNotNull() {
+            addCriterion("dt is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andDtEqualTo(String value) {
+            addCriterion("dt =", value, "dt");
+            return (Criteria) this;
+        }
+
+        public Criteria andDtNotEqualTo(String value) {
+            addCriterion("dt <>", value, "dt");
+            return (Criteria) this;
+        }
+
+        public Criteria andDtGreaterThan(String value) {
+            addCriterion("dt >", value, "dt");
+            return (Criteria) this;
+        }
+
+        public Criteria andDtGreaterThanOrEqualTo(String value) {
+            addCriterion("dt >=", value, "dt");
+            return (Criteria) this;
+        }
+
+        public Criteria andDtLessThan(String value) {
+            addCriterion("dt <", value, "dt");
+            return (Criteria) this;
+        }
+
+        public Criteria andDtLessThanOrEqualTo(String value) {
+            addCriterion("dt <=", value, "dt");
+            return (Criteria) this;
+        }
+
+        public Criteria andDtLike(String value) {
+            addCriterion("dt like", value, "dt");
+            return (Criteria) this;
+        }
+
+        public Criteria andDtNotLike(String value) {
+            addCriterion("dt not like", value, "dt");
+            return (Criteria) this;
+        }
+
+        public Criteria andDtIn(List<String> values) {
+            addCriterion("dt in", values, "dt");
+            return (Criteria) this;
+        }
+
+        public Criteria andDtNotIn(List<String> values) {
+            addCriterion("dt not in", values, "dt");
+            return (Criteria) this;
+        }
+
+        public Criteria andDtBetween(String value1, String value2) {
+            addCriterion("dt between", value1, value2, "dt");
+            return (Criteria) this;
+        }
+
+        public Criteria andDtNotBetween(String value1, String value2) {
+            addCriterion("dt not between", value1, value2, "dt");
+            return (Criteria) this;
+        }
+
+        public Criteria andChannelIsNull() {
+            addCriterion("channel is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andChannelIsNotNull() {
+            addCriterion("channel is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andChannelEqualTo(String value) {
+            addCriterion("channel =", value, "channel");
+            return (Criteria) this;
+        }
+
+        public Criteria andChannelNotEqualTo(String value) {
+            addCriterion("channel <>", value, "channel");
+            return (Criteria) this;
+        }
+
+        public Criteria andChannelGreaterThan(String value) {
+            addCriterion("channel >", value, "channel");
+            return (Criteria) this;
+        }
+
+        public Criteria andChannelGreaterThanOrEqualTo(String value) {
+            addCriterion("channel >=", value, "channel");
+            return (Criteria) this;
+        }
+
+        public Criteria andChannelLessThan(String value) {
+            addCriterion("channel <", value, "channel");
+            return (Criteria) this;
+        }
+
+        public Criteria andChannelLessThanOrEqualTo(String value) {
+            addCriterion("channel <=", value, "channel");
+            return (Criteria) this;
+        }
+
+        public Criteria andChannelLike(String value) {
+            addCriterion("channel like", value, "channel");
+            return (Criteria) this;
+        }
+
+        public Criteria andChannelNotLike(String value) {
+            addCriterion("channel not like", value, "channel");
+            return (Criteria) this;
+        }
+
+        public Criteria andChannelIn(List<String> values) {
+            addCriterion("channel in", values, "channel");
+            return (Criteria) this;
+        }
+
+        public Criteria andChannelNotIn(List<String> values) {
+            addCriterion("channel not in", values, "channel");
+            return (Criteria) this;
+        }
+
+        public Criteria andChannelBetween(String value1, String value2) {
+            addCriterion("channel between", value1, value2, "channel");
+            return (Criteria) this;
+        }
+
+        public Criteria andChannelNotBetween(String value1, String value2) {
+            addCriterion("channel not between", value1, value2, "channel");
+            return (Criteria) this;
+        }
+
+        public Criteria andGhIdIsNull() {
+            addCriterion("gh_id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andGhIdIsNotNull() {
+            addCriterion("gh_id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andGhIdEqualTo(String value) {
+            addCriterion("gh_id =", value, "ghId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGhIdNotEqualTo(String value) {
+            addCriterion("gh_id <>", value, "ghId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGhIdGreaterThan(String value) {
+            addCriterion("gh_id >", value, "ghId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGhIdGreaterThanOrEqualTo(String value) {
+            addCriterion("gh_id >=", value, "ghId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGhIdLessThan(String value) {
+            addCriterion("gh_id <", value, "ghId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGhIdLessThanOrEqualTo(String value) {
+            addCriterion("gh_id <=", value, "ghId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGhIdLike(String value) {
+            addCriterion("gh_id like", value, "ghId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGhIdNotLike(String value) {
+            addCriterion("gh_id not like", value, "ghId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGhIdIn(List<String> values) {
+            addCriterion("gh_id in", values, "ghId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGhIdNotIn(List<String> values) {
+            addCriterion("gh_id not in", values, "ghId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGhIdBetween(String value1, String value2) {
+            addCriterion("gh_id between", value1, value2, "ghId");
+            return (Criteria) this;
+        }
+
+        public Criteria andGhIdNotBetween(String value1, String value2) {
+            addCriterion("gh_id not between", value1, value2, "ghId");
+            return (Criteria) this;
+        }
+
+        public Criteria andUvIsNull() {
+            addCriterion("uv is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andUvIsNotNull() {
+            addCriterion("uv is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andUvEqualTo(Integer value) {
+            addCriterion("uv =", value, "uv");
+            return (Criteria) this;
+        }
+
+        public Criteria andUvNotEqualTo(Integer value) {
+            addCriterion("uv <>", value, "uv");
+            return (Criteria) this;
+        }
+
+        public Criteria andUvGreaterThan(Integer value) {
+            addCriterion("uv >", value, "uv");
+            return (Criteria) this;
+        }
+
+        public Criteria andUvGreaterThanOrEqualTo(Integer value) {
+            addCriterion("uv >=", value, "uv");
+            return (Criteria) this;
+        }
+
+        public Criteria andUvLessThan(Integer value) {
+            addCriterion("uv <", value, "uv");
+            return (Criteria) this;
+        }
+
+        public Criteria andUvLessThanOrEqualTo(Integer value) {
+            addCriterion("uv <=", value, "uv");
+            return (Criteria) this;
+        }
+
+        public Criteria andUvIn(List<Integer> values) {
+            addCriterion("uv in", values, "uv");
+            return (Criteria) this;
+        }
+
+        public Criteria andUvNotIn(List<Integer> values) {
+            addCriterion("uv not in", values, "uv");
+            return (Criteria) this;
+        }
+
+        public Criteria andUvBetween(Integer value1, Integer value2) {
+            addCriterion("uv between", value1, value2, "uv");
+            return (Criteria) this;
+        }
+
+        public Criteria andUvNotBetween(Integer value1, Integer value2) {
+            addCriterion("uv not between", value1, value2, "uv");
+            return (Criteria) this;
+        }
+
+        public Criteria andFirstLevelIsNull() {
+            addCriterion("first_level is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andFirstLevelIsNotNull() {
+            addCriterion("first_level is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andFirstLevelEqualTo(Integer value) {
+            addCriterion("first_level =", value, "firstLevel");
+            return (Criteria) this;
+        }
+
+        public Criteria andFirstLevelNotEqualTo(Integer value) {
+            addCriterion("first_level <>", value, "firstLevel");
+            return (Criteria) this;
+        }
+
+        public Criteria andFirstLevelGreaterThan(Integer value) {
+            addCriterion("first_level >", value, "firstLevel");
+            return (Criteria) this;
+        }
+
+        public Criteria andFirstLevelGreaterThanOrEqualTo(Integer value) {
+            addCriterion("first_level >=", value, "firstLevel");
+            return (Criteria) this;
+        }
+
+        public Criteria andFirstLevelLessThan(Integer value) {
+            addCriterion("first_level <", value, "firstLevel");
+            return (Criteria) this;
+        }
+
+        public Criteria andFirstLevelLessThanOrEqualTo(Integer value) {
+            addCriterion("first_level <=", value, "firstLevel");
+            return (Criteria) this;
+        }
+
+        public Criteria andFirstLevelIn(List<Integer> values) {
+            addCriterion("first_level in", values, "firstLevel");
+            return (Criteria) this;
+        }
+
+        public Criteria andFirstLevelNotIn(List<Integer> values) {
+            addCriterion("first_level not in", values, "firstLevel");
+            return (Criteria) this;
+        }
+
+        public Criteria andFirstLevelBetween(Integer value1, Integer value2) {
+            addCriterion("first_level between", value1, value2, "firstLevel");
+            return (Criteria) this;
+        }
+
+        public Criteria andFirstLevelNotBetween(Integer value1, Integer value2) {
+            addCriterion("first_level not between", value1, value2, "firstLevel");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampIsNull() {
+            addCriterion("create_timestamp is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampIsNotNull() {
+            addCriterion("create_timestamp is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampEqualTo(Long value) {
+            addCriterion("create_timestamp =", value, "createTimestamp");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampNotEqualTo(Long value) {
+            addCriterion("create_timestamp <>", value, "createTimestamp");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampGreaterThan(Long value) {
+            addCriterion("create_timestamp >", value, "createTimestamp");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampGreaterThanOrEqualTo(Long value) {
+            addCriterion("create_timestamp >=", value, "createTimestamp");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampLessThan(Long value) {
+            addCriterion("create_timestamp <", value, "createTimestamp");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampLessThanOrEqualTo(Long value) {
+            addCriterion("create_timestamp <=", value, "createTimestamp");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampIn(List<Long> values) {
+            addCriterion("create_timestamp in", values, "createTimestamp");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampNotIn(List<Long> values) {
+            addCriterion("create_timestamp not in", values, "createTimestamp");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampBetween(Long value1, Long value2) {
+            addCriterion("create_timestamp between", value1, value2, "createTimestamp");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampNotBetween(Long value1, Long value2) {
+            addCriterion("create_timestamp not between", value1, value2, "createTimestamp");
+            return (Criteria) this;
+        }
+    }
+
+    public static class Criteria extends GeneratedCriteria {
+
+        protected Criteria() {
+            super();
+        }
+    }
+
+    public static class Criterion {
+        private String condition;
+
+        private Object value;
+
+        private Object secondValue;
+
+        private boolean noValue;
+
+        private boolean singleValue;
+
+        private boolean betweenValue;
+
+        private boolean listValue;
+
+        private String typeHandler;
+
+        public String getCondition() {
+            return condition;
+        }
+
+        public Object getValue() {
+            return value;
+        }
+
+        public Object getSecondValue() {
+            return secondValue;
+        }
+
+        public boolean isNoValue() {
+            return noValue;
+        }
+
+        public boolean isSingleValue() {
+            return singleValue;
+        }
+
+        public boolean isBetweenValue() {
+            return betweenValue;
+        }
+
+        public boolean isListValue() {
+            return listValue;
+        }
+
+        public String getTypeHandler() {
+            return typeHandler;
+        }
+
+        protected Criterion(String condition) {
+            super();
+            this.condition = condition;
+            this.typeHandler = null;
+            this.noValue = true;
+        }
+
+        protected Criterion(String condition, Object value, String typeHandler) {
+            super();
+            this.condition = condition;
+            this.value = value;
+            this.typeHandler = typeHandler;
+            if (value instanceof List<?>) {
+                this.listValue = true;
+            } else {
+                this.singleValue = true;
+            }
+        }
+
+        protected Criterion(String condition, Object value) {
+            this(condition, value, null);
+        }
+
+        protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
+            super();
+            this.condition = condition;
+            this.value = value;
+            this.secondValue = secondValue;
+            this.typeHandler = typeHandler;
+            this.betweenValue = true;
+        }
+
+        protected Criterion(String condition, Object value, Object secondValue) {
+            this(condition, value, secondValue, null);
+        }
+    }
+}

+ 22 - 0
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 channel;
 
 
+    private String layerType;
+
     private String contactName;
     private String contactName;
 
 
     private String telNum;
     private String telNum;
@@ -21,6 +23,8 @@ public class ContentPlatformAccount {
 
 
     private Long tokenExpireTimestamp;
     private Long tokenExpireTimestamp;
 
 
+    private String replySecret;
+
     private Integer status;
     private Integer status;
 
 
     private String createAccount;
     private String createAccount;
@@ -63,6 +67,14 @@ public class ContentPlatformAccount {
         this.channel = channel;
         this.channel = channel;
     }
     }
 
 
+    public String getLayerType() {
+        return layerType;
+    }
+
+    public void setLayerType(String layerType) {
+        this.layerType = layerType;
+    }
+
     public String getContactName() {
     public String getContactName() {
         return contactName;
         return contactName;
     }
     }
@@ -111,6 +123,14 @@ public class ContentPlatformAccount {
         this.tokenExpireTimestamp = tokenExpireTimestamp;
         this.tokenExpireTimestamp = tokenExpireTimestamp;
     }
     }
 
 
+    public String getReplySecret() {
+        return replySecret;
+    }
+
+    public void setReplySecret(String replySecret) {
+        this.replySecret = replySecret;
+    }
+
     public Integer getStatus() {
     public Integer getStatus() {
         return status;
         return status;
     }
     }
@@ -161,12 +181,14 @@ public class ContentPlatformAccount {
         sb.append(", name=").append(name);
         sb.append(", name=").append(name);
         sb.append(", identity=").append(identity);
         sb.append(", identity=").append(identity);
         sb.append(", channel=").append(channel);
         sb.append(", channel=").append(channel);
+        sb.append(", layerType=").append(layerType);
         sb.append(", contactName=").append(contactName);
         sb.append(", contactName=").append(contactName);
         sb.append(", telNum=").append(telNum);
         sb.append(", telNum=").append(telNum);
         sb.append(", price=").append(price);
         sb.append(", price=").append(price);
         sb.append(", password=").append(password);
         sb.append(", password=").append(password);
         sb.append(", token=").append(token);
         sb.append(", token=").append(token);
         sb.append(", tokenExpireTimestamp=").append(tokenExpireTimestamp);
         sb.append(", tokenExpireTimestamp=").append(tokenExpireTimestamp);
+        sb.append(", replySecret=").append(replySecret);
         sb.append(", status=").append(status);
         sb.append(", status=").append(status);
         sb.append(", createAccount=").append(createAccount);
         sb.append(", createAccount=").append(createAccount);
         sb.append(", createTimestamp=").append(createTimestamp);
         sb.append(", createTimestamp=").append(createTimestamp);

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

@@ -375,6 +375,76 @@ public class ContentPlatformAccountExample {
             return (Criteria) this;
             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() {
         public Criteria andContactNameIsNull() {
             addCriterion("contact_name is null");
             addCriterion("contact_name is null");
             return (Criteria) this;
             return (Criteria) this;
@@ -785,6 +855,76 @@ public class ContentPlatformAccountExample {
             return (Criteria) this;
             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() {
         public Criteria andStatusIsNull() {
             addCriterion("`status` is null");
             addCriterion("`status` is null");
             return (Criteria) this;
             return (Criteria) this;

+ 33 - 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 String title;
 
 
+    private Long customTitleId;
+
     private String customTitle;
     private String customTitle;
 
 
     private String cover;
     private String cover;
 
 
+    private Long customCoverId;
+
     private String customCover;
     private String customCover;
 
 
     private Integer customCoverType;
     private Integer customCoverType;
@@ -21,6 +25,8 @@ public class ContentPlatformGzhPlanVideo {
 
 
     private String pageUrl;
     private String pageUrl;
 
 
+    private String rootSourceId;
+
     private Integer status;
     private Integer status;
 
 
     private Long createAccountId;
     private Long createAccountId;
@@ -59,6 +65,14 @@ public class ContentPlatformGzhPlanVideo {
         this.title = title;
         this.title = title;
     }
     }
 
 
+    public Long getCustomTitleId() {
+        return customTitleId;
+    }
+
+    public void setCustomTitleId(Long customTitleId) {
+        this.customTitleId = customTitleId;
+    }
+
     public String getCustomTitle() {
     public String getCustomTitle() {
         return customTitle;
         return customTitle;
     }
     }
@@ -75,6 +89,14 @@ public class ContentPlatformGzhPlanVideo {
         this.cover = cover;
         this.cover = cover;
     }
     }
 
 
+    public Long getCustomCoverId() {
+        return customCoverId;
+    }
+
+    public void setCustomCoverId(Long customCoverId) {
+        this.customCoverId = customCoverId;
+    }
+
     public String getCustomCover() {
     public String getCustomCover() {
         return customCover;
         return customCover;
     }
     }
@@ -107,6 +129,14 @@ public class ContentPlatformGzhPlanVideo {
         this.pageUrl = pageUrl;
         this.pageUrl = pageUrl;
     }
     }
 
 
+    public String getRootSourceId() {
+        return rootSourceId;
+    }
+
+    public void setRootSourceId(String rootSourceId) {
+        this.rootSourceId = rootSourceId;
+    }
+
     public Integer getStatus() {
     public Integer getStatus() {
         return status;
         return status;
     }
     }
@@ -141,12 +171,15 @@ public class ContentPlatformGzhPlanVideo {
         sb.append(", planId=").append(planId);
         sb.append(", planId=").append(planId);
         sb.append(", videoId=").append(videoId);
         sb.append(", videoId=").append(videoId);
         sb.append(", title=").append(title);
         sb.append(", title=").append(title);
+        sb.append(", customTitleId=").append(customTitleId);
         sb.append(", customTitle=").append(customTitle);
         sb.append(", customTitle=").append(customTitle);
         sb.append(", cover=").append(cover);
         sb.append(", cover=").append(cover);
+        sb.append(", customCoverId=").append(customCoverId);
         sb.append(", customCover=").append(customCover);
         sb.append(", customCover=").append(customCover);
         sb.append(", customCoverType=").append(customCoverType);
         sb.append(", customCoverType=").append(customCoverType);
         sb.append(", video=").append(video);
         sb.append(", video=").append(video);
         sb.append(", pageUrl=").append(pageUrl);
         sb.append(", pageUrl=").append(pageUrl);
+        sb.append(", rootSourceId=").append(rootSourceId);
         sb.append(", status=").append(status);
         sb.append(", status=").append(status);
         sb.append(", createAccountId=").append(createAccountId);
         sb.append(", createAccountId=").append(createAccountId);
         sb.append(", createTimestamp=").append(createTimestamp);
         sb.append(", createTimestamp=").append(createTimestamp);

+ 190 - 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;
             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() {
         public Criteria andCustomTitleIsNull() {
             addCriterion("custom_title is null");
             addCriterion("custom_title is null");
             return (Criteria) this;
             return (Criteria) this;
@@ -505,6 +565,66 @@ public class ContentPlatformGzhPlanVideoExample {
             return (Criteria) this;
             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() {
         public Criteria andCustomCoverIsNull() {
             addCriterion("custom_cover is null");
             addCriterion("custom_cover is null");
             return (Criteria) this;
             return (Criteria) this;
@@ -775,6 +895,76 @@ public class ContentPlatformGzhPlanVideoExample {
             return (Criteria) this;
             return (Criteria) this;
         }
         }
 
 
+        public Criteria andRootSourceIdIsNull() {
+            addCriterion("root_source_id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andRootSourceIdIsNotNull() {
+            addCriterion("root_source_id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andRootSourceIdEqualTo(String value) {
+            addCriterion("root_source_id =", value, "rootSourceId");
+            return (Criteria) this;
+        }
+
+        public Criteria andRootSourceIdNotEqualTo(String value) {
+            addCriterion("root_source_id <>", value, "rootSourceId");
+            return (Criteria) this;
+        }
+
+        public Criteria andRootSourceIdGreaterThan(String value) {
+            addCriterion("root_source_id >", value, "rootSourceId");
+            return (Criteria) this;
+        }
+
+        public Criteria andRootSourceIdGreaterThanOrEqualTo(String value) {
+            addCriterion("root_source_id >=", value, "rootSourceId");
+            return (Criteria) this;
+        }
+
+        public Criteria andRootSourceIdLessThan(String value) {
+            addCriterion("root_source_id <", value, "rootSourceId");
+            return (Criteria) this;
+        }
+
+        public Criteria andRootSourceIdLessThanOrEqualTo(String value) {
+            addCriterion("root_source_id <=", value, "rootSourceId");
+            return (Criteria) this;
+        }
+
+        public Criteria andRootSourceIdLike(String value) {
+            addCriterion("root_source_id like", value, "rootSourceId");
+            return (Criteria) this;
+        }
+
+        public Criteria andRootSourceIdNotLike(String value) {
+            addCriterion("root_source_id not like", value, "rootSourceId");
+            return (Criteria) this;
+        }
+
+        public Criteria andRootSourceIdIn(List<String> values) {
+            addCriterion("root_source_id in", values, "rootSourceId");
+            return (Criteria) this;
+        }
+
+        public Criteria andRootSourceIdNotIn(List<String> values) {
+            addCriterion("root_source_id not in", values, "rootSourceId");
+            return (Criteria) this;
+        }
+
+        public Criteria andRootSourceIdBetween(String value1, String value2) {
+            addCriterion("root_source_id between", value1, value2, "rootSourceId");
+            return (Criteria) this;
+        }
+
+        public Criteria andRootSourceIdNotBetween(String value1, String value2) {
+            addCriterion("root_source_id not between", value1, value2, "rootSourceId");
+            return (Criteria) this;
+        }
+
         public Criteria andStatusIsNull() {
         public Criteria andStatusIsNull() {
             addCriterion("`status` is null");
             addCriterion("`status` is null");
             return (Criteria) this;
             return (Criteria) this;

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

@@ -11,6 +11,10 @@ public class ContentPlatformIllegalMsg {
 
 
     private String businessType;
     private String businessType;
 
 
+    private String illegalTitle;
+
+    private String illegalContent;
+
     private Integer status;
     private Integer status;
 
 
     private Long createTimestamp;
     private Long createTimestamp;
@@ -57,6 +61,22 @@ public class ContentPlatformIllegalMsg {
         this.businessType = businessType;
         this.businessType = businessType;
     }
     }
 
 
+    public String getIllegalTitle() {
+        return illegalTitle;
+    }
+
+    public void setIllegalTitle(String illegalTitle) {
+        this.illegalTitle = illegalTitle;
+    }
+
+    public String getIllegalContent() {
+        return illegalContent;
+    }
+
+    public void setIllegalContent(String illegalContent) {
+        this.illegalContent = illegalContent;
+    }
+
     public Integer getStatus() {
     public Integer getStatus() {
         return status;
         return status;
     }
     }
@@ -92,6 +112,8 @@ public class ContentPlatformIllegalMsg {
         sb.append(", videoId=").append(videoId);
         sb.append(", videoId=").append(videoId);
         sb.append(", title=").append(title);
         sb.append(", title=").append(title);
         sb.append(", businessType=").append(businessType);
         sb.append(", businessType=").append(businessType);
+        sb.append(", illegalTitle=").append(illegalTitle);
+        sb.append(", illegalContent=").append(illegalContent);
         sb.append(", status=").append(status);
         sb.append(", status=").append(status);
         sb.append(", createTimestamp=").append(createTimestamp);
         sb.append(", createTimestamp=").append(createTimestamp);
         sb.append(", updateTimestamp=").append(updateTimestamp);
         sb.append(", updateTimestamp=").append(updateTimestamp);

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff