Browse Source

Merge pull request #2341 from SSPanel-UIM/dev

Dev 20240123
M1Screw 1 year ago
parent
commit
d34c416abd

+ 3 - 5
app/routes.php

@@ -213,11 +213,9 @@ return static function (Slim\App $app): void {
         // 订阅日志
         $group->get('/subscribe', App\Controllers\Admin\SubLogController::class . ':index');
         $group->post('/subscribe/ajax', App\Controllers\Admin\SubLogController::class . ':ajax');
-        // 邀请日志
-        $group->get('/invite', App\Controllers\Admin\InviteController::class . ':index');
-        $group->post('/invite/update_invite', App\Controllers\Admin\InviteController::class . ':update');
-        $group->post('/invite/add_invite', App\Controllers\Admin\InviteController::class . ':add');
-        $group->post('/invite/ajax', App\Controllers\Admin\InviteController::class . ':ajax');
+        // 返利日志
+        $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');

+ 42 - 42
composer.lock

@@ -123,16 +123,16 @@
         },
         {
             "name": "aws/aws-sdk-php",
-            "version": "3.296.1",
+            "version": "3.296.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/aws/aws-sdk-php.git",
-                "reference": "38e47bbd3b5f76f008dd71c8a68545f9e4e47b6b"
+                "reference": "11d0a94f8b2539d587e2f6db7c2fa8e39fe78a67"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/38e47bbd3b5f76f008dd71c8a68545f9e4e47b6b",
-                "reference": "38e47bbd3b5f76f008dd71c8a68545f9e4e47b6b",
+                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/11d0a94f8b2539d587e2f6db7c2fa8e39fe78a67",
+                "reference": "11d0a94f8b2539d587e2f6db7c2fa8e39fe78a67",
                 "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.1"
+                "source": "https://github.com/aws/aws-sdk-php/tree/3.296.6"
             },
-            "time": "2024-01-14T05:20:33+00:00"
+            "time": "2024-01-19T19:14:55+00:00"
         },
         {
             "name": "bacon/bacon-qr-code",
@@ -1200,7 +1200,7 @@
         },
         {
             "name": "illuminate/collections",
-            "version": "v10.40.0",
+            "version": "v10.41.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/collections.git",
@@ -1255,7 +1255,7 @@
         },
         {
             "name": "illuminate/conditionable",
-            "version": "v10.40.0",
+            "version": "v10.41.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/conditionable.git",
@@ -1301,7 +1301,7 @@
         },
         {
             "name": "illuminate/container",
-            "version": "v10.40.0",
+            "version": "v10.41.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/container.git",
@@ -1352,16 +1352,16 @@
         },
         {
             "name": "illuminate/contracts",
-            "version": "v10.40.0",
+            "version": "v10.41.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/contracts.git",
-                "reference": "0b26d49d4bb0986da1ca30bcc701d5c22722576b"
+                "reference": "8d7152c4a1f5d9cf7da3e8b71f23e4556f6138ac"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/illuminate/contracts/zipball/0b26d49d4bb0986da1ca30bcc701d5c22722576b",
-                "reference": "0b26d49d4bb0986da1ca30bcc701d5c22722576b",
+                "url": "https://api.github.com/repos/illuminate/contracts/zipball/8d7152c4a1f5d9cf7da3e8b71f23e4556f6138ac",
+                "reference": "8d7152c4a1f5d9cf7da3e8b71f23e4556f6138ac",
                 "shasum": ""
             },
             "require": {
@@ -1396,20 +1396,20 @@
                 "issues": "https://github.com/laravel/framework/issues",
                 "source": "https://github.com/laravel/framework"
             },
-            "time": "2023-12-28T16:46:25+00:00"
+            "time": "2024-01-15T18:52:32+00:00"
         },
         {
             "name": "illuminate/database",
-            "version": "v10.40.0",
+            "version": "v10.41.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/database.git",
-                "reference": "d41a5b7b1dc67bf640f16bf50c376b29ba575da5"
+                "reference": "f7a7d35dec5e7c6c4711cde31119f67d06846459"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/illuminate/database/zipball/d41a5b7b1dc67bf640f16bf50c376b29ba575da5",
-                "reference": "d41a5b7b1dc67bf640f16bf50c376b29ba575da5",
+                "url": "https://api.github.com/repos/illuminate/database/zipball/f7a7d35dec5e7c6c4711cde31119f67d06846459",
+                "reference": "f7a7d35dec5e7c6c4711cde31119f67d06846459",
                 "shasum": ""
             },
             "require": {
@@ -1469,11 +1469,11 @@
                 "issues": "https://github.com/laravel/framework/issues",
                 "source": "https://github.com/laravel/framework"
             },
-            "time": "2024-01-07T15:44:56+00:00"
+            "time": "2024-01-16T14:41:20+00:00"
         },
         {
             "name": "illuminate/macroable",
-            "version": "v10.40.0",
+            "version": "v10.41.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/macroable.git",
@@ -1519,16 +1519,16 @@
         },
         {
             "name": "illuminate/pagination",
-            "version": "v10.40.0",
+            "version": "v10.41.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/pagination.git",
-                "reference": "7447caf65da6b183a3c247b78942c7633c059bd4"
+                "reference": "b42a851e037984e38f8964d1a96d15b0302bebfc"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/illuminate/pagination/zipball/7447caf65da6b183a3c247b78942c7633c059bd4",
-                "reference": "7447caf65da6b183a3c247b78942c7633c059bd4",
+                "url": "https://api.github.com/repos/illuminate/pagination/zipball/b42a851e037984e38f8964d1a96d15b0302bebfc",
+                "reference": "b42a851e037984e38f8964d1a96d15b0302bebfc",
                 "shasum": ""
             },
             "require": {
@@ -1565,20 +1565,20 @@
                 "issues": "https://github.com/laravel/framework/issues",
                 "source": "https://github.com/laravel/framework"
             },
-            "time": "2024-01-03T22:51:06+00:00"
+            "time": "2024-01-12T17:17:46+00:00"
         },
         {
             "name": "illuminate/support",
-            "version": "v10.40.0",
+            "version": "v10.41.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/support.git",
-                "reference": "76a79337200b06b4b2a7fe93902aa770d6dcec03"
+                "reference": "1355b7d28ebb802e95bffcb27417862961382c52"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/illuminate/support/zipball/76a79337200b06b4b2a7fe93902aa770d6dcec03",
-                "reference": "76a79337200b06b4b2a7fe93902aa770d6dcec03",
+                "url": "https://api.github.com/repos/illuminate/support/zipball/1355b7d28ebb802e95bffcb27417862961382c52",
+                "reference": "1355b7d28ebb802e95bffcb27417862961382c52",
                 "shasum": ""
             },
             "require": {
@@ -1636,7 +1636,7 @@
                 "issues": "https://github.com/laravel/framework/issues",
                 "source": "https://github.com/laravel/framework"
             },
