Просмотр исходного кода

feat: 新增风控344,766,767,768

hidewnd 2 месяцев назад
Родитель
Сommit
2c7230969c
17 измененных файлов с 795 добавлено и 31 удалено
  1. 8 0
      yt-adage/adage-service/src/main/java/com/ytpm/adage/controller/AdController.java
  2. 6 1
      yt-adage/adage-service/src/main/java/com/ytpm/adage/controller/VisitorController.java
  3. 4 0
      yt-adage/adage-service/src/main/java/com/ytpm/adage/dao/AdRecordMapper.java
  4. 3 0
      yt-adage/adage-service/src/main/java/com/ytpm/adage/service/AdService.java
  5. 16 6
      yt-adage/adage-service/src/main/java/com/ytpm/adage/service/impl/AdServiceImpl.java
  6. 17 1
      yt-adage/adage-service/src/main/java/com/ytpm/adage/service/impl/VisitorLoginServiceImpl.java
  7. 5 1
      yt-adage/adage-service/src/main/java/com/ytpm/adage/service/impl/WxLoginServiceImpl.java
  8. 14 0
      yt-adage/adage-service/src/main/resources/mapper/AdRecordMapper.xml
  9. 41 0
      yt-common/src/main/java/com/ytpm/agent/view/UserAdStaticsVo.java
  10. 7 0
      yt-common/src/main/java/com/ytpm/handle/AbstractLoginService.java
  11. 173 4
      yt-middle/middle-platform/src/main/java/com/ytpm/middle/service/impl/ApkServiceImpl.java
  12. 292 0
      yt-middle/middle-platform/src/main/test/com/ytpm/middle/test/TestGenerateRiskTemplate.java
  13. 6 0
      yt-middle/pom.xml
  14. 2 0
      yt-risk/risk-feign/src/main/java/com/ytpm/feign/RiskFeign.java
  15. 6 0
      yt-risk/risk-manage/src/main/java/com/ytpm/controller/PublicApiController.java
  16. 5 0
      yt-risk/risk-manage/src/main/java/com/ytpm/service/RiskService.java
  17. 190 18
      yt-risk/risk-manage/src/main/java/com/ytpm/service/impl/RiskServiceImpl.java

+ 8 - 0
yt-adage/adage-service/src/main/java/com/ytpm/adage/controller/AdController.java

@@ -3,6 +3,7 @@ package com.ytpm.adage.controller;
 import com.ytpm.agent.view.AgentAdGroupStaticsVO;
 import com.ytpm.agent.view.AgentTopCountView;
 import com.ytpm.adage.service.AdService;
+import com.ytpm.agent.view.UserAdStaticsVo;
 import com.ytpm.app.param.DyzAdRecordParam;
 import com.ytpm.general.Result;
 import com.ytpm.middle.view.DashboardRankingListVO;
@@ -91,4 +92,11 @@ public class AdController {
     public List<AgentAdGroupStaticsVO> getAgentProfit(@RequestParam(name = "appIds")String appIds){
         return adService.getAgentProfit(appIds);
     }
+
+    @ApiOperation("查询用户广告收益统计广告数据")
+    @GetMapping("/getUerAdStatics")
+    public List<UserAdStaticsVo> getUerAdStatics(@RequestParam(name = "appId")String appId, @RequestParam(name = "userId")String userId){
+        return adService.getUerAdStatics(appId, userId);
+    }
+
 }

+ 6 - 1
yt-adage/adage-service/src/main/java/com/ytpm/adage/controller/VisitorController.java

@@ -11,7 +11,12 @@ import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.cloud.context.config.annotation.RefreshScope;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;

+ 4 - 0
yt-adage/adage-service/src/main/java/com/ytpm/adage/dao/AdRecordMapper.java

@@ -1,5 +1,6 @@
 package com.ytpm.adage.dao;
 
+import com.ytpm.agent.view.UserAdStaticsVo;
 import com.ytpm.app.model.YtDyzAdRecord;
 import com.ytpm.app.param.YtAppUserListParam;
 import com.ytpm.middle.view.AppRevenueHourVO;
@@ -44,4 +45,7 @@ public interface AdRecordMapper {
      * 查询今日广告
      */
     List<YtDyzAdRecord> getTodayRecord(@Param("appIds")String appIds,@Param("firstDay")String firstDay,@Param("lastDay")String lastDay);
+
+    List<UserAdStaticsVo> getUerAdStatics(@Param("appId") String appId, @Param("userId") String userId);
+
 }

+ 3 - 0
yt-adage/adage-service/src/main/java/com/ytpm/adage/service/AdService.java

@@ -2,6 +2,7 @@ package com.ytpm.adage.service;
 
 import com.ytpm.agent.view.AgentAdGroupStaticsVO;
 import com.ytpm.agent.view.AgentTopCountView;
+import com.ytpm.agent.view.UserAdStaticsVo;
 import com.ytpm.app.param.DyzAdRecordParam;
 import com.ytpm.general.Result;
 import com.ytpm.middle.view.DashboardRankingListVO;
@@ -46,4 +47,6 @@ public interface AdService {
      * 查询代理商首页广告数据统计
      */
     List<AgentAdGroupStaticsVO> getAgentProfit(String appIds);
+
+    List<UserAdStaticsVo> getUerAdStatics(String appId, String userId);
 }

+ 16 - 6
yt-adage/adage-service/src/main/java/com/ytpm/adage/service/impl/AdServiceImpl.java

@@ -4,14 +4,16 @@ import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.IdUtil;
 import cn.hutool.core.util.RandomUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.ytpm.adage.dao.AdRecordMapper;
+import com.ytpm.adage.dao.AppUserMapper;
+import com.ytpm.adage.service.AdService;
 import com.ytpm.advertise.enums.AdPlatformTypeEnum;
 import com.ytpm.advertise.enums.AdSourceTypeEnum;
 import com.ytpm.agent.enums.UserStatusEnum;
 import com.ytpm.agent.view.AgentAdGroupStaticsVO;
 import com.ytpm.agent.view.AgentTopCountView;
-import com.ytpm.adage.dao.AdRecordMapper;
-import com.ytpm.adage.dao.AppUserMapper;
-import com.ytpm.adage.service.AdService;
+import com.ytpm.agent.view.UserAdStaticsVo;
 import com.ytpm.app.model.YtDyzAdRecord;
 import com.ytpm.app.model.YtDyzUser;
 import com.ytpm.app.param.DyzAdRecordParam;
@@ -19,7 +21,6 @@ import com.ytpm.feign.RiskFeign;
 import com.ytpm.general.RepMessage;
 import com.ytpm.general.Result;
 import com.ytpm.general.StatusCode;
-import com.ytpm.handle.CustomerException;
 import com.ytpm.middle.view.AppRankingListVO;
 import com.ytpm.middle.view.AppRevenueHourVO;
 import com.ytpm.middle.view.AppUserHourVO;
