Prechádzať zdrojové kódy

Merge branch 'pingkang'

# Conflicts:
#	job-bytedance/src/main/resources/logback-dev.xml
#	job-bytedance/src/main/resources/logback-prod.xml
#	job-bytedance/src/main/resources/logback-test.xml
hpk 6 mesiacov pred
rodič
commit
314c6c7531

+ 12 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/controller/BytedanceController.java

@@ -376,6 +376,18 @@ public class BytedanceController {
         }
     }
 
+    @GetMapping("/promoterHour")
+    public void promoterHour(@RequestParam(required = false) Long advertiserId, String startDate, String endDate) {
+        List<JSONObject> costAccount = productReportService.getCostAccount(advertiserId, startDate, endDate);
+        for (JSONObject jsonObject : costAccount) {
+            executor10Service1.submit(() -> {
+                Long adverId = jsonObject.getLong("advertiserId");
+                String accessToken = jsonObject.getString("accessToken");
+                promoterReportService.getBytedancePromoterHour(adverId, accessToken, startDate, endDate, 1, 1);
+            });
+        }
+    }
+
 
     @GetMapping("/getWxAppInfo")
     public void getWxAppInfo(Long advertiserId) {

+ 35 - 2
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/impl/BytedanceCdpProjectServiceImpl.java

@@ -15,7 +15,6 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
-
 import java.time.Instant;
 import java.util.*;
 
@@ -195,14 +194,46 @@ public class BytedanceCdpProjectServiceImpl implements IBytedanceCdpProjectServi
         entity.put("advertiser_id", advertiserId);
         JSONObject promotionMaterials = entity.getJSONObject("promotion_materials");
         if (!Check.isNull(promotionMaterials)) {
+            String playletSeriesUrlList = promotionMaterials.getString("playlet_series_url_list");
             entity.put("external_url_material_list", promotionMaterials.getString("external_url_material_list"));
-            entity.put("playlet_series_url_list", promotionMaterials.getString("playlet_series_url_list"));
+            entity.put("playlet_series_url_list", playletSeriesUrlList);
             JSONObject miniProgramInfo = promotionMaterials.getJSONObject("mini_program_info");
             if (!Check.isNull(miniProgramInfo)) {
                 entity.put("params", miniProgramInfo.getString("params"));
                 entity.put("app_id", miniProgramInfo.getString("app_id"));
                 entity.put("url", miniProgramInfo.getString("url"));
             }
+            if(!Check.isNull(playletSeriesUrlList)){
+                try {
+                    JSONArray playletUrlArr = JSONObject.parseArray(playletSeriesUrlList);
+                    String playletUrl = playletUrlArr.getString(0);
+                    if (StringUtils.isNotBlank(playletUrl)) {
+                        // 解析 playlet_id
+                        String playletId = HttpUtils.extractQueryParam(playletUrl, "playlet_id");
+                        if (StringUtils.isNotBlank(playletId)) {
+                            entity.put("playlet_id", playletId);
+                        }
+                        // 解析 advertise_param 并 base64 解码
+                        String advertiseParam = HttpUtils.extractQueryParam(playletUrl, "advertise_param");
+                        if (StringUtils.isNotBlank(advertiseParam)) {
+                            try {
+                                String decodedParam = new String(Base64.getDecoder().decode(advertiseParam), "UTF-8");
+                                JSONObject advertiseObj = JSONObject.parseObject(decodedParam);
+                                if (!Check.isNull(advertiseObj)) {
+                                    Long mediaId = advertiseObj.getLong("media_id");
+                                    if (mediaId != null) {
+                                        entity.put("account_mid", mediaId);
+                                    }
+                                }
+                            } catch (Exception e) {
+                                log.error("广告({})advertise_param base64解码失败: {}", entity.getString("promotion_id"), advertiseParam);
+                            }
+                        }
+                    }
+                }catch (Exception e){
+                    log.error("广告({})playlet_series_url_list字段解析失败", entity.getString("promotion_id"));
+                }
+            }
         }
         JSONObject nativeSetting = entity.getJSONObject("native_setting");
         if (!Check.isNull(nativeSetting)) {
@@ -210,6 +241,8 @@ public class BytedanceCdpProjectServiceImpl implements IBytedanceCdpProjectServi
         }
     }
 
+
+
     @Override
     public void getProjectList(Long advertiserId, JSONArray ids, String type, String date, Long errorId, Integer isLog) {
         this.getProjectListVo(advertiserId, ids, type, date, 1, 1, errorId, isLog);

+ 37 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/utils/HttpUtils.java

@@ -3,6 +3,7 @@ package cn.com.ctop.job.bytedance.data.utils;
 import com.alibaba.fastjson.JSONObject;
 import com.google.gson.Gson;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.http.Header;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
@@ -33,6 +34,7 @@ import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.net.URI;
+import java.net.URLDecoder;
 import java.net.URLEncoder;
 import java.nio.charset.Charset;
 import java.security.cert.CertificateException;
@@ -346,4 +348,39 @@ public class HttpUtils {
         }
         return null;
     }
+
+    /**
+     * 从URL中提取指定参数的值
+     * @param url URL字符串
+     * @param paramName 参数名
+     * @return 参数值,不存在则返回null
+     */
+    public static String extractQueryParam(String url, String paramName) {
+        if (StringUtils.isBlank(url) || StringUtils.isBlank(paramName)) {
+            return null;
+        }
+        try {
+            // 处理 aweme:// 协议
+            String queryString;
+            if (url.contains("?")) {
+                queryString = url.substring(url.indexOf("?") + 1);
+            } else {
+                return null;
+            }
+            String[] pairs = queryString.split("&");
+            for (String pair : pairs) {
+                int idx = pair.indexOf("=");
+                if (idx > 0) {
+                    String key = pair.substring(0, idx);
+                    String value = pair.substring(idx + 1);
+                    if (key.equals(paramName)) {
+                        return URLDecoder.decode(value, "UTF-8");
+                    }
+                }
+            }
+        } catch (Exception e) {
+            log.error("解析URL参数失败, url: {}, param: {}", url, paramName);
+        }
+        return null;
+    }
 }

