'test'] * @var array */ protected $vague = []; /** * 精准查询,精确字段,格式['language_id'=> 1] * @var array */ protected $focus = []; /** * 排序字段。格式 ['sort'=>'desc'] * @var array */ protected $sort = []; /** * 模型 * @var array */ protected $model = null; /** * 语言ID * @var int|mixed */ protected $languageId = 1; /** * 导航栏模型 * @var null */ protected $navModel = null; /** * 系统配置模型 * @var null */ protected $systemConfigModel = null; /** * 接口监控数据 * @var string[] */ protected $apiLog = [ 'items' => '', /*项目名称*/ 'forum' => '', /*模块*/ 'forum_code' => '', /*模块日志编码*/ 'url' => '', /*访问页*/ 'refer' => '', /*访问来源*/ 'click' => '', /*点击次数*/ 'content' => '', /*访问内容*/ 'ip' => '', /*访客IP*/ 'country' => '', /*国家*/ 'province' => '', /*省*/ 'city' => '', /*市*/ 'start_time' => '', /*点击时间*/ 'drive' => '', /*PC OR 移动端*/ 'system' => '', /*设备系统*/ 'brower' => '', /*浏览器*/ 'models' => '', /*设备型号*/ 'date_time' => '' /*生成时间*/ ]; /** * 判断请求来源是否是手机设备 * @return bool */ private function isMobile() : bool { //如果有HTTP_X_WAP_PROFILE则一定是移动设备 if (isset($_SERVER['HTTP_X_WAP_PROFILE'])) { return true; } //如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息 if (isset($_SERVER['HTTP_VIA']) && stristr($_SERVER['HTTP_VIA'], 'wap')) { return true; } //野蛮方法,判断手机发送的客户端标志,兼容性有待提高 if (isset($_SERVER['HTTP_USER_AGENT'])) { $clientKeywords = ['nokia','sony','ericsson','mot','samsung','htc','sgh','lg','sharp','sie-','philips','panasonic','alcatel','lenovo','iphone','ipod','blackberry','meizu','android','netfront','symbian','ucweb','windowsce','palm','operamini','operamobi','openwave','nexusone','cldc','midp','wap','mobile']; //从HTTP_USER_AGENT中查找手机浏览器的关键字 if (preg_match("/(".implode('|', $clientKeywords).")/i", strtolower($_SERVER['HTTP_USER_AGENT']))) { return true; } } //协议法,因为有可能不准确,放到最后判断 if (isset($_SERVER['HTTP_ACCEPT'])) { //如果只支持wml并且不支持html那一定是移动设备 //如果支持wml和html但是wml在html之前则是移动设备 if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== false) && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === false || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))) { return true; } } return false; } /** * 初始化 * @return void * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function initialize() { $controller = $this->request->controller(); $this->languageId = $this->request->language_id??1; //通过中间件过来的语言包,动态设置 Lang::setLangSet($this->request->language_code??'zh-cn'); //重新加载动态设置的语言包 $this->app->loadLangPack(Lang::getLangSet()); // 初始化公共模型 $this->navModel = new Navigator(); $this->systemConfigModel = new SystemConfig(); // 初始化公共页面,判断语言包 // 导航 $navInfo = $this->navModel->getNavInfo($this->languageId,$this->platformId,$controller); $navInfo = recursion_func($navInfo); $footerNavInfo = $this->navModel->getFootNavInfo($this->languageId,$this->platformId); $footerNavInfo = recursion_func($footerNavInfo); // 头部版本号 // 静态版本号 $version = Env::get('front.version'); // 尾部数据 $footerInfo = $this->systemConfigModel->getFooterInfo($this->languageId); // 首页多网站切换 $multiLanguage = $this->systemConfigModel->getWebSiteInfo($this->languageId); // 其他公共数据 // 增加标签显示 $metaTitle = $this->systemConfigModel->getMetaTitle($this->languageId,'common'); View::assign('meta',$metaTitle); View::assign('nav_info',$navInfo); View::assign('nav_footer_info',$footerNavInfo); View::assign('footer_info',$footerInfo); View::assign('multi_lang',$multiLanguage); View::assign('ver',$version); View::assign('is_dev',Env::get('APP_DEBUG')); View::assign('is_mobile',$this->isMobile()); } /** * 访问日志监控,提交kafka生产者接口 * @return \think\response\Json * @throws \GeoIp2\Exception\AddressNotFoundException * @throws \MaxMind\Db\Reader\InvalidDatabaseException */ public function submitActionLog() { $inputData = $this->request->param(); $model = explode('//',$inputData['url']); $model = explode('/',$model[1]); $this->apiLog['items'] = Env::get('platform_name','官网'); $this->apiLog['forum'] = count($model) > 1 && $model[1] != '' ? $model[1] : 'index'; $this->apiLog['forum_code'] = 200; $this->apiLog['url'] = $inputData['url']; $this->apiLog['refer'] = $inputData['url']; $this->apiLog['content'] = $inputData['content']; $this->apiLog['click'] = $inputData['click']; $this->apiLog['start_time'] = date('Y-m-d H:i:s',(int)ceil(($inputData['date_time'] - (int)ceil((int)$inputData['start_time'])) / 1000) ); $this->apiLog['date_time'] = date('Y-m-d H:i:s',(int)ceil($inputData['date_time'] / 1000) ); //获取应用启动时间 //获取访问设备,系统版本,浏览器,设备型号 $userAgent = $inputData['drive']; AbstractDeviceParser::setVersionTruncation(AbstractDeviceParser::VERSION_TRUNCATION_NONE); $dd = new DeviceDetector($userAgent); $dd->parse(); if ($dd->isBot()) { $this->apiLog['brower'] = '未知'; $this->apiLog['system'] = '未知'; $this->apiLog['drive'] = '未知'; $this->apiLog['models'] = '爬虫'; } else { $clientInfo = $dd->getClient(); $osInfo = $dd->getOs(); $device = $dd->getDeviceName(); $brand = $dd->getBrandName(); $model = $dd->getModel(); $this->apiLog['brower'] = !empty($clientInfo) ? $clientInfo['name'].' '.$clientInfo['version'] : '未知'; $this->apiLog['system'] = !empty($osInfo) ? $osInfo['name'].' '.$osInfo['version'] : '未知'; $this->apiLog['models'] = $device . " " . $brand . " ". $model; $this->apiLog['drive'] = $device; } //解析IP地址,得到国家,城市,地址, $this->apiLog['ip'] = $inputData['ip']; if (!filter_var($inputData['ip'],FILTER_VALIDATE_IP,FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE | FILTER_NULL_ON_FAILURE)) { $this->apiLog['country'] = '本地'; $this->apiLog['province'] = '本地'; $this->apiLog['city'] = '本地'; } else { $readerCity = new Reader(public_path() . 'GeoLite2-City.mmdb'); $record = $readerCity->city($inputData['ip']); $country = $record->country->names['zh-CN']; $province = $record->subdivisions[0]->names['zh-CN']??''; $city = $record->city->names['zh-CN']??$record->city->names['en']; $china = ['香港','澳门','台湾']; if (in_array($country,$china)) { $province = $city = $country; $country = '中国'; } $this->apiLog['country'] = $country; $this->apiLog['province'] = $province; $this->apiLog['city'] = $city; } // Cache::set('this-api-log',$this->apiLog); // 返回信息前,写入kafka log日志 $result = $this->sendLogsToKafkaProduce($this->apiLog,'action_logs',Env::get('database.database'),'add'); return $result ? json('提交成功') : json('提交失败',504); } }