ソースを参照

微小 广告位收入

huangpingkang 1 年間 前
コミット
82c41b1f22

+ 5 - 0
job-adq/pom.xml

@@ -178,6 +178,11 @@
             <artifactId>spring-boot-starter-data-redis</artifactId>
         </dependency>
         <dependency>
+            <groupId>redis.clients</groupId>
+            <artifactId>jedis</artifactId>
+            <version>2.9.0</version>
+        </dependency>
+        <dependency>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-pool2</artifactId>
             <version>2.6.2</version>

+ 24 - 0
job-adq/src/main/java/cn/com/ctop/job/adq/controller/AdqAssetController.java

@@ -1,9 +1,11 @@
 package cn.com.ctop.job.adq.controller;
 
 import cn.com.ctop.job.adq.data.entity.MessageModel;
+import cn.com.ctop.job.adq.data.service.IAdqAdIncomeService;
 import cn.com.ctop.job.adq.data.service.IAdqAssetReportService;
 import cn.com.ctop.job.adq.data.service.IAdqCreativeReportService;
 import cn.com.ctop.job.adq.data.utils.Check;
+import cn.com.ctop.job.adq.data.utils.DateUtils;
 import com.alibaba.fastjson.JSONObject;
 import io.swagger.annotations.Api;
 import lombok.extern.slf4j.Slf4j;
