feat: new xboard

This commit is contained in:
xboard
2025-01-21 14:57:54 +08:00
parent de18cfe596
commit 0f43fff242
373 changed files with 17923 additions and 20264 deletions

View File

@@ -13,14 +13,16 @@ class CreateFailedJobsTable extends Migration
*/
public function up()
{
Schema::create('failed_jobs', function (Blueprint $table) {
$table->bigIncrements('id');
$table->text('connection');
$table->text('queue');
$table->longText('payload');
$table->longText('exception');
$table->timestamp('failed_at')->useCurrent();
});
if (!Schema::hasTable('failed_jobs')) {
Schema::create('failed_jobs', function (Blueprint $table) {
$table->bigIncrements('id');
$table->text('connection');
$table->text('queue');
$table->longText('payload');
$table->longText('exception');
$table->timestamp('failed_at')->useCurrent();
});
}
}
/**

View File

@@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
if (!Schema::hasTable('personal_access_tokens')) {
Schema::create('personal_access_tokens', function (Blueprint $table) {
$table->id();
$table->morphs('tokenable');
$table->string('name');
$table->string('token', 64)->unique();
$table->text('abilities')->nullable();
$table->timestamp('last_used_at')->nullable();
$table->timestamp('expires_at')->nullable();
$table->timestamps();
});
}
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('personal_access_tokens');
}
};

View File

@@ -0,0 +1,496 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
// Commission Log
if (!Schema::hasTable('v2_commission_log')) {
Schema::create('v2_commission_log', function (Blueprint $table) {
$table->integer('id', true);
$table->integer('invite_user_id');
$table->integer('user_id');
$table->char('trade_no', 36);
$table->integer('order_amount');
$table->integer('get_amount');
$table->integer('created_at');
$table->integer('updated_at');
});
}
// Invite Code
if (!Schema::hasTable('v2_invite_code')) {
Schema::create('v2_invite_code', function (Blueprint $table) {
$table->integer('id', true);
$table->integer('user_id');
$table->char('code', 32);
$table->boolean('status')->default(false);
$table->integer('pv')->default(0);
$table->integer('created_at');
$table->integer('updated_at');
});
}
// Knowledge
if (!Schema::hasTable('v2_knowledge')) {
Schema::create('v2_knowledge', function (Blueprint $table) {
$table->integer('id', true);
$table->char('language', 5)->comment('語言');
$table->string('category')->comment('分類名');
$table->string('title')->comment('標題');
$table->text('body')->comment('內容');
$table->integer('sort')->nullable()->comment('排序');
$table->boolean('show')->default(false)->comment('顯示');
$table->integer('created_at')->comment('創建時間');
$table->integer('updated_at')->comment('更新時間');
});
}
// Plan
if (!Schema::hasTable('v2_plan')) {
Schema::create('v2_plan', function (Blueprint $table) {
$table->integer('id', true);
$table->integer('group_id');
$table->integer('transfer_enable');
$table->string('name');
$table->integer('speed_limit')->nullable();
$table->boolean('show')->default(false);
$table->integer('sort')->nullable();
$table->boolean('renew')->default(true);
$table->text('content')->nullable();
$table->integer('month_price')->nullable();
$table->integer('quarter_price')->nullable();
$table->integer('half_year_price')->nullable();
$table->integer('year_price')->nullable();
$table->integer('two_year_price')->nullable();
$table->integer('three_year_price')->nullable();
$table->integer('onetime_price')->nullable();
$table->integer('reset_price')->nullable();
$table->integer('reset_traffic_method')->nullable()->comment('重置流量方式:0跟随系统设置、1每月1号、2按月重置、3不重置、4每年1月1日、5按年重置');
$table->integer('capacity_limit')->nullable();
$table->integer('created_at');
$table->integer('updated_at');
});
}
// Server Group
if (!Schema::hasTable('v2_server_group')) {
Schema::create('v2_server_group', function (Blueprint $table) {
$table->integer('id', true);
$table->string('name');
$table->integer('created_at');
$table->integer('updated_at');
});
}
// Server Route
if (!Schema::hasTable('v2_server_route')) {
Schema::create('v2_server_route', function (Blueprint $table) {
$table->integer('id', true);
$table->string('remarks');
$table->text('match');
$table->string('action', 11);
$table->string('action_value')->nullable();
$table->integer('created_at');
$table->integer('updated_at');
});
}
// stat server
if (!Schema::hasTable('v2_stat_server')) {
Schema::create('v2_stat_server', function (Blueprint $table) {
$table->integer('id', true);
$table->integer('server_id')->index('server_id')->comment('节点id');
$table->char('server_type', 11)->comment('节点类型');
$table->bigInteger('u');
$table->bigInteger('d');
$table->char('record_type', 1)->comment('d day m month');
$table->integer('record_at')->index('record_at')->comment('记录时间');
$table->integer('created_at');
$table->integer('updated_at');
$table->unique(['server_id', 'server_type', 'record_at'], 'server_id_server_type_record_at');
});
}
// User
if (!Schema::hasTable('v2_user')) {
Schema::create('v2_user', function (Blueprint $table) {
$table->integer('id', true);
$table->integer('invite_user_id')->nullable();
$table->bigInteger('telegram_id')->nullable();
$table->string('email', 64)->unique('email');
$table->string('password', 64);
$table->char('password_algo', 10)->nullable();
$table->char('password_salt', 10)->nullable();
$table->integer('balance')->default(0);
$table->integer('discount')->nullable();
$table->tinyInteger('commission_type')->default(0)->comment('0: system 1: period 2: onetime');
$table->integer('commission_rate')->nullable();
$table->integer('commission_balance')->default(0);
$table->integer('t')->default(0);
$table->bigInteger('u')->default(0);
$table->bigInteger('d')->default(0);
$table->bigInteger('transfer_enable')->default(0);
$table->boolean('banned')->default(false);
$table->boolean('is_admin')->default(false);
$table->integer('last_login_at')->nullable();
$table->boolean('is_staff')->default(false);
$table->integer('last_login_ip')->nullable();
$table->string('uuid', 36);
$table->integer('group_id')->nullable();
$table->integer('plan_id')->nullable();
$table->integer('speed_limit')->nullable();
$table->tinyInteger('remind_expire')->nullable()->default(1);
$table->tinyInteger('remind_traffic')->nullable()->default(1);
$table->char('token', 32);
$table->bigInteger('expired_at')->nullable()->default(0);
$table->text('remarks')->nullable();
$table->integer('created_at');
$table->integer('updated_at');
});
}
// Mail Log
if (!Schema::hasTable('v2_mail_log')) {
Schema::create('v2_mail_log', function (Blueprint $table) {
$table->integer('id', true);
$table->string('email', 64);
$table->string('subject');
$table->string('template_name');
$table->text('error')->nullable();
$table->integer('created_at');
$table->integer('updated_at');
});
}
// Log
if (!Schema::hasTable('v2_log')) {
Schema::create('v2_log', function (Blueprint $table) {
$table->integer('id', true);
$table->text('title');
$table->string('level', 11)->nullable();
$table->string('host')->nullable();
$table->string('uri');
$table->string('method', 11);
$table->text('data')->nullable();
$table->string('ip', 128)->nullable();
$table->text('context')->nullable();
$table->integer('created_at');
$table->integer('updated_at');
});
}
// Stat
if (!Schema::hasTable('v2_stat')) {
Schema::create('v2_stat', function (Blueprint $table) {
$table->integer('id', true);
$table->integer('record_at');
$table->char('record_type', 1);
$table->integer('order_count')->comment('订单数量');
$table->integer('order_total')->comment('订单合计');
$table->integer('commission_count');
$table->integer('commission_total')->comment('佣金合计');
$table->integer('paid_count');
$table->integer('paid_total');
$table->integer('register_count');
$table->integer('invite_count');
$table->string('transfer_used_total', 32);
$table->integer('created_at');
$table->integer('updated_at');
if (config('database.default') !== 'sqlite') {
$table->unique(['record_at']);
}
});
}
// stat user
if (!Schema::hasTable('v2_stat_user')) {
Schema::create('v2_stat_user', function (Blueprint $table) {
$table->integer('id', true);
$table->integer('user_id');
$table->decimal('server_rate', 10);
$table->bigInteger('u');
$table->bigInteger('d');
$table->char('record_type', 2);
$table->integer('record_at');
$table->integer('created_at');
$table->integer('updated_at');
// 如果是不是sqlite才添加多个索引
if (config('database.default') !== 'sqlite') {
$table->index(['user_id', 'server_rate', 'record_at']);
$table->unique(['server_rate', 'user_id', 'record_at'], 'server_rate_user_id_record_at');
}
});
}
// ticket message
if (!Schema::hasTable('v2_ticket_message')) {
Schema::create('v2_ticket_message', function (Blueprint $table) {
$table->integer('id', true);
$table->integer('user_id');
$table->integer('ticket_id');
$table->text('message');
$table->integer('created_at');
$table->integer('updated_at');
});
}
// Order
if (!Schema::hasTable('v2_order')) {
Schema::create('v2_order', function (Blueprint $table) {
$table->integer('id', true);
$table->integer('invite_user_id')->nullable();
$table->integer('user_id');
$table->integer('plan_id');
$table->integer('coupon_id')->nullable();
$table->integer('payment_id')->nullable();
$table->integer('type')->comment('1新购2续费3升级');
$table->string('period');
$table->string('trade_no', 36)->unique('trade_no');
$table->string('callback_no')->nullable();
$table->integer('total_amount');
$table->integer('handling_amount')->nullable();
$table->integer('discount_amount')->nullable();
$table->integer('surplus_amount')->nullable()->comment('剩余价值');
$table->integer('refund_amount')->nullable()->comment('退款金额');
$table->integer('balance_amount')->nullable()->comment('使用余额');
$table->text('surplus_order_ids')->nullable()->comment('折抵订单');
$table->integer('status')->default(0)->comment('0待支付1开通中2已取消3已完成4已折抵');
$table->integer('commission_status')->default(false)->comment('0待确认1发放中2有效3无效');
$table->integer('commission_balance')->default(0);
$table->integer('actual_commission_balance')->nullable()->comment('实际支付佣金');
$table->integer('paid_at')->nullable();
$table->integer('created_at');
$table->integer('updated_at');
});
}
// Payment
if (!Schema::hasTable('v2_payment')) {
Schema::create('v2_payment', function (Blueprint $table) {
$table->integer('id', true);
$table->char('uuid', 32);
$table->string('payment', 16);
$table->string('name');
$table->string('icon')->nullable();
$table->text('config');
$table->string('notify_domain', 128)->nullable();
$table->integer('handling_fee_fixed')->nullable();
$table->decimal('handling_fee_percent', 5)->nullable();
$table->boolean('enable')->default(false);
$table->integer('sort')->nullable();
$table->integer('created_at');
$table->integer('updated_at');
});
}
// Coupon
if (!Schema::hasTable('v2_coupon')) {
Schema::create('v2_coupon', function (Blueprint $table) {
$table->integer('id', true);
$table->string('code');
$table->string('name');
$table->integer('type');
$table->integer('value');
$table->boolean('show')->default(false);
$table->integer('limit_use')->nullable();
$table->integer('limit_use_with_user')->nullable();
$table->string('limit_plan_ids')->nullable();
$table->string('limit_period')->nullable();
$table->integer('started_at');
$table->integer('ended_at');
$table->integer('created_at');
$table->integer('updated_at');
});
}
// Notice
if (!Schema::hasTable('v2_notice')) {
Schema::create('v2_notice', function (Blueprint $table) {
$table->integer('id', true);
$table->string('title');
$table->text('content');
$table->boolean('show')->default(false);
$table->string('img_url')->nullable();
$table->string('tags')->nullable();
$table->integer('created_at');
$table->integer('updated_at');
});
}
// Ticket
if (!Schema::hasTable('v2_ticket')) {
Schema::create('v2_ticket', function (Blueprint $table) {
$table->integer('id', true);
$table->integer('user_id');
$table->string('subject');
$table->integer('level');
$table->integer('status')->default(0)->comment('0:已开启 1:已关闭');
$table->integer('reply_status')->default(1)->comment('0:待回复 1:已回复');
$table->integer('created_at');
$table->integer('updated_at');
});
}
// Server Hysteria
if (!Schema::hasTable('v2_server_hysteria')) {
Schema::create('v2_server_hysteria', function (Blueprint $table) {
$table->integer('id', true);
$table->string('group_id');
$table->string('route_id')->nullable();
$table->string('name');
$table->integer('parent_id')->nullable();
$table->string('host');
$table->string('port', 11);
$table->integer('server_port');
$table->string('tags')->nullable();
$table->string('rate', 11);
$table->boolean('show')->default(false);
$table->integer('sort')->nullable();
$table->integer('up_mbps');
$table->integer('down_mbps');
$table->string('server_name', 64)->nullable();
$table->boolean('insecure')->default(false);
$table->integer('created_at');
$table->integer('updated_at');
});
}
// Server Shadowsocks
if (!Schema::hasTable('v2_server_shadowsocks')) {
autoIncrement:
Schema::create('v2_server_shadowsocks', function (Blueprint $table) {
$table->integer('id', true);
$table->string('group_id');
$table->string('route_id')->nullable();
$table->integer('parent_id')->nullable();
$table->string('tags')->nullable();
$table->string('name');
$table->string('rate', 11);
$table->string('host');
$table->string('port', 11);
$table->integer('server_port');
$table->string('cipher');
$table->char('obfs', 11)->nullable();
$table->string('obfs_settings')->nullable();
$table->tinyInteger('show')->default(0);
$table->integer('sort')->nullable();
$table->integer('created_at');
$table->integer('updated_at');
});
}
// Server Trojan
if (!Schema::hasTable('v2_server_trojan')) {
Schema::create('v2_server_trojan', function (Blueprint $table) {
$table->integer('id', true)->comment('节点ID');
$table->string('group_id')->comment('节点组');
$table->string('route_id')->nullable();
$table->integer('parent_id')->nullable()->comment('父节点');
$table->string('tags')->nullable()->comment('节点标签');
$table->string('name')->comment('节点名称');
$table->string('rate', 11)->comment('倍率');
$table->string('host')->comment('主机名');
$table->string('port', 11)->comment('连接端口');
$table->integer('server_port')->comment('服务端口');
$table->boolean('allow_insecure')->default(false)->comment('是否允许不安全');
$table->string('server_name')->nullable();
$table->boolean('show')->default(false)->comment('是否显示');
$table->integer('sort')->nullable();
$table->integer('created_at');
$table->integer('updated_at');
});
}
// Server Vless
if (!Schema::hasTable('v2_server_vless')) {
Schema::create('v2_server_vless', function (Blueprint $table) {
$table->integer('id', true);
$table->text('group_id');
$table->text('route_id')->nullable();
$table->string('name');
$table->integer('parent_id')->nullable();
$table->string('host');
$table->integer('port');
$table->integer('server_port');
$table->integer('tls');
$table->text('tls_settings')->nullable();
$table->string('flow', 64)->nullable();
$table->string('network', 11);
$table->text('network_settings')->nullable();
$table->text('tags')->nullable();
$table->string('rate', 11);
$table->boolean('show')->default(false);
$table->integer('sort')->nullable();
$table->integer('created_at');
$table->integer('updated_at');
});
}
// Server Vmess
if (!Schema::hasTable('v2_server_vmess')) {
Schema::create('v2_server_vmess', function (Blueprint $table) {
$table->integer('id', true);
$table->string('group_id');
$table->string('route_id')->nullable();
$table->string('name');
$table->integer('parent_id')->nullable();
$table->string('host');
$table->string('port', 11);
$table->integer('server_port');
$table->tinyInteger('tls')->default(0);
$table->string('tags')->nullable();
$table->string('rate', 11);
$table->string('network', 11);
$table->text('rules')->nullable();
$table->text('networkSettings')->nullable();
$table->text('tlsSettings')->nullable();
$table->text('ruleSettings')->nullable();
$table->text('dnsSettings')->nullable();
$table->boolean('show')->default(false);
$table->integer('sort')->nullable();
$table->integer('created_at');
$table->integer('updated_at');
});
}
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('v2_commission_log');
Schema::dropIfExists('v2_plan');
Schema::dropIfExists('v2_user');
Schema::dropIfExists('v2_mail_log');
Schema::dropIfExists('v2_log');
Schema::dropIfExists('v2_stat');
Schema::dropIfExists('v2_order');
Schema::dropIfExists('v2_coupon');
Schema::dropIfExists('v2_notice');
Schema::dropIfExists('v2_ticket');
Schema::dropIfExists('v2_settings');
Schema::dropIfExists('v2_ticket_message');
Schema::dropIfExists('v2_invite_code');
Schema::dropIfExists('v2_knowledge');
Schema::dropIfExists('v2_server_group');
Schema::dropIfExists('v2_server_route');
Schema::dropIfExists('v2_stat_server');
Schema::dropIfExists('v2_stat_user');
Schema::dropIfExists('v2_server_hysteria');
Schema::dropIfExists('v2_server_shadowsocks');
Schema::dropIfExists('v2_server_trojan');
Schema::dropIfExists('v2_server_vless');
Schema::dropIfExists('v2_server_vmess');
}
};

View File

@@ -1,37 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('v2_commission_log', function (Blueprint $table) {
$table->integer('id', true);
$table->integer('invite_user_id');
$table->integer('user_id');
$table->char('trade_no', 36);
$table->integer('order_amount');
$table->integer('get_amount');
$table->integer('created_at');
$table->integer('updated_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('v2_commission_log');
}
};

View File

@@ -1,43 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('v2_coupon', function (Blueprint $table) {
$table->integer('id', true);
$table->string('code');
$table->string('name');
$table->boolean('type');
$table->integer('value');
$table->boolean('show')->default(false);
$table->integer('limit_use')->nullable();
$table->integer('limit_use_with_user')->nullable();
$table->string('limit_plan_ids')->nullable();
$table->string('limit_period')->nullable();
$table->integer('started_at');
$table->integer('ended_at');
$table->integer('created_at');
$table->integer('updated_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('v2_coupon');
}
};

View File

@@ -1,36 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('v2_invite_code', function (Blueprint $table) {
$table->integer('id', true);
$table->integer('user_id');
$table->char('code', 32);
$table->boolean('status')->default(false);
$table->integer('pv')->default(0);
$table->integer('created_at');
$table->integer('updated_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('v2_invite_code');
}
};

View File

@@ -1,38 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('v2_knowledge', function (Blueprint $table) {
$table->integer('id', true);
$table->char('language', 5)->comment('語言');
$table->string('category')->comment('分類名');
$table->string('title')->comment('標題');
$table->text('body')->comment('內容');
$table->integer('sort')->nullable()->comment('排序');
$table->boolean('show')->default(false)->comment('顯示');
$table->integer('created_at')->comment('創建時間');
$table->integer('updated_at')->comment('更新時間');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('v2_knowledge');
}
};

View File

@@ -1,40 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('v2_log', function (Blueprint $table) {
$table->integer('id', true);
$table->text('title');
$table->string('level', 11)->nullable();
$table->string('host')->nullable();
$table->string('uri');
$table->string('method', 11);
$table->text('data')->nullable();
$table->string('ip', 128)->nullable();
$table->text('context')->nullable();
$table->integer('created_at');
$table->integer('updated_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('v2_log');
}
};

View File

@@ -1,36 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('v2_mail_log', function (Blueprint $table) {
$table->integer('id', true);
$table->string('email', 64);
$table->string('subject');
$table->string('template_name');
$table->text('error')->nullable();
$table->integer('created_at');
$table->integer('updated_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('v2_mail_log');
}
};

View File

@@ -1,37 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('v2_notice', function (Blueprint $table) {
$table->integer('id', true);
$table->string('title');
$table->text('content');
$table->boolean('show')->default(false);
$table->string('img_url')->nullable();
$table->string('tags')->nullable();
$table->integer('created_at');
$table->integer('updated_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('v2_notice');
}
};

View File

@@ -1,53 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('v2_order', function (Blueprint $table) {
$table->integer('id', true);
$table->integer('invite_user_id')->nullable();
$table->integer('user_id');
$table->integer('plan_id');
$table->integer('coupon_id')->nullable();
$table->integer('payment_id')->nullable();
$table->integer('type')->comment('1新购2续费3升级');
$table->string('period');
$table->string('trade_no', 36)->unique('trade_no');
$table->string('callback_no')->nullable();
$table->integer('total_amount');
$table->integer('handling_amount')->nullable();
$table->integer('discount_amount')->nullable();
$table->integer('surplus_amount')->nullable()->comment('剩余价值');
$table->integer('refund_amount')->nullable()->comment('退款金额');
$table->integer('balance_amount')->nullable()->comment('使用余额');
$table->text('surplus_order_ids')->nullable()->comment('折抵订单');
$table->boolean('status')->default(false)->comment('0待支付1开通中2已取消3已完成4已折抵');
$table->boolean('commission_status')->default(false)->comment('0待确认1发放中2有效3无效');
$table->integer('commission_balance')->default(0);
$table->integer('actual_commission_balance')->nullable()->comment('实际支付佣金');
$table->integer('paid_at')->nullable();
$table->integer('created_at');
$table->integer('updated_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('v2_order');
}
};

View File

@@ -1,42 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('v2_payment', function (Blueprint $table) {
$table->integer('id', true);
$table->char('uuid', 32);
$table->string('payment', 16);
$table->string('name');
$table->string('icon')->nullable();
$table->text('config');
$table->string('notify_domain', 128)->nullable();
$table->integer('handling_fee_fixed')->nullable();
$table->decimal('handling_fee_percent', 5)->nullable();
$table->boolean('enable')->default(false);
$table->integer('sort')->nullable();
$table->integer('created_at');
$table->integer('updated_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('v2_payment');
}
};

View File

@@ -1,50 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('v2_plan', function (Blueprint $table) {
$table->integer('id', true);
$table->integer('group_id');
$table->integer('transfer_enable');
$table->string('name');
$table->integer('speed_limit')->nullable();
$table->boolean('show')->default(false);
$table->integer('sort')->nullable();
$table->boolean('renew')->default(true);
$table->text('content')->nullable();
$table->integer('month_price')->nullable();
$table->integer('quarter_price')->nullable();
$table->integer('half_year_price')->nullable();
$table->integer('year_price')->nullable();
$table->integer('two_year_price')->nullable();
$table->integer('three_year_price')->nullable();
$table->integer('onetime_price')->nullable();
$table->integer('reset_price')->nullable();
$table->boolean('reset_traffic_method')->nullable();
$table->integer('capacity_limit')->nullable();
$table->integer('created_at');
$table->integer('updated_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('v2_plan');
}
};

View File

@@ -1,33 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('v2_server_group', function (Blueprint $table) {
$table->integer('id', true);
$table->string('name');
$table->integer('created_at');
$table->integer('updated_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('v2_server_group');
}
};

View File

@@ -1,47 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('v2_server_hysteria', function (Blueprint $table) {
$table->integer('id', true);
$table->string('group_id');
$table->string('route_id')->nullable();
$table->string('name');
$table->integer('parent_id')->nullable();
$table->string('host');
$table->string('port', 11);
$table->integer('server_port');
$table->string('tags')->nullable();
$table->string('rate', 11);
$table->boolean('show')->default(false);
$table->integer('sort')->nullable();
$table->integer('up_mbps');
$table->integer('down_mbps');
$table->string('server_name', 64)->nullable();
$table->boolean('insecure')->default(false);
$table->integer('created_at');
$table->integer('updated_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('v2_server_hysteria');
}
};

View File

@@ -1,36 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('v2_server_route', function (Blueprint $table) {
$table->integer('id', true);
$table->string('remarks');
$table->text('match');
$table->string('action', 11);
$table->string('action_value')->nullable();
$table->integer('created_at');
$table->integer('updated_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('v2_server_route');
}
};

View File

@@ -1,46 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('v2_server_shadowsocks', function (Blueprint $table) {
$table->integer('id', true);
$table->string('group_id');
$table->string('route_id')->nullable();
$table->integer('parent_id')->nullable();
$table->string('tags')->nullable();
$table->string('name');
$table->string('rate', 11);
$table->string('host');
$table->string('port', 11);
$table->integer('server_port');
$table->string('cipher');
$table->char('obfs', 11)->nullable();
$table->string('obfs_settings')->nullable();
$table->tinyInteger('show')->default(0);
$table->integer('sort')->nullable();
$table->integer('created_at');
$table->integer('updated_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('v2_server_shadowsocks');
}
};

View File

@@ -1,45 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('v2_server_trojan', function (Blueprint $table) {
$table->integer('id', true)->comment('节点ID');
$table->string('group_id')->comment('节点组');
$table->string('route_id')->nullable();
$table->integer('parent_id')->nullable()->comment('父节点');
$table->string('tags')->nullable()->comment('节点标签');
$table->string('name')->comment('节点名称');
$table->string('rate', 11)->comment('倍率');
$table->string('host')->comment('主机名');
$table->string('port', 11)->comment('连接端口');
$table->integer('server_port')->comment('服务端口');
$table->boolean('allow_insecure')->default(false)->comment('是否允许不安全');
$table->string('server_name')->nullable();
$table->boolean('show')->default(false)->comment('是否显示');
$table->integer('sort')->nullable();
$table->integer('created_at');
$table->integer('updated_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('v2_server_trojan');
}
};

View File

@@ -1,48 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('v2_server_vless', function (Blueprint $table) {
$table->integer('id', true);
$table->text('group_id');
$table->text('route_id')->nullable();
$table->string('name');
$table->integer('parent_id')->nullable();
$table->string('host');
$table->integer('port');
$table->integer('server_port');
$table->boolean('tls');
$table->text('tls_settings')->nullable();
$table->string('flow', 64)->nullable();
$table->string('network', 11);
$table->text('network_settings')->nullable();
$table->text('tags')->nullable();
$table->string('rate', 11);
$table->boolean('show')->default(false);
$table->integer('sort')->nullable();
$table->integer('created_at');
$table->integer('updated_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('v2_server_vless');
}
};

View File

@@ -1,50 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('v2_server_vmess', function (Blueprint $table) {
$table->integer('id', true);
$table->string('group_id');
$table->string('route_id')->nullable();
$table->string('name');
$table->integer('parent_id')->nullable();
$table->string('host');
$table->string('port', 11);
$table->integer('server_port');
$table->tinyInteger('tls')->default(0);
$table->string('tags')->nullable();
$table->string('rate', 11);
$table->string('network', 11);
$table->text('rules')->nullable();
$table->text('networkSettings')->nullable();
$table->text('tlsSettings')->nullable();
$table->text('ruleSettings')->nullable();
$table->text('dnsSettings')->nullable();
$table->boolean('show')->default(false);
$table->integer('sort')->nullable();
$table->integer('created_at');
$table->integer('updated_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('v2_server_vmess');
}
};

View File

@@ -1,40 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('v2_stat_server', function (Blueprint $table) {
$table->integer('id', true);
$table->integer('server_id')->index('server_id')->comment('节点id');
$table->char('server_type', 11)->comment('节点类型');
$table->bigInteger('u');
$table->bigInteger('d');
$table->char('record_type', 1)->comment('d day m month');
$table->integer('record_at')->index('record_at')->comment('记录时间');
$table->integer('created_at');
$table->integer('updated_at');
$table->unique(['server_id', 'server_type', 'record_at'], 'server_id_server_type_record_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('v2_stat_server');
}
};

View File

@@ -1,48 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('v2_stat', function (Blueprint $table) {
$table->integer('id', true);
$table->integer('record_at');
$table->char('record_type', 1);
$table->integer('order_count')->comment('订单数量');
$table->integer('order_total')->comment('订单合计');
$table->integer('commission_count');
$table->integer('commission_total')->comment('佣金合计');
$table->integer('paid_count');
$table->integer('paid_total');
$table->integer('register_count');
$table->integer('invite_count');
$table->string('transfer_used_total', 32);
$table->integer('created_at');
$table->integer('updated_at');
if(config('database.default') !== 'sqlite'){
$table->unique(['record_at']);
}
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('v2_stat');
}
};

View File

@@ -1,46 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('v2_stat_user', function (Blueprint $table) {
$table->integer('id', true);
$table->integer('user_id');
$table->decimal('server_rate', 10);
$table->bigInteger('u');
$table->bigInteger('d');
$table->char('record_type', 2);
$table->integer('record_at');
$table->integer('created_at');
$table->integer('updated_at');
// 如果是不是sqlite才添加多个索引
if(config('database.default') !== 'sqlite'){
$table->index(['user_id','server_rate','record_at']);
$table->unique(['server_rate', 'user_id', 'record_at'], 'server_rate_user_id_record_at');
}
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('v2_stat_user');
}
};

View File

@@ -1,35 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('v2_ticket_message', function (Blueprint $table) {
$table->integer('id', true);
$table->integer('user_id');
$table->integer('ticket_id');
$table->text('message');
$table->integer('created_at');
$table->integer('updated_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('v2_ticket_message');
}
};

View File

@@ -1,37 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('v2_ticket', function (Blueprint $table) {
$table->integer('id', true);
$table->integer('user_id');
$table->string('subject');
$table->boolean('level');
$table->boolean('status')->default(false)->comment('0:已开启 1:已关闭');
$table->boolean('reply_status')->default(true)->comment('0:待回复 1:已回复');
$table->integer('created_at');
$table->integer('updated_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('v2_ticket');
}
};

View File

@@ -1,61 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('v2_user', function (Blueprint $table) {
$table->integer('id', true);
$table->integer('invite_user_id')->nullable();
$table->bigInteger('telegram_id')->nullable();
$table->string('email', 64)->unique('email');
$table->string('password', 64);
$table->char('password_algo', 10)->nullable();
$table->char('password_salt', 10)->nullable();
$table->integer('balance')->default(0);
$table->integer('discount')->nullable();
$table->tinyInteger('commission_type')->default(0)->comment('0: system 1: period 2: onetime');
$table->integer('commission_rate')->nullable();
$table->integer('commission_balance')->default(0);
$table->integer('t')->default(0);
$table->bigInteger('u')->default(0);
$table->bigInteger('d')->default(0);
$table->bigInteger('transfer_enable')->default(0);
$table->boolean('banned')->default(false);
$table->boolean('is_admin')->default(false);
$table->integer('last_login_at')->nullable();
$table->boolean('is_staff')->default(false);
$table->integer('last_login_ip')->nullable();
$table->string('uuid', 36);
$table->integer('group_id')->nullable();
$table->integer('plan_id')->nullable();
$table->integer('speed_limit')->nullable();
$table->tinyInteger('remind_expire')->nullable()->default(1);
$table->tinyInteger('remind_traffic')->nullable()->default(1);
$table->char('token', 32);
$table->bigInteger('expired_at')->nullable()->default(0);
$table->text('remarks')->nullable();
$table->integer('created_at');
$table->integer('updated_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('v2_user');
}
};

View File

@@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('v2_order', function (Blueprint $table) {
$table->integer('commission_status')->nullable()->default(null)->comment('0待确认1发放中2有效3无效')->change();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('v2_order', function (Blueprint $table) {
$table->integer('commission_status')->default(false)->comment('0待确认1发放中2有效3无效')->change();
});
}
};

View File

@@ -0,0 +1,129 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
// Step 1: Add new columns first
Schema::table('v2_plan', function (Blueprint $table) {
$table->json('prices')->nullable()->after('name')
->comment('Store different duration prices and reset traffic price');
$table->boolean('sell')->default(false)->after('prices')->comment('is sell');
});
// Step 2: Migrate data to new format
DB::table('v2_plan')->orderBy('id')->chunk(100, function ($plans) {
foreach ($plans as $plan) {
$prices = array_filter([
'monthly' => $plan->month_price !== null ? $plan->month_price / 100 : null,
'quarterly' => $plan->quarter_price !== null ? $plan->quarter_price / 100 : null,
'half_yearly' => $plan->half_year_price !== null ? $plan->half_year_price / 100 : null,
'yearly' => $plan->year_price !== null ? $plan->year_price / 100 : null,
'two_yearly' => $plan->two_year_price !== null ? $plan->two_year_price / 100 : null,
'three_yearly' => $plan->three_year_price !== null ? $plan->three_year_price / 100 : null,
'onetime' => $plan->onetime_price !== null ? $plan->onetime_price / 100 : null,
'reset_traffic' => $plan->reset_price !== null ? $plan->reset_price / 100 : null
], function ($price) {
return $price !== null;
});
DB::table('v2_plan')
->where('id', $plan->id)
->update([
'prices' => json_encode($prices),
'sell' => $plan->show
]);
}
});
// Step 3: Optimize existing columns
Schema::table('v2_plan', function (Blueprint $table) {
// Modify existing columns to be more efficient
$table->unsignedInteger('group_id')->nullable()->change();
$table->unsignedBigInteger('transfer_enable')->nullable()
->comment('Transfer limit in bytes')->change();
$table->unsignedInteger('speed_limit')->nullable()
->comment('Speed limit in Mbps, 0 for unlimited')->change();
$table->integer('reset_traffic_method')->nullable()->default(0)
->comment('重置流量方式:0跟随系统设置、1每月1号、2按月重置、3不重置、4每年1月1日、5按年重置')->change();
$table->unsignedInteger('capacity_limit')->nullable()->default(0)
->comment('0 for unlimited')->change();
});
// Step 4: Drop old columns
Schema::table('v2_plan', function (Blueprint $table) {
$table->dropColumn([
'month_price',
'quarter_price',
'half_year_price',
'year_price',
'two_year_price',
'three_year_price',
'onetime_price',
'reset_price',
]);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Step 1: Add back old columns
Schema::table('v2_plan', function (Blueprint $table) {
$table->integer('month_price')->nullable();
$table->integer('quarter_price')->nullable();
$table->integer('half_year_price')->nullable();
$table->integer('year_price')->nullable();
$table->integer('two_year_price')->nullable();
$table->integer('three_year_price')->nullable();
$table->integer('onetime_price')->nullable();
$table->integer('reset_price')->nullable();
});
// Step 2: Restore data from new format to old format
DB::table('v2_plan')->orderBy('id')->chunk(100, function ($plans) {
foreach ($plans as $plan) {
$prices = json_decode($plan->prices, true) ?? [];
DB::table('v2_plan')
->where('id', $plan->id)
->update([
'month_price' => $prices['monthly'] * 100 ?? null,
'quarter_price' => $prices['quarterly'] * 100 ?? null,
'half_year_price' => $prices['half_yearly'] * 100 ?? null,
'year_price' => $prices['yearly'] * 100 ?? null,
'two_year_price' => $prices['two_yearly'] * 100 ?? null,
'three_year_price' => $prices['three_yearly'] * 100 ?? null,
'onetime_price' => $prices['onetime'] * 100 ?? null,
'reset_price' => $prices['reset_traffic'] * 100 ?? null,
]);
}
});
// Step 3: Drop new columns
Schema::table('v2_plan', function (Blueprint $table) {
$table->dropColumn([
'prices',
'sell'
]);
});
// Step 4: Restore column types to original
Schema::table('v2_plan', function (Blueprint $table) {
$table->integer('group_id')->change();
$table->integer('transfer_enable')->change();
$table->integer('speed_limit')->nullable()->change();
$table->boolean('reset_traffic_method')->nullable()->change();
$table->integer('capacity_limit')->nullable()->change();
});
}
};

View File

@@ -0,0 +1,523 @@
<?php
use App\Utils\Helper;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('v2_server', function (Blueprint $table) {
$table->id('id');
$table->string('type')->comment('Server Type');
$table->string('code')->nullable()->comment('Server Spectific Key');
$table->unsignedInteger('parent_id')->nullable()->comment('Parent Server ID');
$table->json('group_ids')->nullable()->comment('Group ID');
$table->json('route_ids')->nullable()->comment('Route ID');
$table->string('name')->comment('Server Name');
$table->decimal('rate', 8, 2)->comment('Traffic Rate');
$table->json('tags')->nullable()->comment('Server Tags');
$table->string('host')->comment('Server Host');
$table->string('port')->comment('Client Port');
$table->integer('server_port')->comment('Server Port');
$table->json('protocol_settings')->nullable();
$table->boolean('show')->default(false)->comment('Show in List');
$table->integer('sort')->nullable()->unsigned()->index();
$table->timestamps();
$table->unique(['type', 'code']);
});
// Migrate Trojan servers
$trojanServers = DB::table('v2_server_trojan')->get();
foreach ($trojanServers as $server) {
DB::table('v2_server')->insert([
'type' => 'trojan',
'code' => (string) $server->id,
'parent_id' => $server->parent_id,
'group_ids' => $server->group_id ?: "[]",
'route_ids' => $server->route_id ?: "[]",
'name' => $server->name,
'rate' => $server->rate,
'tags' => $server->tags ?: "[]",
'host' => $server->host,
'port' => $server->port,
'server_port' => $server->server_port,
'protocol_settings' => json_encode([
'allow_insecure' => $server->allow_insecure,
'server_name' => $server->server_name,
'network' => $server->network,
'network_settings' => $server->networkSettings
]),
'show' => $server->show,
'sort' => $server->sort,
'created_at' => date('Y-m-d H:i:s', $server->created_at),
'updated_at' => date('Y-m-d H:i:s', $server->updated_at)
]);
}
// Migrate VMess servers
$vmessServers = DB::table('v2_server_vmess')->get();
foreach ($vmessServers as $server) {
DB::table('v2_server')->insert([
'type' => 'vmess',
'code' => (string) $server->id,
'parent_id' => $server->parent_id,
'group_ids' => $server->group_id ?: "[]",
'route_ids' => $server->route_id ?: "[]",
'name' => $server->name,
'rate' => $server->rate,
'tags' => $server->tags ?: "[]",
'host' => $server->host,
'port' => $server->port,
'server_port' => $server->server_port,
'protocol_settings' => json_encode([
'tls' => $server->tls,
'network' => $server->network,
'rules' => json_decode($server->rules),
'network_settings' => json_decode($server->networkSettings),
'tls_settings' => json_decode($server->tlsSettings),
]),
'show' => $server->show,
'sort' => $server->sort,
'created_at' => date('Y-m-d H:i:s', $server->created_at),
'updated_at' => date('Y-m-d H:i:s', $server->updated_at)
]);
}
// Migrate VLESS servers
$vlessServers = DB::table('v2_server_vless')->get();
foreach ($vlessServers as $server) {
$tlsSettings = optional(json_decode($server->tls_settings));
DB::table('v2_server')->insert([
'type' => 'vless',
'code' => (string) $server->id,
'parent_id' => $server->parent_id,
'group_ids' => $server->group_id ?: "[]",
'route_ids' => $server->route_id ?: "[]",
'name' => $server->name,
'rate' => $server->rate,
'tags' => $server->tags ?: "[]",
'host' => $server->host,
'port' => $server->port,
'server_port' => $server->server_port,
'protocol_settings' => json_encode([
'tls' => $server->tls,
'tls_settings' => $tlsSettings,
'flow' => $server->flow,
'network' => $server->network,
'network_settings' => json_decode($server->network_settings),
'reality_settings' => ($tlsSettings && $tlsSettings->public_key && $tlsSettings->short_id && $tlsSettings->server_name) ? [
'public_key' => $tlsSettings->public_key,
'short_id' => $tlsSettings->short_id,
'server_name' => $tlsSettings->server_name,
'server_port' => $tlsSettings->server_port,
'private_key' => $tlsSettings->private_key,
] : null
]),
'show' => $server->show,
'sort' => $server->sort,
'created_at' => date('Y-m-d H:i:s', $server->created_at),
'updated_at' => date('Y-m-d H:i:s', $server->updated_at)
]);
}
// Migrate Shadowsocks servers
$ssServers = DB::table('v2_server_shadowsocks')->get();
foreach ($ssServers as $server) {
DB::table('v2_server')->insert([
'type' => 'shadowsocks',
'code' => (string) $server->id,
'parent_id' => $server->parent_id,
'group_ids' => $server->group_id ?: "[]",
'route_ids' => $server->route_id ?: "[]",
'name' => $server->name,
'rate' => $server->rate,
'tags' => $server->tags ?: "[]",
'host' => $server->host,
'port' => $server->port,
'server_port' => $server->server_port,
'protocol_settings' => json_encode([
'cipher' => $server->cipher,
'obfs' => $server->obfs,
'obfs_settings' => json_decode($server->obfs_settings)
]),
'show' => (bool) $server->show,
'sort' => $server->sort,
'created_at' => date('Y-m-d H:i:s', $server->created_at),
'updated_at' => date('Y-m-d H:i:s', $server->updated_at)
]);
}
// Migrate Hysteria servers
$hysteriaServers = DB::table(table: 'v2_server_hysteria')->get();
foreach ($hysteriaServers as $server) {
DB::table('v2_server')->insert([
'type' => 'hysteria',
'code' => (string) $server->id,
'parent_id' => $server->parent_id,
'group_ids' => $server->group_id ?: "[]",
'route_ids' => $server->route_id ?: "[]",
'name' => $server->name,
'rate' => $server->rate,
'tags' => $server->tags ?: "[]",
'host' => $server->host,
'port' => $server->port,
'server_port' => $server->server_port,
'protocol_settings' => json_encode([
'version' => $server->version,
'bandwidth' => [
'up' => $server->up_mbps,
'down' => $server->down_mbps,
],
'obfs' => [
'open' => $server->is_obfs,
'type' => 'salamander',
'password' => Helper::getServerKey($server->created_at, 16),
],
'tls' => [
'server_name' => $server->server_name,
'allow_insecure' => $server->insecure
]
]),
'show' => $server->show,
'sort' => $server->sort,
'created_at' => date('Y-m-d H:i:s', $server->created_at),
'updated_at' => date('Y-m-d H:i:s', $server->updated_at)
]);
}
// Update parent_id for all servers
$this->updateParentIds();
// Drop old tables
Schema::dropIfExists('v2_server_trojan');
Schema::dropIfExists('v2_server_vmess');
Schema::dropIfExists('v2_server_vless');
Schema::dropIfExists('v2_server_shadowsocks');
Schema::dropIfExists('v2_server_hysteria');
}
/**
* Update parent_id references for all servers
*/
private function updateParentIds(): void
{
// Get all servers that have a parent_id
$servers = DB::table('v2_server')
->whereNotNull('parent_id')
->get();
// Update each server's parent_id to reference the new table's id
foreach ($servers as $server) {
$parentId = DB::table('v2_server')
->where('type', $server->type)
->where('code', $server->parent_id)
->value('id');
if ($parentId) {
DB::table('v2_server')
->where('id', $server->id)
->update(['parent_id' => $parentId]);
}
}
}
/**
* Restore parent_id references when rolling back
*/
private function restoreParentIds(string $type, string $table): void
{
// Get all servers of the specified type that have a parent_id
$servers = DB::table($table)
->whereNotNull('parent_id')
->get();
// Update each server's parent_id to reference back to the original id
foreach ($servers as $server) {
$originalParentId = DB::table('v2_server')
->where('type', $type)
->where('id', $server->parent_id)
->value('code');
if ($originalParentId) {
DB::table($table)
->where('id', $server->id)
->update(['parent_id' => $originalParentId]);
}
}
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Recreate old tables
Schema::create('v2_server_trojan', function (Blueprint $table) {
$table->integer('id', true)->comment('节点ID');
$table->string('group_id')->comment('节点组');
$table->string('route_id')->nullable();
$table->string('ips')->nullable();
$table->string('excludes')->nullable();
$table->integer('parent_id')->nullable()->comment('父节点');
$table->string('tags')->nullable()->comment('节点标签');
$table->string('name')->comment('节点名称');
$table->string('rate', 11)->comment('倍率');
$table->string('host')->comment('主机名');
$table->string('port', 11)->comment('连接端口');
$table->integer('server_port')->comment('服务端口');
$table->boolean('allow_insecure')->default(false)->comment('是否允许不安全');
$table->string('server_name')->nullable();
$table->string('network')->nullable();
$table->text('networkSettings')->nullable();
$table->boolean('show')->default(false)->comment('是否显示');
$table->integer('sort')->nullable();
$table->integer('created_at');
$table->integer('updated_at');
});
Schema::create('v2_server_vmess', function (Blueprint $table) {
$table->integer('id', true);
$table->string('group_id');
$table->string('route_id')->nullable();
$table->string('ips')->nullable();
$table->string('excludes')->nullable();
$table->string('name');
$table->integer('parent_id')->nullable();
$table->string('host');
$table->string('port', 11);
$table->integer('server_port');
$table->tinyInteger('tls')->default(0);
$table->string('tags')->nullable();
$table->string('rate', 11);
$table->string('network', 11);
$table->text('rules')->nullable();
$table->text('networkSettings')->nullable();
$table->text('tlsSettings')->nullable();
$table->boolean('show')->default(false);
$table->integer('sort')->nullable();
$table->integer('created_at');
$table->integer('updated_at');
});
Schema::create('v2_server_vless', function (Blueprint $table) {
$table->integer('id', true);
$table->text('group_id');
$table->text('route_id')->nullable();
$table->string('ips')->nullable();
$table->string('excludes')->nullable();
$table->string('name');
$table->integer('parent_id')->nullable();
$table->string('host');
$table->integer('port');
$table->integer('server_port');
$table->boolean('tls');
$table->text('tls_settings')->nullable();
$table->string('flow', 64)->nullable();
$table->string('network', 11);
$table->text('network_settings')->nullable();
$table->text('tags')->nullable();
$table->string('rate', 11);
$table->boolean('show')->default(false);
$table->integer('sort')->nullable();
$table->integer('created_at');
$table->integer('updated_at');
});
Schema::create('v2_server_shadowsocks', function (Blueprint $table) {
$table->integer('id', true);
$table->string('group_id');
$table->string('route_id')->nullable();
$table->string('ips')->nullable();
$table->string('excludes')->nullable();
$table->integer('parent_id')->nullable();
$table->string('tags')->nullable();
$table->string('name');
$table->string('rate', 11);
$table->string('host');
$table->string('port', 11);
$table->integer('server_port');
$table->string('cipher');
$table->char('obfs', 11)->nullable();
$table->string('obfs_settings')->nullable();
$table->tinyInteger('show')->default(0);
$table->integer('sort')->nullable();
$table->integer('created_at');
$table->integer('updated_at');
});
Schema::create('v2_server_hysteria', function (Blueprint $table) {
$table->integer('id', true);
$table->string('group_id');
$table->string('route_id')->nullable();
$table->string('ips')->nullable();
$table->string('excludes')->nullable();
$table->string('name');
$table->integer('parent_id')->nullable();
$table->string('host');
$table->string('port', 11);
$table->integer('server_port');
$table->string('tags')->nullable();
$table->string('rate', 11);
$table->boolean('show')->default(false);
$table->integer('sort')->nullable();
$table->tinyInteger('version', false, true)->default(1)->comment('hysteria版本,Version:1\2');
$table->boolean('is_obfs')->default(true)->comment('是否开启obfs');
$table->string('alpn')->nullable();
$table->integer('up_mbps');
$table->integer('down_mbps');
$table->string('server_name', 64)->nullable();
$table->boolean('insecure')->default(false);
$table->integer('created_at');
$table->integer('updated_at');
});
// Migrate data back to old tables
$servers = DB::table('v2_server')->get();
foreach ($servers as $server) {
$settings = json_decode($server->protocol_settings, true);
$timestamp = strtotime($server->created_at);
$updated = strtotime($server->updated_at);
switch ($server->type) {
case 'trojan':
DB::table('v2_server_trojan')->insert([
'id' => (int) $server->code,
'group_id' => $server->group_ids,
'route_id' => $server->route_ids,
'parent_id' => $server->parent_id,
'tags' => $server->tags,
'name' => $server->name,
'rate' => (string) $server->rate,
'host' => $server->host,
'port' => $server->port,
'server_port' => $server->server_port,
'allow_insecure' => $settings['allow_insecure'],
'server_name' => $settings['server_name'],
'network' => $settings['network'] ?? null,
'networkSettings' => $settings['network_settings'] ?? null,
'show' => $server->show,
'sort' => $server->sort,
'created_at' => $timestamp,
'updated_at' => $updated
]);
break;
case 'vmess':
DB::table('v2_server_vmess')->insert([
'id' => (int) $server->code,
'group_id' => $server->group_ids,
'route_id' => $server->route_ids,
'name' => $server->name,
'parent_id' => $server->parent_id,
'host' => $server->host,
'port' => $server->port,
'server_port' => $server->server_port,
'tls' => $settings['tls'],
'tags' => $server->tags,
'rate' => (string) $server->rate,
'network' => $settings['network'],
'rules' => json_encode($settings['rules']),
'networkSettings' => json_encode($settings['network_settings']),
'tlsSettings' => json_encode($settings['tls_settings']),
'show' => $server->show,
'sort' => $server->sort,
'created_at' => $timestamp,
'updated_at' => $updated
]);
break;
case 'vless':
// 处理 reality settings
$tlsSettings = $settings['tls_settings'] ?? new \stdClass();
if (isset($settings['reality_settings'])) {
$tlsSettings = array_merge((array) $tlsSettings, [
'public_key' => $settings['reality_settings']['public_key'],
'short_id' => $settings['reality_settings']['short_id'],
'server_name' => explode(':', $settings['reality_settings']['dest'])[0],
'server_port' => explode(':', $settings['reality_settings']['dest'])[1] ?? null,
'private_key' => $settings['reality_settings']['private_key']
]);
}
DB::table('v2_server_vless')->insert([
'id' => (int) $server->code,
'group_id' => $server->group_ids,
'route_id' => $server->route_ids,
'name' => $server->name,
'parent_id' => $server->parent_id,
'host' => $server->host,
'port' => $server->port,
'server_port' => $server->server_port,
'tls' => $settings['tls'],
'tls_settings' => json_encode($tlsSettings),
'flow' => $settings['flow'],
'network' => $settings['network'],
'network_settings' => json_encode($settings['network_settings']),
'tags' => $server->tags,
'rate' => (string) $server->rate,
'show' => $server->show,
'sort' => $server->sort,
'created_at' => $timestamp,
'updated_at' => $updated
]);
break;
case 'shadowsocks':
DB::table('v2_server_shadowsocks')->insert([
'id' => (int) $server->code,
'group_id' => $server->group_ids,
'route_id' => $server->route_ids,
'parent_id' => $server->parent_id,
'tags' => $server->tags,
'name' => $server->name,
'rate' => (string) $server->rate,
'host' => $server->host,
'port' => $server->port,
'server_port' => $server->server_port,
'cipher' => $settings['cipher'],
'obfs' => $settings['obfs'],
'obfs_settings' => json_encode($settings['obfs_settings']),
'show' => (int) $server->show,
'sort' => $server->sort,
'created_at' => $timestamp,
'updated_at' => $updated
]);
break;
case 'hysteria':
DB::table('v2_server_hysteria')->insert([
'id' => (int) $server->code,
'group_id' => $server->group_ids,
'route_id' => $server->route_ids,
'name' => $server->name,
'parent_id' => $server->parent_id,
'host' => $server->host,
'port' => $server->port,
'server_port' => $server->server_port,
'tags' => $server->tags,
'rate' => (string) $server->rate,
'show' => $server->show,
'sort' => $server->sort,
'up_mbps' => $settings['bandwidth']['up'],
'down_mbps' => $settings['bandwidth']['down'],
'server_name' => $settings['tls']['server_name'],
'insecure' => $settings['tls']['allow_insecure'],
'created_at' => $timestamp,
'updated_at' => $updated
]);
break;
}
}
// Restore parent_id references for each server type
$this->restoreParentIds('trojan', 'v2_server_trojan');
$this->restoreParentIds('vmess', 'v2_server_vmess');
$this->restoreParentIds('vless', 'v2_server_vless');
$this->restoreParentIds('shadowsocks', 'v2_server_shadowsocks');
$this->restoreParentIds('hysteria', 'v2_server_hysteria');
// Drop new table
Schema::dropIfExists('v2_server');
}
};

