first commit
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
<?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('sys_user')) {
|
||||
Schema::create('sys_user', function (Blueprint $table) {
|
||||
$table->increments('id')->comment('系统用户ID');
|
||||
$table->string('username', 20)->unique()->comment('用户名');
|
||||
$table->string('password', 100)->comment('密码');
|
||||
$table->string('nickname', 20)->default('')->comment('昵称');
|
||||
$table->integer('avatar_id')->nullable()->comment('头像');
|
||||
$table->integer('sex')->default(0)->comment('性别(男、女)');
|
||||
$table->string('bio', 255)->default('')->nullable()->comment('个人简介');
|
||||
$table->string('mobile', 20)->default('')->comment('手机号');
|
||||
$table->string('email', 50)->unique()->comment('邮箱');
|
||||
$table->timestamp('email_verified_at')->nullable();
|
||||
$table->integer('dept_id')->default(0)->comment('部门ID');
|
||||
$table->string('login_ip', 60)->default('')->comment('最后登录IP');
|
||||
$table->timestamp('login_time')->nullable()->comment('最后登录时间');
|
||||
$table->integer('status')->default(1)->comment('状态(1正常 0停用)');
|
||||
$table->rememberToken();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
$table->comment('系统用户表');
|
||||
});
|
||||
}
|
||||
|
||||
// 系统用户角色表
|
||||
if (! Schema::hasTable('sys_role')) {
|
||||
Schema::create('sys_role', function (Blueprint $table) {
|
||||
$table->increments('id')->comment('角色ID');
|
||||
$table->string('name', 20)->default('')->comment('角色名称');
|
||||
$table->integer('sort')->default(0)->comment('排序');
|
||||
$table->string('description', 100)->default('')->comment('角色描述');
|
||||
$table->integer('status')->default(1)->comment('状态(1正常 0停用)');
|
||||
$table->timestamps();
|
||||
$table->comment('系统用户角色表');
|
||||
});
|
||||
}
|
||||
|
||||
// 系统用户角色中间表
|
||||
if (! Schema::hasTable('sys_user_role')) {
|
||||
Schema::create('sys_user_role', function (Blueprint $table) {
|
||||
$table->integer('user_id')->comment('用户ID');
|
||||
$table->integer('role_id')->comment('角色ID');
|
||||
$table->unique(['user_id', 'role_id'], 'user_role_unique');
|
||||
$table->comment('系统用户角色关联表');
|
||||
});
|
||||
}
|
||||
|
||||
// 系统用户部门表
|
||||
if (! Schema::hasTable('sys_dept')) {
|
||||
Schema::create('sys_dept', function (Blueprint $table) {
|
||||
$table->increments('id')->comment('部门ID');
|
||||
$table->integer('parent_id')->default(0)->comment('父级ID');
|
||||
$table->string('name', 100)->default('')->comment('部门名称');
|
||||
$table->string('code', 100)->unique()->default('')->comment('部门编码');
|
||||
$table->tinyInteger('type')->default(0)->comment('部门类型 0:公司 1:部门 2:岗位');
|
||||
$table->integer('sort')->default(0)->comment('排序');
|
||||
$table->string('phone', '20')->default('')->nullable()->comment('部门电话');
|
||||
$table->string('email', '50')->default('')->nullable()->comment('部门邮箱');
|
||||
$table->string('address', '255')->default('')->nullable()->comment('部门地址');
|
||||
$table->string('remark', '255')->default('')->nullable()->comment('备注');
|
||||
$table->integer('status')->default(0)->comment('部门状态(0正常 1停用)');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
$table->comment('系统用户部门表');
|
||||
});
|
||||
}
|
||||
|
||||
// 系统用户权限表
|
||||
if (! Schema::hasTable('sys_rule')) {
|
||||
Schema::create('sys_rule', function (Blueprint $table) {
|
||||
$table->increments('id')->comment('权限ID');
|
||||
$table->integer('parent_id')->default(0)->comment('父级ID');
|
||||
$table->string('type', 20)->comment("类型:'menu' | 'route' | 'rule'");
|
||||
$table->string('key', 100)->unique()->comment('唯一标识');
|
||||
$table->string('name', 100)->comment('名称');
|
||||
$table->string('path', 100)->nullable()->comment('路径');
|
||||
$table->string('icon', 100)->nullable()->comment('图标');
|
||||
$table->integer('order')->default(0)->comment('排序');
|
||||
$table->string('local', 100)->nullable()->comment('语言包');
|
||||
$table->integer('status')->default(1)->comment('状态:1、正常,0、禁用');
|
||||
$table->integer('hidden')->default(1)->comment('显示:1、显示,0、隐藏');
|
||||
$table->integer('link')->default(0)->comment('是否外链:1、是,0、否');
|
||||
$table->timestamps();
|
||||
$table->comment('系统用户权限表');
|
||||
});
|
||||
}
|
||||
|
||||
// 角色权限关联表
|
||||
if (! Schema::hasTable('sys_role_rule')) {
|
||||
Schema::create('sys_role_rule', function (Blueprint $table) {
|
||||
$table->integer('role_id')->comment('角色ID');
|
||||
$table->integer('rule_id')->comment('权限ID');
|
||||
$table->primary(['role_id', 'rule_id'], 'role_rule_primary');
|
||||
$table->comment('角色权限关联表');
|
||||
});
|
||||
}
|
||||
|
||||
// 登录日志表
|
||||
if (! Schema::hasTable('sys_login_record')) {
|
||||
Schema::create('sys_login_record', function (Blueprint $table) {
|
||||
$table->increments('id')->comment('记录ID');
|
||||
$table->string('username', 20)->default('')->comment('用户名');
|
||||
$table->integer('user_id')->comment('用户ID');
|
||||
$table->string('ipaddr', 60)->default('')->comment('登录IP');
|
||||
$table->string('login_location', 255)->default('')->comment('登录地点');
|
||||
$table->string('browser', 255)->default('')->comment('浏览器');
|
||||
$table->string('os', 255)->default('')->comment('操作系统');
|
||||
$table->string('status', 1)->default('0')->comment('登录状态(0成功 1失败)');
|
||||
$table->string('msg', 255)->default('')->comment('提示消息');
|
||||
$table->timestamp('login_time')->comment('登录时间');
|
||||
$table->comment('系统用户登录日志表');
|
||||
});
|
||||
}
|
||||
|
||||
// token 表
|
||||
if (! Schema::hasTable('sys_access_token')) {
|
||||
Schema::create('sys_access_token', 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();
|
||||
$table->comment('token table');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('sys_user');
|
||||
Schema::dropIfExists('sys_rule');
|
||||
Schema::dropIfExists('sys_dept');
|
||||
Schema::dropIfExists('sys_role');
|
||||
Schema::dropIfExists('sys_user_role');
|
||||
Schema::dropIfExists('sys_role_rule');
|
||||
Schema::dropIfExists('sys_login_record');
|
||||
Schema::dropIfExists('sys_access_token');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,51 @@
|
||||
<?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('sys_dict')) {
|
||||
Schema::create('sys_dict', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->string('name', 100)->comment('字典名称');
|
||||
$table->string('code', 100)->unique()->comment('字典编码');
|
||||
$table->string('describe', 500)->nullable()->comment('字典描述');
|
||||
$table->unsignedTinyInteger('status')->default(0)->comment('状态:0正常 1停用');
|
||||
$table->unsignedInteger('sort')->default(0)->comment('排序');
|
||||
$table->timestamps();
|
||||
$table->comment('字典类型表');
|
||||
});
|
||||
}
|
||||
if (! Schema::hasTable('sys_dict_item')) {
|
||||
Schema::create('sys_dict_item', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->unsignedBigInteger('dict_id')->comment('字典ID');
|
||||
$table->string('label', 100)->comment('字典标签');
|
||||
$table->string('value', 100)->comment('字典键值');
|
||||
$table->string('color', 50)->default('default')->comment('颜色');
|
||||
$table->unsignedTinyInteger('status')->default(0)->comment('状态:0正常 1停用');
|
||||
$table->unsignedInteger('sort')->default(0)->comment('排序');
|
||||
$table->timestamps();
|
||||
$table->index('dict_id');
|
||||
$table->comment('字典数据表');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('sys_dict');
|
||||
Schema::dropIfExists('sys_dict_item');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,53 @@
|
||||
<?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('sys_file')) {
|
||||
Schema::create('sys_file', function (Blueprint $table) {
|
||||
$table->increments('id')->comment('文件ID');
|
||||
$table->integer('group_id')->default(0)->comment('文件分组ID');
|
||||
$table->integer('channel')->default(10)->comment('上传来源(10:系统用户 20:App用户端)');
|
||||
$table->string('disk', 10)->comment('存储方式');
|
||||
$table->integer('file_type')->comment('文件类型');
|
||||
$table->string('file_name', 255)->comment('文件名称');
|
||||
$table->string('file_path', 255)->comment('文件路径');
|
||||
$table->integer('file_size')->comment('文件大小(字节)');
|
||||
$table->string('file_ext', 20)->comment('文件扩展名');
|
||||
$table->integer('uploader_id')->comment('上传者用户ID');
|
||||
$table->softDeletes();
|
||||
$table->timestamps();
|
||||
$table->comment('文件表');
|
||||
});
|
||||
}
|
||||
if (! Schema::hasTable('sys_file_group')) {
|
||||
Schema::create('sys_file_group', function (Blueprint $table) {
|
||||
$table->increments('id')->comment('文件分组ID');
|
||||
$table->integer('parent_id')->default(0)->comment('上级ID');
|
||||
$table->string('name', 50)->comment('文件名称');
|
||||
$table->integer('sort')->comment('分组排序');
|
||||
$table->string('describe', 500)->nullable()->comment('分组描述');
|
||||
$table->timestamps();
|
||||
$table->comment('文件分组表');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('sys_file');
|
||||
Schema::dropIfExists('sys_file_group');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,51 @@
|
||||
<?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('sys_site_config_items')) {
|
||||
Schema::create('sys_site_config_items', function (Blueprint $table) {
|
||||
$table->bigIncrements('id');
|
||||
$table->string('key', 50)->comment('设置项标示');
|
||||
$table->string('title', 50)->comment('设置标题');
|
||||
$table->string('describe', 500)->nullable()->default('')->comment('设置项描述');
|
||||
$table->string('values', 255)->nullable()->default('')->comment('设置值');
|
||||
$table->string('type', 50)->comment('设置类型');
|
||||
$table->string('options', 500)->nullable()->comment('options配置');
|
||||
$table->string('props', 500)->nullable()->comment('props配置');
|
||||
$table->integer('group_id')->comment('分组ID');
|
||||
$table->integer('sort')->comment('排序');
|
||||
$table->timestamps();
|
||||
$table->comment('系统设置表');
|
||||
$table->unique(['key', 'group_id']);
|
||||
});
|
||||
}
|
||||
if (! Schema::hasTable('sys_site_config_group')) {
|
||||
Schema::create('sys_site_config_group', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->string('title', 50)->comment('分组标题');
|
||||
$table->string('key', 50)->comment('分组KEY');
|
||||
$table->string('remark', 255)->nullable()->comment('备注描述');
|
||||
$table->timestamps();
|
||||
$table->comment('设置分组表');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('sys_site_config_items');
|
||||
Schema::dropIfExists('sys_site_config_group');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,36 @@
|
||||
<?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('user')) {
|
||||
Schema::create('user', function (Blueprint $table) {
|
||||
$table->increments('id')->comment('用户ID');
|
||||
$table->string('username', 20)->unique()->comment('用户名');
|
||||
$table->string('password', 100)->comment('密码');
|
||||
$table->string('nickname', 20)->default('')->comment('昵称');
|
||||
$table->string('email', 50)->default('')->comment('邮箱');
|
||||
$table->timestamp('email_verified_at')->nullable();
|
||||
$table->rememberToken();
|
||||
$table->timestamps();
|
||||
$table->comment('APP用户表');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('user');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,57 @@
|
||||
<?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('sys_jobs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('queue')->index();
|
||||
$table->longText('payload');
|
||||
$table->unsignedTinyInteger('attempts');
|
||||
$table->unsignedInteger('reserved_at')->nullable();
|
||||
$table->unsignedInteger('available_at');
|
||||
$table->unsignedInteger('created_at');
|
||||
});
|
||||
|
||||
Schema::create('sys_job_batches', function (Blueprint $table) {
|
||||
$table->string('id')->primary();
|
||||
$table->string('name');
|
||||
$table->integer('total_jobs');
|
||||
$table->integer('pending_jobs');
|
||||
$table->integer('failed_jobs');
|
||||
$table->longText('failed_job_ids');
|
||||
$table->mediumText('options')->nullable();
|
||||
$table->integer('cancelled_at')->nullable();
|
||||
$table->integer('created_at');
|
||||
$table->integer('finished_at')->nullable();
|
||||
});
|
||||
|
||||
Schema::create('sys_failed_jobs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('uuid')->unique();
|
||||
$table->text('connection');
|
||||
$table->text('queue');
|
||||
$table->longText('payload');
|
||||
$table->longText('exception');
|
||||
$table->timestamp('failed_at')->useCurrent();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('sys_jobs');
|
||||
Schema::dropIfExists('sys_job_batches');
|
||||
Schema::dropIfExists('sys_failed_jobs');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
<?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
|
||||
{
|
||||
if (! Schema::hasTable('sys_app_settings')) {
|
||||
Schema::create('sys_app_settings', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('key')->unique()->index()->comment('配置键(点号表示法)');
|
||||
$table->tinyInteger('type')->index()->comment('类型枚举:10=String 15=Bool 20=Number 30=Array 40=Object 50=EncryptedString');
|
||||
$table->integer('n')->nullable()->comment('数字/布尔值');
|
||||
$table->string('s')->nullable()->comment('字符串值');
|
||||
$table->text('e')->nullable()->comment('扩展值:JSON/序列化/加密');
|
||||
$table->text('description')->nullable()->comment('描述');
|
||||
$table->timestamps();
|
||||
$table->comment('应用配置表(el-settings 风格列式类型存储)');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('sys_app_settings');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,70 @@
|
||||
<?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('agents')){
|
||||
Schema::create('agents', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('namespace', 500)->unique()->comment('完整类命名空间');
|
||||
$table->string('icon', 100)->nullable()->comment('图标');
|
||||
$table->string('name', 100)->comment('显示名称');
|
||||
$table->text('description')->nullable()->comment('描述');
|
||||
$table->json('tags')->nullable()->comment('标签');
|
||||
$table->boolean('enabled')->default(true)->comment('是否启用');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
if (! Schema::hasTable('agent_conversations')) {
|
||||
Schema::create('agent_conversations', function (Blueprint $table) {
|
||||
$table->string('id', 36)->primary();
|
||||
$table->foreignId('user_id')->nullable();
|
||||
$table->string('title');
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['user_id', 'updated_at']);
|
||||
});
|
||||
}
|
||||
|
||||
if (! Schema::hasTable('agent_conversation_messages')) {
|
||||
Schema::create('agent_conversation_messages', function (Blueprint $table) {
|
||||
$table->string('id', 36)->primary();
|
||||
$table->string('conversation_id', 36)->index();
|
||||
$table->foreignId('user_id')->nullable();
|
||||
$table->string('agent');
|
||||
$table->string('role', 25);
|
||||
$table->text('content');
|
||||
$table->text('attachments');
|
||||
$table->text('tool_calls');
|
||||
$table->text('tool_results');
|
||||
$table->text('usage');
|
||||
$table->text('meta');
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['conversation_id', 'user_id', 'updated_at'], 'conversation_index');
|
||||
$table->index(['user_id']);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('agents');
|
||||
Schema::dropIfExists('agent_conversations');
|
||||
Schema::dropIfExists('agent_conversation_messages');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,51 @@
|
||||
<?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('sys_carousel')) {
|
||||
Schema::create('sys_carousel', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->string('title', 100)->comment('轮播图标题');
|
||||
$table->integer('image_id')->comment('轮播图图片信息(JSON)');
|
||||
$table->string('link', 500)->nullable()->default('')->comment('跳转链接');
|
||||
$table->unsignedTinyInteger('status')->default(0)->comment('状态:0=启用,1=禁用');
|
||||
$table->integer('sort')->default(0)->comment('排序(数字越大越靠前)');
|
||||
$table->timestamps();
|
||||
$table->comment('首页轮播图管理表');
|
||||
});
|
||||
}
|
||||
|
||||
// 首页宫格导航表
|
||||
if (! Schema::hasTable('sys_grid_nav')) {
|
||||
Schema::create('sys_grid_nav', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->string('title', 100)->comment('导航标题');
|
||||
$table->integer('image_id')->comment('导航图标信息(JSON)');
|
||||
$table->string('link', 500)->nullable()->default('')->comment('跳转链接');
|
||||
$table->unsignedTinyInteger('status')->default(0)->comment('状态:0=启用,1=禁用');
|
||||
$table->integer('sort')->default(0)->comment('排序(数字越大越靠前)');
|
||||
$table->timestamps();
|
||||
$table->comment('首页宫格导航管理表');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('sys_carousel');
|
||||
Schema::dropIfExists('sys_grid_nav');
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user