+ 13 - 9
job-bytedance/src/main/resources/logback-dev.xml

@@ -8,7 +8,7 @@
     <property name="LOG_PATTERN" value="%date{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"/>
 
     <!-- 定义日志存储的路径,不要配置相对路径 -->
-    <!-- <property name="FILE_PATH" value="/Users/yumeng/logs/spring-log.%d{yyyy-MM-dd}.%i.log"/>-->
+<!--    <property name="FILE_PATH" value="/Users/yumeng/log/spring-log.%d{yyyy-MM-dd}.%i.log"/>-->
     <property name="FILE_PATH" value="/data/webapp/hr_job-bytedance/log/spring-log.%d{yyyy-MM-dd}.%i.log"/>
 
     <!-- 控制台输出日志 -->
@@ -26,16 +26,20 @@
     <!--每天生成一个日志文件,保存30天的日志文件。rollingFile用来切分文件的 -->
     <appender name="rollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
 
-        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+
             <fileNamePattern>${FILE_PATH}</fileNamePattern>
-            <!-- 日志文件的最大大小 -->
-            <maxFileSize>2MB</maxFileSize>
-            <!-- 保留1天的历史日志 -->
-            <maxHistory>1</maxHistory>
-            <!-- 日志总大小上限,超出删除老文件 -->
+
+            <!-- keep 15 days' worth of history -->
+            <maxHistory>3</maxHistory>
+
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <!-- 日志文件的最大大小 -->
+                <maxFileSize>2MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+
+            <!-- 超出删除老文件 -->
             <totalSizeCap>1GB</totalSizeCap>
-            <!-- 应用启动时清理过期的历史日志 -->
-            <cleanHistoryOnStart>true</cleanHistoryOnStart>
         </rollingPolicy>
 
         <encoder>

+ 13 - 9
job-bytedance/src/main/resources/logback-prod.xml

@@ -8,7 +8,7 @@
     <property name="LOG_PATTERN" value="%date{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"/>
 
     <!-- 定义日志存储的路径,不要配置相对路径 -->
-   <!-- <property name="FILE_PATH" value="/Users/yumeng/logs/spring-log.%d{yyyy-MM-dd}.%i.log"/>-->
+<!--    <property name="FILE_PATH" value="/Users/yumeng/logs/spring-log.%d{yyyy-MM-dd}.%i.log"/>-->
     <property name="FILE_PATH" value="/data/webapp/hr_job-bytedance/log/spring-log.%d{yyyy-MM-dd}.%i.log"/>
 
     <!-- 控制台输出日志 -->
@@ -26,16 +26,20 @@
     <!--每天生成一个日志文件,保存30天的日志文件。rollingFile用来切分文件的 -->
     <appender name="rollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
 
-        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+
             <fileNamePattern>${FILE_PATH}</fileNamePattern>
-            <!-- 日志文件的最大大小 -->
-            <maxFileSize>2MB</maxFileSize>
-            <!-- 保留1天的历史日志 -->
-            <maxHistory>1</maxHistory>
-            <!-- 日志总大小上限,超出删除老文件 -->
+
+            <!-- keep 15 days' worth of history -->
+            <maxHistory>30</maxHistory>
+
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <!-- 日志文件的最大大小 -->
+                <maxFileSize>2MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+
+            <!-- 超出删除老文件 -->
             <totalSizeCap>1GB</totalSizeCap>
-            <!-- 应用启动时清理过期的历史日志 -->
-            <cleanHistoryOnStart>true</cleanHistoryOnStart>
         </rollingPolicy>
 
         <encoder>

+ 13 - 9
job-bytedance/src/main/resources/logback-test.xml

@@ -8,7 +8,7 @@
     <property name="LOG_PATTERN" value="%date{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"/>
 
     <!-- 定义日志存储的路径,不要配置相对路径 -->
-    <!-- <property name="FILE_PATH" value="/Users/yumeng/logs/spring-log.%d{yyyy-MM-dd}.%i.log"/>-->
+<!--        <property name="FILE_PATH" value="/Users/yumeng/log/spring-log.%d{yyyy-MM-dd}.%i.log"/>-->
     <property name="FILE_PATH" value="/data/webapp/hr_job-bytedance/log/spring-log.%d{yyyy-MM-dd}.%i.log"/>
 
     <!-- 控制台输出日志 -->
@@ -26,16 +26,20 @@
     <!--每天生成一个日志文件,保存30天的日志文件。rollingFile用来切分文件的 -->
     <appender name="rollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
 
-        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+
             <fileNamePattern>${FILE_PATH}</fileNamePattern>
-            <!-- 日志文件的最大大小 -->
-            <maxFileSize>2MB</maxFileSize>
-            <!-- 保留1天的历史日志 -->
-            <maxHistory>1</maxHistory>
-            <!-- 日志总大小上限,超出删除老文件 -->
+
+            <!-- keep 15 days' worth of history -->
+            <maxHistory>30</maxHistory>
+
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <!-- 日志文件的最大大小 -->
+                <maxFileSize>2MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+
+            <!-- 超出删除老文件 -->
             <totalSizeCap>1GB</totalSizeCap>
-            <!-- 应用启动时清理过期的历史日志 -->
-            <cleanHistoryOnStart>true</cleanHistoryOnStart>
         </rollingPolicy>
 
         <encoder>