diff --git a/app/routes.php b/app/routes.php index 12ee5f8d44..2db9199b1c 100644 --- a/app/routes.php +++ b/app/routes.php @@ -80,6 +80,8 @@ $group->post('/switch_theme_mode', App\Controllers\UserController::class . ':switchThemeMode'); // 订阅记录 $group->get('/subscribe', App\Controllers\User\SubLogController::class . ':index'); + // 流量记录 + $group->get('/traffic', App\Controllers\User\TrafficLogController::class . ':index'); // 账户余额 $group->get('/money', App\Controllers\User\MoneyController::class . ':index'); $group->post('/giftcard', App\Controllers\User\MoneyController::class . ':applyGiftCard'); @@ -216,9 +218,6 @@ // 返利日志 $group->get('/payback', App\Controllers\Admin\PaybackController::class . ':index'); $group->post('/payback/ajax', App\Controllers\Admin\PaybackController::class . ':ajax'); - // 流量日志 - $group->get('/traffic', App\Controllers\Admin\TrafficLogController::class . ':index'); - $group->post('/traffic/ajax', App\Controllers\Admin\TrafficLogController::class . ':ajax'); // 用户余额日志 $group->get('/money', App\Controllers\Admin\MoneyLogController::class . ':index'); $group->post('/money/ajax', App\Controllers\Admin\MoneyLogController::class . ':ajax'); diff --git a/composer.lock b/composer.lock index 4e7847c0c8..998ee8976b 100644 --- a/composer.lock +++ b/composer.lock @@ -123,16 +123,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.296.6", + "version": "3.297.2", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "11d0a94f8b2539d587e2f6db7c2fa8e39fe78a67" + "reference": "bbf516a4a88f829f92cc396628be705966880dbd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/11d0a94f8b2539d587e2f6db7c2fa8e39fe78a67", - "reference": "11d0a94f8b2539d587e2f6db7c2fa8e39fe78a67", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/bbf516a4a88f829f92cc396628be705966880dbd", + "reference": "bbf516a4a88f829f92cc396628be705966880dbd", "shasum": "" }, "require": { @@ -212,9 +212,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.296.6" + "source": "https://github.com/aws/aws-sdk-php/tree/3.297.2" }, - "time": "2024-01-19T19:14:55+00:00" + "time": "2024-01-26T19:09:20+00:00" }, { "name": "bacon/bacon-qr-code", @@ -1200,16 +1200,16 @@ }, { "name": "illuminate/collections", - "version": "v10.41.0", + "version": "v10.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/collections.git", - "reference": "82025fd7ac761cc50d5dbd9f9532ebf066821858" + "reference": "221c1ee944cb20ed807a8a5e8668552d6ca736ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/collections/zipball/82025fd7ac761cc50d5dbd9f9532ebf066821858", - "reference": "82025fd7ac761cc50d5dbd9f9532ebf066821858", + "url": "https://api.github.com/repos/illuminate/collections/zipball/221c1ee944cb20ed807a8a5e8668552d6ca736ff", + "reference": "221c1ee944cb20ed807a8a5e8668552d6ca736ff", "shasum": "" }, "require": { @@ -1251,11 +1251,11 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2024-01-01T15:17:18+00:00" + "time": "2024-01-22T13:55:20+00:00" }, { "name": "illuminate/conditionable", - "version": "v10.41.0", + "version": "v10.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/conditionable.git", @@ -1301,7 +1301,7 @@ }, { "name": "illuminate/container", - "version": "v10.41.0", + "version": "v10.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/container.git", @@ -1352,7 +1352,7 @@ }, { "name": "illuminate/contracts", - "version": "v10.41.0", + "version": "v10.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/contracts.git", @@ -1400,7 +1400,7 @@ }, { "name": "illuminate/database", - "version": "v10.41.0", + "version": "v10.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/database.git", @@ -1473,7 +1473,7 @@ }, { "name": "illuminate/macroable", - "version": "v10.41.0", + "version": "v10.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/macroable.git", @@ -1519,7 +1519,7 @@ }, { "name": "illuminate/pagination", - "version": "v10.41.0", + "version": "v10.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/pagination.git", @@ -1569,16 +1569,16 @@ }, { "name": "illuminate/support", - "version": "v10.41.0", + "version": "v10.42.0", "source": { "type": "git", "url": "https://github.com/illuminate/support.git", - "reference": "1355b7d28ebb802e95bffcb27417862961382c52" + "reference": "11a87daf9c4bef3d654c853161b34e11a6ca0618" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/support/zipball/1355b7d28ebb802e95bffcb27417862961382c52", - "reference": "1355b7d28ebb802e95bffcb27417862961382c52", + "url": "https://api.github.com/repos/illuminate/support/zipball/11a87daf9c4bef3d654c853161b34e11a6ca0618", + "reference": "11a87daf9c4bef3d654c853161b34e11a6ca0618", "shasum": "" }, "require": { @@ -1636,7 +1636,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2024-01-15T18:53:10+00:00" + "time": "2024-01-22T18:45:06+00:00" }, { "name": "irazasyed/telegram-bot-sdk", @@ -2150,16 +2150,16 @@ }, { "name": "moneyphp/money", - "version": "v4.3.0", + "version": "v4.4.0", "source": { "type": "git", "url": "https://github.com/moneyphp/money.git", - "reference": "50ddfd15b2be01d4bed3bcb0c975a6af5f78a183" + "reference": "5e60aebf09f709dd4ea16bf85e66d65301c0d172" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/moneyphp/money/zipball/50ddfd15b2be01d4bed3bcb0c975a6af5f78a183", - "reference": "50ddfd15b2be01d4bed3bcb0c975a6af5f78a183", + "url": "https://api.github.com/repos/moneyphp/money/zipball/5e60aebf09f709dd4ea16bf85e66d65301c0d172", + "reference": "5e60aebf09f709dd4ea16bf85e66d65301c0d172", "shasum": "" }, "require": { @@ -2183,7 +2183,7 @@ "phpbench/phpbench": "^1.2.5", "phpunit/phpunit": "^9.5.4", "psalm/plugin-phpunit": "^0.18.4", - "psr/cache": "^1.0.1", + "psr/cache": "^1.0.1 || ^2.0 || ^3.0", "vimeo/psalm": "~5.15.0" }, "suggest": { @@ -2232,9 +2232,9 @@ ], "support": { "issues": "https://github.com/moneyphp/money/issues", - "source": "https://github.com/moneyphp/money/tree/v4.3.0" + "source": "https://github.com/moneyphp/money/tree/v4.4.0" }, - "time": "2023-11-22T09:46:30+00:00" + "time": "2024-01-24T08:29:16+00:00" }, { "name": "mtdowling/jmespath.php", @@ -2304,16 +2304,16 @@ }, { "name": "nesbot/carbon", - "version": "2.72.1", + "version": "2.72.2", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "2b3b3db0a2d0556a177392ff1a3bf5608fa09f78" + "reference": "3e7edc41b58d65509baeb0d4a14c8fa41d627130" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/2b3b3db0a2d0556a177392ff1a3bf5608fa09f78", - "reference": "2b3b3db0a2d0556a177392ff1a3bf5608fa09f78", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/3e7edc41b58d65509baeb0d4a14c8fa41d627130", + "reference": "3e7edc41b58d65509baeb0d4a14c8fa41d627130", "shasum": "" }, "require": { @@ -2407,7 +2407,7 @@ "type": "tidelift" } ], - "time": "2023-12-08T23:47:49+00:00" + "time": "2024-01-19T00:21:53+00:00" }, { "name": "nikic/fast-route", @@ -2621,21 +2621,21 @@ }, { "name": "openai-php/client", - "version": "v0.8.1", + "version": "v0.8.2", "source": { "type": "git", "url": "https://github.com/openai-php/client.git", - "reference": "ce84f541fe8a2869de7f48030d5757be1fd604c9" + "reference": "081ea0b0096d5788ae1d4f8e2e4c82d7f68dccb7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/openai-php/client/zipball/ce84f541fe8a2869de7f48030d5757be1fd604c9", - "reference": "ce84f541fe8a2869de7f48030d5757be1fd604c9", + "url": "https://api.github.com/repos/openai-php/client/zipball/081ea0b0096d5788ae1d4f8e2e4c82d7f68dccb7", + "reference": "081ea0b0096d5788ae1d4f8e2e4c82d7f68dccb7", "shasum": "" }, "require": { "php": "^8.1.0", - "php-http/discovery": "^1.19.1", + "php-http/discovery": "^1.19.2", "php-http/multipart-stream-builder": "^1.3.0", "psr/http-client": "^1.0.3", "psr/http-client-implementation": "^1.0.1", @@ -2648,12 +2648,12 @@ "laravel/pint": "^1.13.7", "mockery/mockery": "^1.6.7", "nunomaduro/collision": "^7.10.0", - "pestphp/pest": "^2.28.1", - "pestphp/pest-plugin-arch": "^2.5", - "pestphp/pest-plugin-type-coverage": "^2.5.0", - "phpstan/phpstan": "^1.10.50", + "pestphp/pest": "^2.30.0", + "pestphp/pest-plugin-arch": "^2.6", + "pestphp/pest-plugin-type-coverage": "^2.7.0", + "phpstan/phpstan": "^1.10.55", "rector/rector": "^0.16.0", - "symfony/var-dumper": "^6.4" + "symfony/var-dumper": "^6.4.2" }, "type": "library", "autoload": { @@ -2693,7 +2693,7 @@ ], "support": { "issues": "https://github.com/openai-php/client/issues", - "source": "https://github.com/openai-php/client/tree/v0.8.1" + "source": "https://github.com/openai-php/client/tree/v0.8.2" }, "funding": [ { @@ -2709,7 +2709,7 @@ "type": "github" } ], - "time": "2023-12-22T15:18:26+00:00" + "time": "2024-01-26T08:20:30+00:00" }, { "name": "ozdemir/datatables", @@ -4326,16 +4326,16 @@ }, { "name": "sentry/sentry", - "version": "4.3.1", + "version": "4.4.0", "source": { "type": "git", "url": "https://github.com/getsentry/sentry-php.git", - "reference": "cd89f230bda0833cb9992ebe9a1b7d24d6ee245b" + "reference": "95a428a59ebddf786a27f09d19ec395a32f62082" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/cd89f230bda0833cb9992ebe9a1b7d24d6ee245b", - "reference": "cd89f230bda0833cb9992ebe9a1b7d24d6ee245b", + "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/95a428a59ebddf786a27f09d19ec395a32f62082", + "reference": "95a428a59ebddf786a27f09d19ec395a32f62082", "shasum": "" }, "require": { @@ -4399,7 +4399,7 @@ ], "support": { "issues": "https://github.com/getsentry/sentry-php/issues", - "source": "https://github.com/getsentry/sentry-php/tree/4.3.1" + "source": "https://github.com/getsentry/sentry-php/tree/4.4.0" }, "funding": [ { @@ -4411,7 +4411,7 @@ "type": "custom" } ], - "time": "2023-12-22T18:46:49+00:00" + "time": "2024-01-23T09:49:55+00:00" }, { "name": "slim/http", @@ -4607,16 +4607,16 @@ }, { "name": "smarty/smarty", - "version": "v4.3.4", + "version": "v4.3.5", "source": { "type": "git", "url": "https://github.com/smarty-php/smarty.git", - "reference": "3931d8f54b8f7a4ffab538582d34d4397ba8daa5" + "reference": "e0cbbdf6ea21768d0194e59d2f8c2e20d5f0868c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/smarty-php/smarty/zipball/3931d8f54b8f7a4ffab538582d34d4397ba8daa5", - "reference": "3931d8f54b8f7a4ffab538582d34d4397ba8daa5", + "url": "https://api.github.com/repos/smarty-php/smarty/zipball/e0cbbdf6ea21768d0194e59d2f8c2e20d5f0868c", + "reference": "e0cbbdf6ea21768d0194e59d2f8c2e20d5f0868c", "shasum": "" }, "require": { @@ -4667,9 +4667,9 @@ "support": { "forum": "https://github.com/smarty-php/smarty/discussions", "issues": "https://github.com/smarty-php/smarty/issues", - "source": "https://github.com/smarty-php/smarty/tree/v4.3.4" + "source": "https://github.com/smarty-php/smarty/tree/v4.3.5" }, - "time": "2023-09-14T10:59:08+00:00" + "time": "2024-01-23T10:47:54+00:00" }, { "name": "srmklive/paypal", diff --git a/config/.config.example.php b/config/.config.example.php index 126879078e..0887aa3e98 100644 --- a/config/.config.example.php +++ b/config/.config.example.php @@ -54,11 +54,6 @@ $_ENV['mail_filter_list'] = []; //已注册用户设置--------------------------------------------------------------------------------------- -#基础 -$_ENV['enable_checkin'] = true; //是否啓用簽到功能 -$_ENV['checkinMin'] = 1; //用户签到最少流量 单位MB -$_ENV['checkinMax'] = 50; //用户签到最多流量 - #高级 $_ENV['class_expire_reset_traffic'] = 0; //等级到期时重置为的流量值,单位GB,小于0时不重置 $_ENV['enable_kill'] = true; //是否允许用户注销账户 diff --git a/config/settings.json b/config/settings.json index 02b104bf0d..9222e2fede 100644 --- a/config/settings.json +++ b/config/settings.json @@ -1429,6 +1429,36 @@ "default": "0", "mark": "通知用户新IP登录" }, + { + "id": null, + "item": "enable_checkin", + "value": "0", + "class": "feature", + "is_public": 1, + "type": "bool", + "default": "0", + "mark": "签到开关" + }, + { + "id": null, + "item": "checkin_min", + "value": "1", + "class": "feature", + "is_public": 1, + "type": "int", + "default": "1", + "mark": "签到最少流量" + }, + { + "id": null, + "item": "checkin_max", + "value": "50", + "class": "feature", + "is_public": 1, + "type": "int", + "default": "50", + "mark": "签到最多流量" + }, { "id": null, "item": "enable_forced_replacement", diff --git a/db/migrations/2023020100-init.php b/db/migrations/2023020100-init.php index a220f68ed5..de3e04776c 100644 --- a/db/migrations/2023020100-init.php +++ b/db/migrations/2023020100-init.php @@ -92,6 +92,15 @@ public function up(): int KEY `id` (`id`), KEY `status` (`status`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + + CREATE TABLE `hourly_usage` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '记录ID', + `user_id` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '用户ID', + `date` date NOT NULL DEFAULT 0 COMMENT '记录日期', + `usage` longtext NOT NULL DEFAULT '{}' COMMENT '流量用量' CHECK (json_valid(`usage`)), + PRIMARY KEY (`id`), + KEY `user_id` (`user_id`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE `invoice` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '账单ID', @@ -332,16 +341,6 @@ public function up(): int KEY `expire_time` (`expire_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - CREATE TABLE `user_hourly_usage` ( - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '记录ID', - `user_id` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '用户ID', - `traffic` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '当前总流量', - `hourly_usage` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '过去一小时流量', - `datetime` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '记录时间', - PRIMARY KEY (`id`), - KEY `user_id` (`user_id`) - ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - CREATE TABLE `user_invite_code` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '记录ID', `code` varchar(255) NOT NULL DEFAULT '' COMMENT '邀请码', diff --git a/db/migrations/2024012700-add_hourly_usage.php b/db/migrations/2024012700-add_hourly_usage.php new file mode 100644 index 0000000000..3793d6879f --- /dev/null +++ b/db/migrations/2024012700-add_hourly_usage.php @@ -0,0 +1,43 @@ +exec(" + CREATE TABLE IF NOT EXISTS `hourly_usage` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '记录ID', + `user_id` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '用户ID', + `date` date NOT NULL DEFAULT 0 COMMENT '记录日期', + `usage` longtext NOT NULL DEFAULT '{}' COMMENT '流量用量' CHECK (json_valid(`usage`)), + PRIMARY KEY (`id`), + KEY `user_id` (`user_id`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + DROP TABLE IF EXISTS `user_hourly_usage`; + "); + + return 2024012700; + } + + public function down(): int + { + DB::getPdo()->exec(" + CREATE TABLE IF NOT EXISTS `user_hourly_usage` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '记录ID', + `user_id` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '用户ID', + `traffic` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '当前总流量', + `hourly_usage` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '过去一小时流量', + `datetime` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '记录时间', + PRIMARY KEY (`id`), + KEY `user_id` (`user_id`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + DROP TABLE IF EXISTS `hourly_usage`; + "); + + return 2024012300; + } +}; diff --git a/resources/views/tabler/admin/header.tpl b/resources/views/tabler/admin/header.tpl index 0d095958a0..f4affc25ad 100644 --- a/resources/views/tabler/admin/header.tpl +++ b/resources/views/tabler/admin/header.tpl @@ -205,10 +205,6 @@   在线IP - -   - 流量使用 - +
@@ -173,6 +176,38 @@
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
diff --git a/resources/views/tabler/user/header.tpl b/resources/views/tabler/user/header.tpl index dff4d74033..dc0b6eb197 100644 --- a/resources/views/tabler/user/header.tpl +++ b/resources/views/tabler/user/header.tpl @@ -105,8 +105,14 @@ {if $public_setting['subscribe_log']} -   - 订阅 +   + 订阅日志 + + {/if} + {if $public_setting['traffic_log']} + +   + 流量日志 {/if} diff --git a/resources/views/tabler/user/index.tpl b/resources/views/tabler/user/index.tpl index 40f6787420..3abb0f9a34 100644 --- a/resources/views/tabler/user/index.tpl +++ b/resources/views/tabler/user/index.tpl @@ -531,7 +531,7 @@ - {if $config['enable_checkin']} + {if $public_setting['enable_checkin']}
@@ -543,14 +543,14 @@

