| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- <?php
- namespace app\common\service;
- use think\Db;
- use think\Cache;
- class RuleCheckService
- {
- // 缓存前缀
- const CACHE_PREFIX = 'risk_control:rule:';
- // 缓存时间(秒)
- const CACHE_TIME = 3600;
-
- /**
- * 检查频率规则
- * @param array $detail 规则详情
- * @param array $eventData 事件数据
- * @return bool
- */
- public function checkFrequencyRule(array $detail, array $eventData)
- {
- $cacheKey = self::CACHE_PREFIX . 'frequency:' . $detail['rule_id'] . ':' . $eventData[$detail['object_type']];
-
- // 获取时间窗口内的记录数
- $count = $this->getFrequencyCount($detail, $eventData, $cacheKey);
-
- // 根据逻辑类型判断
- switch ($detail['logic_type']) {
- case 'gt': // 大于
- return $count > $detail['logic_value'];
- case 'gte': // 大于等于
- return $count >= $detail['logic_value'];
- case 'lt': // 小于
- return $count < $detail['logic_value'];
- case 'lte': // 小于等于
- return $count <= $detail['logic_value'];
- case 'eq': // 等于
- return $count == $detail['logic_value'];
- default:
- return false;
- }
- }
-
- /**
- * 获取频率计数
- * @param array $detail
- * @param array $eventData
- * @param string $cacheKey
- * @return int
- */
- private function getFrequencyCount(array $detail, array $eventData, string $cacheKey)
- {
- // 先查缓存
- $count = Cache::get($cacheKey);
- if ($count !== false) {
- return $count;
- }
-
- // 计算时间窗口
- $endTime = $eventData['timestamp'];
- $startTime = $endTime - $detail['time_window'];
-
- // 查询数据库
- $count = Db::name('fk_exception_records')
- ->where([
- 'rule_id' => $detail['rule_id'],
- 'object_type' => $detail['object_type'],
- 'object_value' => $eventData[$detail['object_type']]
- ])
- ->where('create_time', 'between', [$startTime, $endTime])
- ->count();
-
- // 设置缓存
- Cache::set($cacheKey, $count, min($detail['time_window'], self::CACHE_TIME));
-
- return $count;
- }
-
- /**
- * 检查统计规则
- * @param array $detail
- * @param array $eventData
- * @return bool
- */
- public function checkStatisticsRule(array $detail, array $eventData)
- {
- $cacheKey = self::CACHE_PREFIX . 'statistics:' . $detail['rule_id'] . ':' . $eventData[$detail['object_type']];
-
- // 获取统计数据
- $statistics = $this->getStatisticsData($detail, $eventData, $cacheKey);
-
- // 根据逻辑类型判断
- switch ($detail['logic_type']) {
- case 'gt': // 大于
- return $statistics > $detail['logic_value'];
- case 'gte': // 大于等于
- return $statistics >= $detail['logic_value'];
- case 'lt': // 小于
- return $statistics < $detail['logic_value'];
- case 'lte': // 小于等于
- return $statistics <= $detail['logic_value'];
- case 'eq': // 等于
- return $statistics == $detail['logic_value'];
- default:
- return false;
- }
- }
-
- /**
- * 获取统计数据
- * @param array $detail
- * @param array $eventData
- * @param string $cacheKey
- * @return float
- */
- private function getStatisticsData(array $detail, array $eventData, string $cacheKey)
- {
- // 先查缓存
- $data = Cache::get($cacheKey);
- if ($data !== false) {
- return $data;
- }
-
- // 计算时间窗口
- $endTime = $eventData['timestamp'];
- $startTime = $endTime - $detail['time_window'];
-
- // 查询数据库
- $query = Db::name('fk_exception_records')
- ->where([
- 'rule_id' => $detail['rule_id'],
- 'object_type' => $detail['object_type'],
- 'object_value' => $eventData[$detail['object_type']]
- ])
- ->where('create_time', 'between', [$startTime, $endTime]);
-
- // 根据统计类型计算
- switch ($detail['statistics_type']) {
- case 'avg': // 平均值
- $data = $query->avg('exception_level');
- break;
- case 'sum': // 总和
- $data = $query->sum('exception_level');
- break;
- case 'max': // 最大值
- $data = $query->max('exception_level');
- break;
- case 'min': // 最小值
- $data = $query->min('exception_level');
- break;
- default:
- $data = 0;
- }
-
- // 设置缓存
- Cache::set($cacheKey, $data, min($detail['time_window'], self::CACHE_TIME));
-
- return $data;
- }
- }
|