فهرست منبع

feat:iso服务逻辑优化

hidewnd 1 هفته پیش
والد
کامیت
6610671115

+ 2 - 2
yt-ios-lemon/lemon-ios-service/src/main/java/com/ytpm/lemonios/dao/AppUserMapper.java

@@ -1,10 +1,8 @@
 package com.ytpm.lemonios.dao;
 
-import com.ytpm.agent.param.AdRecordListParam;
 import com.ytpm.agent.param.AuditUserParam;
 import com.ytpm.agent.view.AgentAuditCheckVO;
 import com.ytpm.app.model.YtAppDefaultConfig;
-import com.ytpm.app.model.YtDyzAdRecord;
 import com.ytpm.app.model.YtDyzPowerRecord;
 import com.ytpm.app.model.YtDyzUser;
 import com.ytpm.app.param.AppUserParam;
@@ -231,4 +229,6 @@ public interface AppUserMapper {
     List<AgentAuditCheckVO> queryTodayUserAd(AuditUserParam auditParam);
 
     List<YtDyzUser> getMonthRegistryUser(@Param("appIds") String appIds, @Param("type") Integer type);
+
+    void updateTotal(@Param("userId") String userId, @Param("videoCount") int videoCount, @Param("revenue") BigDecimal revenue);
 }

+ 102 - 75
yt-ios-lemon/lemon-ios-service/src/main/java/com/ytpm/lemonios/service/impl/AdServiceImpl.java

@@ -5,7 +5,7 @@ import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.IdUtil;
 import cn.hutool.core.util.RandomUtil;
 import cn.hutool.core.util.StrUtil;
-import com.fasterxml.jackson.databind.ObjectMapper;
+import com.alibaba.fastjson.JSONObject;
 import com.ytpm.advertise.enums.AdPlatformTypeEnum;
 import com.ytpm.advertise.enums.AdSourceTypeEnum;
 import com.ytpm.agent.enums.UserStatusEnum;
@@ -22,7 +22,14 @@ import com.ytpm.lemonios.dao.AdRecordMapper;
 import com.ytpm.lemonios.dao.AppUserMapper;
 import com.ytpm.lemonios.service.AdService;
 import com.ytpm.lemonios.service.AppUserService;
-import com.ytpm.middle.view.*;
+import com.ytpm.middle.view.AppRankingListVO;
+import com.ytpm.middle.view.AppRevenueHourVO;
+import com.ytpm.middle.view.AppUserHourVO;
+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.UserRankingListVO;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -36,7 +43,14 @@ import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.text.SimpleDateFormat;
 import java.time.LocalDateTime;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import java.util.concurrent.CountDownLatch;
 import java.util.stream.Collectors;
 
