Prechádzať zdrojové kódy

feat: 新增参数:分层系数,用户详情返回今日收益,历史收益

hidewnd 1 mesiac pred
rodič
commit
afe4ccbec1

+ 3 - 0
yt-common/src/main/java/com/ytpm/agent/param/AppParam.java

@@ -88,4 +88,7 @@ public class AppParam {
 
     @ApiModelProperty("是否允许自动刷新")
     private Integer canAllowAutoRefresh;
+
+    @ApiModelProperty("收益 分层系数")
+    private String stratificationRate;
 }

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

@@ -176,5 +176,7 @@ public class AgentAppView {
     @ApiModelProperty("是否允许自动刷新")
     private Integer canAllowAutoRefresh;
 
+    @ApiModelProperty("收益 分层系数")
+    private String stratificationRate;
 
 }

+ 3 - 0
yt-common/src/main/java/com/ytpm/app/model/YtAppDefaultConfig.java

@@ -80,6 +80,9 @@ public class YtAppDefaultConfig {
     @ApiModelProperty("是否允许自动刷新")
     private Integer canAllowAutoRefresh;
 
+    @ApiModelProperty("收益 分层系数")
+    private String stratificationRate;
+
     public YtAppDefaultConfig(Object o, String appName, String wxAppId, String wxSecret, String appId, String appKey, int appType,String ditchId) {
         this.configId = Objects.isNull(o)?null: Integer.parseInt(o.toString());
         this.configName = appName;

+ 13 - 7
yt-common/src/main/java/com/ytpm/app/model/YtDyzUser.java

@@ -59,12 +59,7 @@ public class YtDyzUser extends PageMeta {
     @CustomField(node = 1)
     @ApiModelProperty("总观看视频数")
     private Integer totalVideo;
-    /** 总收益 */
-    @ApiModelProperty("总收益")
-    private BigDecimal totalIncome;
 
-    @ApiModelProperty("前三日总收益")
-    private BigDecimal nearlyIncome;
 
     /** 红包余额 */
     @CustomField(node = 1)
@@ -109,13 +104,25 @@ public class YtDyzUser extends PageMeta {
     /** 体力 */
     @ApiModelProperty("体力")
     private Integer power;
+
+    @ApiModelProperty(value = "今日收益")
+    private BigDecimal todayIncome;
+
+    @ApiModelProperty("前三日总收益")
+    private BigDecimal nearlyIncome;
+
+    @ApiModelProperty("总收益")
+    private BigDecimal totalIncome;
+
     /** 今日答题数 */
     @CustomField(node = 1)
     @ApiModelProperty("今日答题数")
     private Integer todayAnswerCount;
+
     /** 历史答题数 */
     @ApiModelProperty("历史答题数")
     private Integer historyAnswerCount;
+
     /** 答题历史记录 */
     @ApiModelProperty("答题历史记录")
     private List<YtDyzAnswerRecord> answerRecordList;
@@ -133,8 +140,7 @@ public class YtDyzUser extends PageMeta {
     private Long ditchId;
     @ApiModelProperty(value = "渠道名称")
     private String ditchName;
-    @ApiModelProperty(value = "今日收益")
-    private BigDecimal todayIncome;
+
     @ApiModelProperty(value = "应用ID")
     private String appId;
     @ApiModelProperty(value = "手机号")

+ 3 - 0
yt-common/src/main/java/com/ytpm/app/view/WxDefaultConfig.java

@@ -75,4 +75,7 @@ public class WxDefaultConfig {
 
     @ApiModelProperty("是否允许自动刷新")
     private Integer canAllowAutoRefresh;
+
+    @ApiModelProperty("收益 分层系数")
+    private String stratificationRate;
 }

+ 41 - 0
yt-common/src/main/java/com/ytpm/util/NumberUtils.java

@@ -0,0 +1,41 @@
+package com.ytpm.util;
+
+
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.core.util.StrUtil;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+/**
+ * @author lih
+ * @date 2025-10-09 18:11
+ */
+public class NumberUtils extends NumberUtil {
+
+    /**
+     * 百分比字符串转换为BigDecimal
+     *
+     * @param str “51.12%” | "51.00"
+     * @return BigDecimal
+     */
+    public static BigDecimal rateToBigDecimal(String str) {
+        return rateToBigDecimal(str, 5, RoundingMode.HALF_UP);
+    }
+
+    public static BigDecimal rateToBigDecimal(String str, int scale, RoundingMode roundingMode) {
+        if (StrUtil.isBlank(str)) {
+            throw new IllegalArgumentException("输入字符串不能为空");
+        }
+        // 处理带百分号的情况
+        if (str.contains("%")) {
+            // 去除百分号并 trim 空格
+            String numStr = StrUtil.trim(str.replace("%", ""));
+            // 转换为BigDecimal后除以100,并指定精度和舍入模式
+            return toBigDecimal(numStr)
+                    .divide(new BigDecimal("100"), scale, roundingMode);
+        }
+        // 处理普通数字字符串(直接转换)
+        return toBigDecimal(StrUtil.trim(str));
+    }
+}

+ 35 - 13
yt-question/yt-question-service/src/main/java/com/ytpm/question/controller/UserController.java

@@ -20,6 +20,7 @@ import com.ytpm.app.param.AppUserQueryParam;
 import com.ytpm.app.param.AppUserTodayBannedParam;
 import com.ytpm.app.param.YtAppUserListParam;
 import com.ytpm.app.view.HourCountView;
+import com.ytpm.app.view.WxDefaultConfig;
 import com.ytpm.app.view.YtAppUserListView;
 import com.ytpm.feign.RiskFeign;
 import com.ytpm.general.RepMessage;
@@ -34,6 +35,7 @@ import com.ytpm.question.redis.RedisService;
 import com.ytpm.risk.enums.BannedTypeEnum;
 import com.ytpm.risk.view.RiskConfigView;
 import com.ytpm.risk.view.RiskTemplateView;
+import com.ytpm.util.NumberUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -44,6 +46,7 @@ import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
@@ -106,8 +109,8 @@ public class UserController {
     /**
      * 设置视频记录和登录信息
      */
-    private void setUserExtInfo(List<YtAppUserListView> result, Map<String, List<YtDyzAdRecord>> userAdMap, Map<String,
-            List<YtDyzLoginRecord>> loginMap) {
+    private void setUserExtInfo(List<YtAppUserListView> result, Map<String, List<YtDyzAdRecord>> userAdMap,
+                                Map<String, List<YtDyzLoginRecord>> loginMap) {
         for (YtAppUserListView user : result) {
             if (loginMap.containsKey(user.getUserId())) {
                 user.setLoginRecordList(loginMap.get(user.getUserId()));
@@ -152,18 +155,37 @@ public class UserController {
     @GetMapping("/getUserInfo")
     public Result<YtDyzUser> getUserInfo(@RequestParam("userId") String userId) {
         YtDyzUser user = appUserMapper.selectPrimaryKey(userId);
-        user.setLoginRecordList(loginRecordMapper.getLoginRecords(userId));
-        user.setTodayAnswerCount(questionMapper.getAnswerCount(userId, 1));
-        user.setHistoryAnswerCount(questionMapper.getAnswerCount(userId, 2));
-        user.setAnswerRecordList(questionMapper.getAnswerRecords(userId));
-        Result<?> result = riskFeign.checkAdRisk(user);
-        if (result != null) {
-            user.setIfPowerLimit(false);
-            if (result.getCode() != 200) {
-                if ("766".equals(result.getMessage()) || result.getCode() == StatusCode.ACCESS_RISK_ERROR && StrUtil.isNotEmpty(result.getMessage())) {
-                    user.setIfPowerLimit(true);
-                }
+        if (user != null) {
+            // 登陆记录
+            user.setLoginRecordList(loginRecordMapper.getLoginRecords(userId));
+            // 今日答题数
+            user.setTodayAnswerCount(questionMapper.getAnswerCount(userId, 1));
+            // 历史答题数
+            user.setHistoryAnswerCount(questionMapper.getAnswerCount(userId, 2));
+            // 答题记录列表
+            user.setAnswerRecordList(questionMapper.getAnswerRecords(userId));
+            WxDefaultConfig defaultConfig = appUserMapper.getDefaultConfigByAppId(user.getAppId());
+            // 分层系数
+            String stratificationRate = defaultConfig == null ? "" : defaultConfig.getStratificationRate();
+            BigDecimal todayRevenue = adRecordMapper.getToTalRevenue(userId, 1);
+            BigDecimal totalRevenue = user.getTotalIncome() == null ? adRecordMapper.getToTalRevenue(userId, 2) : user.getTotalIncome();
+            if (StrUtil.isNotEmpty(stratificationRate)) {
+                BigDecimal rate = NumberUtils.rateToBigDecimal(stratificationRate);
+                todayRevenue = todayRevenue.multiply(rate).setScale(5, RoundingMode.HALF_UP);
+                totalRevenue = totalRevenue.multiply(rate).setScale(5, RoundingMode.HALF_UP);
+            }
+            // 今日收益
+            user.setTodayIncome(todayRevenue);
+            // 历史收益
+            user.setTotalIncome(totalRevenue);
+            // 是否体力已达上限
+            boolean ifPowerLimit = false;
+            Result<?> result = riskFeign.checkAdRisk(user);
+            if (result != null && result.getCode() != 200) {
+                ifPowerLimit = "766".equals(result.getMessage())
+                        || result.getCode() == StatusCode.ACCESS_RISK_ERROR && StrUtil.isNotEmpty(result.getMessage());
             }
+            user.setIfPowerLimit(ifPowerLimit);
         }
         return Result.resultObjOk(user);
     }

+ 7 - 0
yt-question/yt-question-service/src/main/java/com/ytpm/question/dao/AdRecordMapper.java

@@ -82,4 +82,11 @@ public interface AdRecordMapper {
      * 本月按广告平台聚合
      */
     List<AgentNetworkAgg> getMonthAggByNetwork(@Param("appIds") String appIds);
+
+    /**
+     * 统计用户广告收益
+     * @param userId 用户ID
+     * @param type 统计方式|1统计今日|2统计所有
+     */
+    BigDecimal getToTalRevenue(@Param("userId") String userId, @Param("type") Integer type);
 }

+ 7 - 4
yt-question/yt-question-service/src/main/java/com/ytpm/question/dao/AppUserMapper.java

@@ -92,6 +92,12 @@ public interface AppUserMapper {
 
     WxDefaultConfig getDefaultConfigByAppId(@Param("appId") String appId);
 
+    /**
+     * 根据APP_ID获取配置
+     */
+    List<WxDefaultConfig> getConfigByIds(@Param("appIds") String appIds);
+
+
     /**
      * 根据微信openid查询用户
      */
@@ -112,10 +118,7 @@ public interface AppUserMapper {
     void updateAppConfig(YtAppDefaultConfig defaultConfig);
 
 
-    /**
-     * 根据APP_ID获取配置
-     */
-    List<WxDefaultConfig> getConfigByIds(@Param("appIds") String appIds);
+
 
     /**
      * 根据应用统计广告数

+ 8 - 0
yt-question/yt-question-service/src/main/resources/mapper/AdRecordMapper.xml

@@ -276,5 +276,13 @@
             and finish_time > #{startTime}
         </if>
     </select>
+    <select id="getToTalRevenue" resultType="java.math.BigDecimal">
+        select sum(revenue) as revenue
+        from yt_dyz_ad_record
+        where user_id = #{userId}
+        <if test="type != null and type = 1">
+            AND DATE(finish_time) = DATE(NOW())
+        </if>
+    </select>
 
 </mapper>

+ 123 - 128
yt-question/yt-question-service/src/main/resources/mapper/AppUserMapper.xml

@@ -66,112 +66,6 @@
                 #{recordId},#{userId},#{type},#{remark},#{addTime}
             )
     </insert>
-    <insert id="saveAppConfig">
-        insert into yt_app_default_config
-        (
-            config_name,
-            open_id,
-            secret,
-            app_id,
-            app_key,
-            app_type,
-            ditch_id
-        )
-        values
-            (
-                #{configName},
-                #{openId},
-                #{secret},
-                #{appId},
-                #{appKey},
-                #{appType},
-                #{ditchId}
-            )
-    </insert>
-    <update id="updateAppConfig">
-        update yt_app_default_config
-        <set>
-            <if test="canSimulator != null">
-                can_simulator = #{canSimulator},
-            </if>
-            <if test="configName != null">
-                config_name = #{configName},
-            </if>
-            <if test="openId != null">
-                open_id = #{openId},
-            </if>
-            <if test="secret != null">
-                secret = #{secret},
-            </if>
-            <if test="appKey != null">
-                app_key = #{appKey},
-            </if>
-            <if test="appType != null">
-                app_type = #{appType},
-            </if>
-            <if test="takuAppId != null">
-                taku_app_id = #{takuAppId},
-            </if>
-            <if test="takuKey != null">
-                taku_key = #{takuKey},
-            </if>
-            <if test="takuBannerPid != null">
-                taku_banner_pid = #{takuBannerPid},
-            </if>
-            <if test="takuNativePid != null">
-                taku_native_pid = #{takuNativePid},
-            </if>
-            <if test="takuRewardPid != null">
-                taku_reward_pid = #{takuRewardPid},
-            </if>
-            <if test="takuInterstitialPid != null">
-                taku_interstitial_pid = #{takuInterstitialPid},
-            </if>
-            <if test="canUseRoot != null">
-                can_use_root = #{canUseRoot},
-            </if>
-            <if test="canUseAdb != null">
-                can_use_adb = #{canUseAdb},
-            </if>
-            <if test="canUseFloat != null">
-                can_use_float = #{canUseFloat},
-            </if>
-            <if test="canAccumulation != null">
-                can_accumulation = #{canAccumulation},
-            </if>
-            <if test="ditchId != null">
-                ditch_id = #{ditchId},
-            </if>
-            <if test="powerWaitTime != null">
-                power_wait_time = #{powerWaitTime},
-            </if>
-            <if test="interstitialIntervalTime != null">
-                interstitial_interval_time = #{interstitialIntervalTime},
-            </if>
-            <if test="flowIntervalTime != null">
-                flow_interval_time = #{flowIntervalTime},
-            </if>
-            <if test="taskLimitTip != null">
-                task_limit_tip = #{taskLimitTip},
-            </if>
-            <if test="lowValueTip != null">
-                low_value_tip = #{lowValueTip},
-            </if>
-            <if test="brushTip != null">
-                brush_tip = #{brushTip},
-            </if>
-            <if test="startWaitTime != null">
-                start_wait_time = #{startWaitTime},
-            </if>
-            <if test="canCacheVideo != null">
-                can_cache_video = #{canCacheVideo},
-            </if>
-            <if test="canAllowAutoRefresh != null">
-                can_allow_auto_refresh = #{canAllowAutoRefresh}
-            </if>
-        </set>
-        where app_id = #{appId}
-    </update>
     <update id="addOnePower">
         update yt_dyz_user set power = power+1 where user_id = #{userId}
     </update>
@@ -250,9 +144,7 @@
         </set>
         where user_id = #{userId}
     </update>
-    <delete id="delByAppId">
-        delete from yt_app_default_config where app_id = #{appId}
-    </delete>
+
     <select id="getYtAppUser" resultType="com.ytpm.app.model.YtDyzUser">
         select
             user_id, app_id,phone,device_id, ditch_id, nick_name,head_img, power,
@@ -458,6 +350,118 @@
             #{item}
         </foreach>
     </select>
+    <insert id="saveAppConfig">
+        insert into yt_app_default_config
+        (
+            config_name,
+            open_id,
+            secret,
+            app_id,
+            app_key,
+            app_type,
+            ditch_id
+        )
+        values
+            (
+                #{configName},
+                #{openId},
+                #{secret},
+                #{appId},
+                #{appKey},
+                #{appType},
+                #{ditchId}
+            )
+    </insert>
+    <update id="updateAppConfig">
+        update yt_app_default_config
+        <set>
+            <if test="canSimulator != null">
+                can_simulator = #{canSimulator},
+            </if>
+            <if test="configName != null">
+                config_name = #{configName},
+            </if>
+            <if test="openId != null">
+                open_id = #{openId},
+            </if>
+            <if test="secret != null">
+                secret = #{secret},
+            </if>
+            <if test="appKey != null">
+                app_key = #{appKey},
+            </if>
+            <if test="appType != null">
+                app_type = #{appType},
+            </if>
+            <if test="takuAppId != null">
+                taku_app_id = #{takuAppId},
+            </if>
+            <if test="takuKey != null">
+                taku_key = #{takuKey},
+            </if>
+            <if test="takuBannerPid != null">
+                taku_banner_pid = #{takuBannerPid},
+            </if>
+            <if test="takuNativePid != null">
+                taku_native_pid = #{takuNativePid},
+            </if>
+            <if test="takuRewardPid != null">
+                taku_reward_pid = #{takuRewardPid},
+            </if>
+            <if test="takuInterstitialPid != null">
+                taku_interstitial_pid = #{takuInterstitialPid},
+            </if>
+            <if test="canUseRoot != null">
+                can_use_root = #{canUseRoot},
+            </if>
+            <if test="canUseAdb != null">
+                can_use_adb = #{canUseAdb},
+            </if>
+            <if test="canUseFloat != null">
+                can_use_float = #{canUseFloat},
+            </if>
+            <if test="canAccumulation != null">
+                can_accumulation = #{canAccumulation},
+            </if>
+            <if test="ditchId != null">
+                ditch_id = #{ditchId},
+            </if>
+            <if test="powerWaitTime != null">
+                power_wait_time = #{powerWaitTime},
+            </if>
+            <if test="interstitialIntervalTime != null">
+                interstitial_interval_time = #{interstitialIntervalTime},
+            </if>
+            <if test="flowIntervalTime != null">
+                flow_interval_time = #{flowIntervalTime},
+            </if>
+            <if test="taskLimitTip != null">
+                task_limit_tip = #{taskLimitTip},
+            </if>
+            <if test="lowValueTip != null">
+                low_value_tip = #{lowValueTip},
+            </if>
+            <if test="brushTip != null">
+                brush_tip = #{brushTip},
+            </if>
+            <if test="startWaitTime != null">
+                start_wait_time = #{startWaitTime},
+            </if>
+            <if test="canCacheVideo != null">
+                can_cache_video = #{canCacheVideo},
+            </if>
+            <if test="canAllowAutoRefresh != null">
+                can_allow_auto_refresh = #{canAllowAutoRefresh},
+            </if>
+            <if test="stratificationRate != null">
+                stratification_rate = #{stratificationRate}
+            </if>
+        </set>
+        where app_id = #{appId}
+    </update>
+    <delete id="delByAppId">
+        delete from yt_app_default_config where app_id = #{appId}
+    </delete>
     <select id="getDefaultConfig" resultType="com.ytpm.app.view.WxDefaultConfig">
         select
             config_id, config_name, open_id as app_id, secret, app_id as platformAppId, app_key as platformAppSecret,
@@ -466,7 +470,7 @@
             can_use_root, can_use_adb, can_use_float, can_accumulation,
             ditch_id, power_wait_time, interstitial_interval_time,
             low_value_tip, brush_tip,flow_interval_time,task_limit_tip,start_wait_time,
-            can_cache_video,can_allow_auto_refresh
+            can_cache_video,can_allow_auto_refresh, stratification_rate
         from yt_app_default_config
         where app_type = #{appType}
     </select>
@@ -477,20 +481,23 @@
             taku_reward_pid, taku_interstitial_pid, can_use_root, can_use_adb, can_use_float, can_accumulation,
             ditch_id, power_wait_time, interstitial_interval_time,
             low_value_tip, brush_tip,flow_interval_time,task_limit_tip,start_wait_time,
-            can_cache_video,can_allow_auto_refresh
+            can_cache_video,can_allow_auto_refresh, stratification_rate
         from yt_app_default_config
         where app_id = #{appId}
     </select>
-    <select id="getSecretByAppId" resultType="java.lang.String">
+    <select id="getConfigByIds" resultType="com.ytpm.app.view.WxDefaultConfig">
         select
             config_id, config_name, open_id, secret, app_id, app_key, app_type,user_path,login_path,ad_path,
             answer_path,power_path,can_simulator, taku_app_id, taku_key, taku_banner_pid, taku_native_pid,
             taku_reward_pid, taku_interstitial_pid, can_use_root, can_use_adb, can_use_float, can_accumulation,
             ditch_id, power_wait_time, interstitial_interval_time,
-            low_value_tip, brush_tip, flow_interval_time,task_limit_tip,start_wait_time,
-            can_cache_video,can_allow_auto_refresh
+            low_value_tip, brush_tip,flow_interval_time,task_limit_tip,start_wait_time,
+            can_cache_video,can_allow_auto_refresh, stratification_rate
         from yt_app_default_config
-        where app_id = #{appId}
+        where app_id in
+        <foreach collection="appIds.split(',')" item="item" separator="," open="(" close=")">
+            #{item}
+        </foreach>
     </select>
     <select id="queryByOpenid" resultType="com.ytpm.app.model.YtDyzUser">
         select
@@ -506,19 +513,7 @@
         where device_id = #{deviceId} and wx_open_id = #{openid}
         limit 1
     </select>
-    <select id="getConfigByIds" resultType="com.ytpm.app.view.WxDefaultConfig">
-        select
-        config_id, config_name, open_id, secret, app_id, app_key, app_type, user_path, login_path, ad_path,
-        answer_path, power_path,taku_app_id, taku_key, taku_banner_pid, taku_native_pid, taku_reward_pid,
-        taku_interstitial_pid, can_use_root, can_use_adb, can_use_float, can_accumulation,can_simulator,
-        ditch_id, power_wait_time, interstitial_interval_time,
-        low_value_tip, brush_tip, flow_interval_time,task_limit_tip,start_wait_time,can_cache_video,can_allow_auto_refresh
-        from yt_app_default_config
-        where app_id in
-        <foreach collection="appIds.split(',')" item="item" separator="," open="(" close=")">
-            #{item}
-        </foreach>
-    </select>
+
     <select id="getAdCount" resultType="java.lang.Integer">
         select sum(total_video)
         from yt_dyz_user