@@ -81,8 +82,12 @@ public class AdServiceImpl implements AdService {
         //调用风控广告校验
         if(AdSourceTypeEnum.rewarded_video.getAdSourceType() == param.getAdSourceType()){
             Result<?> result = riskFeign.checkAdRisk(user);
-            if(result.getCode()!=200){
-                return new Result<>(StatusCode.ACCESS_ERR,getTipsMsg());
+            if (result.getCode() != 200) {
+                Result<Object> resultObj = new Result<>(StatusCode.ACCESS_ERR, getTipsMsg());
+                if(result.getData() != null){
+                    resultObj.setData(JSONObject.toJSONString(result.getData()));
+                }
+                return resultObj;
             }
         }
         return Result.resultOk(RepMessage.SAVE_SUCCESS);
@@ -285,6 +290,11 @@ public class AdServiceImpl implements AdService {
         return vos;
     }
 
+    @Override
+    public List<UserAdStaticsVo> getUerAdStatics(String appId, String userId) {
+        return adRecordMapper.getUerAdStatics(appId, userId);
+    }
+
     /**
      * 保存记录
      *  始终创建新的事务以保障子方法的独立事务

+ 17 - 1
yt-adage/adage-service/src/main/java/com/ytpm/adage/service/impl/VisitorLoginServiceImpl.java

@@ -149,10 +149,26 @@ public class VisitorLoginServiceImpl extends AbstractLoginService  {
         old.setLoginRecordList(loginRecordMapper.getLoginRecords(old.getUserId()));
     }
 
+    @Override
+    protected void afterVisitorRegistryUser(YtDyzUser ytDyzUser) {
+        super.afterVisitorRegistryUser(ytDyzUser);
+        checkEcPmAndRevenue(ytDyzUser);
+    }
+
     @Override
     protected void beforeDeadWithUserCrud(LoginParam loginParam, YtDyzUser ytDyzUser, Map<String, Object> paramMap) {
         super.beforeDeadWithUserCrud(loginParam, ytDyzUser, paramMap);
-        // 新增风控 相关广告源记录 ecpm  和预估收益 小于 各自 阈值,登陆返回 301
+        checkEcPmAndRevenue(ytDyzUser);
+    }
 
+    /**
+     * 新增风控 相关广告源记录 ecpm  和预估收益 小于 各自 阈值,登陆返回 301
+     * @param ytDyzUser
+     */
+    private void checkEcPmAndRevenue(YtDyzUser ytDyzUser){
+        Result<?> result = riskFeign.checkVisitorLogin(ytDyzUser);
+        if (result == null || result.getCode() != 200) {
+            throw new CommonException(result == null ? "feign invoke Fail!" : result.getMessage());
+        }
     }
 }

+ 5 - 1
yt-adage/adage-service/src/main/java/com/ytpm/adage/service/impl/WxLoginServiceImpl.java

@@ -31,7 +31,11 @@ import org.springframework.stereotype.Component;
 
 import javax.servlet.http.HttpServletRequest;
 import java.math.BigDecimal;
-import java.util.*;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Date;
 
 /**
  * @author lih

+ 14 - 0
yt-adage/adage-service/src/main/resources/mapper/AdRecordMapper.xml

@@ -139,4 +139,18 @@
             and finish_time <![CDATA[<=]]> #{lastDay}
         </if>
     </select>
+    <select id="getUerAdStatics" resultType="com.ytpm.agent.view.UserAdStaticsVo">
+        select
+            user_id,
+            app_id,
+            ad_source_type,
+            count(record_id) as record_count,
+            sum(ecpm) as ecpm,
+            sum(revenue) as revenue
+        from yt_dyz_ad_record ydar
+        where ad_source_type in (0, 2, 4)
+        and app_id = #{appId} and user_id = #{userId}
+        group by user_id, app_id, ad_source_type
+
+    </select>
 </mapper>

+ 41 - 0
yt-common/src/main/java/com/ytpm/agent/view/UserAdStaticsVo.java

@@ -0,0 +1,41 @@
+package com.ytpm.agent.view;
+
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+
+/**
+ * @author lih
+ * @date 2025/9/4
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@ApiModel("用户广告收益统计类")
+public class UserAdStaticsVo {
+
+    @ApiModelProperty("用户ID")
+    private String userId;
+
+    @ApiModelProperty("应用ID")
+    private String appId;
+
+    @ApiModelProperty("广告源类型")
+    private String adSourceType;
+
+    @ApiModelProperty("广告记录数")
+    private Integer totalRecord;
+
+    @ApiModelProperty("总预估广告收益")
+    private BigDecimal totalRevenue;
+
+    @ApiModelProperty("总预估ecpm")
+    private BigDecimal totalEcpm;
+
+
+}

+ 7 - 0
yt-common/src/main/java/com/ytpm/handle/AbstractLoginService.java

@@ -124,9 +124,12 @@ public abstract class AbstractLoginService {
         YtDyzUser ytDyzUser = null;
         List<YtDyzUser> ytDyzUsers = queryDyzUserByParam(loginParam, paramMap);
         if(CollUtil.isEmpty(ytDyzUsers)) {
+            //注册后回调
             beforeRegistryUser(loginParam, paramMap);
             ytDyzUser = new YtDyzUser();
             registryUser(loginParam, ytDyzUser, paramMap);
+            //注册后回调
+            afterVisitorRegistryUser(ytDyzUser);
         } else {
             // 查询当前设备当前渠道是否存在该用户
             ytDyzUser = queryUserByDeviceAndDitch(loginParam.getDeviceId(), loginParam.getDitchId());
@@ -145,6 +148,10 @@ public abstract class AbstractLoginService {
         return ytDyzUser;
     }
 
+    protected void afterVisitorRegistryUser(YtDyzUser ytDyzUser) {
+
+    }
+
     private void visitorCheckRegRisk(YtDyzUser user) {
         Result<?> result = remoteCheckRegRisk(user);
         if (result == null) {

+ 173 - 4
yt-middle/middle-platform/src/main/java/com/ytpm/middle/service/impl/ApkServiceImpl.java

@@ -3,6 +3,7 @@ package com.ytpm.middle.service.impl;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.text.CharSequenceUtil;
 import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.github.pagehelper.PageHelper;
@@ -55,6 +56,34 @@ public class ApkServiceImpl implements ApkService {
     private String initEcpm;
     @Value("${risk.config.initRevenue}")
     private String initRevenue;
+
+    @Value("${risk.config.initAdCompletedCount:10}")
+    private String initAdCompletedCount;
+
+    @Value("${risk.config.initFirstCount:3}")
+    private String initFirstCount;
+
+    @Value("${risk.config.initAverageRevenue:0.05}")
+    private String initAverageRevenue;
+
+    @Value("${risk.config.initMonthCount:1}")
+    private String initMonthCount;
+
+    @Value("${risk.config.initMonthTaskLimit:20}")
+    private String initMonthTaskLimit;
+
+    @Value("${risk.config.initHourCount:24}")
+    private String initHourCount;
+
+    @Value("${risk.config.initHourTaskLimit:5}")
+    private String initHourTaskLimit;
+
+    @Value("${risk.config.visitor.initEcpmLimit:20}")
+    private String initVisitorEcpmLimit;
+
+    @Value("${risk.config.visitor.initRevenueLimit:0.5}")
+    private String initVisitorRevenueLimit;
+
     @Autowired
     private FeignClientInvoker feignInvoker;
     @Autowired
@@ -120,7 +149,7 @@ public class ApkServiceImpl implements ApkService {
     @Transactional(rollbackFor = Exception.class)
     public Result<?> saveApp(AppParam param, MiddleUserInfo loginUser) {
         //数据库操作,有appId为修改, 没有时为新增
-        changeDataAction(param,loginUser.getUserId());
+        changeDataAction(param, loginUser.getUserId());
         //出包修改 default_config
         changeDefaultConfig(param);
         if(CharSequenceUtil.isNotBlank(param.getAppId())){
@@ -175,11 +204,151 @@ public class ApkServiceImpl implements ApkService {
     private void generateRiskDefaultConfig(AppParam param,MiddleUserInfo loginUser) {
         addTemp742(param,loginUser);
         addTemp746(param,loginUser);
-        addTemp748(param, loginUser);
+        // 游客登陆风控校验
+        addTemp344(param, loginUser);
+        // 平均收益风控
+        addTemp766(param, loginUser);
+        // 任务完成数风控
+        addTemp767(param, loginUser);
+        addTemp768(param, loginUser);
+    }
+
+    private void addTemp344(AppParam param, MiddleUserInfo loginUser) {
+        // 风控规则 游客模式用户开屏广告累计ecpm<{}
+        // 风控规则 游客模式用户开屏广告累计预估收益<{}
+        // 风控规则 游客模式用户横幅累计ecpm<{}
+        // 风控规则 游客模式用户横幅累计预估收益<{}
+        // 风控规则 游客模式用户原生(信息流)累计ecpm<{}
+        // 风控规则 游客模式用户原生(信息流)累计预估收益<{}
+        String appId = param.getAppId();
+        String agentId = param.getUserId();
+        Date currentDate = new Date();
+        List<YtRiskConfig> configIds = new ArrayList<>();
+        createTemp344ByAdType(param, configIds, "0", "信息流");
+        createTemp344ByAdType(param, configIds, "2", "横幅");
+        createTemp344ByAdType(param, configIds, "4", "开屏");
+        String templateId = IdUtil.getSnowflakeNextIdStr();
+        String content = configIds.stream().map(YtRiskConfig::getFieldDesc).collect(Collectors.joining(""));
+        YtRiskTemplate template = new YtRiskTemplate(templateId, "游客用户收益限制", content,
+                appId + "-344", agentId, 2, appId,
+                currentDate, loginUser.getUserId(), null, null,
+                1, 1, 1);
+        riskMapper.insertTemplate(template);
+        YtRiskTemplateConfig templateConfig;
+        for (YtRiskConfig config : configIds) {
+            templateConfig = new YtRiskTemplateConfig(templateId, config.getConfigId(),
+                    loginUser.getUserId(), loginUser.getNickName(), currentDate);
+            riskMapper.insertTempConfig(templateConfig);
+        }
+    }
+
+    private void createTemp344ByAdType(AppParam param, List<YtRiskConfig> configs, String adSourceType, String typeName){
+        YtRiskConfig riskConfig;
+        riskConfig = createRiskConfig(param.getUserId(), StrUtil.format("ecpmLimit_{}", adSourceType),
+                StrUtil.format("{}累计ecpm<{},", typeName, initVisitorEcpmLimit), initHourCount, 4);
+        configs.add(riskConfig);
+        riskConfig = createRiskConfig(param.getUserId(),  StrUtil.format("revenueLimit_{}", adSourceType),
+                StrUtil.format("{}累计预估收益<{};", typeName, initVisitorRevenueLimit), initHourTaskLimit, 4);
+        configs.add(riskConfig);
+    }
+
+
+    private void addTemp768(AppParam param, MiddleUserInfo loginUser) {
+        // 每{}小时用户获得完成{}个获得奖励的激励视频
+        String appId = param.getAppId();
+        String agentId = param.getUserId();
+        Date currentDate = new Date();
+        List<String> configIds = new ArrayList<>();
+        YtRiskConfig riskConfig;
+        riskConfig = createRiskConfig(agentId, "hourCount",
+                StrUtil.format("每{}小时", initHourCount), initHourCount, 2);
+        configIds.add(riskConfig.getConfigId());
+        riskConfig = createRiskConfig(agentId, "hourTaskLimit",
+                StrUtil.format("用户获得{}个获得奖励的激励视频", initHourTaskLimit), initHourTaskLimit, 2);
+        configIds.add(riskConfig.getConfigId());
+        String templateId = IdUtil.getSnowflakeNextIdStr();
+        YtRiskTemplate template = new YtRiskTemplate(templateId,"小时区间任务数完成限制",
+                StrUtil.format("每{}小时用户获得完成{}个获得奖励的激励视频", initHourCount, initHourTaskLimit),
+                appId + "-768", agentId, 2, appId,
+                currentDate, loginUser.getUserId(),null, null,
+                1,1,1);
+        riskMapper.insertTemplate(template);
+        YtRiskTemplateConfig templateConfig;
+        for (String itemId : configIds) {
+            templateConfig = new YtRiskTemplateConfig(templateId, itemId, loginUser.getUserId(), loginUser.getNickName(), currentDate);
+            riskMapper.insertTempConfig(templateConfig);
+        }
+        //风控模版关联应用
+        riskMapper.relativeApp(appId, param.getAppName(), template.getTemplateId(), loginUser.getNickName(), loginUser.getUserId());
+    }
+
+    private void addTemp767(AppParam param, MiddleUserInfo loginUser) {
+        // 风控规则 每{}月用户获得{}个获得奖励的激励视频
+        String appId = param.getAppId();
+        String agentId = param.getUserId();
+        Date currentDate = new Date();
+        List<String> configIds = new ArrayList<>();
+        YtRiskConfig riskConfig;
+        riskConfig = createRiskConfig(agentId, "monthCount",
+                StrUtil.format("每{}月", initMonthCount), initMonthCount, 2);
+        configIds.add(riskConfig.getConfigId());
+        riskConfig = createRiskConfig(agentId, "monthTaskLimit",
+                StrUtil.format("用户获得{}个获得奖励的激励视频", initMonthTaskLimit),initMonthTaskLimit, 2);
+        configIds.add(riskConfig.getConfigId());
+        String templateId = IdUtil.getSnowflakeNextIdStr();
+        YtRiskTemplate template = new YtRiskTemplate(templateId,"月区间任务完成数限制",
+                StrUtil.format("每{}月用户获得{}个获得奖励的激励视频", initMonthCount, initMonthTaskLimit),
+                appId + "-767", agentId, 2, appId,
+                currentDate, loginUser.getUserId(),null, null,
+                1,1,1);
+        riskMapper.insertTemplate(template);
+        YtRiskTemplateConfig templateConfig;
+        for (String itemId : configIds) {
+            templateConfig = new YtRiskTemplateConfig(templateId, itemId, loginUser.getUserId(), loginUser.getNickName(), currentDate);
+            riskMapper.insertTempConfig(templateConfig);
+        }
+        //风控模版关联应用
+        riskMapper.relativeApp(appId, param.getAppName(), template.getTemplateId(), loginUser.getNickName(), loginUser.getUserId());
     }
 
-    private void addTemp748(AppParam param, MiddleUserInfo loginUser) {
-        // TODO
+    private void addTemp766(AppParam param, MiddleUserInfo loginUser) {
+        // 风控规则:当用户完成广告类型 激励视频  {}个 数时,获取近期{} * {} 条收益(平均取整)平均值 ,低于预设值 {} 时,
+        String appId = param.getAppId();
+        String agentId = param.getUserId();
+        Date currentDate = new Date();
+        List<String> configIds = new ArrayList<>();
+        YtRiskConfig riskConfig;
+        riskConfig = createRiskConfig(agentId, "adCompletedCount",
+                StrUtil.format("当日用户获得{}个获得奖励的激励视频,"),initAdCompletedCount, 2);
+        configIds.add(riskConfig.getConfigId());
+        riskConfig = createRiskConfig(agentId, "firstCount",
+                StrUtil.format("近期前{}个获得奖励的激励视频", initFirstCount),  initFirstCount, 2);
+        configIds.add(riskConfig.getConfigId());
+        riskConfig = createRiskConfig(agentId, "averageRevenue",
+                StrUtil.format("平均收益<{}", initAverageRevenue),  initAverageRevenue, 4);
+        configIds.add(riskConfig.getConfigId());
+        String templateId = IdUtil.getSnowflakeNextIdStr();
+        String templateContent = StrUtil.format("当日用户获得{}个获得奖励的激励视频,近期前{}个获得奖励的激励视频平均收益<{}",
+                initAdCompletedCount, initFirstCount, initAverageRevenue);
+        YtRiskTemplate template = new YtRiskTemplate(templateId,"成本收益限制", templateContent,
+                appId + "-766", agentId, 2, appId,
+                currentDate, loginUser.getUserId(),null, null,
+                1,1,1);
+        riskMapper.insertTemplate(template);
+        YtRiskTemplateConfig templateConfig;
+        for (String itemId : configIds) {
+            templateConfig = new YtRiskTemplateConfig(templateId, itemId, loginUser.getUserId(), loginUser.getNickName(), currentDate);
+            riskMapper.insertTempConfig(templateConfig);
+        }
+        //风控模版关联应用
+        riskMapper.relativeApp(appId, param.getAppName(), template.getTemplateId(), loginUser.getNickName(), loginUser.getUserId());
+    }
+
+    private YtRiskConfig createRiskConfig(String agentId, String fieldName, String filedDesc, String initVal, Integer multy){
+        String configId = IdUtil.getSnowflakeNextIdStr();
+        YtRiskConfig config = new YtRiskConfig(configId, agentId, fieldName, filedDesc, 1, initVal, multy);
+        riskMapper.insertConfigItem(config);
+        return config;
     }
 
     private void addTemp746(AppParam param, MiddleUserInfo loginUser) {

+ 292 - 0
yt-middle/middle-platform/src/main/test/com/ytpm/middle/test/TestGenerateRiskTemplate.java

@@ -0,0 +1,292 @@
+package com.ytpm.middle.test;
+
+
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.StrUtil;
+import com.ytpm.agent.param.AppParam;
+import com.ytpm.middle.dao.ApkMapper;
+import com.ytpm.middle.dao.RiskMapper;
+import com.ytpm.middle.view.MiddleUserInfo;
+import com.ytpm.risk.model.YtRiskConfig;
+import com.ytpm.risk.model.YtRiskTemplate;
+import com.ytpm.risk.model.YtRiskTemplateConfig;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author lih
+ * @date 2025/9/5
+ */
+@SpringBootTest
+@RunWith(SpringRunner.class)
+@AutoConfigureMockMvc
+public class TestGenerateRiskTemplate {
+
+    @Resource
+    private ApkMapper apkMapper;
+    @Resource
+    private RiskMapper riskMapper;
+
+    @Value("${risk.config.initEcpm}")
+    private String initEcpm;
+    @Value("${risk.config.initRevenue}")
+    private String initRevenue;
+
+    @Value("${risk.config.initAdCompletedCount:10}")
+    private String initAdCompletedCount;
+
+    @Value("${risk.config.initFirstCount:3}")
+    private String initFirstCount;
+
+    @Value("${risk.config.initAverageRevenue:0.05}")
+    private String initAverageRevenue;
+
+    @Value("${risk.config.initMonthCount:1}")
+    private String initMonthCount;
+
+    @Value("${risk.config.initMonthTaskLimit:20}")
+    private String initMonthTaskLimit;
+
+    @Value("${risk.config.initHourCount:24}")
+    private String initHourCount;
+
+    @Value("${risk.config.initHourTaskLimit:5}")
+    private String initHourTaskLimit;
+
+    @Value("${risk.config.visitor.initEcpmLimit:20}")
+    private String initVisitorEcpmLimit;
+
+    @Value("${risk.config.visitor.initRevenueLimit:0.5}")
+    private String initVisitorRevenueLimit;
+
+    @Test
+    public void generateTemplate() {
+        AppParam param = new AppParam();
+        param.setAppId("abdedfedb7f74fe08cff514ae1d22111");
+        param.setUserId("yt_agent_1958702951861489664");
+        MiddleUserInfo loginUser = new MiddleUserInfo();
+        loginUser.setUserId("00711");
+        loginUser.setNickName("lih");
+
+        addTemp742(param,loginUser);
+        addTemp746(param,loginUser);
+        // 游客登陆风控校验
+        addTemp344(param, loginUser);
+        // 平均收益风控
+        addTemp766(param, loginUser);
+        // 任务完成数风控
+        addTemp767(param, loginUser);
+        addTemp768(param, loginUser);
+    }
+
+    private void addTemp742(AppParam param, MiddleUserInfo loginUser) {
+        String appId = param.getAppId();
+        String agentId = param.getUserId();
+        List<String> configIds = new ArrayList<>();
+        String configId = IdUtil.getSnowflakeNextIdStr();
+        configIds.add(configId);
+        YtRiskConfig config = new YtRiskConfig(configId,agentId,"firstAdCount","当日前4条激励视频",1,"4",2);
+        riskMapper.insertConfigItem(config);
+        configId = IdUtil.getSnowflakeNextIdStr();
+        configIds.add(configId);
+        config = new YtRiskConfig(configId,agentId,"haveCount","有2条",1,"2",2);
+        riskMapper.insertConfigItem(config);
+        configId = IdUtil.getSnowflakeNextIdStr();
+        configIds.add(configId);
+        config = new YtRiskConfig(configId,agentId,"ecpm","ecpm值为<"+initEcpm,1,initEcpm,4);
+        riskMapper.insertConfigItem(config);
+        String templateId = IdUtil.getSnowflakeNextIdStr();
+        YtRiskTemplateConfig templateConfig;
+        for (String itemId : configIds) {
+            templateConfig = new YtRiskTemplateConfig(templateId,itemId,loginUser.getUserId(),loginUser.getNickName(),new Date());
+            riskMapper.insertTempConfig(templateConfig);
+        }
+        YtRiskTemplate template = new YtRiskTemplate(templateId,"激励视频ecpm值控制",
+                "当日前4条激励视频,有2条,ecpm值为<"+initEcpm,appId+"-742",agentId,
+                2,appId,new Date(),loginUser.getUserId(),null,
+                null,1,1,1);
+        riskMapper.insertTemplate(template);
+        //风控模版关联应用
+        riskMapper.relativeApp(appId,param.getAppName(),template.getTemplateId(),
+                loginUser.getNickName(),loginUser.getUserId());
+    }
+
+
+    private void addTemp746(AppParam param, MiddleUserInfo loginUser) {
+        String appId = param.getAppId();
+        String agentId = param.getUserId();
+        List<String> configIds = new ArrayList<>();
+        String configId = IdUtil.getSnowflakeNextIdStr();
+        configIds.add(configId);
+        YtRiskConfig config = new YtRiskConfig(configId,agentId,"rewardCount","当日前2条获得奖励的激励视频",1,"2",2);
+        riskMapper.insertConfigItem(config);
+        configId = IdUtil.getSnowflakeNextIdStr();
+        configIds.add(configId);
+        config = new YtRiskConfig(configId,agentId,"income","总收益为<"+initRevenue,1,initRevenue,4);
+        riskMapper.insertConfigItem(config);
+        String templateId = IdUtil.getSnowflakeNextIdStr();
+        YtRiskTemplateConfig templateConfig;
+        for (String itemId : configIds) {
+            templateConfig = new YtRiskTemplateConfig(templateId,itemId,loginUser.getUserId(),loginUser.getNickName(),new Date());
+            riskMapper.insertTempConfig(templateConfig);
+        }
+        YtRiskTemplate template = new YtRiskTemplate(templateId,"最低收益限制",
+                "当日前2条获得奖励的激励视频,总收益为<"+initRevenue,appId+"-746",agentId,
+                2,appId,new Date(),loginUser.getUserId(),null,
+                null,1,1,1);
+        riskMapper.insertTemplate(template);
+        //风控模版关联应用
+        riskMapper.relativeApp(appId,param.getAppName(),template.getTemplateId(),
+                loginUser.getNickName(),loginUser.getUserId());
+    }
+
+
+    private void addTemp344(AppParam param, MiddleUserInfo loginUser) {
+        // 风控规则 游客模式用户开屏广告累计ecpm<{}
+        // 风控规则 游客模式用户开屏广告累计预估收益<{}
+        // 风控规则 游客模式用户横幅累计ecpm<{}
+        // 风控规则 游客模式用户横幅累计预估收益<{}
+        // 风控规则 游客模式用户原生(信息流)累计ecpm<{}
+        // 风控规则 游客模式用户原生(信息流)累计预估收益<{}
+        String appId = param.getAppId();
+        String agentId = param.getUserId();
+        Date currentDate = new Date();
+        List<YtRiskConfig> configIds = new ArrayList<>();
+        createTemp344ByAdType(param, configIds, "0", "信息流");
+        createTemp344ByAdType(param, configIds, "2", "横幅");
+        createTemp344ByAdType(param, configIds, "4", "开屏");
+        String templateId = IdUtil.getSnowflakeNextIdStr();
+        String content = configIds.stream().map(YtRiskConfig::getFieldDesc).collect(Collectors.joining(""));
+        YtRiskTemplate template = new YtRiskTemplate(templateId, "游客用户收益限制", content,
+                appId + "-344", agentId, 2, appId,
+                currentDate, loginUser.getUserId(), null, null,
+                1, 1, 1);
+        riskMapper.insertTemplate(template);
+        YtRiskTemplateConfig templateConfig;
+        for (YtRiskConfig config : configIds) {
+            templateConfig = new YtRiskTemplateConfig(templateId, config.getConfigId(),
+                    loginUser.getUserId(), loginUser.getNickName(), currentDate);
+            riskMapper.insertTempConfig(templateConfig);
+        }
+    }
+
+    private void createTemp344ByAdType(AppParam param, List<YtRiskConfig> configs, String adSourceType, String typeName){
+        YtRiskConfig riskConfig;
+        riskConfig = createRiskConfig(param.getUserId(), StrUtil.format("ecpmLimit_{}", adSourceType),
+                StrUtil.format("{}累计ecpm<{},", typeName, initVisitorEcpmLimit), initHourCount, 4);
+        configs.add(riskConfig);
+        riskConfig = createRiskConfig(param.getUserId(),  StrUtil.format("revenueLimit_{}", adSourceType),
+                StrUtil.format("{}累计预估收益<{};", typeName, initVisitorRevenueLimit), initHourTaskLimit, 4);
+        configs.add(riskConfig);
+    }
+
+
+    private void addTemp768(AppParam param, MiddleUserInfo loginUser) {
+        // 每{}小时用户获得完成{}个获得奖励的激励视频
+        String appId = param.getAppId();
+        String agentId = param.getUserId();
+        Date currentDate = new Date();
+        List<String> configIds = new ArrayList<>();
+        YtRiskConfig riskConfig;
+        riskConfig = createRiskConfig(agentId, "hourCount",
+                StrUtil.format("每{}小时", initHourCount), initHourCount, 2);
+        configIds.add(riskConfig.getConfigId());
+        riskConfig = createRiskConfig(agentId, "hourTaskLimit",
+                StrUtil.format("用户获得{}个获得奖励的激励视频", initHourTaskLimit), initHourTaskLimit, 2);
+        configIds.add(riskConfig.getConfigId());
+        String templateId = IdUtil.getSnowflakeNextIdStr();
+        YtRiskTemplate template = new YtRiskTemplate(templateId,"小时区间任务数完成限制",
+                StrUtil.format("每{}小时用户获得完成{}个获得奖励的激励视频", initHourCount, initHourTaskLimit),
+                appId + "-768", agentId, 2, appId,
+                currentDate, loginUser.getUserId(),null, null,
+                1,1,1);
+        riskMapper.insertTemplate(template);
+        YtRiskTemplateConfig templateConfig;
+        for (String itemId : configIds) {
+            templateConfig = new YtRiskTemplateConfig(templateId, itemId, loginUser.getUserId(), loginUser.getNickName(), currentDate);
+            riskMapper.insertTempConfig(templateConfig);
+        }
+        //风控模版关联应用
+        riskMapper.relativeApp(appId, param.getAppName(), template.getTemplateId(), loginUser.getNickName(), loginUser.getUserId());
+    }
+
+    private void addTemp767(AppParam param, MiddleUserInfo loginUser) {
+        // 风控规则 每{}月用户获得{}个获得奖励的激励视频
+        String appId = param.getAppId();
+        String agentId = param.getUserId();
+        Date currentDate = new Date();
+        List<String> configIds = new ArrayList<>();
+        YtRiskConfig riskConfig;
+        riskConfig = createRiskConfig(agentId, "monthCount",
+                StrUtil.format("每{}月", initMonthCount), initMonthCount, 2);
+        configIds.add(riskConfig.getConfigId());
+        riskConfig = createRiskConfig(agentId, "monthTaskLimit",
+                StrUtil.format("用户获得{}个获得奖励的激励视频", initMonthTaskLimit),initMonthTaskLimit, 2);
+        configIds.add(riskConfig.getConfigId());
+        String templateId = IdUtil.getSnowflakeNextIdStr();
+        YtRiskTemplate template = new YtRiskTemplate(templateId,"月区间任务完成数限制",
+                StrUtil.format("每{}月用户获得{}个获得奖励的激励视频", initMonthCount, initMonthTaskLimit),
+                appId + "-767", agentId, 2, appId,
+                currentDate, loginUser.getUserId(),null, null,
+                1,1,1);
+        riskMapper.insertTemplate(template);
+        YtRiskTemplateConfig templateConfig;
+        for (String itemId : configIds) {
+            templateConfig = new YtRiskTemplateConfig(templateId, itemId, loginUser.getUserId(), loginUser.getNickName(), currentDate);
+            riskMapper.insertTempConfig(templateConfig);
+        }
+        //风控模版关联应用
+        riskMapper.relativeApp(appId, param.getAppName(), template.getTemplateId(), loginUser.getNickName(), loginUser.getUserId());
+    }
+
+    private void addTemp766(AppParam param, MiddleUserInfo loginUser) {
+        // 风控规则:当用户完成广告类型 激励视频  {}个 数时,获取近期{} * {} 条收益(平均取整)平均值 ,低于预设值 {} 时,
+        String appId = param.getAppId();
+        String agentId = param.getUserId();
+        Date currentDate = new Date();
+        List<String> configIds = new ArrayList<>();
+        YtRiskConfig riskConfig;
+        riskConfig = createRiskConfig(agentId, "adCompletedCount",
+                StrUtil.format("当日用户获得{}个获得奖励的激励视频,"),initAdCompletedCount, 2);
+        configIds.add(riskConfig.getConfigId());
+        riskConfig = createRiskConfig(agentId, "firstCount",
+                StrUtil.format("近期前{}个获得奖励的激励视频", initFirstCount),  initFirstCount, 2);
+        configIds.add(riskConfig.getConfigId());
+        riskConfig = createRiskConfig(agentId, "averageRevenue",
+                StrUtil.format("平均收益<{}", initAverageRevenue),  initAverageRevenue, 4);
+        configIds.add(riskConfig.getConfigId());
+        String templateId = IdUtil.getSnowflakeNextIdStr();
+        String templateContent = StrUtil.format("当日用户获得{}个获得奖励的激励视频,近期前{}个获得奖励的激励视频平均收益<{}",
+                initAdCompletedCount, initFirstCount, initAverageRevenue);
+        YtRiskTemplate template = new YtRiskTemplate(templateId,"成本收益限制", templateContent,
+                appId + "-766", agentId, 2, appId,
+                currentDate, loginUser.getUserId(),null, null,
+                1,1,1);
+        riskMapper.insertTemplate(template);
+        YtRiskTemplateConfig templateConfig;
+        for (String itemId : configIds) {
+            templateConfig = new YtRiskTemplateConfig(templateId, itemId, loginUser.getUserId(), loginUser.getNickName(), currentDate);
+            riskMapper.insertTempConfig(templateConfig);
+        }
+        //风控模版关联应用
+        riskMapper.relativeApp(appId, param.getAppName(), template.getTemplateId(), loginUser.getNickName(), loginUser.getUserId());
+    }
+
+    private YtRiskConfig createRiskConfig(String agentId, String fieldName, String filedDesc, String initVal, Integer multy){
+        String configId = IdUtil.getSnowflakeNextIdStr();
+        YtRiskConfig config = new YtRiskConfig(configId, agentId, fieldName, filedDesc, 1, initVal, multy);
+        riskMapper.insertConfigItem(config);
+        return config;
+    }
+
+}

+ 6 - 0
yt-middle/pom.xml

@@ -21,6 +21,12 @@
     </properties>
 
     <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <version>2.1.9.RELEASE</version>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>com.ytpm</groupId>
             <artifactId>yt-common</artifactId>

+ 2 - 0
yt-risk/risk-feign/src/main/java/com/ytpm/feign/RiskFeign.java

@@ -21,4 +21,6 @@ public interface RiskFeign {
     Result<?> checkRegRisk(@RequestBody YtDyzUser ytDyzUser);
     @PostMapping("/public/checkLoginRisk")
     Result<?> checkLoginRisk(YtDyzUser old);
+    @PostMapping("/public/checkVisitorLogin")
+    Result<?> checkVisitorLogin(YtDyzUser old);
 }

+ 6 - 0
yt-risk/risk-manage/src/main/java/com/ytpm/controller/PublicApiController.java

@@ -92,4 +92,10 @@ public class PublicApiController {
     public Result<?> checkLoginRisk(@RequestBody YtDyzUser dyzUser){
         return riskService.checkLoginRisk(dyzUser);
     }
+
+    @ApiOperation("校验游客登录风控配置")
+    @PostMapping("/checkVisitorLogin")
+    public Result<?> checkVisitorLogin(@RequestBody YtDyzUser dyzUser){
+        return riskService.checkVisitorLogin(dyzUser);
+    }
 }

+ 5 - 0
yt-risk/risk-manage/src/main/java/com/ytpm/service/RiskService.java

@@ -129,4 +129,9 @@ public interface RiskService {
      * 校验登录风控配置
      */
     Result<?> checkLoginRisk(YtDyzUser dyzUser);
+
+    /**
+     * 游客用户风控配置 344
+     */
+    Result<?> checkVisitorLogin(YtDyzUser dyzUser);
 }

+ 190 - 18
yt-risk/risk-manage/src/main/java/com/ytpm/service/impl/RiskServiceImpl.java

@@ -2,6 +2,7 @@ package com.ytpm.service.impl;
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.DateField;
 import cn.hutool.core.date.DateUnit;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.text.CharSequenceUtil;
@@ -22,25 +23,40 @@ import com.ytpm.agent.model.YtPlatformUserApp;
 import com.ytpm.agent.view.AgentAppClassView;
 import com.ytpm.agent.view.AgentEnableAppView;
 import com.ytpm.agent.view.AgentUserInfo;
+import com.ytpm.agent.view.UserAdStaticsVo;
 import com.ytpm.app.model.YtDyzAdRecord;
 import com.ytpm.app.model.YtDyzLoginRecord;
 import com.ytpm.app.model.YtDyzUser;
 import com.ytpm.custom.CustomField;
-import com.ytpm.dao.*;
+import com.ytpm.dao.AppMapper;
+import com.ytpm.dao.DictMapper;
+import com.ytpm.dao.RiskConfigMapper;
+import com.ytpm.dao.RiskManageMapper;
+import com.ytpm.dao.RiskUserMapper;
 import com.ytpm.general.RepMessage;
 import com.ytpm.general.Result;
 import com.ytpm.general.ResultTable;
+import com.ytpm.handle.CommonException;
 import com.ytpm.handle.CustomerException;
 import com.ytpm.risk.enums.BannedTypeEnum;
 import com.ytpm.risk.enums.EffectNodeEnum;
 import com.ytpm.risk.model.YtRiskConfig;
 import com.ytpm.risk.model.YtRiskTemplate;
-import com.ytpm.risk.param.*;
-import com.ytpm.risk.view.*;
+import com.ytpm.risk.param.RiskBannedListParam;
+import com.ytpm.risk.param.RiskBannedParam;
+import com.ytpm.risk.param.RiskConfigListParam;
+import com.ytpm.risk.param.RiskConfigParam;
+import com.ytpm.risk.param.RiskDeblockingListParam;
+import com.ytpm.risk.param.RiskRelativeAppParam;
+import com.ytpm.risk.param.RiskUserStatusParam;
+import com.ytpm.risk.view.RiskBannedListView;
+import com.ytpm.risk.view.RiskConfigListView;
+import com.ytpm.risk.view.RiskConfigView;
+import com.ytpm.risk.view.RiskDeblockingListView;
+import com.ytpm.risk.view.RiskTemplateView;
 import com.ytpm.service.RiskService;
 import com.ytpm.util.FeignClientInvoker;
 import com.ytpm.util.RedisService;
-import com.ytpm.util.ReflectUtil;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -52,9 +68,20 @@ import org.springframework.transaction.annotation.Transactional;
 import javax.annotation.Resource;
 import java.lang.reflect.Field;
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
@@ -511,26 +538,95 @@ public class RiskServiceImpl implements RiskService {
             YtApp ytApp = appMapper.selectRiskApp(dyzUser.getAppId());
             userApp =  appMapper.selectParentApp(ytApp.getSuperiorId());
         }
-        Object o = feignInvoker.invoke(userApp.getServiceName(),"adRecords",dyzUser.getUserId(),AdSourceTypeEnum.rewarded_video.getAdSourceType());
+        Object o = feignInvoker.invoke(userApp.getServiceName(), "adRecords", dyzUser.getUserId(),
+                AdSourceTypeEnum.rewarded_video.getAdSourceType());
         JSONObject object = JSON.parseObject(JSON.toJSONString(o));
         List<YtDyzAdRecord> adRecords = JSONArray.parseArray(object.getString("data"), YtDyzAdRecord.class);
         if(CollUtil.isEmpty(adRecords)){
             return Result.resultOk(RepMessage.QUERY_SUCCESS);
         }
-        //过滤出当日的激励视频数据 按照时间正序排以便筛选每日前几条激励视频
-        adRecords = adRecords.stream().filter(s->
-            DateUtil.isSameDay(DateUtil.parse(s.getFinishTime()), new Date())
-        ).sorted(Comparator.comparing(YtDyzAdRecord::getFinishTime)).collect(Collectors.toList());
-        //校验风控742规则
-        RiskTemplateView ecpmLimit= configMapper.getByCode(dyzUser.getAppId()+"-742");
-        checkRisk742(ecpmLimit,dyzUser,adRecords);
-        //校验风控746规则
-        if(!adRecords.isEmpty() && adRecords.size()>1){
-            checkRisk746(dyzUser,adRecords);
+        try {
+            // 校验风控767规则
+            checkRisk767(dyzUser, adRecords);
+            // 校验风控768规则
+            checkRisk768(dyzUser, adRecords);
+            //过滤出当日的激励视频数据 按照时间正序排以便筛选每日前几条激励视频
+            adRecords = adRecords.stream().filter(s ->
+                    DateUtil.isSameDay(DateUtil.parse(s.getFinishTime()), new Date())
+            ).sorted(Comparator.comparing(YtDyzAdRecord::getFinishTime)).collect(Collectors.toList());
+            //校验风控742规则
+            checkRisk742(dyzUser, adRecords);
+            if (!adRecords.isEmpty() && adRecords.size() > 1) {
+                //校验风控746规则
+                checkRisk746(dyzUser, adRecords);
+                // 校验风控766规则
+                checkRisk766(dyzUser, adRecords);
+            }
+        } catch (CommonException e) {
+            return Result.resultOk(e.getMessage(), "766");
         }
         return Result.resultOk(RepMessage.QUERY_SUCCESS);
     }
 
+    private void checkRisk768(YtDyzUser dyzUser, List<YtDyzAdRecord> adRecords) {
+        RiskTemplateView riskTempView = configMapper.getByCode(dyzUser.getAppId() + "-768");
+        if (riskTempView == null || riskTempView.getEnabled() != 1) return;
+        Map<String, String> riskConfigMap = getRsihConfigMap(riskTempView);
+        int hourCount = Integer.parseInt(riskConfigMap.getOrDefault("hourCount", "0"));
+        int hourTaskLimit = Integer.parseInt(riskConfigMap.getOrDefault("monthTaskLimit", "0"));
+        if (hourCount > 0 && hourTaskLimit > 0) {
+            Date limitStartDate = DateUtil.offset(new Date(), DateField.HOUR, -hourTaskLimit);
+            List<YtDyzAdRecord> revenues = adRecords.stream()
+                    .filter(
+                            s -> Objects.nonNull(s.getRevenue()) && (s.getRevenue().compareTo(BigDecimal.ZERO)) > 0)
+                    .filter(item -> DateUtil.parse(item.getFinishTime()).after(limitStartDate))
+                    .collect(Collectors.toList());
+            if (revenues.size() < hourTaskLimit) {
+                if (dyzUser.getIosId() != null) {
+                    riskLockUserForIos(dyzUser, "768", "系统判定重复刷单用户限制", getTipsMsg());
+                } else {
+                    riskLockUser(dyzUser, "768", "系统判定重复刷单用户限制", getTipsMsg());
+                }
+            }
+        }
+    }
+
+    /**
+     * 校验默认风控规则767
+     *  过去{}月用户获得奖励的激励视频
+     */
+    private void checkRisk767(YtDyzUser dyzUser, List<YtDyzAdRecord> adRecords) {
+        RiskTemplateView riskTempView = configMapper.getByCode(dyzUser.getAppId() + "-767");
+        if (riskTempView == null || riskTempView.getEnabled() != 1) return;
+        Map<String, String> riskConfigMap = getRsihConfigMap(riskTempView);
+        int monthCount = Integer.parseInt(riskConfigMap.getOrDefault("monthCount", "0"));
+        int monthTaskLimit = Integer.parseInt(riskConfigMap.getOrDefault("monthTaskLimit", "0"));
+        if (monthCount > 0 && monthTaskLimit > 0) {
+            Date limitStartDate = DateUtil.offset(new Date(), DateField.MONTH, -monthCount);
+            List<YtDyzAdRecord> revenues = adRecords.stream().filter(
+                            s -> Objects.nonNull(s.getRevenue()) && (s.getRevenue().compareTo(BigDecimal.ZERO)) > 0)
+                    .filter(item -> DateUtil.parse(item.getFinishTime()).after(limitStartDate))
+                    .collect(Collectors.toList());
+            if (revenues.size() < monthTaskLimit) {
+                if (dyzUser.getIosId() != null) {
+                    riskLockUserForIos(dyzUser, "767", "系统判定重复刷单用户限制", getTipsMsg());
+                } else {
+                    riskLockUser(dyzUser, "767", "系统判定重复刷单用户限制", getTipsMsg());
+                }
+            }
+        }
+    }
+
+    private Map<String, String> getRsihConfigMap(RiskTemplateView riskTempView) {
+        Map<String, String> riskTempConfig = new HashMap<>();
+        if (riskTempView != null && riskTempView.getEnabled() == 1) {
+            riskTempConfig = riskTempView.getConfigList().stream().collect(Collectors.toMap(
+                    RiskConfigView::getFieldName, RiskConfigView::getConfigVal,
+                    (o1, o2) -> o2));
+        }
+        return riskTempConfig;
+    }
+
     /**
      * 校验用户自定义风控规则
      */
@@ -551,6 +647,37 @@ public class RiskServiceImpl implements RiskService {
         }
     }
 
