瀏覽代碼

对接广点通日流水报表

lining 1 年之前
父節點
當前提交
798f5a75bf

+ 12 - 4
job-adq/src/main/java/cn/com/ctop/job/adq/controller/AdqController.java

@@ -1,9 +1,6 @@
 package cn.com.ctop.job.adq.controller;
 
-import cn.com.ctop.job.adq.data.service.IAdqAccountReportService;
-import cn.com.ctop.job.adq.data.service.IAdqAdminAdvertiserListService;
-import cn.com.ctop.job.adq.data.service.IAdqCreativeReportService;
-import cn.com.ctop.job.adq.data.service.IAdqRetryReportService;
+import cn.com.ctop.job.adq.data.service.*;
 import cn.com.ctop.job.adq.data.utils.Check;
 import cn.com.ctop.job.adq.data.utils.DateUtils;
 import com.alibaba.fastjson.JSONObject;
@@ -13,6 +10,7 @@ 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;
@@ -41,6 +39,9 @@ public class AdqController {
     @Autowired
     private IAdqAdminAdvertiserListService adminAdvertiserListService;
 
+    @Autowired
+    private IAdqFlowDetailsReportService adqFlowDetailsReportService;
+
     @GetMapping("/testCreativeHour")
     public JSONObject testRefreshToken(Long advertiserId, String accessToken, String date) {
        // accountReportService.getAdqAccountHour(advertiserId, accessToken, "2025-03-28", date, 1, 1);
@@ -85,5 +86,12 @@ public class AdqController {
         return null;
     }
 
+    @GetMapping("/flowDetailsReport")
+    public void flowDetailsReport(@RequestParam(required = false) Long advertiserId, String accessToken, String startDate, String endDate) {
+
+        adqFlowDetailsReportService.getAdqFlowDetailsDailyReport(advertiserId, accessToken, startDate, endDate, 1);
+
+    }
+
 
 }

+ 60 - 0
job-adq/src/main/java/cn/com/ctop/job/adq/data/entity/AdqFlowDetailsReportDaily.java

@@ -0,0 +1,60 @@
+package cn.com.ctop.job.adq.data.entity;
+
+import lombok.Builder;
+import lombok.Data;
+
+/**
+ * @author lining
+ * @ClassName AdqFlowDetailsReportDaily
+ * @description: TODO
+ * @date 2025年04月21日
+ * @version: 1.0
+ */
+@Data
+@Builder
+public class AdqFlowDetailsReportDaily {
+    /**
+     * 广告主ID account_id
+     */
+    private Long advertiserId;
+    /**
+     * 数据起始时间 time
+     */
+    private Long statTimeDay;
+    /**
+     * 资金账户类型
+     */
+    private String fundType;
+    /**
+     * 总存入,单位为分
+     */
+    private Long deposit;
+    /**
+     * 总支出,单位为分
+     */
+    private Long paid;
+    /**
+     * 总入账,单位为分
+     */
+    private Long transIn;
+    /**
+     * 总出账,单位为分
+     */
+    private Long transOut;
+    /**
+     * 授信修改,单位为分
+     */
+    private Long creditModify;
+    /**
+     * 授信余额,单位为分
+     */
+    private Long balance;
+    /**
+     * 预授权余额,单位为分
+     */
+    private Long preauthBalance;
+
+
+
+
+}

+ 19 - 0
job-adq/src/main/java/cn/com/ctop/job/adq/data/mapper/AdqFlowDetailsReportDailyMapper.java

@@ -0,0 +1,19 @@
+package cn.com.ctop.job.adq.data.mapper;
+
+import cn.com.ctop.job.adq.data.entity.AdqFlowDetailsReportDaily;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * @author lining
+ * @ClassName AdqFlowDetailsReportDailyMapper
+ * @description: TODO
+ * @date 2025年04月21日
+ * @version: 1.0
+ */
+public interface AdqFlowDetailsReportDailyMapper {
+
+    void replaceFlowDetailsReportDailies(@Param("list") List<AdqFlowDetailsReportDaily> dailyList);
+
+}

+ 34 - 0
job-adq/src/main/java/cn/com/ctop/job/adq/data/mapper/xml/AdqFlowDetailsReportMapper.xml

@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="cn.com.ctop.job.adq.data.mapper.AdqFlowDetailsReportDailyMapper">
+    <insert id="replaceFlowDetailsReportDailies">
+        replace into adq_flow_details_report_daily (
+            advertiser_id,
+            stat_time_day,
+            fund_type,
+            deposit,
+            paid,
+            trans_in,
+            trans_out,
+            credit_modify,
+            balance,
+            preauth_balance
+        )
+        values
+        <foreach collection="list" item="item" separator=",">
+            (
+            #{item.advertiserId},
+            #{item.statTimeDay},
+            #{item.fundType},
+            #{item.deposit},
+            #{item.paid},
+            #{item.transIn},
+            #{item.transOut},
+            #{item.creditModify},
+            #{item.balance},
+            #{item.preauthBalance}
+            )
+        </foreach>
+    </insert>
+</mapper>
+

+ 13 - 0
job-adq/src/main/java/cn/com/ctop/job/adq/data/service/IAdqFlowDetailsReportService.java

@@ -0,0 +1,13 @@
+package cn.com.ctop.job.adq.data.service;
+
+/**
+ * @author lining
+ * @ClassName IAdqFlowDetailsReportService
+ * @description: TODO
+ * @date 2025年04月21日
+ * @version: 1.0
+ */
+public interface IAdqFlowDetailsReportService {
+
+    void getAdqFlowDetailsDailyReport(Long advertiserId, String accessToken, String startDate, String endDate, Integer page);
+}

+ 148 - 0
job-adq/src/main/java/cn/com/ctop/job/adq/data/service/impl/AdqFlowDetailsReportServiceImpl.java

@@ -0,0 +1,148 @@
+package cn.com.ctop.job.adq.data.service.impl;
+
+import cn.com.ctop.job.adq.data.entity.AdqFlowDetailsReportDaily;
+import cn.com.ctop.job.adq.data.mapper.AdqFlowDetailsReportDailyMapper;
+import cn.com.ctop.job.adq.data.service.IAdqFlowDetailsReportService;
+import cn.com.ctop.job.adq.data.utils.Check;
+import cn.com.ctop.job.adq.data.utils.DateUtils;
+import cn.com.ctop.job.adq.data.utils.HttpUtils;
+import cn.com.ctop.job.adq.utils.RandomStringGenerator;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.time.Instant;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author lining
+ * @ClassName AdqFlowDetailsReportServiceImpl
+ * @description: TODO
+ * @date 2025年04月21日
+ * @version: 1.0
+ */
+@Service
+@Slf4j
+public class AdqFlowDetailsReportServiceImpl implements IAdqFlowDetailsReportService {
+
+    @Resource
+    private AdqFlowDetailsReportDailyMapper adqFlowDetailsReportDailyMapper;
+    @Override
+    public void getAdqFlowDetailsDailyReport(Long advertiserId, String accessToken, String startDate, String endDate, Integer page) {
+        Map<String, Object> paramsMap = new HashMap<>();
+        paramsMap.put("access_token", accessToken);
+        long timestamp = Instant.now().getEpochSecond();
+        paramsMap.put("timestamp", String.valueOf(timestamp));
+        paramsMap.put("nonce", RandomStringGenerator.generateRandomString(32));
+        paramsMap.put("page", page);
+        paramsMap.put("page_size", 1000);
+        paramsMap.put("account_id", advertiserId);
+
+        JSONObject date_range = new JSONObject();
+        date_range.put("start_date", startDate);
+        date_range.put("end_date", endDate);
+        paramsMap.put("date_range", date_range);
+
+        String s = HttpUtils.httpGet("https://api.e.qq.com/v3.0/daily_balance_report/get", paramsMap, null);
+        JSONObject jsonObject = JSONObject.parseObject(s);
+
+        if (Check.isNull(jsonObject)) {
+            log.info("账户id:{},广告流水详情请求结果返回为空", advertiserId);
+            return;
+        }
+
+        List<AdqFlowDetailsReportDaily> dailyList = new ArrayList<>();
+        int totalPage = 1;
+        if (!Check.isNull(jsonObject)) {
+            Integer code = jsonObject.getInteger("code");
+            if (code == 0) {
+                JSONObject data = jsonObject.getJSONObject("data");
+                if (!Check.isNull(data)) {
+                    totalPage = data.getJSONObject("page_info").getInteger("total_page");
+                    JSONArray list = data.getJSONArray("list");
+                    if (!Check.isNull(list)) {
+                        for (int i = 0; i < list.size(); i++) {
+                            JSONObject dataJson = list.getJSONObject(i);
+                            Long account_id = dataJson.getLong("account_id");
+                            String fund_type = dataJson.getString("fund_type");
+                            Long time = dataJson.getLong("time");
+                            time = Long.parseLong(DateUtils.getDateFormat(new Date(time * 1000L)));
+                            Long deposit = dataJson.getLong("deposit");
+                            Long paid = dataJson.getLong("paid");
+                            Long trans_in = dataJson.getLong("trans_in");
+                            Long trans_out = dataJson.getLong("trans_out");
+                            Long credit_modify = dataJson.getLong("credit_modify");
+                            Long balance = dataJson.getLong("balance");
+                            Long preauth_balance = dataJson.getLong("preauth_balance");
+
+                            AdqFlowDetailsReportDaily adqFlowDetailsReportDaily = AdqFlowDetailsReportDaily.builder()
+                                    .advertiserId(account_id)
+                                    .fundType(fund_type)
+                                    .statTimeDay(time)
+                                    .deposit(deposit)
+                                    .paid(paid)
+                                    .transIn(trans_in)
+                                    .transOut(trans_out)
+                                    .creditModify(credit_modify)
+                                   .balance(balance)
+                                    .preauthBalance(preauth_balance)
+                                    .build();
+
+                            dailyList.add(adqFlowDetailsReportDaily);
+
+                        }
+
+                        if(!Check.isNull(dailyList)){
+                            log.info("账户id:{},广告流水详情请求结果返回成功,开始入库", advertiserId);
+
+                            dailyList = buildFlowDetailsReportDaily(dailyList);
+
+                            adqFlowDetailsReportDailyMapper.replaceFlowDetailsReportDailies(dailyList);
+                        }
+                    }
+                }
+            }
+        }
+
+        if (page < totalPage) {
+            try {
+                Thread.sleep(500L);
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            }
+            getAdqFlowDetailsDailyReport(advertiserId, accessToken, startDate, endDate, page + 1);
+        }
+    }
+
+    private List<AdqFlowDetailsReportDaily> buildFlowDetailsReportDaily(List<AdqFlowDetailsReportDaily> dailyList) {
+        List<AdqFlowDetailsReportDaily> resultList = new ArrayList<>();
+        Map<Long, List<AdqFlowDetailsReportDaily>> dailyListMap = dailyList.stream().collect(Collectors.groupingBy(AdqFlowDetailsReportDaily::getStatTimeDay));
+        dailyListMap.forEach((k, v) -> {
+            if (v.size() > 1) {
+                resultList.add(merge(v.get(0), v.get(1)));
+            }else{
+                resultList.addAll(v);
+            }
+        });
+        return resultList;
+    }
+
+    private AdqFlowDetailsReportDaily merge(AdqFlowDetailsReportDaily o1, AdqFlowDetailsReportDaily o2){
+        AdqFlowDetailsReportDaily o3 = AdqFlowDetailsReportDaily.builder()
+                .advertiserId(o1.getAdvertiserId())
+                .statTimeDay(o1.getStatTimeDay())
+                .fundType(o1.getFundType())
+                .deposit(o1.getDeposit() + o2.getDeposit())
+                .paid(o1.getPaid() + o2.getPaid())
+                .transIn(o1.getTransIn() + o2.getTransIn())
+                .transOut(o1.getTransOut()+ o2.getTransOut())
+                .creditModify(o1.getCreditModify() + o2.getCreditModify())
+                .balance(o1.getBalance() + o2.getBalance())
+                .preauthBalance(o1.getPreauthBalance() + o2.getPreauthBalance())
+                .build();
+        return o3;
+    }
+}

+ 7 - 0
job-adq/src/main/java/cn/com/ctop/job/adq/data/utils/DateUtils.java

@@ -12,6 +12,7 @@ import java.util.List;
 
 @Slf4j
 public class DateUtils {
+    public static final String DATE_FORMAT = "yyyyMMdd";
 
 
     public static List<String> getDays(String startTime, String endTime) {
@@ -136,4 +137,10 @@ public class DateUtils {
         }
         return dateList;
     }
+
+    public static String getDateFormat(Date date) {
+        SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
+        String formattedDate = sdf.format(date);
+        return formattedDate;
+    }
 }

+ 54 - 0
job-adq/src/main/java/cn/com/ctop/job/adq/handler/AdqFlowDetailsReportJob.java

@@ -0,0 +1,54 @@
+package cn.com.ctop.job.adq.handler;
+
+import cn.com.ctop.job.adq.data.service.IAdqFlowDetailsReportService;
+import cn.com.ctop.job.adq.data.utils.Check;
+import cn.com.ctop.job.adq.data.utils.DateUtils;
+import com.xxl.job.core.context.XxlJobHelper;
+import com.xxl.job.core.handler.annotation.XxlJob;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * @author lining
+ * @ClassName AdqFlowDetailsReportJob
+ * @description: TODO
+ * @date 2025年04月21日
+ * @version: 1.0
+ */
+@Slf4j
+@Component
+public class AdqFlowDetailsReportJob {
+    private static ExecutorService executorService = Executors.newFixedThreadPool(2);
+
+    @Resource
+    private IAdqFlowDetailsReportService adqFlowDetailsReportService;
+
+    @XxlJob("flowDetailsDaily")
+    public void flowDetailsDaily() throws Exception {
+        String param = XxlJobHelper.getJobParam(); // 执行参数
+        if (Check.isNull(param)) {
+            log.error("入参为空");
+            return;
+        }
+
+        String nowDate = DateUtils.getNowDate("yyyy-MM-dd");
+        String data = DateUtils.getAnotherDay("yyyy-MM-dd", nowDate, -1);
+        String[] s = param.split("_");
+        Long advertiserId = Long.valueOf(s[0]);
+        String accessToken = s[1];
+
+        executorService.submit(new Runnable() {
+            @Override
+            public void run() {
+                if (!Check.isNull(accessToken)) {
+                    adqFlowDetailsReportService.getAdqFlowDetailsDailyReport(advertiserId, accessToken, data, data, 1);
+                }
+            }
+        });
+    }
+}