View File

@@ -0,0 +1,31 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void
{
Schema::table('v2_plan', function (Blueprint $table) {
$table->unsignedInteger('device_limit')->nullable()->after('speed_limit');
});
Schema::table('v2_user', function (Blueprint $table) {
$table->integer('device_limit')->nullable()->after('expired_at');
$table->integer('online_count')->nullable()->after('device_limit');
$table->timestamp('last_online_at')->nullable()->after('online_count');
});
}
public function down(): void
{
Schema::table('v2_user', function (Blueprint $table) {
$table->dropColumn('device_limit');
$table->dropColumn('online_count');
$table->dropColumn('last_online_at');
});
Schema::table('v2_plan', function (Blueprint $table) {
$table->dropColumn('device_limit');
});
}
};

View File

@@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('v2_notice', function (Blueprint $table) {
$table->integer('sort')->nullable()->after('id')->index();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('v2_notice', function (Blueprint $table) {
$table->dropColumn('sort');
});
}
};

View File

@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
DB::table('v2_order')->where('commission_status', null)->update([
'commission_status' => 0
]);
Schema::table('v2_order', function (Blueprint $table) {
$table->integer('commission_status')->default(value: 0)->comment('0待确认1发放中2有效3无效')->change();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('v2_order', function (Blueprint $table) {
$table->integer('commission_status')->nullable()->comment('0待确认1发放中2有效3无效')->change();
});
}
};

