tsett
This commit is contained in:
1
database/.gitignore
vendored
Normal file
1
database/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.sqlite*
|
||||
44
database/factories/UserFactory.php
Normal file
44
database/factories/UserFactory.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
|
||||
*/
|
||||
class UserFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The current password being used by the factory.
|
||||
*/
|
||||
protected static ?string $password;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'name' => fake()->name(),
|
||||
'email' => fake()->unique()->safeEmail(),
|
||||
'email_verified_at' => now(),
|
||||
'password' => static::$password ??= Hash::make('password'),
|
||||
'remember_token' => Str::random(10),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the model's email address should be unverified.
|
||||
*/
|
||||
public function unverified(): static
|
||||
{
|
||||
return $this->state(fn (array $attributes) => [
|
||||
'email_verified_at' => null,
|
||||
]);
|
||||
}
|
||||
}
|
||||
32
database/migrations/2014_10_12_000000_create_users_table.php
Normal file
32
database/migrations/2014_10_12_000000_create_users_table.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?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('users', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->string('email')->unique();
|
||||
$table->timestamp('email_verified_at')->nullable();
|
||||
$table->string('password');
|
||||
$table->rememberToken();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('users');
|
||||
}
|
||||
};
|
||||
@@ -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::create('password_reset_tokens', function (Blueprint $table) {
|
||||
$table->string('email')->primary();
|
||||
$table->string('token');
|
||||
$table->timestamp('created_at')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('password_reset_tokens');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
<?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('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('failed_jobs');
|
||||
}
|
||||
};
|
||||
@@ -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('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');
|
||||
}
|
||||
};
|
||||
29
database/migrations/2026_03_12_171109_create_roles_table.php
Normal file
29
database/migrations/2026_03_12_171109_create_roles_table.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?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('roles', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name')->unique();
|
||||
$table->string('slug')->unique();
|
||||
$table->string('description')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('roles');
|
||||
}
|
||||
};
|
||||
@@ -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
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('permissions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name')->unique();
|
||||
$table->string('slug')->unique();
|
||||
$table->string('group')->nullable();
|
||||
$table->text('description')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('permissions');
|
||||
}
|
||||
};
|
||||
@@ -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
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('permission_role', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('permission_id')->constrained()->onDelete('cascade');
|
||||
$table->foreignId('role_id')->constrained()->onDelete('cascade');
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['permission_id', 'role_id']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('permission_role');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
<?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('categories', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->string('slug')->unique();
|
||||
$table->text('description')->nullable();
|
||||
$table->string('icon')->nullable();
|
||||
$table->string('image')->nullable();
|
||||
|
||||
$table->unsignedBigInteger('parent_id')->nullable();
|
||||
|
||||
$table->integer('sort_order')->default(0)->index();
|
||||
$table->boolean('is_active')->default(true);
|
||||
|
||||
$table->index('parent_id');
|
||||
|
||||
$table->foreign('parent_id')
|
||||
->references('id')
|
||||
->on('categories')
|
||||
->onDelete('cascade');
|
||||
|
||||
$table->unique(['name', 'parent_id']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('categories');
|
||||
}
|
||||
};
|
||||
@@ -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('brands', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->string('slug')->unique();
|
||||
$table->text('description')->nullable();
|
||||
$table->string('logo')->nullable();
|
||||
$table->string('website')->nullable();
|
||||
$table->string('country')->nullable();
|
||||
$table->boolean('is_active')->default(true);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('brands');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
<?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('products', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->string('slug')->unique();
|
||||
$table->text('description');
|
||||
|
||||
$table->foreignId('brand_id')->nullable()->constrained()->onDelete('set null');
|
||||
$table->foreignId('category_id')->constrained()->onDelete('cascade');
|
||||
|
||||
$table->json('attributes')->nullable();
|
||||
$table->boolean('is_active')->default(true);
|
||||
$table->timestamps();
|
||||
|
||||
$table->index('brand_id');
|
||||
$table->index('category_id');
|
||||
$table->index('is_active');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('products');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,44 @@
|
||||
<?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('product_variations', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('product_id')->constrained()->onDelete('cascade');
|
||||
|
||||
$table->string('name');
|
||||
$table->string('sku')->unique();
|
||||
$table->decimal('price', 10, 2);
|
||||
$table->decimal('old_price', 10, 2)->nullable();
|
||||
$table->json('attributes')->nullable();
|
||||
|
||||
$table->json('images')->nullable();
|
||||
$table->integer('stock')->default(0);
|
||||
|
||||
$table->boolean('is_default')->default(false);
|
||||
$table->boolean('is_active')->default(true);
|
||||
|
||||
$table->timestamps();
|
||||
|
||||
$table->index('sku');
|
||||
$table->index('product_id');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('product_variations');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,43 @@
|
||||
<?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('reviews', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('user_id')->constrained()->onDelete('cascade');
|
||||
$table->foreignId('product_id')->constrained()->onDelete('cascade');
|
||||
|
||||
$table->tinyInteger('rating');
|
||||
$table->string('title')->nullable();
|
||||
$table->text('comment');
|
||||
$table->text('advantages')->nullable();
|
||||
$table->text('disadvantages')->nullable();
|
||||
|
||||
$table->integer('helpful_count')->default(0);
|
||||
$table->integer('unhelpful_count')->default(0);
|
||||
$table->boolean('is_approved')->default(false);
|
||||
$table->timestamps();
|
||||
|
||||
$table->index('rating');
|
||||
$table->index('is_approved');
|
||||
$table->index('created_at');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('reviews');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
<?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('contacts', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name')->default('Хвостики и лапки');
|
||||
$table->string('description')->nullable();
|
||||
$table->string('logo')->nullable();
|
||||
$table->string('favicon')->nullable();
|
||||
|
||||
$table->string('phone')->nullable();
|
||||
$table->string('email')->nullable();
|
||||
$table->string('address')->nullable();
|
||||
$table->string('work_hours')->nullable();
|
||||
|
||||
$table->string('telegram')->nullable();
|
||||
$table->string('whatsapp')->nullable();
|
||||
$table->string('vkontakte')->nullable();
|
||||
|
||||
$table->string('meta_title')->nullable();
|
||||
$table->text('meta_description')->nullable();
|
||||
$table->text('meta_keywords')->nullable();
|
||||
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('contacts');
|
||||
}
|
||||
};
|
||||
@@ -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
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('products', function (Blueprint $table) {
|
||||
$table->string('meta_title')->nullable()->after('is_active');
|
||||
$table->text('meta_description')->nullable()->after('meta_title');
|
||||
$table->string('meta_keywords')->nullable()->after('meta_description');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('products', function (Blueprint $table) {
|
||||
$table->dropColumn(['meta_title', 'meta_description', 'meta_keywords']);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -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
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->string('phone', 20)->nullable()->after('email');
|
||||
|
||||
$table->index('phone');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->dropColumn('phone');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
<?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('users', function (Blueprint $table) {
|
||||
$table->index('email');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->dropIndex('email');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
<?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('users', function (Blueprint $table) {
|
||||
$table->foreignId('role_id')->nullable()->constrained('roles')->nullOnDelete()->after('phone');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->dropForeign(['role_id']);
|
||||
$table->dropColumn('role_id');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
// Удаляем JSON поля из таблицы products
|
||||
Schema::table('products', function (Blueprint $table) {
|
||||
$table->dropColumn('attributes');
|
||||
});
|
||||
|
||||
// Удаляем JSON поля из таблицы product_variations
|
||||
Schema::table('product_variations', function (Blueprint $table) {
|
||||
$table->dropColumn('attributes');
|
||||
$table->dropColumn('images');
|
||||
});
|
||||
|
||||
// Создаем таблицу для изображений вариаций
|
||||
Schema::create('variation_images', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('variation_id')->constrained('product_variations')->cascadeOnDelete();
|
||||
$table->string('path');
|
||||
$table->integer('sort_order')->default(0);
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['variation_id', 'sort_order']);
|
||||
});
|
||||
|
||||
// Создаем таблицу для атрибутов вариаций
|
||||
Schema::create('variation_attributes', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('variation_id')->constrained('product_variations')->cascadeOnDelete();
|
||||
$table->string('key');
|
||||
$table->string('value')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['variation_id', 'key']);
|
||||
});
|
||||
|
||||
// Создаем таблицу для атрибутов товара
|
||||
Schema::create('product_attributes', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('product_id')->constrained()->cascadeOnDelete();
|
||||
$table->string('key');
|
||||
$table->text('value')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['product_id', 'key']);
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
// Возвращаем JSON поля
|
||||
Schema::table('products', function (Blueprint $table) {
|
||||
$table->json('attributes')->nullable();
|
||||
});
|
||||
|
||||
Schema::table('product_variations', function (Blueprint $table) {
|
||||
$table->json('attributes')->nullable();
|
||||
$table->json('images')->nullable();
|
||||
});
|
||||
|
||||
// Удаляем новые таблицы
|
||||
Schema::dropIfExists('variation_images');
|
||||
Schema::dropIfExists('variation_attributes');
|
||||
Schema::dropIfExists('product_attributes');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateCartItemsTable extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::create('cart_items', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('user_id')->nullable()->constrained()->onDelete('cascade');
|
||||
$table->string('session_id')->nullable()->index();
|
||||
$table->foreignId('variation_id')->constrained('product_variations')->onDelete('cascade');
|
||||
$table->integer('quantity')->default(1);
|
||||
$table->decimal('price', 10, 2);
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['user_id', 'session_id']);
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('cart_items');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateOrdersTable extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::create('orders', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('order_number')->unique();
|
||||
$table->foreignId('user_id')->nullable()->constrained()->nullOnDelete();
|
||||
$table->string('customer_name');
|
||||
$table->string('customer_email');
|
||||
$table->string('customer_phone');
|
||||
$table->text('shipping_address')->nullable();
|
||||
$table->decimal('subtotal', 10, 2);
|
||||
$table->decimal('shipping_cost', 10, 2)->default(0);
|
||||
$table->decimal('discount', 10, 2)->default(0);
|
||||
$table->decimal('total', 10, 2);
|
||||
$table->string('payment_method')->default('cash');
|
||||
$table->string('payment_status')->default('pending');
|
||||
$table->string('delivery_method')->default('courier');
|
||||
$table->string('delivery_status')->default('pending');
|
||||
$table->text('comment')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('orders');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateOrderItemsTable extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::create('order_items', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('order_id')->constrained()->onDelete('cascade');
|
||||
$table->foreignId('variation_id')->constrained('product_variations')->onDelete('cascade');
|
||||
$table->string('product_name');
|
||||
$table->string('variation_name')->nullable();
|
||||
$table->string('sku')->nullable();
|
||||
$table->integer('quantity');
|
||||
$table->decimal('price', 10, 2);
|
||||
$table->decimal('total', 10, 2);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('order_items');
|
||||
}
|
||||
}
|
||||
67
database/seeders/BrandSeeder.php
Normal file
67
database/seeders/BrandSeeder.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use App\Models\Brand;
|
||||
use App\Models\Product;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class BrandSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
$this->cleanTables();
|
||||
|
||||
$brands = [
|
||||
[
|
||||
'name' => 'Royal Canin',
|
||||
'slug' => 'royal-canin',
|
||||
'description' => 'Премиальные корма для кошек и собак',
|
||||
'country' => 'Франция',
|
||||
'website' => 'https://www.royalcanin.com',
|
||||
],
|
||||
[
|
||||
'name' => 'ABBA',
|
||||
'slug' => 'abba',
|
||||
'description' => 'Качественные корма для домашних животных',
|
||||
'country' => 'Россия',
|
||||
'website' => 'https://abba.ru',
|
||||
],
|
||||
[
|
||||
'name' => 'RURRI',
|
||||
'slug' => 'rurri',
|
||||
'description' => 'Одежда и амуниция для собак',
|
||||
'country' => 'Россия',
|
||||
],
|
||||
[
|
||||
'name' => 'Ownat',
|
||||
'slug' => 'ownat',
|
||||
'description' => 'Натуральные корма премиум-класса',
|
||||
'country' => 'Испания',
|
||||
'website' => 'https://www.ownat.com',
|
||||
],
|
||||
[
|
||||
'name' => 'Grandin',
|
||||
'slug' => 'grandin',
|
||||
'description' => 'Корма и лакомства для собак',
|
||||
'country' => 'Россия',
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($brands as $brandData) {
|
||||
Brand::create($brandData);
|
||||
}
|
||||
|
||||
$this->command->info('✅ Бренды созданы: ' . Brand::count());
|
||||
}
|
||||
|
||||
private function cleanTables()
|
||||
{
|
||||
DB::statement('SET FOREIGN_KEY_CHECKS=0');
|
||||
DB::table('products')->truncate();
|
||||
DB::table('brands')->truncate();
|
||||
DB::statement('SET FOREIGN_KEY_CHECKS=1');
|
||||
}
|
||||
}
|
||||
421
database/seeders/CategorySeeder.php
Normal file
421
database/seeders/CategorySeeder.php
Normal file
@@ -0,0 +1,421 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use App\Models\Category;
|
||||
use App\Models\Product;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class CategorySeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
$this->cleanTables();
|
||||
|
||||
$categories = [
|
||||
// ============================================
|
||||
// ДЛЯ СОБАК
|
||||
// ============================================
|
||||
[
|
||||
'name' => 'Для собак',
|
||||
'slug' => 'dlya-sobak',
|
||||
'sort_order' => 10,
|
||||
'children' => [
|
||||
// Корма для собак
|
||||
[
|
||||
'name' => 'Корма',
|
||||
'slug' => 'korma-dlya-sobak',
|
||||
'sort_order' => 10,
|
||||
'children' => [
|
||||
[
|
||||
'name' => 'Сухие корма',
|
||||
'slug' => 'suhie-korma',
|
||||
'sort_order' => 10
|
||||
],
|
||||
[
|
||||
'name' => 'Влажные корма',
|
||||
'slug' => 'vlazhnye-korma',
|
||||
'sort_order' => 20
|
||||
],
|
||||
[
|
||||
'name' => 'Диетическое питание',
|
||||
'slug' => 'dieticheskoe-pitanie',
|
||||
'sort_order' => 30
|
||||
],
|
||||
]
|
||||
],
|
||||
// Амуниция для собак
|
||||
[
|
||||
'name' => 'Амуниция',
|
||||
'slug' => 'amunitsiya',
|
||||
'sort_order' => 20,
|
||||
'children' => [
|
||||
[
|
||||
'name' => 'Ошейники и поводки',
|
||||
'slug' => 'osheyniki-i-povodki',
|
||||
'sort_order' => 10
|
||||
],
|
||||
[
|
||||
'name' => 'Намордники',
|
||||
'slug' => 'namordniki',
|
||||
'sort_order' => 20
|
||||
],
|
||||
[
|
||||
'name' => 'Шлейки',
|
||||
'slug' => 'shleyki',
|
||||
'sort_order' => 30
|
||||
],
|
||||
]
|
||||
],
|
||||
// Игрушки для собак
|
||||
[
|
||||
'name' => 'Игрушки',
|
||||
'slug' => 'igrushki',
|
||||
'sort_order' => 30,
|
||||
'children' => [
|
||||
[
|
||||
'name' => 'Мячики и фрисби',
|
||||
'slug' => 'myachiki-i-frisbi',
|
||||
'sort_order' => 10
|
||||
],
|
||||
[
|
||||
'name' => 'Канаты и кости',
|
||||
'slug' => 'kanaty-i-kosti',
|
||||
'sort_order' => 20
|
||||
],
|
||||
]
|
||||
],
|
||||
// Лежанки и домики
|
||||
[
|
||||
'name' => 'Лежанки и домики',
|
||||
'slug' => 'lezhanki-i-domiki',
|
||||
'sort_order' => 40,
|
||||
'children' => [
|
||||
[
|
||||
'name' => 'Лежанки',
|
||||
'slug' => 'lezhanki',
|
||||
'sort_order' => 10
|
||||
],
|
||||
[
|
||||
'name' => 'Домики',
|
||||
'slug' => 'domiki',
|
||||
'sort_order' => 20
|
||||
],
|
||||
]
|
||||
],
|
||||
// Миски и кормушки
|
||||
[
|
||||
'name' => 'Миски и кормушки',
|
||||
'slug' => 'miski-i-kormushki',
|
||||
'sort_order' => 50,
|
||||
'children' => [
|
||||
[
|
||||
'name' => 'Миски',
|
||||
'slug' => 'miski',
|
||||
'sort_order' => 10
|
||||
],
|
||||
[
|
||||
'name' => 'Автокормушки',
|
||||
'slug' => 'avtokormushki',
|
||||
'sort_order' => 20
|
||||
],
|
||||
]
|
||||
],
|
||||
]
|
||||
],
|
||||
|
||||
// ============================================
|
||||
// ДЛЯ КОШЕК
|
||||
// ============================================
|
||||
[
|
||||
'name' => 'Для кошек',
|
||||
'slug' => 'dlya-koshek',
|
||||
'sort_order' => 20,
|
||||
'children' => [
|
||||
// Корма для кошек
|
||||
[
|
||||
'name' => 'Корма',
|
||||
'slug' => 'korma-dlya-koshek',
|
||||
'sort_order' => 10,
|
||||
'children' => [
|
||||
[
|
||||
'name' => 'Сухие корма',
|
||||
'slug' => 'suhie-korma-dlya-koshek',
|
||||
'sort_order' => 10
|
||||
],
|
||||
[
|
||||
'name' => 'Паучи и консервы',
|
||||
'slug' => 'pauchi-i-konservy',
|
||||
'sort_order' => 20
|
||||
],
|
||||
[
|
||||
'name' => 'Лакомства',
|
||||
'slug' => 'lakomstva-dlya-koshek',
|
||||
'sort_order' => 30
|
||||
],
|
||||
]
|
||||
],
|
||||
// Наполнители
|
||||
[
|
||||
'name' => 'Наполнители',
|
||||
'slug' => 'napolniteli',
|
||||
'sort_order' => 20,
|
||||
'children' => [
|
||||
[
|
||||
'name' => 'Древесные',
|
||||
'slug' => 'drevesnye',
|
||||
'sort_order' => 10
|
||||
],
|
||||
[
|
||||
'name' => 'Силикагелевые',
|
||||
'slug' => 'silikagelevye',
|
||||
'sort_order' => 20
|
||||
],
|
||||
[
|
||||
'name' => 'Комкующиеся',
|
||||
'slug' => 'komkuyuschiesya',
|
||||
'sort_order' => 30
|
||||
],
|
||||
]
|
||||
],
|
||||
// Когтеточки и домики
|
||||
[
|
||||
'name' => 'Когтеточки и домики',
|
||||
'slug' => 'kogtetochki-i-domiki',
|
||||
'sort_order' => 30,
|
||||
'children' => [
|
||||
[
|
||||
'name' => 'Когтеточки',
|
||||
'slug' => 'kogtetochki',
|
||||
'sort_order' => 10
|
||||
],
|
||||
[
|
||||
'name' => 'Лежанки для кошек',
|
||||
'slug' => 'lezhanki-dlya-koshek',
|
||||
'sort_order' => 20
|
||||
],
|
||||
[
|
||||
'name' => 'Игровые комплексы',
|
||||
'slug' => 'igrovye-kompleksy',
|
||||
'sort_order' => 30
|
||||
],
|
||||
]
|
||||
],
|
||||
]
|
||||
],
|
||||
|
||||
// ============================================
|
||||
// ДЛЯ ГРЫЗУНОВ
|
||||
// ============================================
|
||||
[
|
||||
'name' => 'Для грызунов',
|
||||
'slug' => 'dlya-gryzunov',
|
||||
'sort_order' => 30,
|
||||
'children' => [
|
||||
[
|
||||
'name' => 'Корма',
|
||||
'slug' => 'korma-dlya-gryzunov',
|
||||
'sort_order' => 10,
|
||||
'children' => [
|
||||
[
|
||||
'name' => 'Зерновые смеси',
|
||||
'slug' => 'zernovye-smesi',
|
||||
'sort_order' => 10
|
||||
],
|
||||
[
|
||||
'name' => 'Сено и травы',
|
||||
'slug' => 'seno-i-travy',
|
||||
'sort_order' => 20
|
||||
],
|
||||
[
|
||||
'name' => 'Лакомства',
|
||||
'slug' => 'lakomstva-dlya-gryzunov',
|
||||
'sort_order' => 30
|
||||
],
|
||||
]
|
||||
],
|
||||
[
|
||||
'name' => 'Клетки и аксессуары',
|
||||
'slug' => 'kletki-i-aksessuary',
|
||||
'sort_order' => 20,
|
||||
'children' => [
|
||||
[
|
||||
'name' => 'Клетки',
|
||||
'slug' => 'kletki',
|
||||
'sort_order' => 10
|
||||
],
|
||||
[
|
||||
'name' => 'Поилки и миски',
|
||||
'slug' => 'poilki-i-miski',
|
||||
'sort_order' => 20
|
||||
],
|
||||
[
|
||||
'name' => 'Наполнители',
|
||||
'slug' => 'napolniteli-dlya-gryzunov',
|
||||
'sort_order' => 30
|
||||
],
|
||||
]
|
||||
],
|
||||
]
|
||||
],
|
||||
|
||||
// ============================================
|
||||
// ДЛЯ ПТИЦ
|
||||
// ============================================
|
||||
[
|
||||
'name' => 'Для птиц',
|
||||
'slug' => 'dlya-ptic',
|
||||
'sort_order' => 40,
|
||||
'children' => [
|
||||
[
|
||||
'name' => 'Корма',
|
||||
'slug' => 'korma-dlya-ptic',
|
||||
'sort_order' => 10,
|
||||
'children' => [
|
||||
[
|
||||
'name' => 'Корма для попугаев',
|
||||
'slug' => 'korma-dlya-popugaev',
|
||||
'sort_order' => 10
|
||||
],
|
||||
[
|
||||
'name' => 'Корма для канареек',
|
||||
'slug' => 'korma-dlya-kanareek',
|
||||
'sort_order' => 20
|
||||
],
|
||||
[
|
||||
'name' => 'Минеральные камни',
|
||||
'slug' => 'mineralnye-kamni',
|
||||
'sort_order' => 30
|
||||
],
|
||||
]
|
||||
],
|
||||
[
|
||||
'name' => 'Аксессуары',
|
||||
'slug' => 'aksessuary-dlya-ptic',
|
||||
'sort_order' => 20,
|
||||
'children' => [
|
||||
[
|
||||
'name' => 'Клетки и жердочки',
|
||||
'slug' => 'kletki-i-zherdochki',
|
||||
'sort_order' => 10
|
||||
],
|
||||
[
|
||||
'name' => 'Игрушки для птиц',
|
||||
'slug' => 'igrushki-dlya-ptic',
|
||||
'sort_order' => 20
|
||||
],
|
||||
]
|
||||
],
|
||||
]
|
||||
],
|
||||
|
||||
// ============================================
|
||||
// ДЛЯ РЫБ
|
||||
// ============================================
|
||||
[
|
||||
'name' => 'Для рыб',
|
||||
'slug' => 'dlya-ryb',
|
||||
'sort_order' => 50,
|
||||
'children' => [
|
||||
[
|
||||
'name' => 'Корма для рыб',
|
||||
'slug' => 'korma-dlya-ryb',
|
||||
'sort_order' => 10
|
||||
],
|
||||
[
|
||||
'name' => 'Аквариумы',
|
||||
'slug' => 'akvariumy',
|
||||
'sort_order' => 20
|
||||
],
|
||||
[
|
||||
'name' => 'Фильтрация и помпы',
|
||||
'slug' => 'filtratsiya-i-pompy',
|
||||
'sort_order' => 30
|
||||
],
|
||||
[
|
||||
'name' => 'Освещение',
|
||||
'slug' => 'osveschenie',
|
||||
'sort_order' => 40
|
||||
],
|
||||
[
|
||||
'name' => 'Грунт и декор',
|
||||
'slug' => 'grunt-i-dekor',
|
||||
'sort_order' => 50
|
||||
],
|
||||
]
|
||||
],
|
||||
|
||||
// ============================================
|
||||
// ЗДОРОВЬЕ И УХОД
|
||||
// ============================================
|
||||
[
|
||||
'name' => 'Здоровье и уход',
|
||||
'slug' => 'zdorovie-i-uhod',
|
||||
'sort_order' => 60,
|
||||
'children' => [
|
||||
[
|
||||
'name' => 'Шампуни и косметика',
|
||||
'slug' => 'shampuni-i-kosmetika',
|
||||
'sort_order' => 10
|
||||
],
|
||||
[
|
||||
'name' => 'Витамины и добавки',
|
||||
'slug' => 'vitaminy-i-dobavki',
|
||||
'sort_order' => 20
|
||||
],
|
||||
[
|
||||
'name' => 'Средства от паразитов',
|
||||
'slug' => 'sredstva-ot-parazitov',
|
||||
'sort_order' => 30
|
||||
],
|
||||
[
|
||||
'name' => 'Аптечка',
|
||||
'slug' => 'aptechka',
|
||||
'sort_order' => 40
|
||||
],
|
||||
[
|
||||
'name' => 'Груминг',
|
||||
'slug' => 'gruming',
|
||||
'sort_order' => 50
|
||||
],
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($categories as $categoryData) {
|
||||
$this->createCategoryWithChildren($categoryData);
|
||||
}
|
||||
|
||||
$this->command->info('✅ Категории успешно созданы!');
|
||||
$this->command->info('📊 Всего категорий: ' . Category::count());
|
||||
}
|
||||
|
||||
private function cleanTables()
|
||||
{
|
||||
DB::statement('SET FOREIGN_KEY_CHECKS=0');
|
||||
DB::table('products')->truncate();
|
||||
DB::table('categories')->truncate();
|
||||
DB::statement('SET FOREIGN_KEY_CHECKS=1');
|
||||
}
|
||||
|
||||
private function createCategoryWithChildren($data, $parentId = null)
|
||||
{
|
||||
$children = $data['children'] ?? [];
|
||||
unset($data['children']);
|
||||
|
||||
$data['parent_id'] = $parentId;
|
||||
$data['is_active'] = true;
|
||||
|
||||
$data['icon'] = $data['slug'] . '.svg';
|
||||
|
||||
$data['image'] = $data['slug'] . '.jpg';
|
||||
|
||||
$category = Category::create($data);
|
||||
|
||||
foreach ($children as $childData) {
|
||||
$this->createCategoryWithChildren($childData, $category->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
21
database/seeders/DatabaseSeeder.php
Normal file
21
database/seeders/DatabaseSeeder.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class DatabaseSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Seed the application's database.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$this->call([
|
||||
RolesAndPermissionsSeeder::class,
|
||||
CategorySeeder::class,
|
||||
BrandSeeder::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
1651
database/seeders/ProductCatalogSeeder.php
Normal file
1651
database/seeders/ProductCatalogSeeder.php
Normal file
File diff suppressed because it is too large
Load Diff
279
database/seeders/RolesAndPermissionsSeeder.php
Normal file
279
database/seeders/RolesAndPermissionsSeeder.php
Normal file
@@ -0,0 +1,279 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use App\Models\Role;
|
||||
use App\Models\Permission;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
use function Symfony\Component\String\s;
|
||||
|
||||
class RolesAndPermissionsSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void {
|
||||
$this->cleanTables();
|
||||
$this->createPermissions();
|
||||
$this->createRoles();
|
||||
$this->assignPermissionsToRoles();
|
||||
}
|
||||
|
||||
private function cleanTables()
|
||||
{
|
||||
DB::statement('SET FOREIGN_KEY_CHECKS=0');
|
||||
DB::table('permission_role')->truncate();
|
||||
DB::table('role_user')->truncate();
|
||||
DB::table('permissions')->truncate();
|
||||
DB::table('roles')->truncate();
|
||||
DB::statement('SET FOREIGN_KEY_CHECKS=1');
|
||||
}
|
||||
|
||||
private function createPermissions()
|
||||
{
|
||||
$permissions = [
|
||||
|
||||
// ========== ЛИЧНЫЙ КАБИНЕТ ==========
|
||||
[
|
||||
'name' => 'Доступ в личный кабинет',
|
||||
'slug' => 'cabinet_access',
|
||||
'group' => 'cabinet',
|
||||
'description' => 'Возможность входить в личный кабинет и просматривать свои данные'
|
||||
],
|
||||
|
||||
// ========== ЗАКАЗЫ ==========
|
||||
[
|
||||
'name' => 'Просматривать заказы',
|
||||
'slug' => 'view_orders',
|
||||
'group' => 'orders',
|
||||
'description' => 'Просмотр списка заказов'
|
||||
],
|
||||
[
|
||||
'name' => 'Редактировать заказы',
|
||||
'slug' => 'edit_orders',
|
||||
'group' => 'orders',
|
||||
'description' => 'Редактирование заказов (статус, удаление, подтверждение)'
|
||||
],
|
||||
[
|
||||
'name' => 'Оформлять заказы',
|
||||
'slug' => 'checkout',
|
||||
'group' => 'orders',
|
||||
'description' => 'Оформление заказов на сайте'
|
||||
],
|
||||
|
||||
// ========== КОРЗИНА ==========
|
||||
[
|
||||
'name' => 'Управлять корзиной',
|
||||
'slug' => 'manage_cart',
|
||||
'group' => 'cart',
|
||||
'description' => 'Добавление/удаление товаров из корзины'
|
||||
],
|
||||
|
||||
// ========== ТОВАРЫ ==========
|
||||
[
|
||||
'name' => 'Добавлять товары',
|
||||
'slug' => 'create_products',
|
||||
'group' => 'products',
|
||||
'description' => 'Создание новых товаров'
|
||||
],
|
||||
[
|
||||
'name' => 'Редактировать товары',
|
||||
'slug' => 'edit_products',
|
||||
'group' => 'products',
|
||||
'description' => 'Редактирование товаров'
|
||||
],
|
||||
[
|
||||
'name' => 'Управлять количеством товара',
|
||||
'slug' => 'manage_stock',
|
||||
'group' => 'products',
|
||||
'description' => 'Изменение остатков товаров на складе'
|
||||
],
|
||||
|
||||
// ========== ПОЛЬЗОВАТЕЛИ ==========
|
||||
[
|
||||
'name' => 'Просматривать пользователей',
|
||||
'slug' => 'view_users',
|
||||
'group' => 'users',
|
||||
'description' => 'Просмотр списка пользователей'
|
||||
],
|
||||
[
|
||||
'name' => 'Создавать пользователей',
|
||||
'slug' => 'create_users',
|
||||
'group' => 'users',
|
||||
'description' => 'Создание новых пользователей'
|
||||
],
|
||||
|
||||
// ========== РОЛИ И ПРАВА ==========
|
||||
[
|
||||
'name' => 'Управлять ролями',
|
||||
'slug' => 'manage_roles',
|
||||
'group' => 'rbac',
|
||||
'description' => 'Создание/редактирование ролей'
|
||||
],
|
||||
[
|
||||
'name' => 'Управлять правами',
|
||||
'slug' => 'manage_permissions',
|
||||
'group' => 'rbac',
|
||||
'description' => 'Создание/редактирование прав доступа'
|
||||
],
|
||||
|
||||
// ========== МАГАЗИН ==========
|
||||
[
|
||||
'name' => 'Редактировать данные магазина',
|
||||
'slug' => 'edit_shop_settings',
|
||||
'group' => 'shop',
|
||||
'description' => 'Изменение настроек магазина'
|
||||
],
|
||||
|
||||
// ========== ДОСТУП В АДМИНКУ ==========
|
||||
[
|
||||
'name' => 'Доступ в админ-панель',
|
||||
'slug' => 'admin_access',
|
||||
'group' => 'admin',
|
||||
'description' => 'Возможность входить в административную панель'
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($permissions as $permission) {
|
||||
Permission::firstOrCreate(
|
||||
['slug' => $permission['slug']],
|
||||
$permission
|
||||
);
|
||||
$this->command->info("✓ Создано право: {$permission['name']}");
|
||||
}
|
||||
}
|
||||
|
||||
private function createRoles()
|
||||
{
|
||||
$roles = [
|
||||
[
|
||||
'name' => 'Супер администратор',
|
||||
'slug' => 'super_admin',
|
||||
'description' => 'Полный доступ ко всем функциям системы (обходит все проверки прав)'
|
||||
],
|
||||
[
|
||||
'name' => 'Администратор магазина',
|
||||
'slug' => 'shop_admin',
|
||||
'description' => 'Полное управление магазином, товарами и заказами'
|
||||
],
|
||||
[
|
||||
'name' => 'Менеджер по товарам',
|
||||
'slug' => 'product_manager',
|
||||
'description' => 'Управление каталогом товаров'
|
||||
],
|
||||
[
|
||||
'name' => 'Менеджер по заказам',
|
||||
'slug' => 'order_manager',
|
||||
'description' => 'Обработка заказов'
|
||||
],
|
||||
[
|
||||
'name' => 'Кладовщик',
|
||||
'slug' => 'warehouse_manager',
|
||||
'description' => 'Управление остатками товаров'
|
||||
],
|
||||
[
|
||||
'name' => 'Зарегистрированный пользователь',
|
||||
'slug' => 'registered_user',
|
||||
'description' => 'Обычный пользователь сайта'
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($roles as $roleData) {
|
||||
Role::firstOrCreate(
|
||||
['slug' => $roleData['slug']],
|
||||
$roleData
|
||||
);
|
||||
$this->command->info("✓ Создана роль: {$roleData['name']}");
|
||||
}
|
||||
}
|
||||
|
||||
private function assignPermissionsToRoles()
|
||||
{
|
||||
// ============================================
|
||||
// АДМИНИСТРАТОР МАГАЗИНА
|
||||
// ============================================
|
||||
|
||||
$shopAdmin = Role::where('slug', 'shop_admin')->first();
|
||||
$shopAdmin->permissions()->sync(
|
||||
Permission::whereIn('slug', [
|
||||
'admin_access',
|
||||
'cabinet_access',
|
||||
'view_orders',
|
||||
'edit_orders',
|
||||
'checkout',
|
||||
'manage_cart',
|
||||
'create_products',
|
||||
'edit_products',
|
||||
'manage_stock',
|
||||
'view_users',
|
||||
'create_users',
|
||||
'manage_roles',
|
||||
'manage_permissions',
|
||||
'edit_shop_settings',
|
||||
])->pluck('id')
|
||||
);
|
||||
$this->command->info('✓ Назначены права для Администратора магазина');
|
||||
|
||||
// ============================================
|
||||
// МЕНЕДЖЕР ПО ТОВАРАМ
|
||||
// ============================================
|
||||
|
||||
$productManager = Role::where('slug', 'product_manager')->first();
|
||||
$productManager->permissions()->sync(
|
||||
Permission::whereIn('slug', [
|
||||
'admin_access',
|
||||
'cabinet_access',
|
||||
'create_products',
|
||||
'edit_products',
|
||||
'view_orders',
|
||||
])->pluck('id')
|
||||
);
|
||||
$this->command->info('✓ Назначены права для Менеджера по товарам');
|
||||
|
||||
// ============================================
|
||||
// МЕНЕДЖЕР ПО ЗАКАЗАМ
|
||||
// ============================================
|
||||
$orderManager = Role::where('slug', 'order_manager')->first();
|
||||
$orderManager->permissions()->sync(
|
||||
Permission::whereIn('slug', [
|
||||
'admin_access',
|
||||
'cabinet_access',
|
||||
'view_orders',
|
||||
'edit_orders',
|
||||
'checkout',
|
||||
'view_users',
|
||||
])->pluck('id')
|
||||
);
|
||||
$this->command->info('✓ Назначены права для Менеджера по заказам');
|
||||
|
||||
// ============================================
|
||||
// КЛАДОВЩИК
|
||||
// ============================================
|
||||
$warehouseManager = Role::where('slug', 'warehouse_manager')->first();
|
||||
$warehouseManager->permissions()->sync(
|
||||
Permission::whereIn('slug', [
|
||||
'admin_access',
|
||||
'cabinet_access',
|
||||
'manage_stock',
|
||||
'view_orders',
|
||||
])->pluck('id')
|
||||
);
|
||||
$this->command->info('✓ Назначены права для Кладовщика');
|
||||
|
||||
// ============================================
|
||||
// ЗАРЕГИСТРИРОВАННЫЙ ПОЛЬЗОВАТЕЛЬ
|
||||
// ============================================
|
||||
$registeredUser = Role::where('slug', 'registered_user')->first();
|
||||
$registeredUser->permissions()->sync(
|
||||
Permission::whereIn('slug', [
|
||||
'cabinet_access',
|
||||
'manage_cart',
|
||||
'checkout',
|
||||
])->pluck('id')
|
||||
);
|
||||
$this->command->info('✓ Назначены права для Зарегистрированного пользователя');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user