+    /**
+     * 校验默认风控规则766
+     */
+    private void checkRisk766(YtDyzUser dyzUser, List<YtDyzAdRecord> adRecords) {
+        RiskTemplateView riskTempView = configMapper.getByCode(dyzUser.getAppId() + "-766");
+        if (riskTempView == null || riskTempView.getEnabled() != 1) return;
+        Map<String, String> rsihConfigMap = getRsihConfigMap(riskTempView);
+        int adCompletedCount = Integer.parseInt(rsihConfigMap.getOrDefault("adCompletedCount", "-1"));
+        int firstCount = Integer.parseInt(rsihConfigMap.getOrDefault("firstCount", "-1"));
+        BigDecimal averageRevenueLimit = new BigDecimal(rsihConfigMap.getOrDefault("averageRevenue", "-1"));
+        if(adCompletedCount < 0 || firstCount < 0|| averageRevenueLimit.compareTo(BigDecimal.ZERO) < 0){
+            return;
+        }
+        // 查询前firstCount条记录 收益总值,并计算平均值
+        BigDecimal averageRevenue = BigDecimal.ZERO;
+        if (adRecords.size() >= adCompletedCount) {
+            long count = adRecords.stream().map(YtDyzAdRecord::getRevenue)
+                    .filter(revenue -> revenue != null && revenue.compareTo(BigDecimal.ZERO) > 0)
+                    .limit(firstCount).count();
+            if(count > 0){
+                averageRevenue = adRecords.stream().map(YtDyzAdRecord::getRevenue)
+                        .filter(revenue -> revenue != null && revenue.compareTo(BigDecimal.ZERO) > 0)
+                        .limit(firstCount).reduce(BigDecimal.ZERO, BigDecimal::add)
+                        .divide(new BigDecimal(count), RoundingMode.HALF_UP);
+            }
+        }
+        if (averageRevenue.compareTo(averageRevenueLimit) < 0) {
+            throw new CommonException("已达上限");
+        }
+    }
+
     /**
      * 校验默认风控规则746
      */
