Sfoglia il codice sorgente

用户列表增加审核功能
风控放到审核后触发,延时触发持久化到redis
登录存储手机json信息

marxjaw 2 mesi fa
parent
commit
ef7885bf02
44 ha cambiato i file con 779 aggiunte e 68 eliminazioni
  1. 10 0
      yt-agent/agent-service/src/main/java/com/ytpm/controller/YtAppUserController.java
  2. 15 0
      yt-agent/agent-service/src/main/java/com/ytpm/dao/RiskMapper.java
  3. 8 1
      yt-agent/agent-service/src/main/java/com/ytpm/service/YtAppUserService.java
  4. 22 32
      yt-agent/agent-service/src/main/java/com/ytpm/service/impl/YtAppUserServiceImpl.java
  5. 1 1
      yt-agent/agent-service/src/main/resources/mapper/AgentAppMapper.xml
  6. 3 3
      yt-agent/agent-service/src/main/resources/mapper/AppMapper.xml
  7. 42 0
      yt-agent/agent-service/src/main/resources/mapper/RiskMapper.xml
  8. 14 0
      yt-app/app-feign/src/main/java/com/ytpm/feign/AppFeign.java
  9. 29 0
      yt-app/app-service/src/main/java/com/ytpm/config/redis/RedisListenerConfig.java
  10. 111 0
      yt-app/app-service/src/main/java/com/ytpm/controller/dyz/UserController.java
  11. 45 6
      yt-app/app-service/src/main/java/com/ytpm/controller/dyz/WxController.java
  12. 7 0
      yt-app/app-service/src/main/java/com/ytpm/dao/dyz/AppUserMapper.java
  13. 10 0
      yt-app/app-service/src/main/java/com/ytpm/dao/nofeeds/NFUserMapper.java
  14. 10 0
      yt-app/app-service/src/main/java/com/ytpm/dao/qnjz/QNUserMapper.java
  15. 10 0
      yt-app/app-service/src/main/java/com/ytpm/dao/qnmjz/QnmUserMapper.java
  16. 85 0
      yt-app/app-service/src/main/java/com/ytpm/monitor/RedisKeyExpirationListener.java
  17. 14 11
      yt-app/app-service/src/main/java/com/ytpm/service/dyz/impl/AdServiceImpl.java
  18. 2 1
      yt-app/app-service/src/main/java/com/ytpm/service/dyz/impl/AppUserServiceImpl.java
  19. 3 0
      yt-app/app-service/src/main/java/com/ytpm/service/nofeeds/impl/NfAdServiceImpl.java
  20. 1 0
      yt-app/app-service/src/main/java/com/ytpm/service/nofeeds/impl/NfUserServiceImpl.java
  21. 3 0
      yt-app/app-service/src/main/java/com/ytpm/service/qnjz/impl/QnAdServiceImpl.java
  22. 1 0
      yt-app/app-service/src/main/java/com/ytpm/service/qnjz/impl/QnUserServiceImpl.java
  23. 3 0
      yt-app/app-service/src/main/java/com/ytpm/service/qnmjz/impl/QnmAdServiceImpl.java
  24. 1 0
      yt-app/app-service/src/main/java/com/ytpm/service/qnmjz/impl/QnmUserServiceImpl.java
  25. 3 0
      yt-app/app-service/src/main/java/com/ytpm/service/xjlrl/impl/XjlrlAdServiceImpl.java
  26. 1 0
      yt-app/app-service/src/main/java/com/ytpm/service/xjlrl/impl/XjlrlUserServiceImpl.java
  27. 44 2
      yt-app/app-service/src/main/resources/mapper/dyz/AppUserMapper.xml
  28. 4 2
      yt-app/app-service/src/main/resources/mapper/dyz/LoginRecordMapper.xml
  29. 4 2
      yt-app/app-service/src/main/resources/mapper/nofeeds/NFLoginRecordMapper.xml
  30. 47 0
      yt-app/app-service/src/main/resources/mapper/nofeeds/NFUserMapper.xml
  31. 4 2
      yt-app/app-service/src/main/resources/mapper/qnjz/QNLoginRecordMapper.xml
  32. 47 1
      yt-app/app-service/src/main/resources/mapper/qnjz/QNUserMapper.xml
  33. 4 2
      yt-app/app-service/src/main/resources/mapper/qnmjz/QnmLoginRecordMapper.xml
  34. 47 0
      yt-app/app-service/src/main/resources/mapper/qnmjz/QnmUserMapper.xml
  35. 4 2
      yt-app/app-service/src/main/resources/mapper/xjlrl/XjlrlLoginRecordMapper.xml
  36. 25 0
      yt-common/src/main/java/com/ytpm/agent/param/AuditCheckParam.java
  37. 32 0
      yt-common/src/main/java/com/ytpm/agent/param/AuditUserParam.java
  38. 29 0
      yt-common/src/main/java/com/ytpm/agent/view/AgentAuditCheckVO.java
  39. 2 0
      yt-common/src/main/java/com/ytpm/app/model/YtDyzLoginRecord.java
  40. 2 0
      yt-common/src/main/java/com/ytpm/app/param/WxLoginParam.java
  41. 3 0
      yt-risk/risk-feign/src/main/java/com/ytpm/feign/RiskFeign.java
  42. 10 0
      yt-risk/risk-manage/src/main/java/com/ytpm/controller/PublicApiController.java
  43. 5 0
      yt-risk/risk-manage/src/main/java/com/ytpm/service/RiskService.java
  44. 12 0
      yt-risk/risk-manage/src/main/java/com/ytpm/service/impl/RiskServiceImpl.java

+ 10 - 0
yt-agent/agent-service/src/main/java/com/ytpm/controller/YtAppUserController.java

@@ -1,5 +1,6 @@
 package com.ytpm.controller;
 
+import com.ytpm.agent.param.AuditUserParam;
 import com.ytpm.agent.view.AgentUserInfo;
 import com.ytpm.app.param.YtAppUserListParam;
 import com.ytpm.app.view.AppUserStaticsView;
@@ -63,4 +64,13 @@ public class YtAppUserController {
     public ResultTable<YtUserEcpmListView> ecpmList(@RequestParam(name = "userId", required = true) String userId, @RequestParam(name = "adsourceType",required = false)Integer adsourceType){
         return appUserService.ecpmList(userId,adsourceType);
     }
+
+    /**
+     * 批量审核
+     */
+    @PostMapping("/batchAudit")
+    @ApiOperation(value = "批量审核用户")
+    public Result<String> batchAudit(@RequestBody AuditUserParam auditParam){
+        return appUserService.batchAudit(auditParam);
+    }
 }

+ 15 - 0
yt-agent/agent-service/src/main/java/com/ytpm/dao/RiskMapper.java

@@ -0,0 +1,15 @@
+package com.ytpm.dao;
+
+
+import com.ytpm.risk.view.RiskTemplateView;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+
+@Mapper
+public interface RiskMapper {
+    /**
+     * 根据应用查询 742 风控配置
+     */
+    RiskTemplateView getByCode(@Param("code")String code);
+}

+ 8 - 1
yt-agent/agent-service/src/main/java/com/ytpm/service/YtAppUserService.java

@@ -1,5 +1,6 @@
 package com.ytpm.service;
 
+import com.ytpm.agent.param.AuditUserParam;
 import com.ytpm.agent.view.AgentUserInfo;
 import com.ytpm.app.param.YtAppUserListParam;
 import com.ytpm.app.view.AppUserStaticsView;
@@ -10,6 +11,7 @@ import com.ytpm.general.ResultTable;
 import com.ytpm.middle.view.MessageVO;
 
 import java.math.BigDecimal;