View File

@@ -0,0 +1,56 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;
return new class extends Migration {
/**
* 旧的价格字段到新周期的映射关系
*/
private const PERIOD_MAPPING = [
'month_price' => 'monthly',
'quarter_price' => 'quarterly',
'half_year_price' => 'half_yearly',
'year_price' => 'yearly',
'two_year_price' => 'two_yearly',
'three_year_price' => 'three_yearly',
'onetime_price' => 'onetime',
'reset_price' => 'reset_traffic'
];
/**
* Run the migrations.
*/
public function up(): void
{
// 批量更新订单的周期字段
foreach (self::PERIOD_MAPPING as $oldPeriod => $newPeriod) {
DB::table('v2_order')
->where('period', $oldPeriod)
->update(['period' => $newPeriod]);
}
// 检查是否还有未转换的记录
$unconvertedCount = DB::table('v2_order')
->whereNotIn('period', array_values(self::PERIOD_MAPPING))
->count();
if ($unconvertedCount > 0) {
Log::warning("Found {$unconvertedCount} orders with unconverted period values");
}
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// 回滚操作 - 将新的周期值转换回旧的价格字段名
foreach (self::PERIOD_MAPPING as $oldPeriod => $newPeriod) {
DB::table('v2_order')
->where('period', $newPeriod)
->update(['period' => $oldPeriod]);
}
}
};

View File

@@ -0,0 +1,93 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('v2_user', function (Blueprint $table) {
$table->index('t');
$table->index('online_count');
$table->index('created_at');
});
Schema::table('v2_order', function (Blueprint $table) {
$table->index('created_at');
$table->index('status');
$table->index('total_amount');
$table->index('commission_status');
$table->index('invite_user_id');
$table->index('commission_balance');
});
Schema::table('v2_stat_server', function (Blueprint $table) {
$table->index('server_id');
$table->index('record_at');
$table->index('u');
$table->index('d');
});
Schema::table('v2_stat_user', function (Blueprint $table) {
$table->index('u');
$table->index('d');
});
Schema::table('v2_commission_log', function (Blueprint $table) {
$table->index('created_at');
$table->index('get_amount');
});
Schema::table('v2_ticket', function (Blueprint $table) {
$table->index('status');
$table->index('created_at');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('v2_user', function (Blueprint $table) {
$table->dropIndex(['t']);
$table->dropIndex(['online_count']);
$table->dropIndex(['created_at']);
});
Schema::table('v2_order', function (Blueprint $table) {
$table->dropIndex(['created_at']);
$table->dropIndex(['status']);
$table->dropIndex(['total_amount']);
$table->dropIndex(['commission_status']);
$table->dropIndex(['invite_user_id']);
$table->dropIndex(['commission_balance']);
});
Schema::table('v2_stat_server', function (Blueprint $table) {
$table->dropIndex(['server_id']);
$table->dropIndex(['record_at']);
$table->dropIndex(['u']);
$table->dropIndex(['d']);
});
Schema::table('v2_stat_user', function (Blueprint $table) {
$table->dropIndex(['u']);
$table->dropIndex(['d']);
});
Schema::table('v2_commission_log', function (Blueprint $table) {
$table->dropIndex(['created_at']);
$table->dropIndex(['get_amount']);
});
Schema::table('v2_ticket', function (Blueprint $table) {
$table->dropIndex(['status']);
$table->dropIndex(['created_at']);
});
}
};

View File

@@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('v2_order', function (Blueprint $table) {
$table->index('updated_at');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('v2_order', function (Blueprint $table) {
$table->dropIndex(['updated_at']);
});
}
};

View File

@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('v2_plugins', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('code')->unique();
$table->string('version', 50);
$table->boolean('is_enabled')->default(false);
$table->json('config')->nullable();
$table->timestamp('installed_at')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('v2_plugins');
}
};