@@ -582,8 +709,9 @@ public class RiskServiceImpl implements RiskService {
     /**
      * 校验默认风控规则742
      */
-    private void checkRisk742(RiskTemplateView ecpmLimit,YtDyzUser dyzUser,List<YtDyzAdRecord> records) {
-        if(ecpmLimit.getEnabled()!=1)return;
+    private void checkRisk742(YtDyzUser dyzUser,List<YtDyzAdRecord> records) {
+        RiskTemplateView ecpmLimit= configMapper.getByCode(dyzUser.getAppId()+"-742");
+        if(ecpmLimit == null || ecpmLimit.getEnabled()!=1)return;
         Map<String, String> limitMap = ecpmLimit.getConfigList().stream().collect(
                 Collectors.toMap(RiskConfigView::getFieldName, RiskConfigView::getConfigVal));
         int adCount = 0;
@@ -976,4 +1104,48 @@ public class RiskServiceImpl implements RiskService {
         }
         return Result.resultErr(hours+RepMessage.DITCH_REG_LIMIT);
     }
+
+
+    @Override
+    public Result<?> checkVisitorLogin(YtDyzUser dyzUser) {
+        RiskTemplateView view = configMapper.getByCode(dyzUser.getAppId() + "-344");
+        return checkVisitor344(dyzUser,view)
+                ? Result.resultOk(RepMessage.RISK_SUCCESS) : Result.resultErr(RepMessage.ALREADY_RISK_USER);
+    }
+
+    /**
+     * 344 游客模式登陆用户风控校验<br>
+     * 原生(信息流)、开屏广告、横幅对应 ecpm 和预估收益 小于 阈值时,校验失败
+     * @param dyzUser 该设备同应用的最新一条注册用户信息
+     * @param view 当前校验的设备登录的应用风控配置
+     */
+    private boolean checkVisitor344(YtDyzUser dyzUser, RiskTemplateView view) {
+        //根据用户所属应用查询该应用母包openid查询用户信息
+        List<RiskConfigView> configList = view == null ? Collections.emptyList() : view.getConfigList();
+        Map<String, String> configMap = configList.stream()
+                .filter(item -> item.getMulty() != null && item.getMulty() == 4)
+                .collect(Collectors.toMap(RiskConfigView::getFieldName, RiskConfigView::getConfigVal,
+                (o1,o2)-> o2));
+        //根据用户所属应用查询该应用母包openid查询用户信息
+        YtApp ytApp = appMapper.selectRiskApp(dyzUser.getAppId());
+        YtPlatformUserApp userApp = appMapper.selectParentApp(ytApp.getSuperiorId());
+        Object result = feignInvoker.invoke(userApp.getServiceName(), "getUerAdStatics", dyzUser.getAppId(), dyzUser.getUserId());
+        boolean checkResult = true;
+        if (result != null) {
+            List<UserAdStaticsVo> userAdStaticsVos = JSONArray.parseArray(JSONObject.toJSONString(result), UserAdStaticsVo.class);
+            for (UserAdStaticsVo userAdStaticsVo : userAdStaticsVos) {
+                String ecpmKey = StrUtil.format("ecpmLimit_{}", userAdStaticsVo.getAdSourceType());
+                String revenueKey = StrUtil.format("revenueLimit_{}", userAdStaticsVo.getAdSourceType());
+                checkResult = checkResult && limitCompare(userAdStaticsVo.getTotalEcpm(), ecpmKey, configMap);
+                checkResult = checkResult && limitCompare(userAdStaticsVo.getTotalRevenue(), revenueKey, configMap);
+            }
+        }
+        return checkResult;
+    }
+
+    private boolean limitCompare(BigDecimal totalValue, String limitKey,  Map<String, String> configMap) {
+        BigDecimal limitValue = new BigDecimal(configMap.getOrDefault(limitKey, "0"));
+        return totalValue == null || totalValue.compareTo(limitValue) <= 0;
+    }
+
 }