FkStrategiesService.php 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. <?php
  2. namespace app\common\service;
  3. // 风控策略管理
  4. use app\common\model\FkRosterLists;
  5. use think\Cache;
  6. use think\Db;
  7. use think\Exception;
  8. use think\Log;
  9. class FkStrategiesService
  10. {
  11. const CACHE_PREFIX = 'fk_strategies:';
  12. private $fkStrategiesDetailsService;
  13. private $redis;
  14. /**
  15. * 构造函数
  16. */
  17. public function __construct()
  18. {
  19. $this->fkStrategiesDetailsService = new FkStrategiesDetailsService();
  20. $this->redis = Cache::store('default')->handler();
  21. $this->redis->select(1);
  22. }
  23. /**
  24. * 类方法返回
  25. *
  26. * @param bool $status
  27. * @param string $msg
  28. *
  29. * @return array
  30. */
  31. public function result(bool $status=true, string $msg='success'){
  32. return ['status' => $status, 'msg' => $msg];
  33. }
  34. /**
  35. * 实时任务处理
  36. *
  37. * @param array $eventData // 需要验证的数据
  38. * @param string $execution_type 执行类型:realtime/scheduled
  39. * @param string $strategy_code 策略编码
  40. *
  41. * @return array
  42. */
  43. public function processEvent(array $eventData){
  44. try {
  45. // 1. 数据验证
  46. // $this->validateEventData($eventData, $eventData['event_type'] ?? 'login');
  47. // 2. 检查黑白名单
  48. $rosterResult = $this->checkInspectRosterList($eventData);
  49. if ($rosterResult == 3) {
  50. return $this->result(true, '当前账户黑名单');
  51. } else if ($rosterResult == 2) {
  52. return $this->result(false, '当前账户白名单');
  53. }
  54. return $this->result(false, '当前账户无异常');
  55. } catch (Exception $e) {
  56. // 记录错误日志
  57. Log::error('风控处理异常@error:' . $e->getMessage().' - '.$e->getFile().':'.$e->getLine());
  58. Log::error('风控处理异常@getTraceAsString:' . $e->getTraceAsString());
  59. return $this->result(false, '风控系统异常:'. $e->getMessage());
  60. }
  61. }
  62. /**
  63. * 验证事件数据
  64. *
  65. * @param array $eventData
  66. * @param string $type 类型:login|register
  67. *
  68. * @return void
  69. * @throws Exception
  70. */
  71. private function validateEventData(array $eventData, string $type = 'login')
  72. {
  73. if($type == 'login'){
  74. $requiredFields = ['user_name', 'ip', 'imei', 'phone'];
  75. }else{
  76. $requiredFields = ['user_name', 'ip', 'imei', 'phone', 'duration', 'id_card'];
  77. }
  78. foreach ($requiredFields as $field) {
  79. if (!isset($eventData[$field]) || empty($eventData[$field])) {
  80. return "缺少必要字段:{$field}";
  81. // throw new Exception("缺少必要字段:{$field}");
  82. }
  83. }
  84. }
  85. /**
  86. * 检查黑名单状态
  87. *
  88. * @param array $eventData
  89. *
  90. * @return array 是否在黑名单中: true=在黑名单中,false=不在黑名单中
  91. */
  92. public function handleBlackList(array $eventData)
  93. {
  94. // ## 检查IP
  95. if(isset($eventData['ip'])){
  96. if($this->checkInList($eventData['ip'], 'ip', 'black')){
  97. return $this->result(true, '当前IP在黑名单中');
  98. }
  99. }
  100. // ## 检查IMEI
  101. if(isset($eventData['imei'])){
  102. if($this->checkInList($eventData['imei'], 'imei', 'black')){
  103. return $this->result(true, "当前IMEI在黑名单中");
  104. }
  105. }
  106. // ## 检查用户名
  107. if(isset($eventData['user_name'])){
  108. if($this->checkInList($eventData['user_name'], 'user_name', 'black')){
  109. return $this->result(true, "当前用户名在黑名单中");
  110. }
  111. }
  112. // ## 手机号
  113. if(isset($eventData['phone'])){
  114. if($this->checkInList($eventData['phone'], 'phone', 'black')){
  115. return $this->result(true, "当前手机号在黑名单中");
  116. }
  117. }
  118. // ## 身份证号
  119. if(isset($eventData['id_card'])){
  120. if($this->checkInList($eventData['id_card'], 'id_card', 'black')){
  121. return $this->result(true, "当前身份证号在黑名单中");
  122. }
  123. }
  124. return $this->result(false);
  125. }
  126. /**
  127. * 检查名单状态
  128. * @param array $eventData
  129. * @return string 状态:1=待处理、2=正常、3=拒绝
  130. */
  131. private function checkInspectRosterList(array $eventData)
  132. {
  133. // ## 检查IP
  134. if(isset($eventData['ip'])){
  135. if ($this->checkInList($eventData['ip'], 'ip', 'black')) {
  136. return 3;
  137. }
  138. if ($this->checkInList($eventData['ip'], 'ip', 'white')) {
  139. return 2;
  140. }
  141. }
  142. // ## 检查IMEI
  143. if(isset($eventData['imei'])){
  144. if ($this->checkInList($eventData['imei'], 'imei', 'black')) {
  145. return 3;
  146. }
  147. if ($this->checkInList($eventData['imei'], 'imei', 'white')) {
  148. return 2;
  149. }
  150. }
  151. // ## 检查用户名
  152. if(isset($eventData['username'])){
  153. if ($this->checkInList($eventData['username'], 'username', 'black')) {
  154. return 3;
  155. }
  156. if ($this->checkInList($eventData['username'], 'username', 'white')) {
  157. return 2;
  158. }
  159. }
  160. // ## 手机号
  161. if(isset($eventData['mobile'])){
  162. if ($this->checkInList($eventData['mobile'], 'mobile', 'black')) {
  163. return 3;
  164. }
  165. if ($this->checkInList($eventData['mobile'], 'mobile', 'white')) {
  166. return 2;
  167. }
  168. }
  169. // ## 身份证号
  170. if(isset($eventData['id_card'])){
  171. if ($this->checkInList($eventData['id_card'], 'id_card', 'black')) {
  172. return 3;
  173. }
  174. if ($this->checkInList($eventData['id_card'], 'id_card', 'white')) {
  175. return 2;
  176. }
  177. }
  178. return 1;
  179. }
  180. // 添加名单
  181. public function addRoster($value, $type, $listType){
  182. $cacheKey = self::CACHE_PREFIX . 'inspect_list:';
  183. $key = $cacheKey . $listType . ':' . $type . ':' . $value;
  184. $this->redis->set($key, 1, 604800); // 缓存一周
  185. }
  186. // 删除名单
  187. public function delRoster($value, $type, $listType){
  188. $cacheKey = self::CACHE_PREFIX . 'inspect_list:';
  189. $key = $cacheKey . $listType . ':' . $type . ':' . $value;
  190. $this->redis->del($key);
  191. }
  192. /**
  193. * 检查是否在名单中
  194. * @param string $value 对象值
  195. * @param string $type 对象类型
  196. * @param string $listType 名单类型:black/white
  197. * @param string $cacheKey
  198. * @return bool
  199. */
  200. private function checkInList($value, $type, $listType)
  201. {
  202. if((new FkRosterLists())->getCacheInfo(['object_value' => $value, 'object_type' => $type, 'list_type' => $listType])){
  203. return true;
  204. }
  205. return false;
  206. }
  207. }