@@ -28,6 +30,8 @@ public class AdqAssetController {
     private IAdqCreativeReportService adqCreativeReportService;
     @Autowired
     private IAdqAssetReportService adqAssetReportService;
+    @Autowired
+    private IAdqAdIncomeService adqAdIncomeService;
 
     @GetMapping("/assetInfo")
     public MessageModel assetInfo(@RequestParam(required = false) Long advertiserId) {
@@ -66,4 +70,24 @@ public class AdqAssetController {
         return MessageModel.ok();
     }
 
+    @GetMapping("/miniAppAdIncome")
+    public MessageModel miniAppAdIncome(@RequestParam(required = false) String appId,
+                                        @RequestParam(required = false) String startDate,
+                                        @RequestParam(required = false) String endDate) {
+        List<JSONObject> adqMiniApp = adqAdIncomeService.getAdqMiniApp(appId);
+        String start = startDate == null ? DateUtils.getNowAddDate("yyyy-MM-dd", -1) : startDate;
+        String end = endDate == null ? DateUtils.getNowDate("yyyy-MM-dd") : endDate;
+        for (JSONObject jsonObject : adqMiniApp) {
+            String app = jsonObject.getString("app_id");
+            Long appletId = jsonObject.getLong("applet_id");
+            dailyExecutorService.submit(new Runnable() {
+                @Override
+                public void run() {
+                    adqAdIncomeService.getAdqAdIncome(start, end, app, appletId, 1, 1, null, null);
+                }
+            });
+        }
+        return MessageModel.ok();
+    }
+
 }

+ 30 - 0
job-adq/src/main/java/cn/com/ctop/job/adq/data/entity/AdqPublisherAdunitGeneral.java

@@ -0,0 +1,30 @@
+package cn.com.ctop.job.adq.data.entity;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+public class AdqPublisherAdunitGeneral {
+    private String appId;
+    private String date;
+    private Integer statDate;
+    private String adUnitId;
+    private String adUnitName;
+    private String adSlot;
+    private Long agencyIncome;
+    private Long clickCount;
+    private java.math.BigDecimal clickRate;
+    private java.math.BigDecimal ecpm;
+    private Long exposureCount;
+    private java.math.BigDecimal exposureRate;
+    private Long income;
+    private Long isSmartAds;
+    private String parentTemplType;
+    private Long publisherIncome;
+    private Long reqSuccCount;
+    private String slotStr;
+}

+ 14 - 0
job-adq/src/main/java/cn/com/ctop/job/adq/data/mapper/AdqAdIncomeMapper.java

@@ -0,0 +1,14 @@
+package cn.com.ctop.job.adq.data.mapper;
+
+import cn.com.ctop.job.adq.data.entity.AdqPublisherAdunitGeneral;
+import com.alibaba.fastjson.JSONObject;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface AdqAdIncomeMapper {
+
+    void insertAdqAdIncome(List<AdqPublisherAdunitGeneral> reports);
+
+    List<JSONObject> queryAdqIaaMiniApp(@Param("appId")String appId);
+}

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

@@ -0,0 +1,31 @@
+<?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.AdqAdIncomeMapper">
+
+    <insert id="insertAdqAdIncome">
+        replace INTO media_api.adq_publisher_adunit_general (
+        app_id,ad_unit_id, ad_unit_name, ad_slot, agency_income,
+        click_count, click_rate, stat_date, ecpm,
+        exposure_count, exposure_rate, income, is_smart_ads,
+        parent_templ_type, publisher_income, req_succ_count, slot_str
+        ) VALUES
+        <foreach collection="list" item="item" separator=",">
+            (
+            #{item.appId}, #{item.adUnitId}, #{item.adUnitName}, #{item.adSlot}, #{item.agencyIncome},
+            #{item.clickCount}, #{item.clickRate}, #{item.statDate}, #{item.ecpm},
+            #{item.exposureCount}, #{item.exposureRate}, #{item.income}, #{item.isSmartAds},
+            #{item.parentTemplType}, #{item.publisherIncome}, #{item.reqSuccCount}, #{item.slotStr}
+            )
+        </foreach>
+    </insert>
+
+    <select id="queryAdqIaaMiniApp" resultType="com.alibaba.fastjson.JSONObject">
+        select m.app_id,l.id applet_id
+        from deepthink.mini_app_info m
+        join thirtpart.ly_applet l on m.app_id = l.app_id
+        where m.business_method in('IAA','MIX') and m.app_id like 'wx%'
+        <if test="appId != null">
+            and m.app_id = #{appId}
+        </if>
+    </select>
+</mapper>

+ 10 - 0
job-adq/src/main/java/cn/com/ctop/job/adq/data/service/IAdqAdIncomeService.java

@@ -0,0 +1,10 @@
+package cn.com.ctop.job.adq.data.service;
+
+import com.alibaba.fastjson.JSONObject;
+
+import java.util.List;
+
+public interface IAdqAdIncomeService {
+    List<JSONObject> getAdqMiniApp(String appId);
+    void getAdqAdIncome(String startDt, String endDt, String appId, Long appletId, Integer page, Integer isLog, Long errId, Integer isSend);
+}

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

@@ -0,0 +1,122 @@
+package cn.com.ctop.job.adq.data.service.impl;
+
+import cn.com.ctop.job.adq.data.entity.AdqErrorLog;
+import cn.com.ctop.job.adq.data.entity.AdqPublisherAdunitGeneral;
+import cn.com.ctop.job.adq.data.mapper.AdqAdIncomeMapper;
+import cn.com.ctop.job.adq.data.mapper.AdqErrorLogMapper;
+import cn.com.ctop.job.adq.data.service.IAdqAdIncomeService;
+import cn.com.ctop.job.adq.data.utils.AlertUtils;
+import cn.com.ctop.job.adq.data.utils.Check;
+import cn.com.ctop.job.adq.data.utils.HttpUtils;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+@Service
+@Slf4j
+public class AdqAdIncomeServiceImpl implements IAdqAdIncomeService {
+    @Resource
+    private RedisTemplate redis2Template_db5;
+    @Resource
+    private AdqAdIncomeMapper adqAdIncomeMapper;
+    @Autowired
+    private AdqErrorLogMapper adqErrorLogMapper;
+
+    public List<JSONObject> getAdqMiniApp(String appId) {
+        return adqAdIncomeMapper.queryAdqIaaMiniApp(appId);
+    }
+
+    public void getAdqAdIncome(String startDt, String endDt, String appId, Long appletId, Integer page, Integer isLog, Long errId, Integer isSend) {
+        try {
+            String url = "https://api.weixin.qq.com/publisher/stat";
+            Object tokenObj = redis2Template_db5.opsForValue().get("wechat-applet-access-token-key-" + appletId);
+            if (tokenObj == null) {
+                log.error("微小广告收入拉取获取token为空 [{}] {}~{} {}", appId, startDt, endDt, appletId);
+                return;
+            }
+            int pageSize = 1000;
+            Map<String, Object> paramsMap = new HashMap<>();
+            paramsMap.put("access_token", tokenObj.toString());
+            paramsMap.put("action", "publisher_adunit_general");
+            paramsMap.put("page", page);
+            paramsMap.put("page_size", pageSize);
+            paramsMap.put("start_date", startDt);
+            paramsMap.put("end_date", endDt);
+            String s = HttpUtils.httpGet(url, paramsMap, null);
+            JSONObject jsonObject = JSONObject.parseObject(s);
+            List<AdqPublisherAdunitGeneral> reports = new ArrayList<>();
+            boolean hasMore = false;
+            if (!Check.isNull(jsonObject)) {
+                Integer code = jsonObject.getInteger("ret");
+                if(code == 2009) {
+                    return; //无效的流量主
+                }
+                if (code == 0) {
+                    JSONArray list = jsonObject.getJSONArray("list");
+                    if (!Check.isNull(list)) {
+                        hasMore = list.size() == pageSize;
+                        for (int i = 0; i < list.size(); i++) {
+                            JSONObject dataJson = list.getJSONObject(i);
+                            JSONObject statItem = dataJson.getJSONObject("stat_item");
+                            statItem.put("ad_unit_id", dataJson.getString("ad_unit_id"));
+                            statItem.put("ad_unit_name", dataJson.getString("ad_unit_name"));
+                            AdqPublisherAdunitGeneral report = JSONObject.parseObject(statItem.toJSONString(), AdqPublisherAdunitGeneral.class);
+                            report.setAppId(appId);
+                            report.setStatDate(Integer.valueOf(report.getDate().replace("-", "")));
+                            System.out.println(report);
+                            reports.add(report);
+                        }
+                    }
+
+                } else {
+                    log.error("微小广告收入拉取失败,app_id:{} {}~{},返回信息:{}", appId, startDt, endDt, jsonObject);
+                    insertErrorLog(isLog, System.currentTimeMillis(), "adq_ma_ad_income", startDt, endDt, jsonObject.fluentPut("app_id", appId).toJSONString());
+                }
+            } else {
+                log.error("微小广告收入拉取失败,app_id:{} {}~{},返回为空。", appId, startDt, endDt);
+                insertErrorLog(isLog, System.currentTimeMillis(), "adq_ma_ad_income", startDt, endDt, new JSONObject().fluentPut("app_id", appId).fluentPut("msg", "返回为空").toJSONString());
+            }
+            if (!Check.isNull(reports)) {
+                adqAdIncomeMapper.insertAdqAdIncome(reports);
+            }
+
+            if (hasMore) {
+                getAdqAdIncome(startDt, endDt, appId, appletId, page + 1, isLog, errId, isSend);
+            } else {
+                log.info("微小广告收入拉取完成,app_id:{} {}~{}。", appId, startDt, endDt);
+                if (errId != null) {
+                    adqErrorLogMapper.deleteInfoByErrorId(errId);
+                }
+                if (isSend != null && isSend == 1) {
+                    AlertUtils.sendMessage(System.currentTimeMillis(), startDt, endDt, 3, "daily", 1, "adq_ma_ad_income");
+                }
+            }
+        } catch (Exception e) {
+            log.error("微小广告收入拉取失败,app_id:{} {}~{}。", appId, startDt, endDt,e);
+        }
+    }
+
+    private void insertErrorLog(Integer isLog, Long advertiserId, String dataDimension, String startDate, String endDate, String msg) {
+        if (isLog != null && isLog == 1) {
+            AdqErrorLog errorInfo = new AdqErrorLog();
+            errorInfo.setAdvertiserId(advertiserId);
+            errorInfo.setStartDate(startDate);
+            errorInfo.setEndDate(endDate);
+            errorInfo.setDataDimension(dataDimension);
+            errorInfo.setDataType("daily");
+            errorInfo.setMsg(msg);
+            adqErrorLogMapper.replaceErrorInfo(errorInfo);
+        }
+    }
+
+}

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

@@ -54,6 +54,14 @@ public class DateUtils {
         return sdf.format(date);
     }
 
+    public static String getNowAddDate(String format, Integer day) {
+        SimpleDateFormat sdf = new SimpleDateFormat(format);
+        Calendar calendar = Calendar.getInstance();
+        calendar.add(Calendar.DAY_OF_MONTH, day);
+        Date resultDate = calendar.getTime();
+        return sdf.format(resultDate);
+    }
+
     public static Integer getIntegerDate(String date) {
         return Integer.valueOf(date.replace("-", ""));
     }

+ 206 - 0
job-adq/src/main/java/cn/com/ctop/job/adq/utils/Redis2Config.java

@@ -0,0 +1,206 @@
+package cn.com.ctop.job.adq.utils;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.RedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+import redis.clients.jedis.JedisPoolConfig;
+
+@Configuration
+public class Redis2Config {
+
+    @Value("${spring.redis2.host}")
+    private String host;
+
+    @Value("${spring.redis2.port}")
+    private int port;
+
+    @Value("${spring.redis2.database}")
+    private int database;
+
+    @Value("${spring.redis2.password}")
+    private String password;
+
+    @Value("${spring.redis2.pool.max-idle}")
+    private int maxIdle;
+
+    @Value("${spring.redis2.pool.min-idle}")
+    private int minIdle;
+
+    @Value("${spring.redis2.pool.max-active}")
+    private int maxActive;
+
+    @Value("${spring.redis2.pool.max-wait}")
+    private int maxWait;
+
+
+    /**
+     * JedisPoolConfig 连接池
+     * @return
+     */
+    public JedisPoolConfig redis2PoolConfig() {
+        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
+        // 最大空闲数
+        jedisPoolConfig.setMaxIdle(maxIdle);
+        jedisPoolConfig.setMinIdle(minIdle);
+        // 连接池的最大数据库连接数
+        jedisPoolConfig.setMaxTotal(maxActive);
+        // 最大建立连接等待时间
+        jedisPoolConfig.setMaxWaitMillis(maxWait);
+        return jedisPoolConfig;
+    }
+
+    private JedisConnectionFactory redis2ConnectionFactory(JedisPoolConfig redisPoolConfig, int database){
+
+        JedisConnectionFactory JedisConnectionFactory = new JedisConnectionFactory(redisPoolConfig);
+
+        JedisConnectionFactory.setHostName(host);
+        JedisConnectionFactory.setPort(port);
+        JedisConnectionFactory.setPassword(password);
+        JedisConnectionFactory.setDatabase(database);
+        JedisConnectionFactory.afterPropertiesSet();
+        return JedisConnectionFactory;
+    }
+
+    private RedisTemplate buildRedis2Template(RedisConnectionFactory connectionFactory){
+
+        RedisTemplate template = new RedisTemplate();
+        template.setConnectionFactory(connectionFactory);
+
+        RedisSerializer<String> stringSerializer = new StringRedisSerializer();
+        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
+        ObjectMapper objectMapper = new ObjectMapper();
+        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
+        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
+
+        template.setKeySerializer(stringSerializer);
+        template.setValueSerializer(stringSerializer);
+        template.setHashKeySerializer(stringSerializer);
+        template.setHashValueSerializer(jackson2JsonRedisSerializer);
+
+        template.afterPropertiesSet();
+        return template;
+    }
+
+    @Bean(name = "redis2TemplateDefault")
+    public RedisTemplate redis2TemplateDefault() {
+        RedisTemplate redisTemplate = buildRedis2Template(redis2ConnectionFactory(redis2PoolConfig(), database));
+        redisTemplate.setHashValueSerializer(new StringRedisSerializer());
+        return redisTemplate;
+    }
+
+    @Bean(name = "redis2Template_db2")
+    public RedisTemplate redis2Template_db2() {
+        RedisTemplate redisTemplate = buildRedis2Template(redis2ConnectionFactory(redis2PoolConfig(), 2));
+        redisTemplate.setHashValueSerializer(new StringRedisSerializer());
+        return redisTemplate;
+    }
+
+    @Bean(name = "redis2Template_db5")
+    public RedisTemplate redis2Template_db5() {
+        RedisTemplate redisTemplate = buildRedis2Template(redis2ConnectionFactory(redis2PoolConfig(), 5));
+        redisTemplate.setHashValueSerializer(new StringRedisSerializer());
+        return redisTemplate;
+    }
+
+    @Bean(name = "redis2Template_db6")
+    public RedisTemplate redis2Template_db6() {
+        RedisTemplate redisTemplate = buildRedis2Template(redis2ConnectionFactory(redis2PoolConfig(), 6));
+        redisTemplate.setHashValueSerializer(new StringRedisSerializer());
+        return redisTemplate;
+    }
+
+    @Bean(name = "redis2Template_db7")
+    public RedisTemplate redis2Template_db7() {
+        RedisTemplate redisTemplate = buildRedis2Template(redis2ConnectionFactory(redis2PoolConfig(), 7));
+        return redisTemplate;
+    }
+
+    @Bean(name = "redis2Template_db8")
+    public RedisTemplate redis2Template_db8() {
+        RedisTemplate redisTemplate = buildRedis2Template(redis2ConnectionFactory(redis2PoolConfig(), 8));
+        redisTemplate.setHashValueSerializer(new StringRedisSerializer());
+        return redisTemplate;
+    }
+
+    @Bean(name = "redis2Template_db9")
+    public RedisTemplate redis2Template_db9() {
+        RedisTemplate redisTemplate = buildRedis2Template(redis2ConnectionFactory(redis2PoolConfig(), 9));
+        redisTemplate.setHashValueSerializer(new StringRedisSerializer());
+        return redisTemplate;
+    }
+
+
+    public void setHost(String host) {
+        this.host = host;
+    }
+
+    public void setPort(int port) {
+        this.port = port;
+    }
+
+    public void setDatabase(int database) {
+        this.database = database;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public void setMaxIdle(int maxIdle) {
+        this.maxIdle = maxIdle;
+    }
+
+    public void setMinIdle(int minIdle) {
+        this.minIdle = minIdle;
+    }
+
+    public void setMaxActive(int maxActive) {
+        this.maxActive = maxActive;
+    }
+
+    public void setMaxWait(int maxWait) {
+        this.maxWait = maxWait;
+    }
+
+    public String getHost() {
+
+        return host;
+    }
+
+    public int getPort() {
+        return port;
+    }
+
+    public int getDatabase() {
+        return database;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public int getMaxIdle() {
+        return maxIdle;
+    }
+
+    public int getMinIdle() {
+        return minIdle;
+    }
+
+    public int getMaxActive() {
+        return maxActive;
+    }
+
+    public int getMaxWait() {
+        return maxWait;
+    }
+}

+ 10 - 1
job-adq/src/main/resources/application.yml

@@ -109,7 +109,16 @@ spring:
         # #连接池最大阻塞等待时间(使用负值表示没有限制)
         max-wait: -1ms
 
-
+  redis2:
+    database: 0
+    host: r-2zelacjrljt205nsb1pd.redis.rds.aliyuncs.com
+    password: Huanrui@2025!@
+    pool:
+      max-active: 10
+      max-idle: 10
+      max-wait: 80
+      min-idle: 8
+    port: 6379
 
 #mybatis plus 设置
 mybatis-plus: