mirror of
				https://github.com/v2board/v2board.git
				synced 2025-10-31 01:11:46 +08:00 
			
		
		
		
	update: log api
This commit is contained in:
		| @@ -36,11 +36,13 @@ class StatController extends Controller | |||||||
|                 ->get() |                 ->get() | ||||||
|                 ->makeHidden(['record_at', 'created_at', 'updated_at', 'id', 'record_type']) |                 ->makeHidden(['record_at', 'created_at', 'updated_at', 'id', 'record_type']) | ||||||
|                 ->toArray(); |                 ->toArray(); | ||||||
|  |         } else { | ||||||
|  |             $statisticalService = new StatisticalService(); | ||||||
|  |             return [ | ||||||
|  |                 'data' => $statisticalService->generateStatData() | ||||||
|  |             ]; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         $statisticalService = new StatisticalService(); |  | ||||||
|         $stats = array_merge($stats ?? [], [$statisticalService->generateStatData()]); |  | ||||||
|  |  | ||||||
|         $stats = array_reduce($stats, function($carry, $item) { |         $stats = array_reduce($stats, function($carry, $item) { | ||||||
|             foreach($item as $key => $value) { |             foreach($item as $key => $value) { | ||||||
|                 if(isset($carry[$key]) && $carry[$key]) { |                 if(isset($carry[$key]) && $carry[$key]) { | ||||||
| @@ -60,9 +62,9 @@ class StatController extends Controller | |||||||
|     public function getStatRecord(Request $request) |     public function getStatRecord(Request $request) | ||||||
|     { |     { | ||||||
|         $request->validate([ |         $request->validate([ | ||||||
|             'type' => 'required|in:order_total,commission_total,register_count', |             'type' => 'required|in:paid_total,commission_total,register_count', | ||||||
|             'start_at' => '', |             'start_at' => '', | ||||||
|             'end_at' |             'end_at' => '' | ||||||
|         ]); |         ]); | ||||||
|  |  | ||||||
|         $statisticalService = new StatisticalService(); |         $statisticalService = new StatisticalService(); | ||||||
| @@ -73,6 +75,23 @@ class StatController extends Controller | |||||||
|         ]; |         ]; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public function getRanking(Request $request) | ||||||
|  |     { | ||||||
|  |         $request->validate([ | ||||||
|  |             'type' => 'required|in:server_traffic_rank,user_consumption_rank,invite_rank', | ||||||
|  |             'start_at' => '', | ||||||
|  |             'end_at' => '', | ||||||
|  |             'limit' => 'nullable|integer' | ||||||
|  |         ]); | ||||||
|  |  | ||||||
|  |         $statisticalService = new StatisticalService(); | ||||||
|  |         $statisticalService->setStartAt($request->input('start_at')); | ||||||
|  |         $statisticalService->setEndAt($request->input('end_at')); | ||||||
|  |         return [ | ||||||
|  |             'data' => $statisticalService->getRanking($request->input('type'), $request->input('limit') ?? 20) | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public function getOverride(Request $request) |     public function getOverride(Request $request) | ||||||
|     { |     { | ||||||
|         return [ |         return [ | ||||||
|   | |||||||
							
								
								
									
										11
									
								
								app/Logging/MysqlLogger.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								app/Logging/MysqlLogger.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | <?php | ||||||
|  | namespace App\Logging; | ||||||
|  |  | ||||||
|  | class MysqlLogger | ||||||
|  | { | ||||||
|  |     public function __invoke(array $config){ | ||||||
|  |         return tap(new \Monolog\Logger('mysql'), function ($logger) { | ||||||
|  |             $logger->pushHandler(new MysqlLoggerHandler()); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										44
									
								
								app/Logging/MysqlLoggerHandler.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								app/Logging/MysqlLoggerHandler.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | |||||||
|  | <?php | ||||||
|  | namespace App\Logging; | ||||||
|  |  | ||||||
|  | use Illuminate\Support\Facades\DB; | ||||||
|  | use Illuminate\Support\Facades\Log; | ||||||
|  | use Monolog\Handler\AbstractProcessingHandler; | ||||||
|  | use Monolog\Logger; | ||||||
|  | use App\Models\Log as LogModel; | ||||||
|  |  | ||||||
|  | class MysqlLoggerHandler extends AbstractProcessingHandler | ||||||
|  | { | ||||||
|  |     public function __construct($level = Logger::DEBUG, bool $bubble = true) | ||||||
|  |     { | ||||||
|  |         parent::__construct($level, $bubble); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     protected function write(array $record): void | ||||||
|  |     { | ||||||
|  |         try{ | ||||||
|  |             if(isset($record['context']['exception']) && is_object($record['context']['exception'])){ | ||||||
|  |                 $record['context']['exception'] = (array)$record['context']['exception']; | ||||||
|  |             } | ||||||
|  |             $record['request_data'] = request()->all() ??[]; | ||||||
|  |             $log = [ | ||||||
|  |                 'title' => $record['message'], | ||||||
|  |                 'level' => $record['level_name'], | ||||||
|  |                 'host' => $record['request_host'] ?? request()->getSchemeAndHttpHost(), | ||||||
|  |                 'uri' => $record['request_uri'] ?? request()->getRequestUri(), | ||||||
|  |                 'method' => $record['request_method'] ?? request()->getMethod(), | ||||||
|  |                 'ip' => request()->getClientIp(), | ||||||
|  |                 'data' => json_encode($record['request_data']) , | ||||||
|  |                 'context' => isset($record['context']) ? json_encode($record['context']) : '', | ||||||
|  |                 'created_at' => strtotime($record['datetime']), | ||||||
|  |                 'updated_at' => strtotime($record['datetime']), | ||||||
|  |             ]; | ||||||
|  |  | ||||||
|  |             LogModel::insert( | ||||||
|  |                 $log | ||||||
|  |             ); | ||||||
|  |         }catch (\Exception $e){ | ||||||
|  |             Log::channel('daily')->error($e->getMessage().$e->getFile().$e->getTraceAsString()); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										16
									
								
								app/Models/Log.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								app/Models/Log.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace App\Models; | ||||||
|  |  | ||||||
|  | use Illuminate\Database\Eloquent\Model; | ||||||
|  |  | ||||||
|  | class Log extends Model | ||||||
|  | { | ||||||
|  |     protected $table = 'v2_log'; | ||||||
|  |     protected $dateFormat = 'U'; | ||||||
|  |     protected $guarded = ['id']; | ||||||
|  |     protected $casts = [ | ||||||
|  |         'created_at' => 'timestamp', | ||||||
|  |         'updated_at' => 'timestamp' | ||||||
|  |     ]; | ||||||
|  | } | ||||||
| @@ -209,40 +209,75 @@ class StatisticalService { | |||||||
|     { |     { | ||||||
|         switch ($type) { |         switch ($type) { | ||||||
|             case 'server_traffic_rank': { |             case 'server_traffic_rank': { | ||||||
|                 return StatServer::select([ |                 return $this->buildServerTrafficRank($limit); | ||||||
|                     'server_id', |  | ||||||
|                     'server_type', |  | ||||||
|                     DB::raw('sum(u) as u'), |  | ||||||
|                     DB::raw('sum(d) as d'), |  | ||||||
|                     DB::raw('sum(u) + sum(d) as total') |  | ||||||
|                 ]) |  | ||||||
|                     ->where('record_at', '>=', $this->startAt) |  | ||||||
|                     ->where('record_at', '<', $this->endAt) |  | ||||||
|                     ->groupBy('server_id', 'server_type') |  | ||||||
|                     ->orderBy('total', 'DESC') |  | ||||||
|                     ->limit($limit) |  | ||||||
|                     ->get(); |  | ||||||
|             } |             } | ||||||
|             case 'user_consumption_rank': { |             case 'user_consumption_rank': { | ||||||
|                 $stats = StatUser::select([ |                 return $this->buildUserConsumptionRank($limit); | ||||||
|                     'user_id', |             } | ||||||
|                     DB::raw('sum(u) as u'), |             case 'invite_rank': { | ||||||
|                     DB::raw('sum(d) as d'), |                 return $this->buildInviteRank($limit); | ||||||
|                     DB::raw('sum(u) + sum(d) as total') |  | ||||||
|                 ]) |  | ||||||
|                     ->where('record_at', '>=', $this->startAt) |  | ||||||
|                     ->where('record_at', '<', $this->endAt) |  | ||||||
|                     ->groupBy('user_id') |  | ||||||
|                     ->orderBy('total', 'DESC') |  | ||||||
|                     ->limit($limit) |  | ||||||
|                     ->get(); |  | ||||||
|                 $users = User::whereIn('id', $stats->pluck('user_id')->toArray())->get()->keyBy('id'); |  | ||||||
|                 foreach ($stats as $k => $v) { |  | ||||||
|                     if (!isset($users[$v['user_id']])) continue; |  | ||||||
|                     $stats[$k]['email'] = $users[$v['user_id']]['email']; |  | ||||||
|                 } |  | ||||||
|                 return $stats; |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     private function buildInviteRank($limit) | ||||||
|  |     { | ||||||
|  |         $stats = User::select([ | ||||||
|  |             'invite_user_id', | ||||||
|  |             DB::raw('count(*) as count') | ||||||
|  |         ]) | ||||||
|  |             ->where('created_at', '>=', $this->startAt) | ||||||
|  |             ->where('created_at', '<', $this->endAt) | ||||||
|  |             ->whereNotNull('invite_user_id') | ||||||
|  |             ->groupBy('invite_user_id') | ||||||
|  |             ->orderBy('count', 'DESC') | ||||||
|  |             ->limit($limit) | ||||||
|  |             ->get(); | ||||||
|  |  | ||||||
|  |         $users = User::whereIn('id', $stats->pluck('invite_user_id')->toArray())->get()->keyBy('id'); | ||||||
|  |         foreach ($stats as $k => $v) { | ||||||
|  |             if (!isset($users[$v['invite_user_id']])) continue; | ||||||
|  |             $stats[$k]['email'] = $users[$v['invite_user_id']]['email']; | ||||||
|  |         } | ||||||
|  |         return $stats; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private function buildUserConsumptionRank($limit) | ||||||
|  |     { | ||||||
|  |         $stats = StatUser::select([ | ||||||
|  |             'user_id', | ||||||
|  |             DB::raw('sum(u) as u'), | ||||||
|  |             DB::raw('sum(d) as d'), | ||||||
|  |             DB::raw('sum(u) + sum(d) as total') | ||||||
|  |         ]) | ||||||
|  |             ->where('record_at', '>=', $this->startAt) | ||||||
|  |             ->where('record_at', '<', $this->endAt) | ||||||
|  |             ->groupBy('user_id') | ||||||
|  |             ->orderBy('total', 'DESC') | ||||||
|  |             ->limit($limit) | ||||||
|  |             ->get(); | ||||||
|  |         $users = User::whereIn('id', $stats->pluck('user_id')->toArray())->get()->keyBy('id'); | ||||||
|  |         foreach ($stats as $k => $v) { | ||||||
|  |             if (!isset($users[$v['user_id']])) continue; | ||||||
|  |             $stats[$k]['email'] = $users[$v['user_id']]['email']; | ||||||
|  |         } | ||||||
|  |         return $stats; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private function buildServerTrafficRank($limit) | ||||||
|  |     { | ||||||
|  |         return StatServer::select([ | ||||||
|  |             'server_id', | ||||||
|  |             'server_type', | ||||||
|  |             DB::raw('sum(u) as u'), | ||||||
|  |             DB::raw('sum(d) as d'), | ||||||
|  |             DB::raw('sum(u) + sum(d) as total') | ||||||
|  |         ]) | ||||||
|  |             ->where('record_at', '>=', $this->startAt) | ||||||
|  |             ->where('record_at', '<', $this->endAt) | ||||||
|  |             ->groupBy('server_id', 'server_type') | ||||||
|  |             ->orderBy('total', 'DESC') | ||||||
|  |             ->limit($limit) | ||||||
|  |             ->get(); | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ return [ | |||||||
|     | |     | | ||||||
|     */ |     */ | ||||||
|  |  | ||||||
|     'default' => env('LOG_CHANNEL', 'stack'), |     'default' => 'mysql', | ||||||
|  |  | ||||||
|     /* |     /* | ||||||
|     |-------------------------------------------------------------------------- |     |-------------------------------------------------------------------------- | ||||||
| @@ -34,6 +34,11 @@ return [ | |||||||
|     */ |     */ | ||||||
|  |  | ||||||
|     'channels' => [ |     'channels' => [ | ||||||
|  |         'mysql' => [ | ||||||
|  |             'driver' => 'custom', | ||||||
|  |             'via' => App\Logging\MysqlLogger::class, | ||||||
|  |         ], | ||||||
|  |  | ||||||
|         'stack' => [ |         'stack' => [ | ||||||
|             'driver' => 'stack', |             'driver' => 'stack', | ||||||
|             'channels' => ['daily'], |             'channels' => ['daily'], | ||||||
|   | |||||||
| @@ -81,6 +81,23 @@ CREATE TABLE `v2_knowledge` ( | |||||||
| ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='知識庫'; | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='知識庫'; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | DROP TABLE IF EXISTS `v2_log`; | ||||||
|  | CREATE TABLE `v2_log` ( | ||||||
|  |                           `id` int(11) NOT NULL AUTO_INCREMENT, | ||||||
|  |                           `title` varchar(255) NOT NULL, | ||||||
|  |                           `level` varchar(11) DEFAULT NULL, | ||||||
|  |                           `host` varchar(255) DEFAULT NULL, | ||||||
|  |                           `uri` varchar(255) NOT NULL, | ||||||
|  |                           `method` varchar(11) NOT NULL, | ||||||
|  |                           `data` text, | ||||||
|  |                           `ip` varchar(128) DEFAULT NULL, | ||||||
|  |                           `context` text, | ||||||
|  |                           `created_at` int(11) NOT NULL, | ||||||
|  |                           `updated_at` int(11) NOT NULL, | ||||||
|  |                           PRIMARY KEY (`id`) | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; | ||||||
|  |  | ||||||
|  |  | ||||||
| DROP TABLE IF EXISTS `v2_mail_log`; | DROP TABLE IF EXISTS `v2_mail_log`; | ||||||
| CREATE TABLE `v2_mail_log` ( | CREATE TABLE `v2_mail_log` ( | ||||||
|                                `id` int(11) NOT NULL AUTO_INCREMENT, |                                `id` int(11) NOT NULL AUTO_INCREMENT, | ||||||
| @@ -163,8 +180,8 @@ CREATE TABLE `v2_plan` ( | |||||||
|                            `id` int(11) NOT NULL AUTO_INCREMENT, |                            `id` int(11) NOT NULL AUTO_INCREMENT, | ||||||
|                            `group_id` int(11) NOT NULL, |                            `group_id` int(11) NOT NULL, | ||||||
|                            `transfer_enable` int(11) NOT NULL, |                            `transfer_enable` int(11) NOT NULL, | ||||||
|                            `speed_limit` int(11) DEFAULT NULL, |  | ||||||
|                            `name` varchar(255) NOT NULL, |                            `name` varchar(255) NOT NULL, | ||||||
|  |                            `speed_limit` int(11) DEFAULT NULL, | ||||||
|                            `show` tinyint(1) NOT NULL DEFAULT '0', |                            `show` tinyint(1) NOT NULL DEFAULT '0', | ||||||
|                            `sort` int(11) DEFAULT NULL, |                            `sort` int(11) DEFAULT NULL, | ||||||
|                            `renew` tinyint(1) NOT NULL DEFAULT '1', |                            `renew` tinyint(1) NOT NULL DEFAULT '1', | ||||||
| @@ -408,8 +425,8 @@ CREATE TABLE `v2_user` ( | |||||||
|                            `transfer_enable` bigint(20) NOT NULL DEFAULT '0', |                            `transfer_enable` bigint(20) NOT NULL DEFAULT '0', | ||||||
|                            `banned` tinyint(1) NOT NULL DEFAULT '0', |                            `banned` tinyint(1) NOT NULL DEFAULT '0', | ||||||
|                            `is_admin` tinyint(1) NOT NULL DEFAULT '0', |                            `is_admin` tinyint(1) NOT NULL DEFAULT '0', | ||||||
|                            `is_staff` tinyint(1) NOT NULL DEFAULT '0', |  | ||||||
|                            `last_login_at` int(11) DEFAULT NULL, |                            `last_login_at` int(11) DEFAULT NULL, | ||||||
|  |                            `is_staff` tinyint(1) NOT NULL DEFAULT '0', | ||||||
|                            `last_login_ip` int(11) DEFAULT NULL, |                            `last_login_ip` int(11) DEFAULT NULL, | ||||||
|                            `uuid` varchar(36) NOT NULL, |                            `uuid` varchar(36) NOT NULL, | ||||||
|                            `group_id` int(11) DEFAULT NULL, |                            `group_id` int(11) DEFAULT NULL, | ||||||
| @@ -418,8 +435,8 @@ CREATE TABLE `v2_user` ( | |||||||
|                            `remind_expire` tinyint(4) DEFAULT '1', |                            `remind_expire` tinyint(4) DEFAULT '1', | ||||||
|                            `remind_traffic` tinyint(4) DEFAULT '1', |                            `remind_traffic` tinyint(4) DEFAULT '1', | ||||||
|                            `token` char(32) NOT NULL, |                            `token` char(32) NOT NULL, | ||||||
|                            `remarks` text, |  | ||||||
|                            `expired_at` bigint(20) DEFAULT '0', |                            `expired_at` bigint(20) DEFAULT '0', | ||||||
|  |                            `remarks` text, | ||||||
|                            `created_at` int(11) NOT NULL, |                            `created_at` int(11) NOT NULL, | ||||||
|                            `updated_at` int(11) NOT NULL, |                            `updated_at` int(11) NOT NULL, | ||||||
|                            PRIMARY KEY (`id`), |                            PRIMARY KEY (`id`), | ||||||
| @@ -427,4 +444,4 @@ CREATE TABLE `v2_user` ( | |||||||
| ) ENGINE=InnoDB DEFAULT CHARSET=utf8; | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; | ||||||
|  |  | ||||||
|  |  | ||||||
| -- 2023-05-03 07:27:22 | -- 2023-05-23 17:01:12 | ||||||
|   | |||||||
| @@ -107,17 +107,6 @@ CREATE TABLE `v2_coupon` ( | |||||||
| ALTER TABLE `v2_order` | ALTER TABLE `v2_order` | ||||||
| ADD `discount_amount` int(11) NULL AFTER `total_amount`; | ADD `discount_amount` int(11) NULL AFTER `total_amount`; | ||||||
|  |  | ||||||
| CREATE TABLE `v2_tutorial` ( |  | ||||||
|   `id` int NOT NULL AUTO_INCREMENT PRIMARY KEY, |  | ||||||
|   `title` varchar(255) COLLATE 'utf8mb4_general_ci' NOT NULL, |  | ||||||
|   `description` varchar(255) COLLATE 'utf8mb4_general_ci' NOT NULL, |  | ||||||
|   `icon` varchar(255) COLLATE 'utf8mb4_general_ci' NOT NULL, |  | ||||||
|   `steps` text NULL, |  | ||||||
|   `show` tinyint(1) NOT NULL DEFAULT '0', |  | ||||||
|   `created_at` int(11) NOT NULL, |  | ||||||
|   `updated_at` int(11) NOT NULL |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| ALTER TABLE `v2_server_log` | ALTER TABLE `v2_server_log` | ||||||
| CHANGE `rate` `rate` decimal(10,2) NOT NULL AFTER `d`; | CHANGE `rate` `rate` decimal(10,2) NOT NULL AFTER `d`; | ||||||
|  |  | ||||||
| @@ -375,20 +364,6 @@ ALTER TABLE `v2_stat_server` | |||||||
| ADD INDEX `record_at` (`record_at`), | ADD INDEX `record_at` (`record_at`), | ||||||
| ADD INDEX `server_id` (`server_id`); | ADD INDEX `server_id` (`server_id`); | ||||||
|  |  | ||||||
| CREATE TABLE `v2_stat_order` ( |  | ||||||
|   `id` int(11) NOT NULL AUTO_INCREMENT, |  | ||||||
|   `order_count` int(11) NOT NULL COMMENT '订单数量', |  | ||||||
|   `order_amount` int(11) NOT NULL COMMENT '订单合计', |  | ||||||
|   `commission_count` int(11) NOT NULL, |  | ||||||
|   `commission_amount` int(11) NOT NULL COMMENT '佣金合计', |  | ||||||
|   `record_type` char(1) NOT NULL, |  | ||||||
|   `record_at` int(11) NOT NULL, |  | ||||||
|   `created_at` int(11) NOT NULL, |  | ||||||
|   `updated_at` int(11) NOT NULL, |  | ||||||
|   PRIMARY KEY (`id`), |  | ||||||
|   UNIQUE KEY `record_at` (`record_at`) |  | ||||||
| ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='订单统计'; |  | ||||||
|  |  | ||||||
| ALTER TABLE `v2_user` | ALTER TABLE `v2_user` | ||||||
| DROP `enable`; | DROP `enable`; | ||||||
|  |  | ||||||
| @@ -697,3 +672,18 @@ ALTER TABLE `v2_stat_order` | |||||||
|     ADD `invite_count` int(11) NOT NULL AFTER `register_count`, |     ADD `invite_count` int(11) NOT NULL AFTER `register_count`, | ||||||
|     ADD `transfer_used_total` varchar(32) NOT NULL AFTER `invite_count`, |     ADD `transfer_used_total` varchar(32) NOT NULL AFTER `invite_count`, | ||||||
|     RENAME TO `v2_stat`; |     RENAME TO `v2_stat`; | ||||||
|  |  | ||||||
|  | CREATE TABLE `v2_log` ( | ||||||
|  |                           `id` int(11) NOT NULL AUTO_INCREMENT, | ||||||
|  |                           `title` varchar(255) NOT NULL, | ||||||
|  |                           `level` varchar(11) DEFAULT NULL, | ||||||
|  |                           `host` varchar(255) DEFAULT NULL, | ||||||
|  |                           `uri` varchar(255) NOT NULL, | ||||||
|  |                           `method` varchar(11) NOT NULL, | ||||||
|  |                           `data` text, | ||||||
|  |                           `ip` varchar(128) DEFAULT NULL, | ||||||
|  |                           `context` text, | ||||||
|  |                           `created_at` int(11) NOT NULL, | ||||||
|  |                           `updated_at` int(11) NOT NULL, | ||||||
|  |                           PRIMARY KEY (`id`) | ||||||
|  | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user