+import java.util.List;
 
 
 public interface YtAppUserService {
@@ -41,7 +43,12 @@ public interface YtAppUserService {
     ResultTable<MessageVO> unreadMessage(String userId);
 
     /**
-     *
+     * 标记已读
      */
     Result<String> markRead(String messageId, String userId);
+
+    /**
+     * 批量审核
+     */
+    Result<String> batchAudit(AuditUserParam auditParam);
 }

+ 22 - 32
yt-agent/agent-service/src/main/java/com/ytpm/service/impl/YtAppUserServiceImpl.java

@@ -1,10 +1,11 @@
 package com.ytpm.service.impl;
 
 import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.text.CharSequenceUtil;
 import cn.hutool.core.util.StrUtil;
 import com.github.pagehelper.PageInfo;
 import com.ytpm.agent.model.YtApp;
+import com.ytpm.agent.param.AuditCheckParam;
+import com.ytpm.agent.param.AuditUserParam;
 import com.ytpm.agent.view.AgentUserInfo;
 import com.ytpm.app.model.YtAppUserLoginRecord;
 import com.ytpm.app.model.YtDyzAdRecord;
@@ -19,6 +20,7 @@ import com.ytpm.dao.AppUserLoginMapper;
 import com.ytpm.dao.AppVideoWatchMapper;
 import com.ytpm.dao.AppWithdrawMapper;
 import com.ytpm.dao.MessageMapper;
+import com.ytpm.dao.RiskMapper;
 import com.ytpm.feign.AppFeign;
 import com.ytpm.general.RepMessage;
 import com.ytpm.general.Result;
@@ -26,6 +28,7 @@ import com.ytpm.general.ResultTable;
 import com.ytpm.middle.model.YtPlatformMessage;
 import com.ytpm.middle.view.MessageRecordVO;
 import com.ytpm.middle.view.MessageVO;
+import com.ytpm.risk.view.RiskTemplateView;
 import com.ytpm.service.YtAppUserService;
 import org.springframework.stereotype.Service;
 
@@ -48,6 +51,8 @@ public class YtAppUserServiceImpl implements YtAppUserService {
     @Resource
     private AppMapper appMapper;
     @Resource
+    private RiskMapper riskMapper;
+    @Resource
     private AppUserLoginMapper userLoginMapper;
     @Resource
     private AppVideoWatchMapper videoWatchMapper;
@@ -195,6 +200,22 @@ public class YtAppUserServiceImpl implements YtAppUserService {
         return Result.resultOk(RepMessage.MODIFY_SUCCESS);
     }
 
+    /**
+     * 批量审核
+     */
+    @Override
+    public Result<String> batchAudit(AuditUserParam auditParam) {
+        //根据appId 查询出配置的风控规则
+        RiskTemplateView ecpmLimit= riskMapper.getByCode(auditParam.getAppId()+"-742");
+        RiskTemplateView revenueLimit= riskMapper.getByCode(auditParam.getAppId()+"-746");
+        auditParam.setAdSourceType(1);
+        if(Objects.isNull(ecpmLimit) || Objects.isNull(revenueLimit)){
+            return Result.resultErr(RepMessage.OBJECT_NOT_EXIST);
+        }
+        appFeign.batchAudit(new AuditCheckParam(ecpmLimit,revenueLimit,auditParam));
+        return Result.resultOk(RepMessage.CONFIRM_SUCCESS);
+    }
+
     /**
      * 修改消息已读状态
      */
@@ -205,35 +226,4 @@ public class YtAppUserServiceImpl implements YtAppUserService {
         msg.setUpdateParam(userId);
         messageMapper.updateById(msg);
     }
-
-
-    /**
-     * 查询用户当日播放视频总数
-     */
-    private void setWithDrawInfo(String userId, String appId, YtAppUserListView view) {
-        view.setTodayVideo(videoWatchMapper.getVideoPlayCount(appId,userId));
-    }
-
-    /**
-     * 查询用户提现记录计算提现笔数
-     */
-    private void setTodayVideoNum(String userId, String appId, YtAppUserListView view) {
-        view.setWithdrawCount(withdrawMapper.getTodayVideoNum(appId,userId));
-    }
-
-    /**
-     * 查询并设置登录信息
-     */
-    private void setLoginInfo(String userId, String appId, YtAppUserListView view) {
-        //查询用户登录记录
-        YtAppUserLoginRecord record = userLoginMapper.getLastLoginInfo(userId,appId);
-        if(Objects.nonNull(record)){
-            String loginIp = record.getLoginIp();
-            String phoneModel = record.getPhoneModel();
-            view.setIpRepeatCount(userLoginMapper.getIpRepeatCount(userId,appId,loginIp));
-            view.setDeviceRepeatCount(userLoginMapper.getDeviceCount(userId,appId,phoneModel));
-            view.setCommunicationOperator(record.getCommunicationOperator());
-            view.setLastLoginTime(record.getLoginTime());
-        }
-    }
 }

+ 1 - 1
yt-agent/agent-service/src/main/resources/mapper/AgentAppMapper.xml

@@ -70,7 +70,7 @@
                 LEFT JOIN yt_app_channel_relative acr ON ya.app_id = acr.app_id
                 LEFT JOIN yt_platform_user u ON ya.user_id = u.user_id
         WHERE
-            ya.user_id = #{userId}
+            ya.enabled = 1 and ya.user_id = #{userId}
         <if test="appName !=null and appName != ''">
             and ya.app_name like concat('%', #{appName} ,'%')
         </if>

+ 3 - 3
yt-agent/agent-service/src/main/resources/mapper/AppMapper.xml

@@ -125,9 +125,9 @@
         </set>
         where app_id = #{appId}
     </update>
-    <delete id="deleteApp">
-        delete from yt_app where app_id = #{appId}
-    </delete>
+    <update id="deleteApp">
+        update yt_app set enabled = 0 where app_id = #{appId}
+    </update>
     <select id="selectPrimary" resultType="com.ytpm.agent.model.YtApp">
         select
             app_id,ditch_id, ditch_name,  app_key, app_name,user_id, app_type, apk_url, qr_code, version_code, update_tips, enabled

+ 42 - 0
yt-agent/agent-service/src/main/resources/mapper/RiskMapper.xml

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ytpm.dao.RiskMapper">
+    <resultMap id="RiskTemplateViewMap" type="com.ytpm.risk.view.RiskTemplateView">
+        <id column="template_id" property="templateId" />
+        <result column="template_code" property="templateCode" />
+        <result column="template_name" property="templateName" />
+        <result column="template_content" property="templateContent" />
+        <result column="enabled" property="enabled" />
+        <result column="all_satisfy" property="allSatisfy" />
+        <result column="effect_node" property="effectNode" />
+        <collection property="configList" ofType="com.ytpm.risk.view.RiskConfigView">
+            <result column="config_id" property="configId" />
+            <result column="field_name" property="fieldName" />
+            <result column="field_desc" property="fieldDesc" />
+            <result column="config_type" property="configType" />
+            <result column="config_val" property="configVal" />
+            <result column="multy" property="multy" />
+        </collection>
+    </resultMap>
+    <select id="getByCode" resultMap="RiskTemplateViewMap">
+        SELECT
+            rt.template_id,
+            rt.template_code,
+            rt.template_name,
+            rt.template_content,
+            rt.effect_node,
+            rt.enabled,
+            rc.config_id,
+            rc.field_name,
+            rc.field_desc,
+            rc.config_type,
+            rc.config_val,
+            rc.multy
+        FROM
+            yt_risk_template rt
+                LEFT JOIN yt_risk_template_config rtc ON rt.template_id = rtc.template_id
+                LEFT JOIN yt_risk_config rc ON rtc.config_id = rc.config_id
+        WHERE
+            rt.template_code = #{code}
+    </select>
+</mapper>

+ 14 - 0
yt-app/app-feign/src/main/java/com/ytpm/feign/AppFeign.java

@@ -1,5 +1,6 @@
 package com.ytpm.feign;
 
+import com.ytpm.agent.param.AuditCheckParam;
 import com.ytpm.agent.view.AgentAdGroupStaticsVO;
 import com.ytpm.agent.view.AgentTopCountView;
 import com.ytpm.app.model.YtAppDefaultConfig;
@@ -58,6 +59,13 @@ public interface AppFeign {
 
     @PostMapping("/wx/saveAppConfig")
     Result<String> saveAppConfig(@RequestBody YtAppDefaultConfig defaultConfig);
+    @PostMapping("/qn/wx/saveAppConfig")
+    Result<String> qnSaveAppConfig(@RequestBody YtAppDefaultConfig defaultConfig);
+    @PostMapping("/nf/wx/saveAppConfig")
+    Result<String> nfSaveAppConfig(@RequestBody YtAppDefaultConfig defaultConfig);
+    @PostMapping("/qnm/wx/saveAppConfig")
+    Result<String> qnmSaveAppConfig(@RequestBody YtAppDefaultConfig defaultConfig);
+
     @GetMapping("/wx/getConfigs")
     List<WxDefaultConfig> getConfigs(@RequestParam(name = "appIds")String appIds);
 
@@ -96,4 +104,10 @@ public interface AppFeign {
      */
     @GetMapping("/user/lockUser")
     YtDyzUser lockUser(@RequestParam(name="userId")String userId,@RequestParam("userStatus")Integer userStatus);
+
+    /**
+     * 批量审核用户
+     */
+    @PostMapping("/user/batchAudit")
+    void batchAudit(@RequestBody AuditCheckParam auditCheckParam);
 }

+ 29 - 0
yt-app/app-service/src/main/java/com/ytpm/config/redis/RedisListenerConfig.java

@@ -0,0 +1,29 @@
+package com.ytpm.config.redis;
+
+import com.ytpm.monitor.RedisKeyExpirationListener;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
+import org.springframework.data.redis.listener.RedisMessageListenerContainer;
+
+/**
+ * redis 监听器配置
+ * @author marx
+ * @date 2025/7/29 16:09
+ */
+@Configuration
+public class RedisListenerConfig {
+
+    @Bean
+    RedisMessageListenerContainer listenerContainer(RedisConnectionFactory connectionFactory) {
+        RedisMessageListenerContainer listenerContainer = new RedisMessageListenerContainer();
+        listenerContainer.setConnectionFactory(connectionFactory);
+        return listenerContainer;
+    }
+
+    @Bean
+    KeyExpirationEventMessageListener redisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
+        return new RedisKeyExpirationListener(listenerContainer);
+    }
+}

+ 111 - 0
yt-app/app-service/src/main/java/com/ytpm/controller/dyz/UserController.java

@@ -4,6 +4,10 @@ import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.date.DateUtil;
 import com.github.pagehelper.PageInfo;
 import com.ytpm.advertise.enums.AdSourceTypeEnum;
+import com.ytpm.agent.enums.UserStatusEnum;
+import com.ytpm.agent.param.AuditCheckParam;
+import com.ytpm.agent.param.AuditUserParam;
+import com.ytpm.agent.view.AgentAuditCheckVO;
 import com.ytpm.app.model.YtDyzAdRecord;
 import com.ytpm.app.model.YtDyzLoginRecord;
 import com.ytpm.app.model.YtDyzUser;
@@ -27,11 +31,17 @@ import com.ytpm.dao.qnjz.QNUserMapper;
 import com.ytpm.dao.qnmjz.QnmAdRecordMapper;
 import com.ytpm.dao.qnmjz.QnmLoginRecordMapper;
 import com.ytpm.dao.qnmjz.QnmUserMapper;
+import com.ytpm.feign.RiskFeign;
 import com.ytpm.general.RepMessage;
 import com.ytpm.general.Result;
 import com.ytpm.general.ResultTable;
 import com.ytpm.risk.enums.BannedTypeEnum;
+import com.ytpm.risk.view.RiskConfigView;
+import com.ytpm.risk.view.RiskTemplateView;
+import com.ytpm.util.RedisService;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
@@ -85,6 +95,11 @@ public class UserController {
     private QuestionMapper questionMapper;
 
     private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+    @Qualifier("com.ytpm.feign.RiskFeign")
+    @Autowired
+    private RiskFeign riskFeign;
+    @Autowired
+    private RedisService redisService;
 
     /**
      * 查询app 所有玩家
@@ -382,4 +397,100 @@ public class UserController {
         }
         return null;
     }
+
+    /**
+     * 批量审核用户是否满足风控规则
+     * 不满足风控规则的审核通过后直接封禁指定天数
+     */
+    @PostMapping("/batchAudit")
+    public void batchAudit(@RequestBody AuditCheckParam checkParam){
+        AuditUserParam auditParam = checkParam.getAuditParam();
+        RiskTemplateView ecpmLimit = checkParam.getEcpmLimit();
+        RiskTemplateView revenueLimit = checkParam.getRevenueLimit();
+        //查询用户,指定应用激励视频的广告记录
+        List<AgentAuditCheckVO> auditList = new ArrayList<>();
+        List<AgentAuditCheckVO> auditCheckList = appUserMapper.queryTodayUserAd(auditParam);
+        if(CollUtil.isNotEmpty(auditCheckList)){auditList.addAll(auditCheckList);}
+        List<AgentAuditCheckVO> qnAuditCheckList = qnUserMapper.queryTodayUserAd(auditParam);
+        if(CollUtil.isNotEmpty(qnAuditCheckList)){auditList.addAll(qnAuditCheckList);}
+        List<AgentAuditCheckVO> nfAuditCheckList = nfUserMapper.queryTodayUserAd(auditParam);
+        if(CollUtil.isNotEmpty(nfAuditCheckList)){auditList.addAll(nfAuditCheckList);}
+        List<AgentAuditCheckVO> qnmAuditCheckList = qnmUserMapper.queryTodayUserAd(auditParam);
+        if(CollUtil.isNotEmpty(qnmAuditCheckList)){auditList.addAll(qnmAuditCheckList);}
+
+        Map<String, List<YtDyzAdRecord>> adRecordMap = auditList.stream().collect(
+                Collectors.toMap(AgentAuditCheckVO::getUserId, AgentAuditCheckVO::getAdRecordList));
+        checkRisk742(ecpmLimit,adRecordMap,auditParam);
+        checkRisk746(revenueLimit,adRecordMap,auditParam);
+    }
+
+    /**
+     * 校验默认风控规则742
+     */
+    private void checkRisk742(RiskTemplateView ecpmLimit,Map<String, List<YtDyzAdRecord>> adRecordMap,AuditUserParam auditParam) {
+        if(ecpmLimit.getEnabled()!=1)return;
+        Map<String, String> limitMap = ecpmLimit.getConfigList().stream().collect(
+                Collectors.toMap(RiskConfigView::getFieldName, RiskConfigView::getConfigVal));
+        int adCount = 0;
+        for (Map.Entry<String, List<YtDyzAdRecord>> entry : adRecordMap.entrySet()) {
+            adCount = CollUtil.isEmpty(entry.getValue())?adCount:entry.getValue().size();
+            ++adCount;
+            //判断当日观看视频数已经达到风控条件预设的视频数
+            int firstAdCount = Integer.parseInt(limitMap.get("firstAdCount"));
+            if(adCount>=firstAdCount){
+                //过滤出ecpm值小于预设值的视频数
+                int ecpm = Integer.parseInt(limitMap.get("ecpm"));
+                long count = entry.getValue().stream().filter(
+                        s -> Objects.nonNull(s.getEcpm())&&(s.getEcpm().compareTo(BigDecimal.valueOf(ecpm))) < 0).count();
+                int exact = Math.toIntExact(count);
+                //判断小于预设值的视频数超出预设次数
+                int haveCount = Integer.parseInt(limitMap.get("haveCount"));
+                if(exact>haveCount){//把风控不满足的用户记录redis 进行封禁
+                    checkLock(entry,auditParam);
+                }
+            }
+        }
+
+    }
+
+    /**
+     * 用户锁定操作
+     */
+    private void checkLock(Map.Entry<String, List<YtDyzAdRecord>> entry, AuditUserParam auditParam) {
+        log.error("执行对低价值用户{}的定时风控操作", entry.getKey());
+        if(auditParam.getEffectTime() == 0){ //立即锁定
+            lockUser(entry.getKey(), UserStatusEnum.RISK.getCode());
+            redisService.setTimeOutHoursStr("unlock_"+entry.getKey(),auditParam.getAppId(), auditParam.getBannedLimit()*24L);
+        }else{//延迟锁定
+            redisService.setTimeOutHoursStr("lock_"+entry.getKey(), auditParam.getAppId(), auditParam.getEffectTime());
+            redisService.setTimeOutHoursStr("unlock_"+entry.getKey(),auditParam.getAppId(),
+                    auditParam.getBannedLimit()*24L + auditParam.getEffectTime());
+        }
+    }
+
+    /**
+     * 校验默认风控规则746
+     */
+    private void checkRisk746(RiskTemplateView revenueLimit,Map<String, List<YtDyzAdRecord>> adRecordMap,AuditUserParam auditParam) {
+        if(revenueLimit.getEnabled()!=1)return;
+        Map<String, String> revenueMap = revenueLimit.getConfigList().stream().collect(
+                Collectors.toMap(RiskConfigView::getFieldName, RiskConfigView::getConfigVal));
+        for (Map.Entry<String, List<YtDyzAdRecord>> entry : adRecordMap.entrySet()) {
+            List<YtDyzAdRecord> revenues = entry.getValue().stream().filter(
+                    s -> Objects.nonNull(s.getRevenue())&&(s.getRevenue().compareTo(BigDecimal.ZERO)) > 0).collect(Collectors.toList());
+            int incomeCount = 0;
+            incomeCount = CollUtil.isEmpty(revenues)?incomeCount:entry.getValue().size();
+            //判断当日获得收益的广告达到预设数值,触发风控规则
+            int rewardCount = Integer.parseInt(revenueMap.get("rewardCount"));
+            if(incomeCount>=rewardCount){
+                BigDecimal income = new BigDecimal(revenueMap.get("income"));
+                //获取最先的两条
+                BigDecimal reduce = revenues.stream().map(YtDyzAdRecord::getRevenue).reduce(BigDecimal.ZERO, BigDecimal::add);
+                if(reduce.compareTo(income)<0){
+                    checkLock(entry,auditParam);
+                }
+            }
+        }
+
+    }
 }

+ 45 - 6
yt-app/app-service/src/main/java/com/ytpm/controller/dyz/WxController.java

@@ -1,9 +1,11 @@
 package com.ytpm.controller.dyz;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.IdUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.http.HttpUtil;
 import com.alibaba.fastjson.JSON;
+import com.ytpm.agent.model.YtApp;
 import com.ytpm.app.enums.AppTypeEnums;
 import com.ytpm.app.model.YtAppDefaultConfig;
 import com.ytpm.app.param.WxLoginParam;
@@ -11,6 +13,9 @@ import com.ytpm.app.view.WxDefaultConfig;
 import com.ytpm.app.view.WxLoginResult;
 import com.ytpm.app.view.WxUserInfo;
 import com.ytpm.dao.dyz.AppUserMapper;
+import com.ytpm.dao.nofeeds.NFUserMapper;
+import com.ytpm.dao.qnjz.QNUserMapper;
+import com.ytpm.dao.qnmjz.QnmUserMapper;
 import com.ytpm.feign.RiskFeign;
 import com.ytpm.general.RepMessage;
 import com.ytpm.general.Result;
@@ -21,7 +26,6 @@ import com.ytpm.service.dyz.AppUserService;
 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.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -30,7 +34,9 @@ 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;
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Objects;
@@ -42,11 +48,17 @@ import java.util.Objects;
 @RequestMapping("/wx")
 public class WxController {
     private final static String GRANT_TYPE = "authorization_code";
-    @Autowired
+    @Resource
     private AppUserMapper appUserMapper;
-    @Autowired
+    @Resource
+    private QNUserMapper qnUserMapper;
+    @Resource
+    private NFUserMapper nfUserMapper;
+    @Resource
+    private QnmUserMapper qnmUserMapper;
+    @Resource
     private RiskFeign riskFeign;
-    @Autowired
+    @Resource
     private AppUserService appUserService;
 
     @PostMapping("/login")
@@ -153,12 +165,39 @@ public class WxController {
     @ApiOperation("根据APP_ID获取配置")
     @GetMapping("/getConfigs")
     public List<WxDefaultConfig> getConfigs(@RequestParam(name = "appIds")String appIds){
-        return appUserMapper.getConfigByIds(appIds);
+        List<WxDefaultConfig> configs = new ArrayList<>();
+        List<WxDefaultConfig> dyzConfigs = appUserMapper.getConfigByIds(appIds);
+        if(CollUtil.isNotEmpty(dyzConfigs)){configs.addAll(dyzConfigs);}
+
+        List<WxDefaultConfig> qnConfigs = qnUserMapper.getConfigByIds(appIds);
+        if(CollUtil.isNotEmpty(qnConfigs)){configs.addAll(qnConfigs);}
+
+        List<WxDefaultConfig> nfConfigs = nfUserMapper.getConfigByIds(appIds);
+        if(CollUtil.isNotEmpty(nfConfigs)){configs.addAll(nfConfigs);}
+
+        List<WxDefaultConfig> qnmConfigs = qnmUserMapper.getConfigByIds(appIds);
+        if(CollUtil.isNotEmpty(qnmConfigs)){configs.addAll(qnmConfigs);}
+        return configs;
     }
 
     @ApiOperation("删除默认配置")
     @GetMapping("/delDefaultConfig")
     public void delDefaultConfig(@RequestParam(name = "appId")String appId){
-        appUserMapper.delByAppId(appId);
+        List<WxDefaultConfig> dyzConfig = appUserMapper.getConfigByIds(appId);
+        if(CollUtil.isNotEmpty(dyzConfig)){
+            appUserMapper.delByAppId(appId);
+        }
+        dyzConfig = qnUserMapper.getConfigByIds(appId);
+        if(CollUtil.isNotEmpty(dyzConfig)){
+            qnUserMapper.delByAppId(appId);
+        }
+        dyzConfig = nfUserMapper.getConfigByIds(appId);
+        if(CollUtil.isNotEmpty(dyzConfig)){
+            nfUserMapper.delByAppId(appId);
+        }
+        dyzConfig = qnmUserMapper.getConfigByIds(appId);
+        if(CollUtil.isNotEmpty(dyzConfig)){
+            qnmUserMapper.delByAppId(appId);
+        }
     }
 }

+ 7 - 0
yt-app/app-service/src/main/java/com/ytpm/dao/dyz/AppUserMapper.java

@@ -1,5 +1,7 @@
 package com.ytpm.dao.dyz;
 
+import com.ytpm.agent.param.AuditUserParam;
+import com.ytpm.agent.view.AgentAuditCheckVO;
 import com.ytpm.app.model.YtAppDefaultConfig;
 import com.ytpm.app.model.YtDyzPowerRecord;
 import com.ytpm.app.model.YtDyzUser;
@@ -175,4 +177,9 @@ public interface AppUserMapper {
     void unlockUser(@Param("userIds")String userIds);
 
     List<YtDyzUser> queryByUserIds(@Param("userIds")String userIds);
+
+    /**
+     * 分类型查询用户当天视频广告
+     */
+    List<AgentAuditCheckVO> queryTodayUserAd(AuditUserParam auditParam);
 }

+ 10 - 0
yt-app/app-service/src/main/java/com/ytpm/dao/nofeeds/NFUserMapper.java

@@ -1,5 +1,7 @@
 package com.ytpm.dao.nofeeds;
 
+import com.ytpm.agent.param.AuditUserParam;
+import com.ytpm.agent.view.AgentAuditCheckVO;
 import com.ytpm.app.model.YtAppDefaultConfig;
 import com.ytpm.app.model.YtDyzPowerRecord;
 import com.ytpm.app.model.YtDyzUser;
@@ -152,4 +154,12 @@ public interface NFUserMapper {
     List<YtDyzUser> queryByUserIds(@Param("userIds")String userIds);
 
     List<YtDyzUser> queryUserList(AppUserParam param);
+
+    void delByAppId(@Param("appId") String appId);
+
+
+    /**
+     * 分类型查询用户当天视频广告
+     */
+    List<AgentAuditCheckVO> queryTodayUserAd(AuditUserParam auditParam);
 }

+ 10 - 0
yt-app/app-service/src/main/java/com/ytpm/dao/qnjz/QNUserMapper.java

@@ -1,5 +1,7 @@
 package com.ytpm.dao.qnjz;
 
+import com.ytpm.agent.param.AuditUserParam;
+import com.ytpm.agent.view.AgentAuditCheckVO;
 import com.ytpm.app.model.YtAppDefaultConfig;
 import com.ytpm.app.model.YtDyzPowerRecord;
 import com.ytpm.app.model.YtDyzUser;
@@ -151,4 +153,12 @@ public interface QNUserMapper {
     List<YtDyzUser> queryByUserIds(@Param("userIds")String userIds);
 
     List<YtDyzUser> queryUserList(AppUserParam param);
+
+    void delByAppId(@Param("appId") String appId);
+
+
+    /**
+     * 分类型查询用户当天视频广告
+     */
+    List<AgentAuditCheckVO> queryTodayUserAd(AuditUserParam auditParam);
 }

+ 10 - 0
yt-app/app-service/src/main/java/com/ytpm/dao/qnmjz/QnmUserMapper.java

@@ -1,5 +1,7 @@
 package com.ytpm.dao.qnmjz;
 
+import com.ytpm.agent.param.AuditUserParam;
+import com.ytpm.agent.view.AgentAuditCheckVO;
 import com.ytpm.app.model.YtAppDefaultConfig;
 import com.ytpm.app.model.YtDyzPowerRecord;
 import com.ytpm.app.model.YtDyzUser;
@@ -136,4 +138,12 @@ public interface QnmUserMapper {
     List<YtDyzUser> queryByUserIds(@Param("userIds")String userIds);
 
     List<YtDyzUser> queryUserList(AppUserParam param);
+
+    void delByAppId(@Param("appId") String appId);
+
+
+    /**
+     * 分类型查询用户当天视频广告
+     */
+    List<AgentAuditCheckVO> queryTodayUserAd(AuditUserParam auditParam);
 }

+ 85 - 0
yt-app/app-service/src/main/java/com/ytpm/monitor/RedisKeyExpirationListener.java

@@ -0,0 +1,85 @@
+package com.ytpm.monitor;
+
+import com.ytpm.agent.enums.UserStatusEnum;
+import com.ytpm.app.model.YtDyzUser;
+import com.ytpm.dao.dyz.AppUserMapper;
+import com.ytpm.dao.nofeeds.NFUserMapper;
+import com.ytpm.dao.qnjz.QNUserMapper;
+import com.ytpm.dao.qnmjz.QnmUserMapper;
+import com.ytpm.risk.enums.BannedTypeEnum;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+import org.springframework.data.redis.connection.Message;
+import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
+import org.springframework.data.redis.listener.RedisMessageListenerContainer;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import javax.annotation.Resource;
+import java.util.Objects;
+
+/**
+ * redis 监听器
+ */
+@Slf4j(topic = "RedisKeyExpire")
+@Component
+@RefreshScope
+public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
+
+    @Resource
+    private AppUserMapper appUserMapper;
+    @Resource
+    private QNUserMapper qnUserMapper;
+    @Resource
+    private NFUserMapper nfUserMapper;
+    @Resource
+    private QnmUserMapper qnmUserMapper;
+
+    /**
+     * Creates new {@link } for {@code __keyevent@*__:expired} messages.
+     *
+     * @param listenerContainer must not be {@literal null}.
+     */
+    public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
+        super(listenerContainer);
+    }
+ 
+    /**
+     * 监听redis过期的 key 进行处理
+     */
+    @Override
+    public void onMessage(Message message, byte[] pattern) {
+        String key = String.valueOf(message);
+        log.error("App-Service 发现预定风控用户:{}",key);
+        if(key.startsWith("lock_")){
+            String[] arr = key.split("_");
+            lockUser(arr[1], UserStatusEnum.RISK.getCode());
+        }
+    }
+
+     private void lockUser(@RequestParam("userId")String userId, @RequestParam("userStatus")Integer userStatus){
+        YtDyzUser dyzUser = appUserMapper.selectPrimaryKey(userId);
+        YtDyzUser newUser = new YtDyzUser();
+        newUser.setUserId(userId);
+        newUser.setUserStatus(userStatus);
+        newUser.setRiskReason(BannedTypeEnum.CHANNEL.getDesc()+"禁止登录");
+        if(Objects.nonNull(dyzUser)){
+            appUserMapper.updateUser(newUser);
+            return;
+        }
+        dyzUser = qnUserMapper.selectPrimaryKey(userId);
+        if(Objects.nonNull(dyzUser)){
+            qnUserMapper.updateUser(newUser);
+            return;
+        }
+        dyzUser = nfUserMapper.selectPrimaryKey(userId);
+        if(Objects.nonNull(dyzUser)){
+            nfUserMapper.updateUser(newUser);
+            return;
+        }
+        dyzUser = qnmUserMapper.selectPrimaryKey(userId);
+        if(Objects.nonNull(dyzUser)){
+            qnmUserMapper.updateUser(newUser);
+        }
+    }
+}

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

@@ -75,8 +75,8 @@ public class AdServiceImpl implements AdService {
     private QNUserMapper qnUserMapper;
     @Resource
     private NFUserMapper nfUserMapper;
-    @Resource
-    private RiskFeign riskFeign;
+//    @Resource
+//    private RiskFeign riskFeign;
     @Value("${risk.config.banned.tips}")
     private String tips;
 
@@ -84,7 +84,7 @@ public class AdServiceImpl implements AdService {
      * 保存广告记录
      */
     @Override
-    @Transactional
+    @Transactional(rollbackFor = Exception.class)
     public Result<?> saveRecord(DyzAdRecordParam param) {
         YtDyzUser user = appUserMapper.selectPrimaryKey(param.getUserId());
         if(Objects.isNull(user)){
@@ -94,13 +94,13 @@ public class AdServiceImpl implements AdService {
             return new Result<>(StatusCode.ACCESS_ERR,getTipsMsg());
         }
         saveRecordAndChangeUser(param, user);
-        //调用风控广告校验
-        if(AdSourceTypeEnum.rewarded_video.getAdSourceType() == param.getAdSourceType()){
-            Result<?> result = riskFeign.checkAdRisk(user);
-            if(result.getCode()!=200){
-                throw new CustomerException(result.getMessage());
-            }
-        }
+//        //调用风控广告校验
+//        if(AdSourceTypeEnum.rewarded_video.getAdSourceType() == param.getAdSourceType()){
+//            Result<?> result = riskFeign.checkAdRisk(user);
+//            if(result.getCode()!=200){
+//                throw new CustomerException(result.getMessage());
+//            }
+//        }
         return Result.resultOk(RepMessage.SAVE_SUCCESS);
     }
 
@@ -308,10 +308,13 @@ public class AdServiceImpl implements AdService {
      * 保存记录
      *  始终创建新的事务以保障子方法的独立事务
      */
-    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
+//    @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());
+        }
         BeanUtils.copyProperties(param, adRecord);
         adRecord.setRecordId(IdUtil.fastSimpleUUID());
         adRecord.setNetworkName(AdPlatformTypeEnum.getDesc(Integer.parseInt(param.getNetworkFormId())));

+ 2 - 1
yt-app/app-service/src/main/java/com/ytpm/service/dyz/impl/AppUserServiceImpl.java

@@ -72,7 +72,7 @@ public class AppUserServiceImpl implements AppUserService {
      */
     private void setExtInfo(YtDyzUser old, String headimgurl) {
         old.setHeadImg(headimgurl);
-        old.setLastQuestionId(questionMapper.getLastQuestionId(old.getUserId()));
+            old.setLastQuestionId(questionMapper.getLastQuestionId(old.getUserId()));
         old.setTodayAnswerCount(questionMapper.getAnswerCount(old.getUserId(),1));
         old.setHistoryAnswerCount(questionMapper.getAnswerCount(old.getUserId(),2));
         old.setAnswerRecordList(questionMapper.getAnswerRecords(old.getUserId()));
@@ -92,6 +92,7 @@ public class AppUserServiceImpl implements AppUserService {
         loginRecord.setLoginIp(param.getLoginIp());
         loginRecord.setOperator(param.getIpOperator());
         loginRecord.setIpAddr(param.getIpLocation());
+        loginRecord.setPhoneJson(param.getPhoneJson());
         loginRecordMapper.insertOne(loginRecord);
     }
 

+ 3 - 0
yt-app/app-service/src/main/java/com/ytpm/service/nofeeds/impl/NfAdServiceImpl.java

@@ -114,6 +114,9 @@ public class NfAdServiceImpl implements NfAdService {
     public void saveRecordAndChangeUser(DyzAdRecordParam param,YtDyzUser user) {
         //增加广告记录
         YtDyzAdRecord adRecord = new YtDyzAdRecord();
+        if(Objects.isNull(param.getBeginTime())){
+            param.setBeginTime(param.getFinishTime());
+        }
         BeanUtils.copyProperties(param, adRecord);
         adRecord.setRecordId(IdUtil.fastSimpleUUID());
         adRecord.setNetworkName(AdPlatformTypeEnum.getDesc(Integer.parseInt(param.getNetworkFormId())));

+ 1 - 0
yt-app/app-service/src/main/java/com/ytpm/service/nofeeds/impl/NfUserServiceImpl.java

@@ -85,6 +85,7 @@ public class NfUserServiceImpl implements NfUserService {
         loginRecord.setLoginIp(param.getLoginIp());
         loginRecord.setOperator(param.getIpOperator());
         loginRecord.setIpAddr(param.getIpLocation());
+        loginRecord.setPhoneJson(param.getPhoneJson());
         nfloginRecordMapper.insertOne(loginRecord);
     }
 

+ 3 - 0
yt-app/app-service/src/main/java/com/ytpm/service/qnjz/impl/QnAdServiceImpl.java

@@ -114,6 +114,9 @@ public class QnAdServiceImpl implements QnAdService {
     public void saveRecordAndChangeUser(DyzAdRecordParam param,YtDyzUser user) {
         //增加广告记录
         YtDyzAdRecord adRecord = new YtDyzAdRecord();
+        if(Objects.isNull(param.getBeginTime())){
+            param.setBeginTime(param.getFinishTime());
+        }
         BeanUtils.copyProperties(param, adRecord);
         adRecord.setRecordId(IdUtil.fastSimpleUUID());
         adRecord.setNetworkName(AdPlatformTypeEnum.getDesc(Integer.parseInt(param.getNetworkFormId())));

+ 1 - 0
yt-app/app-service/src/main/java/com/ytpm/service/qnjz/impl/QnUserServiceImpl.java

@@ -85,6 +85,7 @@ public class QnUserServiceImpl implements QnUserService {
         loginRecord.setLoginIp(param.getLoginIp());
         loginRecord.setOperator(param.getIpOperator());
         loginRecord.setIpAddr(param.getIpLocation());
+        loginRecord.setPhoneJson(param.getPhoneJson());
         qnLoginRecordMapper.insertOne(loginRecord);
     }
 

+ 3 - 0
yt-app/app-service/src/main/java/com/ytpm/service/qnmjz/impl/QnmAdServiceImpl.java

@@ -114,6 +114,9 @@ public class QnmAdServiceImpl implements QnmAdService {
     public void saveRecordAndChangeUser(DyzAdRecordParam param,YtDyzUser user) {
         //增加广告记录
         YtDyzAdRecord adRecord = new YtDyzAdRecord();
+        if(Objects.isNull(param.getBeginTime())){
+            param.setBeginTime(param.getFinishTime());
+        }
         BeanUtils.copyProperties(param, adRecord);
         adRecord.setRecordId(IdUtil.fastSimpleUUID());
         adRecord.setNetworkName(AdPlatformTypeEnum.getDesc(Integer.parseInt(param.getNetworkFormId())));

+ 1 - 0
yt-app/app-service/src/main/java/com/ytpm/service/qnmjz/impl/QnmUserServiceImpl.java

@@ -89,6 +89,7 @@ public class QnmUserServiceImpl implements QnmUserService {
         loginRecord.setLoginIp(param.getLoginIp());
         loginRecord.setOperator(param.getIpOperator());
         loginRecord.setIpAddr(param.getIpLocation());
+        loginRecord.setPhoneJson(param.getPhoneJson());
         qnmLoginRecordMapper.insertOne(loginRecord);
     }
 

+ 3 - 0
yt-app/app-service/src/main/java/com/ytpm/service/xjlrl/impl/XjlrlAdServiceImpl.java

@@ -114,6 +114,9 @@ public class XjlrlAdServiceImpl implements XjlrlAdService {
     public void saveRecordAndChangeUser(DyzAdRecordParam param,YtDyzUser user) {
         //增加广告记录
         YtDyzAdRecord adRecord = new YtDyzAdRecord();
+        if(Objects.isNull(param.getBeginTime())){
+            param.setBeginTime(param.getFinishTime());
+        }
         BeanUtils.copyProperties(param, adRecord);
         adRecord.setRecordId(IdUtil.fastSimpleUUID());
         adRecord.setNetworkName(AdPlatformTypeEnum.getDesc(Integer.parseInt(param.getNetworkFormId())));

+ 1 - 0
yt-app/app-service/src/main/java/com/ytpm/service/xjlrl/impl/XjlrlUserServiceImpl.java

@@ -85,6 +85,7 @@ public class XjlrlUserServiceImpl implements XjlrlUserService {
         loginRecord.setLoginIp(param.getLoginIp());
         loginRecord.setOperator(param.getIpOperator());
         loginRecord.setIpAddr(param.getIpLocation());
+        loginRecord.setPhoneJson(param.getPhoneJson());
         xjlLoginRecordMapper.insertOne(loginRecord);
     }
 

+ 44 - 2
yt-app/app-service/src/main/resources/mapper/dyz/AppUserMapper.xml

@@ -358,8 +358,6 @@
             #{item}
         </foreach>
     </select>
-
-
     <select id="getDefaultConfig" resultType="com.ytpm.app.view.WxDefaultConfig">
         select
             config_id, config_name, open_id appId, secret, app_id platformAppId, app_key platformAppSecret, app_type,user_path,login_path,ad_path,answer_path,power_path
@@ -571,6 +569,50 @@
             #{item}
         </foreach>
     </select>
+    <resultMap id="UserAdMap" type="com.ytpm.agent.view.AgentAuditCheckVO">
+        <id column="user_id" property="userId" />
+        <result column="app_id" property="appId" />
+        <result column="nick_name" property="nickName" />
+        <collection property="adRecordList" ofType="com.ytpm.app.model.YtDyzAdRecord">
+            <result column="record_id" property="recordId" />
+            <result column="placement_id" property="placementId" />
+            <result column="ad_source_id" property="adSourceId" />
+            <result column="ad_source_type" property="adSourceType" />
+            <result column="ad_source_index" property="adSourceIndex" />
+            <result column="revenue" property="revenue" />
+            <result column="ecpm" property="ecpm" />
+            <result column="network_form_id" property="networkFormId" />
+            <result column="network_name" property="networkName" />
+            <result column="network_placement_id" property="networkPlacementId" />
+            <result column="finish_time" property="finishTime" />
+            <result column="begin_time" property="beginTime" />
+        </collection>
+    </resultMap>
+    <select id="queryTodayUserAd" resultMap="UserAdMap">
+        select
+            u.user_id,
+            u.app_id,
+            u.nick_name,
+            ar.record_id,
+            ar.placement_id,
+            ar.ad_source_id,
+            ar.ad_source_type,
+            ar.ad_source_index,
+            ar.revenue,
+            ar.ecpm,
+            ar.network_form_id,
+            ar.network_name,
+            ar.network_placement_id,
+            ar.finish_time,
+            ar.begin_time
+        from yt_dyz_ad_record ar
+        join yt_dyz_user u on ar.user_id = u.user_id
+        where ar.ad_source_type = #{adSourceType} and ar.app_id = #{appId} and ar.user_id in
+        <foreach collection="userIds.split(',')" separator="," item="item" open="(" close=")">
+            #{item}
+        </foreach>
+        and DATE_FORMAT(ar.finish_time, '%Y-%m-%d') = current_date()
+    </select>
     <update id="unlockUser">
         update yt_dyz_user
         set user_status = 1

+ 4 - 2
yt-app/app-service/src/main/resources/mapper/dyz/LoginRecordMapper.xml

@@ -12,7 +12,8 @@
          device_model,
          login_ip,
          operator,
-         ip_addr
+         ip_addr,
+         phone_json
         )
         values
         (
@@ -23,7 +24,8 @@
          #{deviceModel},
          #{loginIp},
          #{operator},
-         #{ipAddr}
+         #{ipAddr},
+         #{phoneJson}
          );
     </insert>
     <select id="getLoginRecords" resultType="com.ytpm.app.model.YtDyzLoginRecord">

+ 4 - 2
yt-app/app-service/src/main/resources/mapper/nofeeds/NFLoginRecordMapper.xml

@@ -12,7 +12,8 @@
          device_model,
          login_ip,
          operator,
-         ip_addr
+         ip_addr,
+         phone_json
         )
         values
         (
@@ -23,7 +24,8 @@
          #{deviceModel},
          #{loginIp},
          #{operator},
-         #{ipAddr}
+         #{ipAddr},
+         #{phoneJson}
          );
     </insert>
     <select id="getLoginRecords" resultType="com.ytpm.app.model.YtDyzLoginRecord">

+ 47 - 0
yt-app/app-service/src/main/resources/mapper/nofeeds/NFUserMapper.xml

@@ -159,6 +159,9 @@
         </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, registry_time, last_login_time, last_login_ip, login_days, total_video, total_income, red_packet_balance, red_packet_amount, points_balance, points_total, withdraw_total, sign_days, user_status, risk_reason, wx_open_id, platform_id
@@ -545,4 +548,48 @@
         </where>
         group by du.user_id
     </select>
+    <resultMap id="UserAdMap" type="com.ytpm.agent.view.AgentAuditCheckVO">
+        <id column="user_id" property="userId" />
+        <result column="app_id" property="appId" />
+        <result column="nick_name" property="nickName" />
+        <collection property="adRecordList" ofType="com.ytpm.app.model.YtDyzAdRecord">
+            <result column="record_id" property="recordId" />
+            <result column="placement_id" property="placementId" />
+            <result column="ad_source_id" property="adSourceId" />
+            <result column="ad_source_type" property="adSourceType" />
+            <result column="ad_source_index" property="adSourceIndex" />
+            <result column="revenue" property="revenue" />
+            <result column="ecpm" property="ecpm" />
+            <result column="network_form_id" property="networkFormId" />
+            <result column="network_name" property="networkName" />
+            <result column="network_placement_id" property="networkPlacementId" />
+            <result column="finish_time" property="finishTime" />
+            <result column="begin_time" property="beginTime" />
+        </collection>
+    </resultMap>
+    <select id="queryTodayUserAd" resultMap="UserAdMap">
+        select
+        u.user_id,
+        u.app_id,
+        u.nick_name,
+        ar.record_id,
+        ar.placement_id,
+        ar.ad_source_id,
+        ar.ad_source_type,
+        ar.ad_source_index,
+        ar.revenue,
+        ar.ecpm,
+        ar.network_form_id,
+        ar.network_name,
+        ar.network_placement_id,
+        ar.finish_time,
+        ar.begin_time
+        from yt_dyz_ad_record ar
+        join yt_dyz_user u on ar.user_id = u.user_id
+        where ar.ad_source_type = #{adSourceType} and ar.app_id = #{appId} and ar.user_id in
+        <foreach collection="userIds.split(',')" separator="," item="item" open="(" close=")">
+            #{item}
+        </foreach>
+        and DATE_FORMAT(ar.finish_time, '%Y-%m-%d') = current_date()
+    </select>
 </mapper>

+ 4 - 2
yt-app/app-service/src/main/resources/mapper/qnjz/QNLoginRecordMapper.xml

@@ -12,7 +12,8 @@
          device_model,
          login_ip,
          operator,
-         ip_addr
+         ip_addr,
+         phone_json
         )
         values
         (
@@ -23,7 +24,8 @@
          #{deviceModel},
          #{loginIp},
          #{operator},
-         #{ipAddr}
+         #{ipAddr},
+         #{phoneJson}
          );
     </insert>
     <select id="getLoginRecords" resultType="com.ytpm.app.model.YtDyzLoginRecord">

+ 47 - 1
yt-app/app-service/src/main/resources/mapper/qnjz/QNUserMapper.xml

@@ -159,6 +159,9 @@
         </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, registry_time, last_login_time, last_login_ip, login_days, total_video, total_income, red_packet_balance, red_packet_amount, points_balance, points_total, withdraw_total, sign_days, user_status, risk_reason, wx_open_id, platform_id
@@ -545,5 +548,48 @@
         </where>
         group by du.user_id
     </select>
-
+    <resultMap id="UserAdMap" type="com.ytpm.agent.view.AgentAuditCheckVO">
+        <id column="user_id" property="userId" />
+        <result column="app_id" property="appId" />
+        <result column="nick_name" property="nickName" />
+        <collection property="adRecordList" ofType="com.ytpm.app.model.YtDyzAdRecord">
+            <result column="record_id" property="recordId" />
+            <result column="placement_id" property="placementId" />
+            <result column="ad_source_id" property="adSourceId" />
+            <result column="ad_source_type" property="adSourceType" />
+            <result column="ad_source_index" property="adSourceIndex" />
+            <result column="revenue" property="revenue" />
+            <result column="ecpm" property="ecpm" />
+            <result column="network_form_id" property="networkFormId" />
+            <result column="network_name" property="networkName" />
+            <result column="network_placement_id" property="networkPlacementId" />
+            <result column="finish_time" property="finishTime" />
+            <result column="begin_time" property="beginTime" />
+        </collection>
+    </resultMap>
+    <select id="queryTodayUserAd" resultMap="UserAdMap">
+        select
+        u.user_id,
+        u.app_id,
+        u.nick_name,
+        ar.record_id,
+        ar.placement_id,
+        ar.ad_source_id,
+        ar.ad_source_type,
+        ar.ad_source_index,
+        ar.revenue,
+        ar.ecpm,
+        ar.network_form_id,
+        ar.network_name,
+        ar.network_placement_id,
+        ar.finish_time,
+        ar.begin_time
+        from yt_dyz_ad_record ar
+        join yt_dyz_user u on ar.user_id = u.user_id
+        where ar.ad_source_type = #{adSourceType} and ar.app_id = #{appId} and ar.user_id in
+        <foreach collection="userIds.split(',')" separator="," item="item" open="(" close=")">
+            #{item}
+        </foreach>
+        and DATE_FORMAT(ar.finish_time, '%Y-%m-%d') = current_date()
+    </select>
 </mapper>

+ 4 - 2
yt-app/app-service/src/main/resources/mapper/qnmjz/QnmLoginRecordMapper.xml

@@ -12,7 +12,8 @@
          device_model,
          login_ip,
          operator,
-         ip_addr
+         ip_addr,
+         phone_json
         )
         values
         (
@@ -23,7 +24,8 @@
          #{deviceModel},
          #{loginIp},
          #{operator},
-         #{ipAddr}
+         #{ipAddr},
+         #{phoneJson}
          );
     </insert>
     <select id="getLoginRecords" resultType="com.ytpm.app.model.YtDyzLoginRecord">

+ 47 - 0
yt-app/app-service/src/main/resources/mapper/qnmjz/QnmUserMapper.xml

@@ -159,6 +159,9 @@
         </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, registry_time, last_login_time, last_login_ip, login_days, total_video, total_income, red_packet_balance, red_packet_amount, points_balance, points_total, withdraw_total, sign_days, user_status, risk_reason, wx_open_id, platform_id
@@ -518,4 +521,48 @@
         </where>
         group by du.user_id
     </select>
+    <resultMap id="UserAdMap" type="com.ytpm.agent.view.AgentAuditCheckVO">
+        <id column="user_id" property="userId" />
+        <result column="app_id" property="appId" />
+        <result column="nick_name" property="nickName" />
+        <collection property="adRecordList" ofType="com.ytpm.app.model.YtDyzAdRecord">
+            <result column="record_id" property="recordId" />
+            <result column="placement_id" property="placementId" />
+            <result column="ad_source_id" property="adSourceId" />
+            <result column="ad_source_type" property="adSourceType" />
+            <result column="ad_source_index" property="adSourceIndex" />
+            <result column="revenue" property="revenue" />
+            <result column="ecpm" property="ecpm" />
+            <result column="network_form_id" property="networkFormId" />
+            <result column="network_name" property="networkName" />
+            <result column="network_placement_id" property="networkPlacementId" />
+            <result column="finish_time" property="finishTime" />
+            <result column="begin_time" property="beginTime" />
+        </collection>
+    </resultMap>
+    <select id="queryTodayUserAd" resultMap="UserAdMap">
+        select
+        u.user_id,
+        u.app_id,
+        u.nick_name,
+        ar.record_id,
+        ar.placement_id,
+        ar.ad_source_id,
+        ar.ad_source_type,
+        ar.ad_source_index,
+        ar.revenue,
+        ar.ecpm,
+        ar.network_form_id,
+        ar.network_name,
+        ar.network_placement_id,
+        ar.finish_time,
+        ar.begin_time
+        from yt_dyz_ad_record ar
+        join yt_dyz_user u on ar.user_id = u.user_id
+        where ar.ad_source_type = #{adSourceType} and ar.app_id = #{appId} and ar.user_id in
+        <foreach collection="userIds.split(',')" separator="," item="item" open="(" close=")">
+            #{item}
+        </foreach>
+        and DATE_FORMAT(ar.finish_time, '%Y-%m-%d') = current_date()
+    </select>
 </mapper>

+ 4 - 2
yt-app/app-service/src/main/resources/mapper/xjlrl/XjlrlLoginRecordMapper.xml

@@ -12,7 +12,8 @@
          device_model,
          login_ip,
          operator,
-         ip_addr
+         ip_addr,
+         phone_json
         )
         values
         (
@@ -23,7 +24,8 @@
          #{deviceModel},
          #{loginIp},
          #{operator},
-         #{ipAddr}
+         #{ipAddr},
+         #{phoneJson}
          );
     </insert>
     <select id="getLoginRecords" resultType="com.ytpm.app.model.YtDyzLoginRecord">

+ 25 - 0
yt-common/src/main/java/com/ytpm/agent/param/AuditCheckParam.java

@@ -0,0 +1,25 @@
+package com.ytpm.agent.param;
+
+import com.ytpm.risk.view.RiskTemplateView;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author Marx
+ * @date 2025/8/14 10:02
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ApiModel("审核校验参数")
+public class AuditCheckParam {
+    @ApiModelProperty("ecpm 风控配置")
+    private RiskTemplateView ecpmLimit;
+    @ApiModelProperty("收益 风控配置")
+    private RiskTemplateView revenueLimit;
+    @ApiModelProperty("审核入参")
+    private AuditUserParam auditParam;
+}

+ 32 - 0
yt-common/src/main/java/com/ytpm/agent/param/AuditUserParam.java

@@ -0,0 +1,32 @@
+package com.ytpm.agent.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author Marx
+ * @date 2025/8/14 9:23
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@ApiModel("审核用户入参")
+public class AuditUserParam {
+    @ApiModelProperty(value = "用户ID",required = true)
+    private String userIds;
+    @ApiModelProperty(value = "应用ID", required = true)
+    private String appId;
+    @ApiModelProperty(value = "渠道ID",required = true)
+    private String ditchId;
+    @ApiModelProperty(value = "审核备注",required = true)
+    private String remark;
+    @ApiModelProperty(value = "广告类型",hidden = true)
+    private Integer adSourceType;
+    @ApiModelProperty(value = "封禁时间(天)",required = true)
+    private Integer bannedLimit;
+    @ApiModelProperty(value = "生效时间(小时)",required = true)
+    private Integer effectTime;
+}

+ 29 - 0
yt-common/src/main/java/com/ytpm/agent/view/AgentAuditCheckVO.java

@@ -0,0 +1,29 @@
+package com.ytpm.agent.view;
+
+import com.ytpm.app.model.YtDyzAdRecord;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * @author Marx
+ * @date 2025/8/14 10:15
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ApiModel("代理商审核校验")
+public class AgentAuditCheckVO {
+    @ApiModelProperty("用户ID")
+    private String userId;
+    @ApiModelProperty("应用ID")
+    private String appId;
+    @ApiModelProperty("昵称")
+    private String nickName;
+    @ApiModelProperty("广告记录")
+    private List<YtDyzAdRecord> adRecordList;
+}

+ 2 - 0
yt-common/src/main/java/com/ytpm/app/model/YtDyzLoginRecord.java

@@ -41,4 +41,6 @@ public class YtDyzLoginRecord {
     @CustomField(node = 1)
     @ApiModelProperty("IP归属地")
     private String ipAddr;
+    @ApiModelProperty("手机信息json")
+    private String phoneJson;
 }

+ 2 - 0
yt-common/src/main/java/com/ytpm/app/param/WxLoginParam.java

@@ -31,4 +31,6 @@ public class WxLoginParam {
     private String appId;
     @ApiModelProperty(value = "设备ID",required = false)
     private String deviceId;
+    @ApiModelProperty(value = "手机信息json")
+    private String phoneJson;
 }

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

@@ -87,4 +87,7 @@ public interface RiskFeign {
 
     @PostMapping ("/riskManage/queryBannedByHourToday")
     Result<Map<String, int[]>> queryBannedByHourToday(@RequestBody AppQueryUserTodayTimeParam appQueryUserTodayTimeParam);
+
+    @PostMapping("/public/batchAudit")
+    void batchAudit(@RequestParam(value = "userList") List<YtDyzUser> userList);
 }

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

@@ -13,6 +13,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.util.List;
+
 @RestController
 @RequestMapping("/public")
 public class PublicApiController {
@@ -56,4 +58,12 @@ public class PublicApiController {
        return riskService.checkAdRisk(dyzUser);
     }
 
+    /**
+     * 批量审核用户
+     */
+    @ApiOperation("批量审核用户")
+    @PostMapping("/batchAudit")
+    public void batchAudit(@RequestParam("userList") List<YtDyzUser> userList){
+        riskService.batchAudit(userList);
+    }
 }

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

@@ -104,4 +104,9 @@ public interface RiskService {
     List<YtPlatformBanned> queryBannedRecord(Date startTime,Date endTime,List<String> appIdList);
 
     List<YtPlatformBanned> queryBannedRecordGroupByUserId(Date startTime,Date endTime,List<String> appIdList);
+
+    /**
+     * 批量审核用户
+     */
+    void batchAudit(List<YtDyzUser> userList);
 }

+ 12 - 0
yt-risk/risk-manage/src/main/java/com/ytpm/service/impl/RiskServiceImpl.java

@@ -836,8 +836,20 @@ public class RiskServiceImpl extends ReflectUtil implements RiskService {
         return riskManageMapper.queryBannedRecord(startTime, endTime,appIdList);
     }
 
+    /**
+     * 分组查询风控
+     */
     @Override
     public List<YtPlatformBanned> queryBannedRecordGroupByUserId(Date startTime, Date endTime,List<String> appIdList) {
         return riskManageMapper.queryBannedRecordGroupByUserId(startTime, endTime,appIdList);
     }
+
+    /**
+     * 批量审核用户
+     */
+    @Override
+    public void batchAudit(List<YtDyzUser> userList) {
+        //查询这些用户当天的激励视频收益是否符合
+
+    }
 }