| 
					
				 | 
			
			
				@@ -1,20 +1,35 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 package com.tzld.piaoquan.risk.control.service.impl; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.alibaba.fastjson.JSON; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.tzld.piaoquan.risk.control.config.QywxConfig; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.tzld.piaoquan.risk.control.model.qywx.RoomListResponse; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.tzld.piaoquan.risk.control.model.qywx.UserListFromAdPlatformModel; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.tzld.piaoquan.risk.control.util.HttpClientUtil; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.tzld.piaoquan.risk.control.util.HttpPoolClient; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import lombok.extern.slf4j.Slf4j; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import org.springframework.beans.factory.annotation.Autowired; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.springframework.beans.factory.annotation.Value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import org.springframework.stereotype.Service; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import java.util.ArrayList; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import java.util.HashMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import java.util.List; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import java.util.Map; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.*; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 @Slf4j 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 @Service 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 public class RiskRuleConfigService { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     @Autowired 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     private WorkWechatServiceImpl workWechatServiceImpl; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static final int USER_COUNT_THRESHOLD = 1; //生效人数阈值 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static final int USER_COUNT_THRESHOLD_FOR_ANOMALY_USER_RATIO = 30; //大于30人才触发是否关闭判断 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static final float ANOMALY_USER_RATIO = 0.2f; //异常用户比例20% 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Autowired 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private QywxConfig config; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Value("${qywx.corpid}") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private long corpid; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static final HttpPoolClient httpPoolClientDefault = HttpClientUtil.create(10000, 10000, 2000, 5000, 5, 10000); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Value("${getUserList.url:https://api.piaoquantv.com/ad/platform/wechat/group/groupUserDetailData}") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private String getUserList; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     Map<String, List<RoomListResponse.RoomInfo>> getKickOpenedRoom(Map<String, List<RoomListResponse.RoomInfo>> tobeOperate) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Map<String, List<RoomListResponse.RoomInfo>> filteredMap = new HashMap<>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -35,4 +50,87 @@ public class RiskRuleConfigService { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return filteredMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    //防止误踢,只有满足存在五个正常群人数才会生效 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public FixedRuleResult getFixedRulesForThisChat(String chatId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        FixedRuleResult ruleResult = new FixedRuleResult(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        List<UserListFromAdPlatformModel.ChatMember> memberList = getUserListFromAdPlatform(chatId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (memberList == null || memberList.isEmpty()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            log.error("checkIfOpenedForFixedRules, memberList is empty for chatId: {}", chatId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return ruleResult; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            int size = memberList.size();//群总数,包括异常和正常 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //memberList中isAbnormal是0代表正常用户 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            int normalSize = (int) memberList.stream() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    .filter(member -> member.getIsAbnormal() == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    .count(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ruleResult.normalCount = normalSize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ruleResult.abnormalCount = size - normalSize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if(normalSize >= USER_COUNT_THRESHOLD) {//大于等于3才生效 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                log.info("checkIfOpenedForFixedRules, chatId: {}, size: {}, normalSize: {}", chatId, size, normalSize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                //如果群成员大于30人,才判断异常用户比例 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ruleResult.isNormalCountEnough = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (size >= USER_COUNT_THRESHOLD_FOR_ANOMALY_USER_RATIO) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    //计算异常用户比例 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    float anomalyUserRatio = (float) (size - normalSize) / size; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    log.info("checkIfOpenedForFixedRules, chatId: {}, anomalyUserRatio: {}", chatId, anomalyUserRatio); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (anomalyUserRatio >= ANOMALY_USER_RATIO) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        log.info("checkIfOpenedForFixedRules, chatId: {}, anomalyUserRatio is high enough, opening rules", chatId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                        return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        ruleResult.isAbnormalRatioHighEnough = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        log.info("checkIfOpenedForFixedRules, chatId: {}, anomalyUserRatio is not high enough, not opening rules", chatId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return ruleResult; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                log.info("checkIfOpenedForFixedRules, chatId: {}, size: {}, normalSize: {}, not enough normal users", chatId, size, normalSize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return ruleResult; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private List<UserListFromAdPlatformModel.ChatMember> getUserListFromAdPlatform(String chatId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String url = String.format("%s?chatId=%s", getUserList, chatId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        List<UserListFromAdPlatformModel.ChatMember> result = Collections.emptyList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        log.info("getUserListFromAdPlatform, url: {}", url); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Optional<String> response = httpPoolClientDefault.get(url); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!response.isPresent()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            log.error("getUserListFromAdPlatform, response is empty for chatId: {}", chatId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            log.info("getUserListFromAdPlatform, response: {}", response.get()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            UserListFromAdPlatformModel model =  JSON.parseObject(response.get(), UserListFromAdPlatformModel.class); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (model != null && model.getData() != null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                result = model.getData(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                log.error("getUserListFromAdPlatform, model is null or data is empty for chatId: {}", chatId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return new ArrayList<>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return result; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public static class FixedRuleResult { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        boolean isNormalCountEnough = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int normalCount = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        boolean isAbnormalRatioHighEnough = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        float abnormalUserRatio = 0.0f; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int abnormalCount = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        @Override 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        public String toString() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return "FixedRuleResult{" + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    "isNormalCountEnough=" + isNormalCountEnough + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ", normalCount=" + normalCount + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ", isAbnormalRatioHighEnough=" + isAbnormalRatioHighEnough + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ", abnormalUserRatio=" + abnormalUserRatio + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ", abnormalCount=" + abnormalCount + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    '}'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |