Przeglądaj źródła

redis 缓存Agent首页广告统计数据每小时一次

marxjaw 3 miesięcy temu
rodzic
commit
34f385fbac

+ 25 - 7
yt-agent/agent-service/src/main/java/com/ytpm/controller/AgentIndexController.java

@@ -1,21 +1,27 @@
 package com.ytpm.controller;
 
 import cn.hutool.core.collection.CollUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.mysql.cj.xdevapi.JsonArray;
 import com.ytpm.agent.model.YtApp;
 import com.ytpm.agent.view.AgentAdGroupStaticsVO;
 import com.ytpm.agent.view.AgentTopCountView;
 import com.ytpm.agent.view.AgentUserInfo;
 import com.ytpm.app.param.AppQueryUserTodayTimeParam;
 import com.ytpm.app.param.AppUserQueryParam;
+import com.ytpm.constant.StrConstant;
 import com.ytpm.dao.AppMapper;
 import com.ytpm.feign.AppFeign;
 import com.ytpm.feign.RiskFeign;
 import com.ytpm.general.Result;
 import com.ytpm.service.AgentAppService;
 import com.ytpm.util.DateUtil;
+import com.ytpm.util.RedisService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -47,6 +53,8 @@ public class AgentIndexController {
 
     @Resource
     private AppMapper appMapper;
+    @Autowired
+    private RedisService redisService;
 
 
     /**
@@ -72,14 +80,24 @@ public class AgentIndexController {
     @ApiOperation("查询广告平台收益")
     @PostMapping("/profit")
     public Result<List<AgentAdGroupStaticsVO>> profit(@ApiIgnore @AuthenticationPrincipal AgentUserInfo userInfo) {
-        //查询代理商拥有的app
-        List<YtApp> ytApps = appMapper.queryAll(userInfo.getUserId());
-        if(CollUtil.isEmpty(ytApps)){
-            return Result.resultErr("未找到您的应用,请在应用管理新增");
+        String redisKey = StrConstant.PLATFORM_AGENT_SUFFIX+StrConstant.PROFIT+userInfo.getUserId();
+        //判断无缓存或者缓存小于3分钟时查询最新数据, 保存一小时
+        if(!redisService.hasKey(redisKey) || redisService.getExpire(redisKey) < 3){
+            //查询代理商拥有的app
+            List<YtApp> ytApps = appMapper.queryAll(userInfo.getUserId());
+            if(CollUtil.isEmpty(ytApps)){
+                return Result.resultErr("未找到您的应用,请在应用管理新增");
+            }
+            String appIds = ytApps.stream().map(YtApp::getAppId).collect(Collectors.joining(","));
+            //分广告平台,分别统计用户当天、昨日、本月的数据封装并返回
+            List<AgentAdGroupStaticsVO> agentProfit = appFeign.getAgentProfit(appIds);
+            redisService.setTimeOutMinutesStr(redisKey, JSON.toJSONString(agentProfit),60);
+            return Result.resultObjOk(agentProfit);
         }
-        String appIds = ytApps.stream().map(YtApp::getAppId).collect(Collectors.joining(","));
-        //分广告平台,分别统计用户当天、昨日、本月的数据封装并返回
-        return Result.resultObjOk(appFeign.getAgentProfit(appIds));
+        //有缓存则从缓存中获取
+        String str = redisService.getStr(redisKey);
+        List<AgentAdGroupStaticsVO> vos = JSONArray.parseArray(str, AgentAdGroupStaticsVO.class);
+        return Result.resultObjOk(vos);
     }
 
     @ApiOperation("查询用户行为数据统计")

+ 15 - 1
yt-app/app-service/src/main/java/com/ytpm/dao/dyz/AdRecordMapper.java

@@ -2,9 +2,10 @@ package com.ytpm.dao.dyz;
 
 import com.ytpm.agent.view.AgentAdGroupStaticsVO;
 import com.ytpm.app.model.YtDyzAdRecord;
-import com.ytpm.app.param.AppQueryUserTodayTimeParam;
 import com.ytpm.app.param.YtAppUserListParam;
 import com.ytpm.middle.view.AppRevenueHourVO;
+import com.ytpm.middle.view.NetWorkEcpmVO;
+import com.ytpm.middle.view.NetWorkRevenueVO;
 import org.apache.ibatis.annotations.Param;
 import org.mapstruct.Mapper;
 
@@ -42,8 +43,16 @@ public interface AdRecordMapper {
      */
     BigDecimal getRevenueByType(@Param("appIds") String appIds,@Param("type") int type);
 
+    /**
+     * 根据应用和广告平台查询收益
+     */
     BigDecimal getNetworkRevenueByType(@Param("appIds") String appIds,@Param("type") int type,@Param("networkId") String networkId);
 
+    /**
+     * 根据广告平台ID获取收益
+     */
+    List<NetWorkRevenueVO> getRevenueByIds(@Param("appIds") String appIds, @Param("type") int type, @Param("networkIds") String networkIds);
+
     /**
      * 根据应用查询ecpm
      */
@@ -51,6 +60,11 @@ public interface AdRecordMapper {
 
     BigDecimal getNetworkEcpmByType(@Param("appIds")String appIds, @Param("type")int type,@Param("networkId") String networkId);
 
+    /**
+     * 根据广告平台ID获取平均ecpm
+     */
+    List<NetWorkEcpmVO> getEcpmByIds(@Param("appIds")String appIds, @Param("type")int type, @Param("networkIds") String networkIds);
+
     /**
      * 查询广告平台分组统计
      */

+ 30 - 11
yt-app/app-service/src/main/java/com/ytpm/service/dyz/impl/AdServiceImpl.java

@@ -27,6 +27,8 @@ import com.ytpm.middle.view.DashboardAppRevenueVO;
 import com.ytpm.middle.view.DashboardRankingListVO;
 import com.ytpm.middle.view.DashboardRevenueVO;
 import com.ytpm.middle.view.DashboardRiskVO;
+import com.ytpm.middle.view.NetWorkEcpmVO;
+import com.ytpm.middle.view.NetWorkRevenueVO;
 import com.ytpm.middle.view.UserRankingListVO;
 import com.ytpm.service.dyz.AdService;
 import org.springframework.beans.BeanUtils;
@@ -208,6 +210,27 @@ public class AdServiceImpl implements AdService {
     public List<AgentAdGroupStaticsVO> getAgentProfit(String appIds) {
         //查询今日的 按小时 按广告平台分组数据
         List<AgentAdGroupStaticsVO> vos = adRecordMapper.getAdGroupStatics(appIds);
+        String networkIds = vos.stream().map(AgentAdGroupStaticsVO::getNetowrkId).collect(Collectors.joining(","));
+        //根据广告平台查询 收益分组 1-今日  2-昨日 3-本月
+        List<NetWorkRevenueVO> revenueToday = adRecordMapper.getRevenueByIds(appIds, 1, networkIds);
+        List<NetWorkRevenueVO> revenueYestDay = adRecordMapper.getRevenueByIds(appIds, 2, networkIds);
+        List<NetWorkRevenueVO> revenueMonth = adRecordMapper.getRevenueByIds(appIds, 3, networkIds);
+        Map<String, BigDecimal> revenueTodayMap = revenueToday.stream().collect(
+                Collectors.toMap(NetWorkRevenueVO::getNetWorkId, NetWorkRevenueVO::getNetWorkRevenue));
+        Map<String, BigDecimal> revenueYestdayMap = revenueYestDay.stream().collect(
+                Collectors.toMap(NetWorkRevenueVO::getNetWorkId, NetWorkRevenueVO::getNetWorkRevenue));
+        Map<String, BigDecimal> revenueMonthMap = revenueMonth.stream().collect(
+                Collectors.toMap(NetWorkRevenueVO::getNetWorkId, NetWorkRevenueVO::getNetWorkRevenue));
+        //根据广告平台查询 ecpm分组 1-今日  2-昨日 3-本月
+        List<NetWorkEcpmVO> ecpmToday = adRecordMapper.getEcpmByIds(appIds, 1, networkIds);
+        List<NetWorkEcpmVO> ecpmYestDay = adRecordMapper.getEcpmByIds(appIds, 2, networkIds);
+        List<NetWorkEcpmVO> ecpmMonth = adRecordMapper.getEcpmByIds(appIds, 3, networkIds);
+        Map<String, BigDecimal> ecpmTodayMap = ecpmToday.stream().collect(
+                Collectors.toMap(NetWorkEcpmVO::getNetWorkId, NetWorkEcpmVO::getNetWorkEcpm));
+        Map<String, BigDecimal> ecpmYestdayMap = ecpmYestDay.stream().collect(
+                Collectors.toMap(NetWorkEcpmVO::getNetWorkId, NetWorkEcpmVO::getNetWorkEcpm));
+        Map<String, BigDecimal> ecpmMonthMap = ecpmMonth.stream().collect(
+                Collectors.toMap(NetWorkEcpmVO::getNetWorkId, NetWorkEcpmVO::getNetWorkEcpm));
         for (AgentAdGroupStaticsVO vo : vos) {
             //今日收益
             List<AgentNetworkRevenueGroupVO> networkRevenueGroups = vo.getNetworkRevenueGroups();
@@ -215,24 +238,20 @@ public class AdServiceImpl implements AdService {
                 Map<String, BigDecimal> revenueMap = networkRevenueGroups.stream().collect(
                         Collectors.toMap(AgentNetworkRevenueGroupVO::getHour, AgentNetworkRevenueGroupVO::getRevenue));
                 vo.setTodayHourRevenueMap(revenueMap);
-                vo.setTodayRevenue(revenueMap.values().stream().reduce(BigDecimal.ZERO, BigDecimal::add));
             }
-            vo.setYesterdayRevenue(adRecordMapper.getNetworkRevenueByType(appIds,2,vo.getNetowrkId()));
-            vo.setMonthRevenue(adRecordMapper.getNetworkRevenueByType(appIds,3,vo.getNetowrkId()));
+            vo.setTodayRevenue(revenueTodayMap.get(vo.getNetowrkId()));
+            vo.setYesterdayRevenue(revenueYestdayMap.get(vo.getNetowrkId()));
+            vo.setMonthRevenue(revenueMonthMap.get(vo.getNetowrkId()));
             //今日ecpm
             List<AgentNetworkEcpmGroupVO> networkEcpmGroups = vo.getNetworkEcpmGroups();
             if(CollUtil.isNotEmpty(networkEcpmGroups)){
-                Map<String, BigDecimal> ecpmMap = networkEcpmGroups.stream().collect(Collectors.toMap(AgentNetworkEcpmGroupVO::getHour, AgentNetworkEcpmGroupVO::getEcpm));
-                Map<String, AgentNetworkEcpmGroupVO> hourMap = networkEcpmGroups.stream().collect(
-                        Collectors.toMap(AgentNetworkEcpmGroupVO::getHour, o->o));
+                Map<String, BigDecimal> ecpmMap = networkEcpmGroups.stream().collect(Collectors.toMap(AgentNetworkEcpmGroupVO::getHour, s->s.getEcpm().divide(BigDecimal.valueOf(s.getCount()),2,BigDecimal.ROUND_HALF_UP)));
                 //统计每个小时的计数加起来为全天总次数
                 vo.setTodayHourEcpmMap(ecpmMap);
-                int count = hourMap.values().stream().mapToInt(AgentNetworkEcpmGroupVO::getCount).sum();
-                //分小时总值求和得到全天总值, 全天总值÷全天次数 得平均值
-                vo.setTodayEcpm(ecpmMap.values().stream().reduce(BigDecimal.ZERO, BigDecimal::add).divide(BigDecimal.valueOf(count), 2, BigDecimal.ROUND_HALF_UP));
             }
-            vo.setYesterdayEcpm(adRecordMapper.getNetworkEcpmByType(appIds,2,vo.getNetowrkId()));
-            vo.setMonthEcpm(adRecordMapper.getNetworkEcpmByType(appIds,3,vo.getNetowrkId()));
+            vo.setTodayEcpm(ecpmTodayMap.get(vo.getNetowrkId()));
+            vo.setYesterdayEcpm(ecpmYestdayMap.get(vo.getNetowrkId()));
+            vo.setMonthEcpm(ecpmMonthMap.get(vo.getNetowrkId()));
         }
         return vos;
     }

+ 62 - 8
yt-app/app-service/src/main/resources/mapper/dyz/AdRecordMapper.xml

@@ -118,8 +118,7 @@
         FROM
             yt_dyz_ad_record
         WHERE
-            ad_source_type = 1
-            and network_form_id = #{networkId}
+             network_form_id = #{networkId}
             and app_id in
             <foreach collection="appIds.split(',')" separator="," item="item" open="(" close=")">
                 #{item}
@@ -161,8 +160,7 @@
         FROM
             yt_dyz_ad_record
         WHERE
-            ad_source_type = 1
-            and network_form_id = #{networkId}
+             network_form_id = #{networkId}
             and app_id in
         <foreach collection="appIds.split(',')" separator="," item="item" open="(" close=")">
             #{item}
@@ -184,11 +182,13 @@
             <result column="count" property="count" />
             <result column="hour" property="hour" />
             <result column="ecpm" property="ecpm" />
+            <result column="ad_source_type" property="adSourceType" />
         </collection>
         <collection property="networkRevenueGroups" ofType="com.ytpm.agent.view.AgentNetworkRevenueGroupVO">
             <result column="count" property="count" />
             <result column="hour" property="hour" />
             <result column="revenue" property="revenue" />
+            <result column="ad_source_type" property="adSourceType" />
         </collection>
     </resultMap>
     <select id="getAdGroupStatics" resultMap="AdGroupStaticsMap">
@@ -198,12 +198,12 @@
             count(*) count,
             DATE_FORMAT(finish_time,'%Y-%m-%d %H:00:00') as `hour`,
             sum( revenue ) revenue,
-            sum( ecpm ) ecpm
+            sum( ecpm ) ecpm,
+            ad_source_type
         FROM
             yt_dyz_ad_record
         WHERE
-            ad_source_type = 1
-            and app_id in
+             app_id in
         <foreach collection="appIds.split(',')" separator="," item="item" open="(" close=")">
             #{item}
         </foreach>
@@ -214,7 +214,7 @@
         select
             sum(ar.revenue)
         from yt_dyz_ad_record ar
-        join yt_app_user au on ar.user_id = au.user_id
+        join yt_dyz_user au on ar.user_id = au.user_id
         <where>
             <if test="appIds != null and appIds != ''">
                 and ar.app_id in
@@ -230,4 +230,58 @@
             </if>
         </where>
     </select>
+    <select id="getRevenueByIds" resultType="com.ytpm.middle.view.NetWorkRevenueVO">
+        SELECT
+        network_form_id networkId,
+        network_name networkName,
+        sum( revenue ) netWorkRevenue
+        FROM
+        yt_dyz_ad_record
+        WHERE
+        network_form_id in
+        <foreach collection="networkIds.split(',')" separator="," item="item" open="(" close=")">
+            #{item}
+        </foreach>
+        and app_id in
+        <foreach collection="appIds.split(',')" separator="," item="item" open="(" close=")">
+            #{item}
+        </foreach>
+        <if test="type != null and type ==1">
+            and DATE(finish_time) = DATE(now())
+        </if>
+        <if test="type != null and type ==2">
+            and DATE(finish_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)
+        </if>
+        <if test="type != null and type ==3">
+            and DATE_FORMAT(finish_time, '%Y-%m') = DATE_FORMAT(CURDATE(), '%Y-%m')
+        </if>
+        group by networkId
+    </select>
+    <select id="getEcpmByIds" resultType="com.ytpm.middle.view.NetWorkEcpmVO">
+        SELECT
+        network_form_id netWorkId,
+        network_name netWorkName,
+        avg( ecpm ) networkEcpm
+        FROM
+        yt_dyz_ad_record
+        WHERE
+        network_form_id in
+        <foreach collection="networkIds.split(',')" separator="," item="item" open="(" close=")">
+            #{item}
+        </foreach>
+        and app_id in
+        <foreach collection="appIds.split(',')" separator="," item="item" open="(" close=")">
+            #{item}
+        </foreach>
+        <if test="type != null and type ==1">
+            and DATE(finish_time) = DATE(now())
+        </if>
+        <if test="type != null and type ==2">
+            and DATE(finish_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)
+        </if>
+        <if test="type != null and type ==3">
+            and DATE_FORMAT(finish_time, '%Y-%m') = DATE_FORMAT(CURDATE(), '%Y-%m')
+        </if>
+        group by netWorkId
+    </select>
 </mapper>

+ 2 - 0
yt-common/src/main/java/com/ytpm/agent/view/AgentNetworkEcpmGroupVO.java

@@ -24,4 +24,6 @@ public class AgentNetworkEcpmGroupVO {
     private String hour;
     @ApiModelProperty("ecpm")
     private BigDecimal ecpm;
+    @ApiModelProperty("广告类型")
+    private Integer adSourceType;
 }

+ 2 - 0
yt-common/src/main/java/com/ytpm/agent/view/AgentNetworkRevenueGroupVO.java

@@ -24,4 +24,6 @@ public class AgentNetworkRevenueGroupVO {
     private String hour;
     @ApiModelProperty("revenue")
     private BigDecimal revenue;
+    @ApiModelProperty("广告类型")
+    private Integer adSourceType;
 }

+ 8 - 0
yt-common/src/main/java/com/ytpm/constant/StrConstant.java

@@ -18,6 +18,14 @@ public class StrConstant {
      * 平台ID前缀
      */
     public static final String PLATFORM_ID_PREFIX="YT_";
+    /**
+     * 代理商前缀
+     */
+    public static final String PLATFORM_AGENT_SUFFIX="YT_AGENT_";
+    /**
+     * 首页广告统计数据
+     */
+    public static final String PROFIT="PROFIT_";
 
 
 }

+ 26 - 0
yt-common/src/main/java/com/ytpm/middle/view/NetWorkEcpmVO.java

@@ -0,0 +1,26 @@
+package com.ytpm.middle.view;
+
+import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+
+/**
+ * 广告平台 ECPM
+ * @author Marx
+ * @date 2025/8/4 13:36
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@ApiModel("广告平台 ECPM")
+public class NetWorkEcpmVO {
+    /** 广告平台ID */
+    private String netWorkId;
+    /** 广告平台名称 */
+    private String netWorkName;
+    /** 广告平台 ecpm 平均值 */
+    private BigDecimal netWorkEcpm;
+}

+ 26 - 0
yt-common/src/main/java/com/ytpm/middle/view/NetWorkRevenueVO.java

@@ -0,0 +1,26 @@
+package com.ytpm.middle.view;
+
+import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+
+/**
+ * 广告平台收益
+ * @author Marx
+ * @date 2025/8/4 11:31
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@ApiModel("广告平台收益")
+public class NetWorkRevenueVO {
+    /** 广告平台ID */
+    private String netWorkId;
+    /** 广告平台名称 */
+    private String netWorkName;
+    /** 广告平台收益 */
+    private BigDecimal netWorkRevenue;
+}

+ 8 - 0
yt-common/src/main/java/com/ytpm/util/RedisService.java

@@ -48,6 +48,14 @@ public class RedisService {
         return valOpsStr.get(key);
     }
 
+
+    /**
+     * 查询并获取key的有效时间
+     */
+    public Long getExpire(String key) {
+        return valOpsObj.getOperations().getExpire(key, TimeUnit.MINUTES);
+    }
+
     /**
      * 设置Str缓存
      * @param key