-            "time": "2024-01-07T16:54:08+00:00"
+            "time": "2024-01-15T18:53:10+00:00"
         },
         {
             "name": "irazasyed/telegram-bot-sdk",
@@ -6992,16 +6992,16 @@
         },
         {
             "name": "friendsofphp/php-cs-fixer",
-            "version": "v3.47.0",
+            "version": "v3.48.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
-                "reference": "184dd992fe49169a18300dba4435212db55220f7"
+                "reference": "a92472c6fb66349de25211f31c77eceae3df024e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/184dd992fe49169a18300dba4435212db55220f7",
-                "reference": "184dd992fe49169a18300dba4435212db55220f7",
+                "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/a92472c6fb66349de25211f31c77eceae3df024e",
+                "reference": "a92472c6fb66349de25211f31c77eceae3df024e",
                 "shasum": ""
             },
             "require": {
@@ -7071,7 +7071,7 @@
             ],
             "support": {
                 "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
-                "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.47.0"
+                "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.48.0"
             },
             "funding": [
                 {
@@ -7079,7 +7079,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2024-01-15T15:35:57+00:00"
+            "time": "2024-01-19T21:44:39+00:00"
         },
         {
             "name": "justinrainbow/json-schema",
@@ -7994,16 +7994,16 @@
         },
         {
             "name": "phpunit/phpunit",
-            "version": "10.5.7",
+            "version": "10.5.9",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/phpunit.git",
-                "reference": "e5c5b397a95cb0db013270a985726fcae93e61b8"
+                "reference": "0bd663704f0165c9e76fe4f06ffa6a1ca727fdbe"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e5c5b397a95cb0db013270a985726fcae93e61b8",
-                "reference": "e5c5b397a95cb0db013270a985726fcae93e61b8",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0bd663704f0165c9e76fe4f06ffa6a1ca727fdbe",
+                "reference": "0bd663704f0165c9e76fe4f06ffa6a1ca727fdbe",
                 "shasum": ""
             },
             "require": {
@@ -8075,7 +8075,7 @@
             "support": {
                 "issues": "https://github.com/sebastianbergmann/phpunit/issues",
                 "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
-                "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.7"
+                "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.9"
             },
             "funding": [
                 {
@@ -8091,7 +8091,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-01-14T16:40:30+00:00"
+            "time": "2024-01-22T14:35:40+00:00"
         },
         {
             "name": "psr/cache",

+ 25 - 35
config/settings.json

@@ -1271,83 +1271,73 @@
     },
     {
         "id": null,
-        "item": "invitation_to_register_balance_reward",
-        "value": "1",
+        "item": "invite_reg_money_reward",
+        "value": "0",
         "class": "ref",
         "is_public": 1,
         "type": "int",
-        "default": "1",
+        "default": "0",
         "mark": "邀请注册余额奖励(元)"
     },
     {
         "id": null,
-        "item": "invitation_to_register_traffic_reward",
-        "value": "10",
+        "item": "invite_reg_traffic_reward",
+        "value": "0",
         "class": "ref",
         "is_public": 1,
         "type": "int",
-        "default": "10",
+        "default": "0",
         "mark": "邀请注册流量奖励(GB)"
     },
     {
         "id": null,
-        "item": "invitation_mode",
-        "value": "after_paid",
+        "item": "invite_mode",
+        "value": "reg_only",
         "class": "ref",
         "is_public": 0,
         "type": "string",
-        "default": "after_paid",
+        "default": "reg_only",
         "mark": "邀请模式"
     },
     {
         "id": null,
-        "item": "invite_rebate_mode",
-        "value": "limit_amount",
+        "item": "invite_reward_mode",
+        "value": "reward_count",
         "class": "ref",
         "is_public": 0,
         "type": "string",
-        "default": "limit_amount",
+        "default": "reward_count",
         "mark": "返利模式"
     },
     {
         "id": null,
-        "item": "rebate_frequency_limit",
-        "value": "3",
+        "item": "invite_reward_rate",
+        "value": "0.2",
         "class": "ref",
-        "is_public": 0,
+        "is_public": 1,
         "type": "string",
-        "default": "3",
-        "mark": "返利总次数限制"
+        "default": "0.2",
+        "mark": "返利比例"
     },
     {
         "id": null,
-        "item": "rebate_amount_limit",
-        "value": "100",
+        "item": "invite_reward_count_limit",
+        "value": "1",
         "class": "ref",
         "is_public": 0,
-        "type": "int",
-        "default": "100",
-        "mark": "返利总金额限制"
-    },
-    {
-        "id": null,
-        "item": "rebate_ratio",
-        "value": "0.2",
-        "class": "ref",
-        "is_public": 1,
         "type": "string",
-        "default": "0.2",
-        "mark": "返利比例"
+        "default": "1",
+        "mark": "返利次数限制"
     },
     {
         "id": null,
-        "item": "rebate_time_range_limit",
-        "value": "180",
+        "item": "invite_reward_total_limit",
+        "value": "50",
         "class": "ref",
         "is_public": 0,
         "type": "int",
-        "default": "180",
-        "mark": "返利时间范围限制(天)"
+        "default": "50",
+        "mark": "返利金额限制"
     },
     {
         "id": null,

+ 1 - 1
db/migrations/2023020100-init.php

@@ -198,6 +198,7 @@ return new class() implements MigrationInterface {
                 `userid` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '用户ID',
                 `ref_by` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '推荐人ID',
                 `ref_get` decimal(12,2) unsigned NOT NULL DEFAULT 0 COMMENT '推荐人获得金额',
+                `invoice_id` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '账单ID',
                 `datetime` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '创建时间',
                 PRIMARY KEY (`id`)
             ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
@@ -276,7 +277,6 @@ return new class() implements MigrationInterface {
                 `last_check_in_time` int(11) unsigned DEFAULT 0 COMMENT '最后签到时间',
                 `last_login_time` int(11) unsigned DEFAULT 0 COMMENT '最后登录时间',
                 `reg_date` datetime NOT NULL DEFAULT '1989-06-04 00:05:00' COMMENT '注册时间',
-                `invite_num` int(11) NOT NULL DEFAULT 0 COMMENT '可用邀请次数',
                 `money` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '账户余额',
                 `ref_by` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '邀请人ID',
                 `method` varchar(255) NOT NULL DEFAULT 'aes-128-gcm' COMMENT 'Shadowsocks加密方式',

+ 0 - 1
db/migrations/2023060300-add_user_locale_and_update_data_type.php

@@ -23,7 +23,6 @@ return new class() implements MigrationInterface {
         ALTER TABLE user MODIFY COLUMN `all_detect_number` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '累计违规次数';
         ALTER TABLE user MODIFY COLUMN `last_check_in_time` int(11) unsigned DEFAULT 0 COMMENT '最后签到时间';
         ALTER TABLE user MODIFY COLUMN `reg_date` datetime NOT NULL DEFAULT '1989-06-04 00:05:00' COMMENT '注册时间';
-        ALTER TABLE user MODIFY COLUMN `invite_num` int(11) NOT NULL DEFAULT 0 COMMENT '可用邀请次数';
         ALTER TABLE user MODIFY COLUMN `money` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '账户余额';
         ALTER TABLE user MODIFY COLUMN `ref_by` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '邀请人ID';
         ALTER TABLE user MODIFY COLUMN `method` varchar(255) NOT NULL DEFAULT 'aes-128-gcm' COMMENT 'Shadowsocks加密方式';

+ 26 - 0
db/migrations/2024012000-add_payback_invoice_id.php

@@ -0,0 +1,26 @@
+<?php
+
+declare(strict_types=1);
+
+use App\Interfaces\MigrationInterface;
+use App\Services\DB;
+
+return new class() implements MigrationInterface {
+    public function up(): int
+    {
+        DB::getPdo()->exec("
+            ALTER TABLE payback ADD COLUMN IF NOT EXISTS `invoice_id` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '账单ID';
+        ");
+
+        return 2024012000;
+    }
+
+    public function down(): int
+    {
+        DB::getPdo()->exec('
+            ALTER TABLE payback DROP COLUMN IF EXISTS `invoice_id`;
+        ');
+
+        return 2023120700;
+    }
+};

+ 26 - 0
db/migrations/2024012300-remove_user_invite_num.php

@@ -0,0 +1,26 @@
+<?php
+
+declare(strict_types=1);
+
+use App\Interfaces\MigrationInterface;
+use App\Services\DB;
+
+return new class() implements MigrationInterface {
+    public function up(): int
+    {
+        DB::getPdo()->exec('
+            ALTER TABLE user DROP COLUMN IF EXISTS `invite_num`;
+        ');
+
+        return 2024012300;
+    }
+
+    public function down(): int
+    {
+        DB::getPdo()->exec("
+            ALTER TABLE user ADD COLUMN IF NOT EXISTS `invite_num` int(11) NOT NULL DEFAULT 0 COMMENT '可用邀请次数';
+        ");
+
+        return 2024012000;
+    }
+};

+ 1 - 1
resources/views/tabler/admin/announcement/create.tpl

@@ -1,6 +1,6 @@
 {include file='admin/header.tpl'}
 
-<script src="//cdnjs.cloudflare.com/ajax/libs/tinymce/6.8.0/tinymce.min.js"></script>
+<script src="//cdnjs.cloudflare.com/ajax/libs/tinymce/6.8.2/tinymce.min.js"></script>
 
 <div class="page-wrapper">
     <div class="container-xl">

+ 1 - 1
resources/views/tabler/admin/announcement/edit.tpl

@@ -1,6 +1,6 @@
 {include file='admin/header.tpl'}
 
-<script src="//cdnjs.cloudflare.com/ajax/libs/tinymce/6.8.0/tinymce.min.js"></script>
+<script src="//cdnjs.cloudflare.com/ajax/libs/tinymce/6.8.2/tinymce.min.js"></script>
 
 <div class="page-wrapper">
     <div class="container-xl">

+ 1 - 1
resources/views/tabler/admin/docs/create.tpl

@@ -1,6 +1,6 @@
 {include file='admin/header.tpl'}
 
-<script src="//cdnjs.cloudflare.com/ajax/libs/tinymce/6.8.0/tinymce.min.js"></script>
+<script src="//cdnjs.cloudflare.com/ajax/libs/tinymce/6.8.2/tinymce.min.js"></script>
 
 <div class="page-wrapper">
     <div class="container-xl">

+ 1 - 1
resources/views/tabler/admin/docs/edit.tpl

@@ -1,6 +1,6 @@
 {include file='admin/header.tpl'}
 
-<script src="//cdnjs.cloudflare.com/ajax/libs/tinymce/6.8.0/tinymce.min.js"></script>
+<script src="//cdnjs.cloudflare.com/ajax/libs/tinymce/6.8.2/tinymce.min.js"></script>
 
 <div class="page-wrapper">
     <div class="container-xl">

+ 2 - 2
resources/views/tabler/admin/header.tpl

@@ -189,9 +189,9 @@
                                     <i class="ti ti-rss"></i>&nbsp;
                                     订阅
                                 </a>
-                                <a class="dropdown-item" href="/admin/invite">
+                                <a class="dropdown-item" href="/admin/payback">
                                     <i class="ti ti-friends"></i>&nbsp;
-                                    邀请
+                                    返利
                                 </a>
                                 <a class="dropdown-item" href="/admin/money">
                                     <i class="ti ti-coin"></i>&nbsp;

+ 0 - 253
resources/views/tabler/admin/log/invite.tpl

@@ -1,253 +0,0 @@
-{include file='admin/header.tpl'}
-
-<div class="page-wrapper">
-    <div class="container-xl">
-        <div class="page-header d-print-none text-white">
-            <div class="row align-items-center">
-                <div class="col">
-                    <h2 class="page-title">
-                        <span class="home-title">返利记录</span>
-                    </h2>
-                    <div class="page-pretitle my-3">
-                        <span class="home-subtitle">查看用户的返利记录</span>
-                    </div>
-                </div>
-                <div class="col-auto">
-                    <div class="btn-list">
-                        <button href="#" class="btn btn-primary" data-bs-toggle="modal"
-                                data-bs-target="#update-invite-dialog">
-                            <i class="icon ti ti-user-edit"></i>
-                            修改邀请者
-                        </button>
-                        <button href="#" class="btn btn-primary" data-bs-toggle="modal"
-                                data-bs-target="#add-invite-dialog">
-                            <i class="icon ti ti-plus"></i>
-                            添加邀请数量
-                        </button>
-                    </div>
-                </div>
-            </div>
-        </div>
-    </div>
-    <div class="page-body">
-        <div class="container-xl">
-            <div class="row row-deck row-cards">
-                <div class="col-12">
-                    <div class="card">
-                        <div class="table-responsive">
-                            <table id="data-table" class="table card-table table-vcenter text-nowrap datatable">
-                                <thead>
-                                <tr>
-                                    {foreach $details['field'] as $key => $value}
-                                        <th>{$value}</th>
-                                    {/foreach}
-                                </tr>
-                                </thead>
-                            </table>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>
-    </div>
-
-    <div class="modal modal-blur fade" id="update-invite-dialog" tabindex="-1" role="dialog" aria-hidden="true">
-        <div class="modal-dialog modal-dialog-centered modal-dialog-scrollable" role="document">
-            <div class="modal-content">
-                <div class="modal-header">
-                    <h5 class="modal-title">修改邀请者</h5>
-                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-                </div>
-                <div class="modal-body">
-                    {foreach $details['update_dialog'] as $from}
-                        {if $from['type'] === 'input'}
-                            <div class="form-group mb-3 row">
-                                <label class="form-label col-3 col-form-label">{$from['info']}</label>
-                                <div class="col">
-                                    <input id="{$from['id']}" type="text" class="form-control"
-                                           placeholder="{$from['placeholder']}">
-                                </div>
-                            </div>
-                        {/if}
-                        {if $from['type'] === 'textarea'}
-                            <div class="form-group mb-3 row">
-                                <label class="form-label col-3 col-form-label">{$from['info']}</label>
-                                <textarea id="{$from['id']}" class="col form-control" rows="{$from['rows']}"
-                                          placeholder="{$from['placeholder']}"></textarea>
-                            </div>
-                        {/if}
-                        {if $from['type'] === 'select'}
-                            <div class="form-group mb-3 row">
-                                <label class="form-label col-3 col-form-label">{$from['info']}</label>
-                                <div class="col">
-                                    <select id="{$from['id']}" class="col form-select">
-                                        {foreach $from['select'] as $key => $value}
-                                            <option value="{$key}">{$value}</option>
-                                        {/foreach}
-                                    </select>
-                                </div>
-                            </div>
-                        {/if}
-                    {/foreach}
-                </div>
-                <div class="modal-footer">
-                    <button type="button" class="btn me-auto" data-bs-dismiss="modal">取消</button>
-                    <button id="update-invite-button" type="button" class="btn btn-primary" data-bs-dismiss="modal">
-                        提交
-                    </button>
-                </div>
-            </div>
-        </div>
-    </div>
-
-    <div class="modal modal-blur fade" id="add-invite-dialog" tabindex="-1" role="dialog" aria-hidden="true">
-        <div class="modal-dialog modal-dialog-centered modal-dialog-scrollable" role="document">
-            <div class="modal-content">
-                <div class="modal-header">
-                    <h5 class="modal-title">添加邀请数量</h5>
-                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-                </div>
-                <div class="modal-body">
-                    {foreach $details['add_dialog'] as $from}
-                        {if $from['type'] === 'input'}
-                            <div class="form-group mb-3 row">
-                                <label class="form-label col-3 col-form-label">{$from['info']}</label>
-                                <div class="col">
-                                    <input id="{$from['id']}" type="text" class="form-control"
-                                           placeholder="{$from['placeholder']}">
-                                </div>
-                            </div>
-                        {/if}
-                        {if $from['type'] === 'textarea'}
-                            <div class="form-group mb-3 row">
-                                <label class="form-label col-3 col-form-label">{$from['info']}</label>
-                                <textarea id="{$from['id']}" class="col form-control" rows="{$from['rows']}"
-                                          placeholder="{$from['placeholder']}"></textarea>
-                            </div>
-                        {/if}
-                        {if $from['type'] === 'select'}
-                            <div class="form-group mb-3 row">
-                                <label class="form-label col-3 col-form-label">{$from['info']}</label>
-                                <div class="col">
-                                    <select id="{$from['id']}" class="col form-select">
-                                        {foreach $from['select'] as $key => $value}
-                                            <option value="{$key}">{$value}</option>
-                                        {/foreach}
-                                    </select>
-                                </div>
-                            </div>
-                        {/if}
-                    {/foreach}
-                </div>
-                <div class="modal-footer">
-                    <button type="button" class="btn me-auto" data-bs-dismiss="modal">取消</button>
-                    <button id="add-invite-button" type="button" class="btn btn-primary" data-bs-dismiss="modal">提交
-                    </button>
-                </div>
-            </div>
-        </div>
-    </div>
-
-    <script>
-        let table = new DataTable('#data-table', {
-            ajax: {
-                url: '/admin/invite/ajax',
-                type: 'POST',
-                dataSrc: 'paybacks'
-            },
-            "autoWidth": false,
-            'iDisplayLength': 10,
-            'scrollX': true,
-            'order': [
-                [0, 'desc']
-            ],
-            columns: [
-                {foreach $details['field'] as $key => $value}
-                {
-                    data: '{$key}'
-                },
-                {/foreach}
-            ],
-            "dom": "<'row px-3 py-3'<'col-sm-12 col-md-6'l><'col-sm-12 col-md-6'f>>" +
-                "<'row'<'col-sm-12'tr>>" +
-                "<'row card-footer d-flex align-items-center'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>",
-            language: {
-                "sProcessing": "处理中...",
-                "sLengthMenu": "显示 _MENU_ 条",
-                "sZeroRecords": "没有匹配结果",
-                "sInfo": "第 _START_ 至 _END_ 项结果,共 _TOTAL_ 项",
-                "sInfoEmpty": "第 0 至 0 项结果,共 0 项",
-                "sInfoFiltered": "(在 _MAX_ 项中查找)",
-                "sInfoPostFix": "",
-                "sSearch": "<i class=\"ti ti-search\"></i> ",
-                "sUrl": "",
-                "sEmptyTable": "表中数据为空",
-                "sLoadingRecords": "载入中...",
-                "sInfoThousands": ",",
-                "oPaginate": {
-                    "sFirst": "首页",
-                    "sPrevious": "<i class=\"ti ti-arrow-left\"></i>",
-                    "sNext": "<i class=\"ti ti-arrow-right\"></i>",
-                    "sLast": "末页"
-                },
-                "oAria": {
-                    "sSortAscending": ": 以升序排列此列",
-                    "sSortDescending": ": 以降序排列此列"
-                }
-            }
-        });
-
-        $("#update-invite-button").click(function () {
-            $.ajax({
-                type: "POST",
-                url: "/admin/invite/update_invite",
-                dataType: "json",
-                data: {
-                    {foreach $details['update_dialog'] as $from}
-                    {$from['id']}: $('#{$from['id']}').val(),
-                    {/foreach}
-                },
-                success: function (data) {
-                    if (data.ret === 1) {
-                        $('#success-message').text(data.msg);
-                        $('#success-dialog').modal('show');
-                        reloadTableAjax();
-                    } else {
-                        $('#fail-message').text(data.msg);
-                        $('#fail-dialog').modal('show');
-                    }
-                }
-            })
-        });
-
-        $("#add-invite-button").click(function () {
-            $.ajax({
-                type: "POST",
-                url: "/admin/invite/add_invite",
-                dataType: "json",
-                data: {
-                    {foreach $details['add_dialog'] as $from}
-                    {$from['id']}: $('#{$from['id']}').val(),
-                    {/foreach}
-                },
-                success: function (data) {
-                    if (data.ret === 1) {
-                        $('#success-message').text(data.msg);
-                        $('#success-dialog').modal('show');
-                        reloadTableAjax();
-                    } else {
-                        $('#fail-message').text(data.msg);
-                        $('#fail-dialog').modal('show');
-                    }
-                }
-            })
-        });
-
-        function loadTable() {
-            table;
-        }
-
-        loadTable();
-    </script>
-
-    {include file='admin/footer.tpl'}

+ 96 - 0
resources/views/tabler/admin/log/payback.tpl

@@ -0,0 +1,96 @@
+{include file='admin/header.tpl'}
+
+<div class="page-wrapper">
+    <div class="container-xl">
+        <div class="page-header d-print-none text-white">
+            <div class="row align-items-center">
+                <div class="col">
+                    <h2 class="page-title">
+                        <span class="home-title">返利记录</span>
+                    </h2>
+                    <div class="page-pretitle my-3">
+                        <span class="home-subtitle">查看用户的返利记录</span>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="page-body">
+        <div class="container-xl">
+            <div class="row row-deck row-cards">
+                <div class="col-12">
+                    <div class="card">
+                        <div class="table-responsive">
+                            <table id="data-table" class="table card-table table-vcenter text-nowrap datatable">
+                                <thead>
+                                <tr>
+                                    {foreach $details['field'] as $key => $value}
+                                        <th>{$value}</th>
+                                    {/foreach}
+                                </tr>
+                                </thead>
+                            </table>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <script>
+        let table = new DataTable('#data-table', {
+            ajax: {
+                url: '/admin/payback/ajax',
+                type: 'POST',
+                dataSrc: 'paybacks'
+            },
+            "autoWidth": false,
+            'iDisplayLength': 10,
+            'scrollX': true,
+            'order': [
+                [0, 'desc']
+            ],
+            columns: [
+                {foreach $details['field'] as $key => $value}
+                {
+                    data: '{$key}'
+                },
+                {/foreach}
+            ],
+            "dom": "<'row px-3 py-3'<'col-sm-12 col-md-6'l><'col-sm-12 col-md-6'f>>" +
+                "<'row'<'col-sm-12'tr>>" +
+                "<'row card-footer d-flex align-items-center'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>",
+            language: {
+                "sProcessing": "处理中...",
+                "sLengthMenu": "显示 _MENU_ 条",
+                "sZeroRecords": "没有匹配结果",
+                "sInfo": "第 _START_ 至 _END_ 项结果,共 _TOTAL_ 项",
+                "sInfoEmpty": "第 0 至 0 项结果,共 0 项",
+                "sInfoFiltered": "(在 _MAX_ 项中查找)",
+                "sInfoPostFix": "",
+                "sSearch": "<i class=\"ti ti-search\"></i> ",
+                "sUrl": "",
+                "sEmptyTable": "表中数据为空",
+                "sLoadingRecords": "载入中...",
+                "sInfoThousands": ",",
+                "oPaginate": {
+                    "sFirst": "首页",
+                    "sPrevious": "<i class=\"ti ti-arrow-left\"></i>",
+                    "sNext": "<i class=\"ti ti-arrow-right\"></i>",
+                    "sLast": "末页"
+                },
+                "oAria": {
+                    "sSortAscending": ": 以升序排列此列",
+                    "sSortDescending": ": 以降序排列此列"
+                }
+            }
+        });
+
+        function loadTable() {
+            table;
+        }
+
+        loadTable();
+    </script>
+
+    {include file='admin/footer.tpl'}

+ 24 - 39
resources/views/tabler/admin/setting/ref.tpl

@@ -45,17 +45,17 @@
                                         <div class="form-group mb-3 row">
                                             <label class="form-label col-3 col-form-label">被邀请者初始账户余额(元)</label>
                                             <div class="col">
-                                                <input id="invitation_to_register_balance_reward" type="text"
+                                                <input id="invite_reg_money_reward" type="text"
                                                        class="form-control"
-                                                       value="{$settings['invitation_to_register_balance_reward']}">
+                                                       value="{$settings['invite_reg_money_reward']}">
                                             </div>
                                         </div>
                                         <div class="form-group mb-3 row">
                                             <label class="form-label col-3 col-form-label">邀请者流量奖励(GB)</label>
                                             <div class="col">
-                                                <input id="invitation_to_register_traffic_reward" type="text"
+                                                <input id="invite_reg_traffic_reward" type="text"
                                                        class="form-control"
-                                                       value="{$settings['invitation_to_register_traffic_reward']}">
+                                                       value="{$settings['invite_reg_traffic_reward']}">
                                             </div>
                                         </div>
                                     </div>
@@ -65,14 +65,14 @@
                                         <div class="form-group mb-3 row">
                                             <label class="form-label col-3 col-form-label">邀请模式</label>
                                             <div class="col">
-                                                <select id="invitation_mode" class="col form-select"
-                                                        value="{$settings['invitation_mode']}">
+                                                <select id="invite_mode" class="col form-select"
+                                                        value="{$settings['invite_mode']}">
                                                     <option value="reg_only"
-                                                            {if $settings['invitation_mode'] === 'reg_only'}selected{/if}>
+                                                            {if $settings['invite_mode'] === 'reg_only'}selected{/if}>
                                                         不返利
                                                     </option>
-                                                    <option value="after_paid"
-                                                            {if $settings['invitation_mode'] === 'after_paid'}selected{/if}>
+                                                    <option value="reward"
+                                                            {if $settings['invite_mode'] === 'reward'}selected{/if}>
                                                         被邀请用户支付账单时返利
                                                     </option>
                                                 </select>
@@ -81,23 +81,15 @@
                                         <div class="form-group mb-3 row">
                                             <label class="form-label col-3 col-form-label">返利模式</label>
                                             <div class="col">
-                                                <select id="invite_rebate_mode" class="col form-select"
-                                                        value="{$settings['invite_rebate_mode']}">
-                                                    <option value="continued"
-                                                            {if $settings['invite_rebate_mode'] === 'continued'}selected{/if}>
-                                                        持续返利
+                                                <select id="invite_reward_mode" class="col form-select"
+                                                        value="{$settings['invite_reward_mode']}">
+                                                    <option value="reward_count"
+                                                            {if $settings['invite_reward_mode'] === 'reward_count'}selected{/if}>
+                                                        限制返利次数
                                                     </option>
-                                                    <option value="limit_frequency"
-                                                            {if $settings['invite_rebate_mode'] === 'limit_frequency'}selected{/if}>
-                                                        限制邀请人能从被邀请人身上获得的返利次数
-                                                    </option>
-                                                    <option value="limit_amount"
-                                                            {if $settings['invite_rebate_mode'] === 'limit_amount'}selected{/if}>
-                                                        限制邀请人能从被邀请人身上获得的返利金额
-                                                    </option>
-                                                    <option value="limit_time_range"
-                                                            {if $settings['invite_rebate_mode'] === 'limit_time_range'}selected{/if}>
-                                                        限制邀请人能从被邀请人身上获得返利的时间范围
+                                                    <option value="reward_total"
+                                                            {if $settings['invite_reward_mode'] === 'reward_total'}selected{/if}>
+                                                        限制返利金额
                                                     </option>
                                                 </select>
                                             </div>
@@ -105,29 +97,22 @@
                                         <div class="form-group mb-3 row">
                                             <label class="form-label col-3 col-form-label">返利比例,10% 填 0.1</label>
                                             <div class="col">
-                                                <input id="rebate_ratio" type="text" class="form-control"
-                                                       value="{$settings['rebate_ratio']}">
-                                            </div>
-                                        </div>
-                                        <div class="form-group mb-3 row">
-                                            <label class="form-label col-3 col-form-label">返利时间范围(天)</label>
-                                            <div class="col">
-                                                <input id="rebate_time_range_limit" type="text" class="form-control"
-                                                       value="{$settings['rebate_time_range_limit']}">
+                                                <input id="invite_reward_rate" type="text" class="form-control"
+                                                       value="{$settings['invite_reward_rate']}">
                                             </div>
                                         </div>
                                         <div class="form-group mb-3 row">
-                                            <label class="form-label col-3 col-form-label">返利次数</label>
+                                            <label class="form-label col-3 col-form-label">返利次数限制</label>
                                             <div class="col">
-                                                <input id="rebate_frequency_limit" type="text" class="form-control"
-                                                       value="{$settings['rebate_frequency_limit']}">
+                                                <input id="invite_reward_count_limit" type="text" class="form-control"
+                                                       value="{$settings['invite_reward_count_limit']}">
                                             </div>
                                         </div>
                                         <div class="form-group mb-3 row">
                                             <label class="form-label col-3 col-form-label">返利金额限制</label>
                                             <div class="col">
-                                                <input id="rebate_amount_limit" type="text" class="form-control"
-                                                       value="{$settings['rebate_amount_limit']}">
+                                                <input id="invite_reward_total_limit" type="text" class="form-control"
+                                                       value="{$settings['invite_reward_total_limit']}">
                                             </div>
                                         </div>
                                     </div>

+ 0 - 7
resources/views/tabler/admin/user/edit.tpl

@@ -169,13 +169,6 @@
                             <div class="hr-text">
                                 <span>邀请注册</span>
                             </div>
-                            <div class="form-group mb-3 row">
-                                <label class="form-label col-4 col-form-label">可用邀请数量</label>
-                                <div class="col">
-                                    <input id="invite_num" type="text" class="form-control"
-                                           value="{$edit_user->invite_num}">
-                                </div>
-                            </div>
                             <div class="form-group mb-3 row">
                                 <label class="form-label col-4 col-form-label">邀请人</label>
                                 <div class="col">

+ 0 - 1
src/Command/Tool.php

@@ -371,7 +371,6 @@ EOL;
             $user->u = 0;
             $user->d = 0;
             $user->transfer_enable = 0;
-            $user->invite_num = 0;
             $user->ref_by = 0;
             $user->is_admin = 1;
             $user->reg_date = date('Y-m-d H:i:s');

+ 0 - 163
src/Controllers/Admin/InviteController.php

@@ -1,163 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace App\Controllers\Admin;
-
-use App\Controllers\BaseController;
-use App\Models\Payback;
-use App\Models\User;
-use App\Utils\Tools;
-use Exception;
-use Psr\Http\Message\ResponseInterface;
-use Slim\Http\Response;
-use Slim\Http\ServerRequest;
-use function is_numeric;
-
-final class InviteController extends BaseController
-{
-    private static array $details =
-        [
-            'field' => [
-                'id' => '事件ID',
-                'total' => '原始金额',
-                'userid' => '发起用户ID',
-                'user_name' => '发起用户名',
-                'ref_by' => '获利用户ID',
-                'ref_user_name' => '获利用户名',
-                'ref_get' => '获利金额',
-                'datetime' => '时间',
-            ],
-            'update_dialog' => [
-                [
-                    'id' => 'userid',
-                    'info' => '修改的用户',
-                    'type' => 'input',
-                    'placeholder' => '需要修改邀请者的用户 ID 或 Email',
-                ],
-                [
-                    'id' => 'refid',
-                    'info' => '邀请者 ID',
-                    'type' => 'input',
-                    'placeholder' => '目标邀请者的用户 ID',
-                ],
-            ],
-            'add_dialog' => [
-                [
-                    'id' => 'userid',
-                    'info' => '修改的用户',
-                    'type' => 'input',
-                    'placeholder' => '需要邀请数量的用户 ID 或 Email',
-                ],
-                [
-                    'id' => 'invite_num',
-                    'info' => '邀请数量',
-                    'type' => 'input',
-                    'placeholder' => '需要添加的邀请数量',
-                ],
-            ],
-        ];
-
-    /**
-     * 后台邀请记录页面
-     *
-     * @throws Exception
-     */
-    public function index(ServerRequest $request, Response $response, array $args): Response|ResponseInterface
-    {
-        return $response->write(
-            $this->view()
-                ->assign('details', self::$details)
-                ->fetch('admin/log/invite.tpl')
-        );
-    }
-
-    /**
-     * 更改用户邀请者
-     */
-    public function update(ServerRequest $request, Response $response, array $args): Response|ResponseInterface
-    {
-        $userid = $request->getParam('userid');
-
-        if ($userid === null) {
-            return $response->withJson([
-                'ret' => 0,
-                'msg' => '参数错误',
-            ]);
-        }
-
-        if (str_contains($userid, '@')) {
-            $user = (new User())->where('email', '=', $userid)->first();
-        } else {
-            $user = (new User())->find((int) $userid);
-        }
-
-        if ($user === null) {
-            return $response->withJson([
-                'ret' => 0,
-                'msg' => '邀请者更改失败,检查用户 ID/Email 是否输入正确',
-            ]);
-        }
-
-        $user->ref_by = $request->getParam('refid', 0);  //如未提供,则删除用户的邀请者
-        $user->save();
-
-        return $response->withJson([
-            'ret' => 1,
-            'msg' => '邀请者更改成功',
-        ]);
-    }
-
-    /**
-     * 为用户添加邀请次数
-     */
-    public function add(ServerRequest $request, Response $response, array $args): Response|ResponseInterface
-    {
-        $invite_num = (int) $request->getParam('invite_num');
-
-        if (! is_numeric($invite_num)) {
-            return $response->withJson([
-                'ret' => 0,
-                'msg' => '邀请次数错误',
-            ]);
-        }
-
-        if (str_contains($request->getParam('userid'), '@')) {
-            $user = (new User())->where('email', '=', $request->getParam('userid'))->first();
-        } else {
-            $user = (new User())->find((int) $request->getParam('userid'));
-        }
-
-        if ($user === null) {
-            return $response->withJson([
-                'ret' => 0,
-                'msg' => '邀请次数添加失败,检查用户 ID/Email 是否输入正确',
-            ]);
-        }
-
-        $user->addInviteNum($invite_num);
-
-        return $response->withJson([
-            'ret' => 1,
-            'msg' => '邀请次数添加成功',
-        ]);
-    }
-
-    /**
-     * 后台登录记录页面 AJAX
-     */
-    public function ajax(ServerRequest $request, Response $response, array $args): Response|ResponseInterface
-    {
-        $paybacks = (new Payback())->orderBy('id', 'desc')->get();
-
-        foreach ($paybacks as $payback) {
-            $payback->datetime = Tools::toDateTime((int) $payback->datetime);
-            $payback->user_name = $payback->getAttributes();
-            $payback->ref_user_name = $payback->getAttributes();
-        }
-
-        return $response->withJson([
-            'paybacks' => $paybacks,
-        ]);
-    }
-}

+ 63 - 0
src/Controllers/Admin/PaybackController.php

@@ -0,0 +1,63 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Controllers\Admin;
+
+use App\Controllers\BaseController;
+use App\Models\Payback;
+use App\Utils\Tools;
+use Exception;
+use Psr\Http\Message\ResponseInterface;
+use Slim\Http\Response;
+use Slim\Http\ServerRequest;
+
+final class PaybackController extends BaseController
+{
+    private static array $details =
+        [
+            'field' => [
+                'id' => '事件ID',
+                'total' => '原始金额',
+                'userid' => '发起用户ID',
+                'user_name' => '发起用户名',
+                'ref_by' => '获利用户ID',
+                'ref_user_name' => '获利用户名',
+                'ref_get' => '获利金额',
+                'invoice_id' => '账单ID',
+                'datetime' => '时间',
+            ],
+        ];
+
+    /**
+     * 后台邀请记录页面
+     *
+     * @throws Exception
+     */
+    public function index(ServerRequest $request, Response $response, array $args): Response|ResponseInterface
+    {
+        return $response->write(
+            $this->view()
+                ->assign('details', self::$details)
+                ->fetch('admin/log/payback.tpl')
+        );
+    }
+
+    /**
+     * 后台登录记录页面 AJAX
+     */
+    public function ajax(ServerRequest $request, Response $response, array $args): Response|ResponseInterface
+    {
+        $paybacks = (new Payback())->orderBy('id', 'desc')->get();
+
+        foreach ($paybacks as $payback) {
+            $payback->datetime = Tools::toDateTime((int) $payback->datetime);
+            $payback->user_name = $payback->getAttributes();
+            $payback->ref_user_name = $payback->getAttributes();
+        }
+
+        return $response->withJson([
+            'paybacks' => $paybacks,
+        ]);
+    }
+}

+ 7 - 8
src/Controllers/Admin/Setting/RefController.php

@@ -11,14 +11,13 @@ use Exception;
 final class RefController extends BaseController
 {
     private static array $update_field = [
-        'invitation_to_register_balance_reward',
-        'invitation_to_register_traffic_reward',
-        'invitation_mode',
-        'invite_rebate_mode',
-        'rebate_ratio',
-        'rebate_frequency_limit',
-        'rebate_amount_limit',
-        'rebate_time_range_limit',
+        'invite_reg_money_reward',
+        'invite_reg_traffic_reward',
+        'invite_mode',
+        'invite_reward_mode',
+        'invite_reward_rate',
+        'invite_reward_count_limit',
+        'invite_reward_total_limit',
     ];
 
     /**

+ 0 - 2
src/Controllers/Admin/UserController.php

@@ -76,7 +76,6 @@ final class UserController extends BaseController
         'banned_reason',
         'is_shadow_banned',
         'transfer_enable',
-        'invite_num',
         'ref_by',
         'class_expire',
         'node_group',
@@ -199,7 +198,6 @@ final class UserController extends BaseController
         $user->banned_reason = $request->getParam('banned_reason');
         $user->is_shadow_banned = $request->getParam('is_shadow_banned') === 'true' ? 1 : 0;
         $user->transfer_enable = Tools::autoBytesR($request->getParam('transfer_enable'));
-        $user->invite_num = $request->getParam('invite_num');
         $user->ref_by = $request->getParam('ref_by');
         $user->class_expire = $request->getParam('class_expire');
         $user->node_group = $request->getParam('node_group');

+ 13 - 8
src/Controllers/AuthController.php

@@ -14,6 +14,7 @@ use App\Services\Captcha;
 use App\Services\Mail;
 use App\Services\MFA;
 use App\Services\RateLimit;
+use App\Services\Reward;
 use App\Utils\Cookie;
 use App\Utils\Hash;
 use App\Utils\ResponseHelper;
@@ -244,7 +245,6 @@ final class AuthController extends BaseController
         $user->im_type = $imtype;
         $user->im_value = $imvalue;
         $user->transfer_enable = Tools::toGB($configs['sign_up_for_free_traffic']);
-        $user->invite_num = $configs['sign_up_for_invitation_codes'];
         $user->auto_reset_day = Config::obtain('free_user_reset_day');
         $user->auto_reset_bandwidth = Config::obtain('free_user_reset_bandwidth');
         $user->daily_mail_enable = $configs['sign_up_for_daily_report'];
@@ -259,9 +259,10 @@ final class AuthController extends BaseController
 
         if ($invite_code !== '') {
             $invite = (new InviteCode())->where('code', $invite_code)->first();
-            $invite->reward();
-            $user->ref_by = $invite->user_id;
-            $user->money = Config::obtain('invitation_to_register_balance_reward');
+
+            if ($invite !== null) {
+                $user->ref_by = $invite->user_id;
+            }
         }
 
         $user->ga_token = MFA::generateGaToken();
@@ -283,6 +284,10 @@ final class AuthController extends BaseController
         }
 
         if ($user->save() && ! $is_admin_reg) {
+            if ($user->ref_by !== 0) {
+                Reward::issueRegReward($user->id, $user->ref_by);
+            }
+
             Auth::login($user->id, 3600);
             (new LoginIp())->collectLoginIP($_SERVER['REMOTE_ADDR'], 0, $user->id);
 
@@ -331,15 +336,15 @@ final class AuthController extends BaseController
         }
 
         if ($invite_code !== '') {
-            $user_invite = (new InviteCode())->where('code', $invite_code)->first();
+            $invite = (new InviteCode())->where('code', $invite_code)->first();
 
-            if ($user_invite === null) {
+            if ($invite === null) {
                 return ResponseHelper::error($response, '邀请码无效');
             }
 
-            $gift_user = (new User())->where('id', $user_invite->user_id)->first();
+            $ref_user = (new User())->where('id', $invite->user_id)->first();
 
-            if ($gift_user === null || $gift_user->invite_num === 0) {
+            if ($ref_user === null) {
                 return ResponseHelper::error($response, '邀请码无效');
             }
         }

+ 0 - 20
src/Models/InviteCode.php

@@ -4,7 +4,6 @@ declare(strict_types=1);
 
 namespace App\Models;
 
-use App\Utils\Tools;
 use Illuminate\Database\Query\Builder;
 
 /**
@@ -18,23 +17,4 @@ final class InviteCode extends Model
 {
     protected $connection = 'default';
     protected $table = 'user_invite_code';
-
-    public function reward(): void
-    {
-        $user = (new User())->where('id', $this->user_id)
-            ->where('is_banned', 0)
-            ->where('is_shadow_banned', 0)
-            ->first();
-
-        if ($user !== null) {
-            $user->transfer_enable += Tools::toGB(Config::obtain('invitation_to_register_traffic_reward'));
-
-            if ($user->invite_num > 0) {
-                --$user->invite_num;
-                // 避免设置为不限制邀请次数的值 -1 发生变动
-            }
-
-            $user->save();
-        }
-    }
 }

+ 15 - 76
src/Models/Payback.php

@@ -8,12 +8,13 @@ use Illuminate\Database\Query\Builder;
 use function time;
 
 /**
- * @property int   $id       记录ID
- * @property float $total    总金额
- * @property int   $userid   用户ID
- * @property int   $ref_by   推荐人ID
- * @property float $ref_get  推荐人获得金额
- * @property int   $datetime 创建时间
+ * @property int   $id         记录ID
+ * @property float $total      总金额
+ * @property int   $userid     用户ID
+ * @property int   $ref_by     推荐人ID
+ * @property float $ref_get    推荐人获得金额
+ * @property int   $invoice_id 账单ID
+ * @property int   $datetime   创建时间
  *
  * @mixin Builder
  */
@@ -44,76 +45,14 @@ final class Payback extends Model
             (new User())->where('id', $this->ref_by)->first()->user_name;
     }
 
-    public function rebate($user_id, $order_amount): void
+    public function add(float $total, int $user_id, int $ref_by, float $ref_get, int $invoice_id): void
     {
-        $configs = Config::getClass('ref');
-        $user = (new User())->where('id', $user_id)->first();
-        $gift_user_id = $user->ref_by;
-        // 判断
-        $invite_rebate_mode = (string) $configs['invite_rebate_mode'];
-
-        if ($invite_rebate_mode === 'continued') {
-            // 不设限制
-            $this->execute($user_id, $gift_user_id, $order_amount);
-        } elseif ($invite_rebate_mode === 'limit_frequency') {
-            // 限制返利次数
-            $rebate_frequency = self::where('userid', $user_id)->count();
-
-            if ($rebate_frequency < $configs['rebate_frequency_limit']) {
-                $this->execute($user_id, $gift_user_id, $order_amount);
-            }
-        } elseif ($invite_rebate_mode === 'limit_amount') {
-            // 限制返利金额
-            $total_rebate_amount = self::where('userid', $user_id)->sum('ref_get');
-            // 预计返利 (expected_rebate) 是指:订单金额 * 返点比例
-            $expected_rebate = $order_amount * $configs['rebate_ratio'];
-            // 调整返利 (adjust_rebate) 是指:若历史返利总额在加上此次预计返利金额超过总返利限制,总返利限制与历史返利总额的差值
-            if ($total_rebate_amount + $expected_rebate > $configs['rebate_amount_limit']
-                && $total_rebate_amount <= $configs['rebate_amount_limit']
-            ) {
-                $adjust_rebate = $configs['rebate_amount_limit'] - $total_rebate_amount;
-
-                if ($adjust_rebate > 0) {
-                    $this->execute($user_id, $gift_user_id, $order_amount, $adjust_rebate);
-                }
-            } else {
-                $this->execute($user_id, $gift_user_id, $order_amount);
-            }
-        } elseif ($invite_rebate_mode === 'limit_time_range') {
-            if (strtotime($user->reg_date) + $configs['rebate_time_range_limit'] * 86400 > time()) {
-                $this->execute($user_id, $gift_user_id, $order_amount);
-            }
-        }
-    }
-
-    public function execute($user_id, $gift_user_id, $order_amount, $adjust_rebate = null): void
-    {
-        $gift_user = (new User())->where('id', $gift_user_id)
-            ->where('is_banned', 0)
-            ->where('is_shadow_banned', 0)
-            ->first();
-
-        if ($gift_user !== null) {
-            $rebate_amount = $order_amount * Config::obtain('rebate_ratio');
-            // 返利
-            $money_before = $gift_user->money;
-            $gift_user->money += $adjust_rebate ?? $rebate_amount;
-            $gift_user->save();
-            // 余额变动记录
-            (new UserMoneyLog())->add(
-                $gift_user->id,
-                (float) $money_before,
-                (float) $gift_user->money,
-                $adjust_rebate ?? $rebate_amount,
-                '邀请用户 #' . $user_id . ' 返利',
-            );
-            // 添加记录
-            $this->total = $order_amount;
-            $this->userid = $user_id;
-            $this->ref_by = $gift_user_id;
-            $this->ref_get = $adjust_rebate ?? $rebate_amount;
-            $this->datetime = time();
-            $this->save();
-        }
+        $this->total = $total;
+        $this->userid = $user_id;
+        $this->ref_by = $ref_by;
+        $this->ref_get = $ref_get;
+        $this->invoice_id = $invoice_id;
+        $this->datetime = time();
+        $this->save();
     }
 }

+ 0 - 11
src/Models/User.php

@@ -40,7 +40,6 @@ use const PHP_EOL;
  * @property int    $last_check_in_time 最后签到时间
  * @property int    $last_login_time 最后登录时间
  * @property string $reg_date 注册时间
- * @property int    $invite_num 可用邀请次数
  * @property float  $money 账户余额
  * @property int    $ref_by 邀请人ID
  * @property string $method Shadowsocks加密方式
@@ -186,16 +185,6 @@ final class User extends Model
         return $code->code;
     }
 
-    /**
-     * 添加邀请次数
-     */
-    public function addInviteNum(int $num): bool
-    {
-        $this->invite_num += $num;
-
-        return $this->save();
-    }
-
     /**
      * 生成新的 API Token
      */

+ 4 - 4
src/Services/Bot/Telegram/Callback.php

@@ -890,11 +890,11 @@ final class Callback
         $invite = Config::getClass('ref');
 
         $text = [
-            '<strong>你每邀请 1 位用户注册:</strong>',
+            '<strong>你每邀请 <code>1</code> 位用户注册:</strong>',
             '',
-            '- 你会获得 <strong>' . $invite['invitation_to_register_traffic_reward'] . 'G</strong> 流量奖励。',
-            '- 对方将获得 <strong>' . $invite['invitation_to_register_balance_reward'] . ' 元</strong> 初始账户余额。',
-            '- 对方充值时你还会获得对方充值金额的 <strong>' . $invite['rebate_ratio'] * 100 . '%</strong> 的返利。',
+            '- 你会获得 <code>' . Config::obtain('invite_reg_money_reward') . 'G</code> 流量奖励。',
+            '- 对方将获得 <code>' . Config::obtain('invite_reg_traffic_reward') . ' 元</code> 初始账户余额。',
+            '- 对方支付账单时你会获得对方账单金额的 <code>' . Config::obtain('invite_reward_rate') * 100 . '%</code> 的返利。',
             '',
             '已获得返利:' . $paybacks_sum . ' 元。',
         ];

+ 3 - 3
src/Services/Gateway/Base.php

@@ -6,9 +6,9 @@ namespace App\Services\Gateway;
 
 use App\Models\Config;
 use App\Models\Invoice;
-use App\Models\Payback;
 use App\Models\Paylist;
 use App\Models\User;
+use App\Services\Reward;
 use App\Utils\Tools;
 use Psr\Http\Message\ResponseInterface;
 use Slim\Http\Response;
@@ -80,8 +80,8 @@ abstract class Base
 
         $user = (new User())->find($paylist?->userid);
         // 返利
-        if ($user !== null && $user->ref_by > 0 && Config::obtain('invitation_mode') === 'after_paid') {
-            (new Payback())->rebate($user->id, $paylist->total);
+        if ($user !== null && $user->ref_by > 0 && Config::obtain('invitation_mode') === 'reward') {
+            Reward::issuePaybackReward($user->id, $user->ref_by, $paylist->total, $paylist->invoice_id);
         }
     }
 

+ 116 - 0
src/Services/Reward.php

@@ -0,0 +1,116 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Services;
+
+use App\Models\Config;
+use App\Models\Payback;
+use App\Models\User;
+use App\Models\UserMoneyLog;
+
+final class Reward
+{
+    public static function issuePaybackReward($user_id, $ref_user_id, $total, $invoice_id): void
+    {
+        $ref_get = 0;
+
+        $ref_user = (new User())->where('id', $ref_user_id)
+            ->where('is_banned', 0)
+            ->where('is_shadow_banned', 0)
+            ->first();
+
+        $exsit_payback = (new Payback())->where('userid', $user_id)
+            ->where('invoice_id', $invoice_id)
+            ->first();
+
+        if ($ref_user !== null && $exsit_payback === null) {
+            $invite_reward_mode = Config::obtain('invite_reward_mode');
+            $invite_reward_rate = Config::obtain('invite_reward_rate');
+
+            if ($invite_reward_mode === 'reward_count') {
+                $invite_reward_count_limit = Config::obtain('invite_reward_count_limit');
+
+                $invite_reward_count = (new Payback())->where('userid', $user_id)
+                    ->where('ref_by', $ref_user_id)
+                    ->count();
+
+                if ($invite_reward_count < $invite_reward_count_limit) {
+                    $ref_get = $total * $invite_reward_rate;
+                }
+            }
+
+            if ($invite_reward_mode === 'reward_total') {
+                $invite_reward_total_limit = Config::obtain('invite_reward_total_limit');
+
+                $invite_reward_total = (new Payback())->where('userid', $user_id)
+                    ->where('ref_by', $ref_user_id)
+                    ->sum('ref_get');
+
+                if ($invite_reward_total < $invite_reward_total_limit) {
+                    $ref_get = $total * $invite_reward_rate;
+
+                    if ($invite_reward_total + $ref_get > $invite_reward_total_limit) {
+                        $ref_get = $invite_reward_total_limit - $invite_reward_total;
+                    }
+                }
+            }
+        }
+
+        if ($ref_get !== 0) {
+            $money_before = $ref_user->money;
+            $ref_user->money += $ref_get;
+            $ref_user->save();
+            // 添加余额记录
+            (new UserMoneyLog())->add(
+                $ref_user->id,
+                (float) $money_before,
+                (float) $ref_user->money,
+                $ref_get,
+                '邀请用户 #' . $user_id . ' 返利',
+            );
+            // 添加返利记录
+            (new Payback())->add(
+                (float) $total,
+                $user_id,
+                $ref_user_id,
+                (float) $ref_get,
+                $invoice_id,
+            );
+        }
+    }
+
+    public static function issueRegReward($user_id, $ref_user_id): void
+    {
+        $invite_reg_money_reward = Config::obtain('invite_reg_money_reward');
+        $invite_reg_traffic_reward = Config::obtain('invite_reg_traffic_reward');
+
+        $user = (new User())->where('id', $user_id)->first();
+
+        $ref_user = (new User())->where('id', $ref_user_id)
+            ->where('is_banned', 0)
+            ->where('is_shadow_banned', 0)
+            ->first();
+
+        if ($user !== null && $ref_user !== null) {
+            if ($invite_reg_money_reward !== 0) {
+                $money_before = $user->money;
+                $user->money += $invite_reg_money_reward;
+                $user->save();
+                // 添加余额记录
+                (new UserMoneyLog())->add(
+                    $user->id,
+                    (float) $money_before,
+                    (float) $user->money,
+                    $invite_reg_money_reward,
+                    '被用户 #' . $ref_user_id . ' 邀请注册奖励',
+                );
+            }
+
+            if ($invite_reg_traffic_reward !== 0) {
+                $ref_user->transfer_enable += Tools::toGB($invite_reg_traffic_reward);
+                $ref_user->save();
+            }
+        }
+    }
+}

+ 9 - 5
src/Services/Subscribe/Clash.php

@@ -44,7 +44,8 @@ final class Clash extends Base
 
                     break;
                 case 1:
-                    $ss_2022_port = $node_custom_config['offset_port_user'] ?? ($node_custom_config['offset_port_node'] ?? 443);
+                    $ss_2022_port = $node_custom_config['offset_port_user'] ??
+                        ($node_custom_config['offset_port_node'] ?? 443);
                     $method = $node_custom_config['method'] ?? '2022-blake3-aes-128-gcm';
 
                     $pk_len = match ($method) {
@@ -68,7 +69,8 @@ final class Clash extends Base
 
                     break;
                 case 2:
-                    $tuic_port = $node_custom_config['offset_port_user'] ?? ($node_custom_config['offset_port_node'] ?? 443);
+                    $tuic_port = $node_custom_config['offset_port_user'] ??
+                        ($node_custom_config['offset_port_node'] ?? 443);
                     $host = $node_custom_config['host'] ?? '';
                     $congestion_control = $node_custom_config['congestion_control'] ?? 'bbr';
                     // Only Clash.Meta core has TUIC support
@@ -87,10 +89,11 @@ final class Clash extends Base
 
                     break;
                 case 11:
-                    $v2_port = $node_custom_config['offset_port_user'] ?? ($node_custom_config['offset_port_node'] ?? 443);
+                    $v2_port = $node_custom_config['offset_port_user'] ??
+                        ($node_custom_config['offset_port_node'] ?? 443);
                     $security = $node_custom_config['security'] ?? 'none';
                     $encryption = $node_custom_config['encryption'] ?? 'auto';
-                    $network = $node_custom_config['header']['type'] ?? $node_custom_config['network'] ?? '';
+                    $network = $node_custom_config['network'] ?? '';
                     $host = $node_custom_config['header']['request']['headers']['Host'][0] ??
                         $node_custom_config['host'] ?? '';
                     $allow_insecure = $node_custom_config['allow_insecure'] ?? false;
@@ -127,7 +130,8 @@ final class Clash extends Base
 
                     break;
                 case 14:
-                    $trojan_port = $node_custom_config['offset_port_user'] ?? ($node_custom_config['offset_port_node'] ?? 443);
+                    $trojan_port = $node_custom_config['offset_port_user'] ??
+                        ($node_custom_config['offset_port_node'] ?? 443);
                     $network = $node_custom_config['header']['type'] ?? $node_custom_config['network'] ?? 'tcp';
                     $host = $node_custom_config['host'] ?? '';
                     $allow_insecure = $node_custom_config['allow_insecure'] ?? false;