每日签到

签到可领取 - {if $config['checkinMin'] !== $config['checkinMax']} + {if $public_setting['checkin_min'] !== $public_setting['checkin_max']}   - {$config['checkinMin']} MB + {$public_setting['checkin_min']} MB 至 - {$config['checkinMax']} MB + {$public_setting['checkin_max']} MB 范围内的流量 {else} - {$config['checkinMin']} MB + {$public_setting['checkin_min']} MB {/if}

diff --git a/resources/views/tabler/user/traffic_log.tpl b/resources/views/tabler/user/traffic_log.tpl new file mode 100644 index 0000000000..925988c336 --- /dev/null +++ b/resources/views/tabler/user/traffic_log.tpl @@ -0,0 +1,132 @@ +{include file='user/header.tpl'} + +

+
+ +
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + +{include file='user/footer.tpl'} diff --git a/src/Command/Cron.php b/src/Command/Cron.php index b92bb011e4..255c2fc22d 100644 --- a/src/Command/Cron.php +++ b/src/Command/Cron.php @@ -49,11 +49,6 @@ public function boot(): void $jobs->detectNodeOffline(); } - // Run traffic log job - if ($minute === 0 && Config::obtain('traffic_log')) { - $jobs->addTrafficLog(); - } - // Run daily job if ($hour === Config::obtain('daily_job_hour') && $minute === Config::obtain('daily_job_minute') && diff --git a/src/Controllers/Admin/Setting/FeatureController.php b/src/Controllers/Admin/Setting/FeatureController.php index d9629ff78e..7be27291a7 100644 --- a/src/Controllers/Admin/Setting/FeatureController.php +++ b/src/Controllers/Admin/Setting/FeatureController.php @@ -21,6 +21,9 @@ final class FeatureController extends BaseController 'notify_new_subscribe', 'login_log', 'notify_new_login', + 'enable_checkin', + 'checkin_min', + 'checkin_max', ]; /** diff --git a/src/Controllers/Admin/TrafficLogController.php b/src/Controllers/Admin/TrafficLogController.php deleted file mode 100644 index feb86155c4..0000000000 --- a/src/Controllers/Admin/TrafficLogController.php +++ /dev/null @@ -1,87 +0,0 @@ - [ - 'id' => '记录ID', - 'user_id' => '用户ID', - 'traffic' => '累计流量/GB', - 'hourly_usage' => '过去一小时使用流量/GB', - 'datetime' => '时间', - ], - ]; - - /** - * 后台流量记录页面 - * - * @throws Exception - */ - public function index(ServerRequest $request, Response $response, array $args): ResponseInterface - { - return $response->write( - $this->view() - ->assign('details', self::$details) - ->fetch('admin/log/traffic.tpl') - ); - } - - /** - * 后台流量记录页面 AJAX - */ - public function ajax(ServerRequest $request, Response $response, array $args): ResponseInterface - { - $length = $request->getParam('length'); - $page = $request->getParam('start') / $length + 1; - $draw = $request->getParam('draw'); - - $traffic_log = UserHourlyUsage::query(); - - $search = $request->getParam('search')['value']; - - if ($search !== '') { - $traffic_log->where('user_id', '=', $search); - } - - $order = $request->getParam('order')[0]['dir']; - - if ($request->getParam('order')[0]['column'] !== '0') { - $order_by = $request->getParam('columns')[$request->getParam('order')[0]['column']]['data']; - - $traffic_log->orderBy($order_by, $order)->orderBy('id', 'desc'); - } else { - $traffic_log->orderBy('id', $order); - } - - $filtered = $traffic_log->count(); - $total = (new UserHourlyUsage())->count(); - - $trafficlogs = $traffic_log->paginate($length, '*', '', $page); - - foreach ($trafficlogs as $trafficlog) { - $trafficlog->traffic = Tools::flowToGB($trafficlog->traffic); - $trafficlog->hourly_usage = Tools::flowToGB($trafficlog->hourly_usage); - $trafficlog->datetime = Tools::toDateTime((int) $trafficlog->datetime); - } - - return $response->withJson([ - 'draw' => $draw, - 'recordsTotal' => $total, - 'recordsFiltered' => $filtered, - 'trafficlogs' => $trafficlogs, - ]); - } -} diff --git a/src/Controllers/User/DetectLogController.php b/src/Controllers/User/DetectLogController.php index b8b24125d6..458bb43ab1 100644 --- a/src/Controllers/User/DetectLogController.php +++ b/src/Controllers/User/DetectLogController.php @@ -21,6 +21,10 @@ final class DetectLogController extends BaseController */ public function index(ServerRequest $request, Response $response, array $args): Response|ResponseInterface { + if (! Config::obtain('display_detect_log')) { + return $response->withRedirect('/user'); + } + $logs = (new DetectLog())->orderBy('id', 'desc')->where('user_id', $this->user->id)->get(); foreach ($logs as $log) { diff --git a/src/Controllers/User/SubLogController.php b/src/Controllers/User/SubLogController.php index 5043182359..9c29e71902 100644 --- a/src/Controllers/User/SubLogController.php +++ b/src/Controllers/User/SubLogController.php @@ -22,6 +22,10 @@ final class SubLogController extends BaseController */ public function index(ServerRequest $request, Response $response, array $args): Response|ResponseInterface { + if (! Config::obtain('subscribe_log')) { + return $response->withRedirect('/user'); + } + $logs = (new SubscribeLog())->orderBy('id', 'desc')->where('user_id', $this->user->id)->get(); foreach ($logs as $log) { diff --git a/src/Controllers/User/TrafficLogController.php b/src/Controllers/User/TrafficLogController.php new file mode 100644 index 0000000000..56e74a086e --- /dev/null +++ b/src/Controllers/User/TrafficLogController.php @@ -0,0 +1,41 @@ +withRedirect('/user'); + } + + $logs = []; + $hourly_usage = Analytics::getUserTodayHourlyUsage($this->user->id); + + foreach ($hourly_usage as $hour => $usage) { + $logs[] = Tools::flowToMB((int) $usage); + } + + return $response->write($this->view() + ->assign('logs', json_encode($logs)) + ->fetch('user/traffic_log.tpl')); + } +} diff --git a/src/Controllers/UserController.php b/src/Controllers/UserController.php index f9eb12d9d5..78f00a6c65 100644 --- a/src/Controllers/UserController.php +++ b/src/Controllers/UserController.php @@ -13,6 +13,7 @@ use App\Models\Payback; use App\Services\Auth; use App\Services\Captcha; +use App\Services\Reward; use App\Services\Subscribe; use App\Utils\ResponseHelper; use App\Utils\Tools; @@ -139,7 +140,7 @@ public function invite(ServerRequest $request, Response $response, array $args): public function checkin(ServerRequest $request, Response $response, array $args): Response|ResponseInterface { - if (! $_ENV['enable_checkin']) { + if (! Config::obtain('enable_checkin') || ! $this->user->isAbleToCheckin()) { return ResponseHelper::error($response, '暂时还不能签到'); } @@ -151,17 +152,17 @@ public function checkin(ServerRequest $request, Response $response, array $args) } } - $checkin = $this->user->checkin(); + $traffic = Reward::issueCheckinReward($this->user->id); - if (! $checkin['ok']) { - return ResponseHelper::error($response, (string) $checkin['msg']); + if (! $traffic) { + return ResponseHelper::error($response, '签到失败'); } return $response->withJson([ 'ret' => 1, - 'msg' => $checkin['msg'], + 'msg' => '获得了 ' . $traffic . 'MB 流量', 'data' => [ - 'last-checkin-time' => $this->user->lastCheckInTime(), + 'last-checkin-time' => Tools::toDateTime(time()), ], ]); } diff --git a/src/Controllers/WebAPI/UserController.php b/src/Controllers/WebAPI/UserController.php index 9469bf3234..2b2d9d1907 100644 --- a/src/Controllers/WebAPI/UserController.php +++ b/src/Controllers/WebAPI/UserController.php @@ -5,7 +5,9 @@ namespace App\Controllers\WebAPI; use App\Controllers\BaseController; +use App\Models\Config; use App\Models\DetectLog; +use App\Models\HourlyUsage; use App\Models\Node; use App\Services\DB; use App\Services\DynamicRate; @@ -204,6 +206,7 @@ public function addTraffic(ServerRequest $request, Response $response, array $ar } $sum = 0; + $is_traffic_log = Config::obtain('traffic_log'); foreach ($data as $log) { $u = $log?->u; @@ -211,7 +214,11 @@ public function addTraffic(ServerRequest $request, Response $response, array $ar $user_id = $log?->user_id; if ($user_id) { - $stat->execute([(int) ($u * $rate), (int) ($d * $rate), (int) ($u + $d), (int) ($u + $d), $user_id]); + $stat->execute([(int) ($u * $rate), (int) ($d * $rate), (int) ($u + $d), (int) ($u + $d), (int) $user_id]); + } + + if ($is_traffic_log) { + (new HourlyUsage())->add((int) $user_id, (int) ($u + $d)); } $sum += $u + $d; diff --git a/src/Models/HourlyUsage.php b/src/Models/HourlyUsage.php new file mode 100644 index 0000000000..e38a4186d1 --- /dev/null +++ b/src/Models/HourlyUsage.php @@ -0,0 +1,46 @@ +where('user_id', $user_id)->where('date', $date)->first(); + + if ($exist_usage === null) { + $new_usage_array = array_fill(0, 24, 0); + $new_usage_array[$hour] = $usage; + $this->user_id = $user_id; + $this->date = $date; + $this->usage = json_encode($new_usage_array); + $this->save(); + } else { + $exist_usage_array = json_decode($exist_usage->usage, true); + $exist_usage_array[$hour] += $usage; + $exist_usage->usage = json_encode($exist_usage_array); + $exist_usage->save(); + } + } +} diff --git a/src/Models/User.php b/src/Models/User.php index d677b1ffad..4044779c6f 100644 --- a/src/Models/User.php +++ b/src/Models/User.php @@ -7,7 +7,6 @@ use App\Services\IM; use App\Utils\Hash; use App\Utils\Tools; -use Exception; use GuzzleHttp\Exception\GuzzleException; use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Query\Builder; @@ -16,7 +15,6 @@ use function date; use function is_null; use function md5; -use function random_int; use function round; use function time; use const PHP_EOL; @@ -292,7 +290,7 @@ public function lastUsedTrafficPercent(): float */ public function isAbleToCheckin(): bool { - return date('Ymd') !== date('Ymd', $this->last_check_in_time); + return date('Ymd') !== date('Ymd', $this->last_check_in_time) && ! $this->is_shadow_banned; } /** @@ -348,34 +346,6 @@ public function kill(): bool return $this->delete(); } - /** - * 签到 - */ - public function checkin(): array - { - $return = [ - 'ok' => true, - ]; - - if (! $this->isAbleToCheckin() || $this->is_shadow_banned) { - $return['ok'] = false; - $return['msg'] = '签到失败,请稍后再试'; - } else { - try { - $traffic = random_int((int) $_ENV['checkinMin'], (int) $_ENV['checkinMax']); - } catch (Exception $e) { - $traffic = 0; - } - - $this->transfer_enable += Tools::toMB($traffic); - $this->last_check_in_time = time(); - $this->save(); - $return['msg'] = '获得了 ' . $traffic . 'MB 流量.'; - } - - return $return; - } - public function unbindIM(): bool { $this->im_type = 0; diff --git a/src/Models/UserHourlyUsage.php b/src/Models/UserHourlyUsage.php deleted file mode 100644 index 7211fb56bb..0000000000 --- a/src/Models/UserHourlyUsage.php +++ /dev/null @@ -1,22 +0,0 @@ -where('is_inactive', 0)->count(); } + + public static function getUserHourlyUsage(int $user_id, string $date): array + { + $hourly_usage = (new HourlyUsage())->where('user_id', $user_id)->where('date', $date)->first(); + + return $hourly_usage ? json_decode($hourly_usage->usage, true) : array_fill(0, 24, 0); + } + + public static function getUserTodayHourlyUsage(int $user_id): array + { + $date = date('Y-m-d'); + + return self::getUserHourlyUsage($user_id, $date); + } } diff --git a/src/Services/Bot/Telegram/Callback.php b/src/Services/Bot/Telegram/Callback.php index 9add8bdbe6..1c36a2fb39 100644 --- a/src/Services/Bot/Telegram/Callback.php +++ b/src/Services/Bot/Telegram/Callback.php @@ -11,6 +11,7 @@ use App\Models\Payback; use App\Models\SubscribeLog; use App\Models\User; +use App\Services\Reward; use App\Services\Subscribe; use App\Utils\Tools; use GuzzleHttp\Exception\GuzzleException; @@ -892,8 +893,8 @@ public function getUserInviteKeyboard(): array $text = [ '你每邀请 1 位用户注册:', '', - '- 你会获得 ' . Config::obtain('invite_reg_money_reward') . 'G 流量奖励。', - '- 对方将获得 ' . Config::obtain('invite_reg_traffic_reward') . '元 初始账户余额。', + '- 你会获得 ' . Config::obtain('invite_reg_traffic_reward') . 'G 流量奖励。', + '- 对方将获得 ' . Config::obtain('invite_reg_money_reward') . '元 初始账户余额。', '- 对方支付账单时你会获得对方账单金额的 ' . Config::obtain('invite_reward_rate') * 100 . '% 的返利。', '', '已获得返利:' . $paybacks_sum . ' 元。', @@ -981,10 +982,20 @@ public function userInvite(): void */ public function userCheckin(): void { - $checkin = $this->user->checkin(); + if ($this->user->isAbleToCheckin()) { + $traffic = Reward::issueCheckinReward($this->user->id); + + if (! $traffic) { + $msg = '签到失败'; + } else { + $msg = '获得了 ' . $traffic . 'MB 流量.'; + } + } else { + $msg = '你今天已经签到过了'; + } $this->answerCallbackQuery([ - 'text' => $checkin['msg'], + 'text' => $msg, 'show_alert' => true, ]); // 回送信息 @@ -1006,7 +1017,7 @@ public function userCheckin(): void } $this->replyWithMessage([ - 'text' => $temp['text'] . PHP_EOL . PHP_EOL . $checkin['msg'], + 'text' => $temp['text'] . PHP_EOL . PHP_EOL . $msg, 'reply_to_message_id' => $this->message_id, 'parse_mode' => 'Markdown', 'reply_markup' => json_encode( diff --git a/src/Services/Bot/Telegram/Commands/CheckinCommand.php b/src/Services/Bot/Telegram/Commands/CheckinCommand.php index b107aafee7..239f23f2ab 100644 --- a/src/Services/Bot/Telegram/Commands/CheckinCommand.php +++ b/src/Services/Bot/Telegram/Commands/CheckinCommand.php @@ -6,6 +6,7 @@ use App\Models\Config; use App\Services\Bot\Telegram\Message; +use App\Services\Reward; use Telegram\Bot\Actions; use Telegram\Bot\Commands\Command; @@ -64,11 +65,21 @@ public function handle() ] ); } else { - $checkin = $user->checkin(); + if ($user->isAbleToCheckin()) { + $traffic = Reward::issueCheckinReward($this->user->id); + + if (! $traffic) { + $msg = '签到失败'; + } else { + $msg = '获得了 ' . $traffic . 'MB 流量.'; + } + } else { + $msg = '你今天已经签到过了'; + } // 回送信息 $response = $this->replyWithMessage( [ - 'text' => $checkin['msg'], + 'text' => $msg, 'parse_mode' => 'Markdown', 'reply_to_message_id' => $message->getMessageId(), ] diff --git a/src/Services/Cron.php b/src/Services/Cron.php index 35f7702bc6..37374ea23b 100644 --- a/src/Services/Cron.php +++ b/src/Services/Cron.php @@ -8,6 +8,7 @@ use App\Models\Config; use App\Models\DetectLog; use App\Models\EmailQueue; +use App\Models\HourlyUsage; use App\Models\Invoice; use App\Models\Node; use App\Models\OnlineLog; @@ -15,7 +16,6 @@ use App\Models\Paylist; use App\Models\SubscribeLog; use App\Models\User; -use App\Models\UserHourlyUsage; use App\Services\IM\Telegram; use App\Utils\Tools; use DateTime; @@ -34,31 +34,6 @@ final class Cron { - public static function addTrafficLog(): void - { - $users = User::all(); - - foreach ($users as $user) { - $transfer_total = $user->transfer_total; - $transfer_total_last = (new UserHourlyUsage())->where('user_id', $user->id)->orderBy('id', 'desc')->first(); - - if ($transfer_total_last === null) { - $transfer_total_last = 0; - } else { - $transfer_total_last = $transfer_total_last->traffic; - } - - $trafficlog = new UserHourlyUsage(); - $trafficlog->user_id = $user->id; - $trafficlog->traffic = $transfer_total; - $trafficlog->hourly_usage = $transfer_total - $transfer_total_last; - $trafficlog->datetime = time(); - $trafficlog->save(); - } - - echo Tools::toDateTime(time()) . ' 流量记录处理完成' . PHP_EOL; - } - public static function cleanDb(): void { (new SubscribeLog())->where( @@ -66,7 +41,11 @@ public static function cleanDb(): void '<', time() - 86400 * Config::obtain('subscribe_log_retention_days') )->delete(); - (new UserHourlyUsage())->where('datetime', '<', time() - 86400 * Config::obtain('traffic_log_retention_days'))->delete(); + (new HourlyUsage())->where( + 'date', + '<', + date('Y-m-d', time() - 86400 * Config::obtain('traffic_log_retention_days')) + )->delete(); (new DetectLog())->where('datetime', '<', time() - 86400 * 3)->delete(); (new EmailQueue())->where('time', '<', time() - 86400)->delete(); (new OnlineLog())->where('last_time', '<', time() - 86400)->delete(); @@ -430,7 +409,8 @@ public static function resetTodayTraffic(): void public static function resetFreeUserTraffic(): void { - $freeUsers = (new User())->where('class', 0)->where('auto_reset_day', date('d'))->get(); + $freeUsers = (new User())->where('class', 0) + ->where('auto_reset_day', date('d'))->get(); foreach ($freeUsers as $user) { try { @@ -455,7 +435,8 @@ public static function resetFreeUserTraffic(): void public static function sendDailyFinanceMail(): void { $today = strtotime('00:00:00'); - $paylists = (new Paylist())->where('status', 1)->whereBetween('datetime', [strtotime('-1 day', $today), $today])->get(); + $paylists = (new Paylist())->where('status', 1) + ->whereBetween('datetime', [strtotime('-1 day', $today), $today])->get(); $text_html = ''; foreach ($paylists as $paylist) { diff --git a/src/Services/Gateway/AopF2F.php b/src/Services/Gateway/AopF2F.php index 734cc21a15..fef069984b 100644 --- a/src/Services/Gateway/AopF2F.php +++ b/src/Services/Gateway/AopF2F.php @@ -98,17 +98,11 @@ public function notify($request, $response, $args): ResponseInterface if ($aliResponse->isPaid()) { $this->postPayment($pid); - - return $response->withJson([ - 'ret' => 1, - 'msg' => '支付成功', - ]); + // https://opendocs.alipay.com/open/194/103296#%E5%BC%82%E6%AD%A5%E9%80%9A%E7%9F%A5%E7%89%B9%E6%80%A7 + return $response->write('success'); } - return $response->withJson([ - 'ret' => 0, - 'msg' => '支付失败', - ]); + return $response->write('failed'); } /** diff --git a/src/Services/Gateway/Base.php b/src/Services/Gateway/Base.php index 78acc26f53..dcf740aba7 100644 --- a/src/Services/Gateway/Base.php +++ b/src/Services/Gateway/Base.php @@ -80,7 +80,7 @@ public function postPayment($trade_no): void $user = (new User())->find($paylist?->userid); // 返利 - if ($user !== null && $user->ref_by > 0 && Config::obtain('invitation_mode') === 'reward') { + if ($user !== null && $user->ref_by > 0 && Config::obtain('invite_mode') === 'reward') { Reward::issuePaybackReward($user->id, $user->ref_by, $paylist->total, $paylist->invoice_id); } } @@ -104,9 +104,11 @@ protected static function getActiveGateway($key): bool { $payment_gateways = (new Config())->where('item', 'payment_gateway')->first(); $active_gateways = json_decode($payment_gateways->value); + if (in_array($key, $active_gateways)) { return true; } + return false; } } diff --git a/src/Services/Reward.php b/src/Services/Reward.php index c8994411b6..110fde884d 100644 --- a/src/Services/Reward.php +++ b/src/Services/Reward.php @@ -9,6 +9,9 @@ use App\Models\User; use App\Models\UserMoneyLog; use App\Utils\Tools; +use Exception; +use function random_int; +use function time; final class Reward { @@ -114,4 +117,34 @@ public static function issueRegReward($user_id, $ref_user_id): void } } } + + public static function issueCheckinReward($user_id): int|false + { + $user = (new User())->where('id', $user_id)->first(); + + if ($user === null) { + return false; + } + + $checkin_min = Config::obtain('checkin_min'); + $checkin_max = Config::obtain('checkin_max'); + + if ($checkin_min === $checkin_max) { + $traffic = $checkin_min; + } else { + try { + $traffic = random_int($checkin_min, $checkin_max); + } catch (Exception $e) { + $traffic = 0; + } + } + + if ($traffic !== 0) { + $user->transfer_enable += Tools::toMB($traffic); + $user->last_check_in_time = time(); + $user->save(); + } + + return $traffic; + } } diff --git a/src/Services/View.php b/src/Services/View.php index 89a9521169..283b319c76 100755 --- a/src/Services/View.php +++ b/src/Services/View.php @@ -63,10 +63,6 @@ public static function getConfig(): array 'appName' => $_ENV['appName'], 'baseUrl' => $_ENV['baseUrl'], - 'enable_checkin' => $_ENV['enable_checkin'], - 'checkinMin' => $_ENV['checkinMin'], - 'checkinMax' => $_ENV['checkinMax'], - 'jump_delay' => $_ENV['jump_delay'], 'enable_kill' => $_ENV['enable_kill'], diff --git a/src/Utils/Tools.php b/src/Utils/Tools.php index 6d715b473b..ce34c30f15 100644 --- a/src/Utils/Tools.php +++ b/src/Utils/Tools.php @@ -189,9 +189,9 @@ public static function toGB($traffic): int * * @return float */ - public static function flowToGB($traffic): float + public static function flowToMB($traffic): float { - return round($traffic / 1073741824, 2); + return round($traffic / 1048576, 2); } /** @@ -199,9 +199,9 @@ public static function flowToGB($traffic): float * * @return float */ - public static function flowToMB($traffic): float + public static function flowToGB($traffic): float { - return round($traffic / 1048576, 2); + return round($traffic / 1073741824, 2); } public static function genSubToken(): string
金额用户ID用户名充值时间