| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- <?php
- namespace App\Jobs;
- use App\Model\Mongo\UserLoginLogModel;
- use App\Repositories\Utils\TelegramRepository;
- use Carbon\Carbon;
- use Hyperf\AsyncQueue\Job;
- use Psr\SimpleCache\CacheInterface;
- use Zhuzhichao\IpLocationZh\Ip;
- class MongoUserLoginJob extends Job
- {
- protected $params = [];
- public function __construct($params = [])
- {
- $this->params = $params;
- }
- public function handle()
- {
- $isEnableTelegram = true;
- $this->insertLog();
- if ($isEnableTelegram) {
- $cacheKey = $this->getCacheKey($this->params['device_no']);
- $cacheData = make(CacheInterface::class)->get($cacheKey);
- $diffHours = 99999999;
- if (!empty($cacheData['time'])) {
- $diffHours = abs(Carbon::parse($cacheData['time'])->diffInHours(Carbon::now()));
- }
- if ($diffHours > 24) {
- $this->reportSameDeviceNo();
- }
- }
- }
- private function insertLog()
- {
- $arrIpAddr = Ip::find($this->params['ip']);
- array_pop($arrIpAddr); //剔除最后一个下标, 国标
- $arrIpAddr = array_filter($arrIpAddr);
- $ipAddr = !empty($arrIpAddr) ? implode('|', $arrIpAddr) : '';
- $nowDate = toMongoIsoDate(Carbon::now());
- $setarr = [
- 'user_uid' => $this->params['user_id'],
- 'login_at' => $nowDate,
- 'version' => $this->params['version'],
- 'device_type' => $this->params['device_type'],
- 'device_no' => $this->params['device_no'],
- 'finger_hash' => $this->params['finger_hash'],
- 'ip' => $this->params['ip'],
- 'ip_addr' => $ipAddr,
- ];
- make(UserLoginLogModel::class)->db()->insertOne($setarr);
- }
- private function reportSameDeviceNo()
- {
- $arrDiff = [];
- // $tmpIp = '180.142.72.108';
- $tmpIp = $this->params['ip'];
- $pipeline = [
- [
- '$match' => [
- 'device_no' => $this->params['device_no'],
- 'ip' => [
- '$ne' => $tmpIp,
- ],
- ],
- ],
- [
- '$group' => [
- '_id' => '$ip',
- 'ip_addr' => [
- '$first' => '$ip_addr',
- ],
- 'mid' => [
- '$first' => '$_id',
- ],
- 'user_uid' => [
- '$first' => '$user_uid',
- ],
- 'list_login_at' => [
- '$push' => '$login_at',
- ],
- 'last_login_at' => [
- '$first' => '$login_at',
- ],
- 'device_type' => [
- '$first' => '$device_type',
- ],
- 'version' => [
- '$first' => '$version',
- ],
- ],
- ],
- [
- '$sort' => [
- 'last_login_at' => -1
- ],
- ],
- [
- '$limit' => 6,
- ],
- ];
- $options = [];
- /**
- * @var \MongoDB\Driver\Cursor $cursor
- */
- $cursor = make(UserLoginLogModel::class)->db()->aggregate($pipeline, $options);
- if (!$cursor->isDead()) {
- $tempArrIpAddr = Ip::find($this->params['ip']);
- array_pop($tempArrIpAddr); //剔除最后一个下标, 国标
- $tempArrIpAddr = array_filter($tempArrIpAddr); // 入库的这个IP和以前的对比
- $i = 0;
- foreach ($cursor as $itemObj) {
- $id = $itemObj->mid->__toString();
- $isDiff = false;
- $ipAddr = $itemObj->ip_addr;
- $arrIpAddr = !empty($ipAddr) ? explode('|', $ipAddr) : [];
- /**
- * @var \ArrayObject $listLoginAt
- */
- $listLoginAt = $itemObj->list_login_at;
- $listLoginAt->count();
- $lastLoginAt = $itemObj->last_login_at;
- $ip = $itemObj->_id;
- $userUid = $itemObj->user_uid;
- $version = $itemObj->version;
- $deviceType = $itemObj->device_type;
- $tmpData = [
- 'user_uid' => $userUid,
- 'device_no' => $this->params['device_no'],
- 'device_type' => $deviceType,
- 'version' => $version,
- 'login_at' => null,
- 'ip' => $ip,
- 'ip_addr' => $ipAddr,
- ];
- if (!empty($tempArrIpAddr) && !empty($arrIpAddr) && count($tempArrIpAddr) >= 2 && count($arrIpAddr) >= 2) {
- if ($tempArrIpAddr[0] != $arrIpAddr[0]) {
- $isDiff = true;
- $tmpData['login_at'] = $lastLoginAt;
- } elseif ($tempArrIpAddr[1] != $arrIpAddr[1]) {
- $isDiff = true;
- $tmpData['login_at'] = $lastLoginAt;
- }
- }
- if ($isDiff) {
- $arrDiff[] = $tmpData;
- }
- $i++;
- }
- }
- if (!empty($arrDiff)) {
- $nowDate = Carbon::now()->toDateTimeString();
- $arrIpAddr = Ip::find($this->params['ip']);
- array_pop($arrIpAddr); //剔除最后一个下标, 国标
- $arrIpAddr = array_filter($arrIpAddr);
- $nowIpAddr = !empty($arrIpAddr) ? implode('|', $arrIpAddr) : '';
- $arrCurrentLogin = [
- 'user_uid' => $this->params['user_id'],
- 'device_no' => $this->params['device_no'],
- 'device_type' => $this->params['device_type'],
- 'version' => $this->params['version'],
- 'login_at' => toMongoIsoDate($nowDate),
- 'ip' => $this->params['ip'],
- 'ip_addr' => $nowIpAddr,
- ];
- $cacheKey = $this->getCacheKey($this->params['device_no']);
- make(CacheInterface::class)->set($cacheKey, ['time' => $nowDate], 24 * 60 * 60);
- $appFlag = env('APP_NAME', '');
- $msgContent = <<<EOT
- 【事件】疑似同设备号不同人登陆(根据ip地区)
- 【项目标识】{$appFlag}
- 【报告时间】{$nowDate}
- 【清单如下】
- ------------------
- EOT;
- $msgContent .= $this->formatCurrentLoginMsg($arrCurrentLogin). "\n";
- foreach ($arrDiff as $k => $v) {
- $liNo = $k + 1;
- $msgContent .= $this->formatAddonMsg($liNo, $v);
- }
- $msgContent = "\r\n" .rtrim($msgContent) . "\n";
- $msgContent .= "\n---------------\n";
- make(TelegramRepository::class)->sendCommonText($msgContent);
- }
- }
- private function formatAddonMsg($liNo, $v)
- {
- $loginDate = !empty($v['login_at']) ? mongoIsoDateToCarbonTime($v['login_at']) : '未知';
- $ipInfo = $v['ip_addr'] . '('. $v['ip'] .')';
- $deviceTypeName = '未知';
- if ($v['device_type'] == 'I') {
- $deviceTypeName = 'iOS';
- } elseif ($v['device_type'] == 'A') {
- $deviceTypeName = 'Android';
- } elseif ($v['device_type'] == 'H') {
- $deviceTypeName = 'WebH5';
- }
- $userUid = $v['user_uid'];
- $deviceNo = $v['device_no'];
- $version = $v['version'];
- $strTpl = <<<EOT2
-
- 序号: %s
- 用户UID: %s
- 设备号: %s
- 设备类型: %s
- 版本: %s
- 登陆时间 :%s
- 登陆IP: %s
-
- EOT2;
- $msg = sprintf($strTpl, $liNo, $userUid, $deviceNo, $deviceTypeName, $version, $loginDate, $ipInfo);
- return $msg;
- }
- private function formatCurrentLoginMsg($v)
- {
- $loginDate = !empty($v['login_at']) ? mongoIsoDateToCarbonTime($v['login_at']) : '未知';
- $ipInfo = $v['ip_addr'] . '('. $v['ip'] .')';
- $deviceTypeName = '未知';
- if ($v['device_type'] == 'I') {
- $deviceTypeName = 'iOS';
- } elseif ($v['device_type'] == 'A') {
- $deviceTypeName = 'Android';
- } elseif ($v['device_type'] == 'H') {
- $deviceTypeName = 'WebH5';
- }
- $userUid = $v['user_uid'];
- $deviceNo = $v['device_no'];
- $version = $v['version'];
- $strTpl = <<<EOT2
- 本次登陆用户UID: %s
- 本次登陆设备号: %s
- 本次登陆设备类型: %s
- 本次登陆APP版本: %s
- 本次登陆登陆时间 :%s
- 本次登陆登陆IP: %s
-
- EOT2;
- $msg = sprintf($strTpl, $userUid, $deviceNo, $deviceTypeName, $version, $loginDate, $ipInfo);
- return $msg;
- }
- private function getCacheKey($deviceNo)
- {
- $key = 'user:device_same_notify:'. $deviceNo;
- return $key;
- }
- }
|