@@ -67,60 +81,100 @@ public class AdServiceImpl implements AdService {
     @Transactional(rollbackFor = Exception.class)
     public Result<?> saveRecord(DyzAdRecordParam param) {
         if (StrUtil.isEmpty(param.getUserId())) {
-            YtDyzAdRecord adRecord = new YtDyzAdRecord();
-            if(Objects.isNull(param.getBeginTime()) || "null".equals(param.getBeginTime())){
-                if ("null".equals(param.getBeginTime())) {
-                    log.warn("param beginTime is null !");
-                }
-                param.setBeginTime(param.getFinishTime());
+            // 登陆前保存广告(游客登陆)
+            saveRecordAndChangeUser(param, null);
+            return Result.resultOk(RepMessage.SAVE_SUCCESS);
+        }
+        // 登陆后保存广告
+        YtDyzUser user = appUserMapper.selectPrimaryKey(param.getUserId());
+        if (Objects.isNull(user)) {
+            return Result.resultOk(RepMessage.SAVE_SUCCESS);
+        }
+        if (!UserStatusEnum.NORMAL.getCode().equals(user.getUserStatus())) {
+            return new Result<>(StatusCode.ACCESS_ERR, getTipsMsg());
+        }
+        //增加广告记录
+        saveRecordAndChangeUser(param, user);
+        //调用风控广告校验
+        if(AdSourceTypeEnum.rewarded_video.getAdSourceType() == param.getAdSourceType()){
+            appUserService.addPower(user.getUserId());
+            Result<?> result = riskFeign.checkAdRisk(user);
+            if(result.getCode()!=200){
+                return new Result<>(StatusCode.ACCESS_ERR, getTipsMsg());
             }
-            BeanUtils.copyProperties(param, adRecord);
+        }
+        return Result.resultOk(RepMessage.SAVE_SUCCESS);
+    }
 
-            getEcpm(param);
-            timeParse(param, adRecord);
-            adRecord.setIosId(param.getIosId());
-            adRecord.setAppId(appId);
-            adRecord.setRecordId(IdUtil.fastSimpleUUID());
-            adRecord.setNetworkName(AdPlatformTypeEnum.getDesc(Integer.parseInt(param.getNetworkFormId())));
-            adRecordMapper.addOneVisitor(adRecord);
-        } else {
-            YtDyzUser user = appUserMapper.selectPrimaryKey(param.getUserId());
-            if(!UserStatusEnum.NORMAL.getCode().equals(user.getUserStatus())){
-                return new Result<>(StatusCode.ACCESS_ERR,getTipsMsg());
+    /**
+     * 统一处理入参时间
+     */
+    private void handleParam(DyzAdRecordParam param){
+        String timeFormat = "yyyy-MM-dd HH:mm:ss";
+        if (param.getBegintimestamp() != null && param.getFinishtimestamp() != null) {
+            // 处理 begintimestamp(兼容秒级和毫秒级)
+            long beginTimestamp = param.getBegintimestamp();
+            if (String.valueOf(beginTimestamp).length() == 10) { // 秒级时间戳(10位)
+                beginTimestamp *= 1000; // 转为毫秒级
+            }
+            param.setBeginTime(DateUtil.format(new Date(beginTimestamp), timeFormat));
+
+            // 处理 finishtimestamp(兼容秒级和毫秒级)
+            long finishTimestamp = param.getFinishtimestamp();
+            if (String.valueOf(finishTimestamp).length() == 10) { // 秒级时间戳(10位)
+                finishTimestamp *= 1000; // 转为毫秒级
             }
-            if(Objects.isNull(user)){
-                return Result.resultOk(RepMessage.SAVE_SUCCESS);
+            param.setFinishTime(DateUtil.format(new Date(finishTimestamp), timeFormat));
+        }
+        if (StrUtil.isEmpty(param.getFinishTime())) {
+            param.setFinishTime(DateUtil.format(new Date(), timeFormat));
+        }
+        if(Objects.isNull(param.getBeginTime()) || "null".equals(param.getBeginTime())){
+            if ("null".equals(param.getBeginTime())) {
+                log.warn("param beginTime is null !");
             }
-            saveRecordAndChangeUser(param, user);
-            //调用风控广告校验
-            if(AdSourceTypeEnum.rewarded_video.getAdSourceType() == param.getAdSourceType()){
-                appUserService.addPower(user.getUserId());
-                Result<?> result = riskFeign.checkAdRisk(user);
-                if(result.getCode()!=200){
-                    return new Result<>(StatusCode.ACCESS_ERR, getTipsMsg());
-                }
+            param.setBeginTime(param.getFinishTime());
+        }
+        // ecpm 值统一解析json获取
+        if (StrUtil.isNotEmpty(param.getResultJson())) {
+            JSONObject resultJson = JSONObject.parseObject(param.getResultJson());
+            String ecpmStr = resultJson.getString("adsource_price");
+            if (StrUtil.isNotEmpty(ecpmStr)) {
+                param.setEcpm(new BigDecimal(ecpmStr));
             }
         }
-        return Result.resultOk(RepMessage.SAVE_SUCCESS);
     }
 
-    private static void getEcpm(DyzAdRecordParam param) {
-        if (param.getEcpm() == null){
-            try {
-                // 1. 将 JSON 字符串解析为 Map 或自定义对象
-                ObjectMapper objectMapper = new ObjectMapper();
-                Map<String, Object> jsonMap = objectMapper.readValue(param.getResultJson(), Map.class);
-
-                // 2. 提取 adsource_price 的值
-                BigDecimal adsourcePrice = new BigDecimal(jsonMap.get("adsource_price").toString()) ;
-
-                // 3. 设置到 ecpm 字段
-                param.setEcpm(adsourcePrice);
-
-            } catch (Exception e) {
-                // 异常处理(如 JSON 解析失败)
-                e.printStackTrace();
+    /**
+     * 保存记录
+     *  始终创建新的事务以保障子方法的独立事务
+     */
+//    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
+    public void saveRecordAndChangeUser(DyzAdRecordParam param, YtDyzUser user) {
+        //增加广告记录
+        //修改用户信息, 广告次数+1  总收益 + revenue
+//        YtDyzUser dyzUser = new YtDyzUser();
+//        dyzUser.setUserId(user.getUserId());
+//        dyzUser.setTotalVideo(Objects.isNull(user.getTotalVideo())?1:(user.getTotalVideo()+1));
+//        dyzUser.setTotalIncome(user.getTotalIncome().add(param.getRevenue()));
+//        appUserMapper.updateUser(dyzUser);
+        YtDyzAdRecord adRecord = new YtDyzAdRecord();
+        handleParam(param);
+        BeanUtils.copyProperties(param, adRecord);
+        timeParse(param, adRecord);
+        adRecord.setRecordId(IdUtil.fastSimpleUUID());
+        adRecord.setIosId(param.getIosId());
+        adRecord.setNetworkName(AdPlatformTypeEnum.getDesc(Integer.parseInt(param.getNetworkFormId())));
+        if (user == null) {
+            adRecord.setAppId(appId);
+            adRecordMapper.addOneVisitor(adRecord);
+        } else {
+            adRecord.setUserId(user.getUserId());
+            adRecordMapper.addOne(adRecord);
+            if (param.getRevenue() == null) {
+                param.setRevenue(BigDecimal.ZERO);
             }
+            appUserMapper.updateTotal(user.getUserId(), 1, param.getRevenue());
         }
     }
 
@@ -320,33 +374,6 @@ public class AdServiceImpl implements AdService {
         return vos;
     }
 
-    /**
-     * 保存记录
-     *  始终创建新的事务以保障子方法的独立事务
-     */
-//    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
-    public void saveRecordAndChangeUser(DyzAdRecordParam param,YtDyzUser user) {
-        //增加广告记录
-        YtDyzAdRecord adRecord = new YtDyzAdRecord();
-        if(Objects.isNull(param.getBeginTime())){
-            param.setBeginTime(param.getFinishTime());
-        }
-        getEcpm(param);
-        BeanUtils.copyProperties(param, adRecord);
-        timeParse(param, adRecord);
-        adRecord.setIosId(param.getIosId());
-        adRecord.setRecordId(IdUtil.fastSimpleUUID());
-        adRecord.setUserId(user.getUserId());
-        adRecord.setNetworkName(AdPlatformTypeEnum.getDesc(Integer.parseInt(param.getNetworkFormId())));
-        adRecordMapper.addOne(adRecord);
-        //修改用户信息, 广告次数+1  总收益 + revenue
-        YtDyzUser dyzUser = new YtDyzUser();
-        dyzUser.setUserId(user.getUserId());
-        dyzUser.setTotalVideo(Objects.isNull(user.getTotalVideo())?1:(user.getTotalVideo()+1));
-        dyzUser.setTotalIncome(user.getTotalIncome().add(param.getRevenue()));
-        appUserMapper.updateUser(dyzUser);
-    }
-
     private static void timeParse(DyzAdRecordParam param, YtDyzAdRecord adRecord) {
         if (param.getBegintimestamp() != null && param.getFinishtimestamp() != null) {
             // 处理 begintimestamp(兼容秒级和毫秒级)

+ 1 - 1
yt-ios-lemon/lemon-ios-service/src/main/java/com/ytpm/lemonios/service/impl/AppUserServiceImpl.java

@@ -153,8 +153,8 @@ public class AppUserServiceImpl implements AppUserService {
         List<YtDyzAnswerRecord> recordList = questionMapper.getAnswerRecords(old.getUserId());
         List<String> viewList  = new ArrayList<>();
         int count = recordList.size();
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
         for (YtDyzAnswerRecord ytDyzAnswerRecord : recordList) {
-            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
             String timeStr = count + ":" + sdf.format(ytDyzAnswerRecord.getAnswerTime());
             count--;
             viewList.add(timeStr);

+ 23 - 0
yt-ios-lemon/lemon-ios-service/src/main/resources/mapper/AppUserMapper.xml

@@ -1023,4 +1023,27 @@
             #{item}
         </foreach>
     </update>
+    <update id="updateTotal">
+        UPDATE yt_dyz_user
+        SET
+            -- 处理近4天未登录 或间隔时间超过4天
+            nearly_income = (
+                CASE
+                    WHEN last_login_time <![CDATA[ < ]]> DATE_SUB(DATE(NOW()), INTERVAL 4 DAY)
+                         OR IFNULL(nearly_begin_time, NOW()) <![CDATA[ < ]]> DATE_SUB(DATE(NOW()), INTERVAL 4 DAY)
+                        THEN #{revenue}
+                    ELSE COALESCE(nearly_income, 0) + #{revenue}
+                END
+            ),
+            nearly_begin_time = CASE
+                WHEN last_login_time <![CDATA[ < ]]> DATE_SUB(DATE(NOW()), INTERVAL 4 DAY)
+                    OR IFNULL(nearly_begin_time, NOW()) <![CDATA[ < ]]> DATE_SUB(DATE(NOW()), INTERVAL 4 DAY)
+                    THEN NOW()
+                WHEN nearly_begin_time IS NULL THEN NOW()
+                ELSE nearly_begin_time
+            END,
+            total_video = COALESCE(total_video, 0) + #{videoCount},
+            total_income = COALESCE(total_income, 0) + #{revenue}
+        WHERE user_id = #{userId};
+    </update>
 </mapper>