This commit is contained in:
35
app/Models/Category.php
Normal file
35
app/Models/Category.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Category extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'slug',
|
||||
'description',
|
||||
'is_active',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
}
|
||||
|
||||
public function products()
|
||||
{
|
||||
return $this->hasMany(Product::class);
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'slug';
|
||||
}
|
||||
}
|
||||
57
app/Models/ChatConversation.php
Normal file
57
app/Models/ChatConversation.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ChatConversation extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
public const STATUS_OPEN = 'open';
|
||||
public const STATUS_CLOSED = 'closed';
|
||||
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'visitor_token',
|
||||
'status',
|
||||
'last_message_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'last_message_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function messages()
|
||||
{
|
||||
return $this->hasMany(ChatMessage::class);
|
||||
}
|
||||
|
||||
public function latestMessage()
|
||||
{
|
||||
return $this->hasOne(ChatMessage::class)->latestOfMany();
|
||||
}
|
||||
|
||||
public function getDisplayNameAttribute(): string
|
||||
{
|
||||
if ($this->user?->name) {
|
||||
return $this->user->name;
|
||||
}
|
||||
|
||||
return 'Гость #' . $this->id;
|
||||
}
|
||||
|
||||
public function isClosed(): bool
|
||||
{
|
||||
return $this->status === self::STATUS_CLOSED;
|
||||
}
|
||||
}
|
||||
30
app/Models/ChatMessage.php
Normal file
30
app/Models/ChatMessage.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ChatMessage extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'chat_conversation_id',
|
||||
'sender',
|
||||
'body',
|
||||
'is_read',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'is_read' => 'boolean',
|
||||
];
|
||||
}
|
||||
|
||||
public function conversation()
|
||||
{
|
||||
return $this->belongsTo(ChatConversation::class, 'chat_conversation_id');
|
||||
}
|
||||
}
|
||||
69
app/Models/HomeSlide.php
Normal file
69
app/Models/HomeSlide.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class HomeSlide extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'zone',
|
||||
'title',
|
||||
'show_title',
|
||||
'subtitle',
|
||||
'show_subtitle',
|
||||
'button_text',
|
||||
'button_url',
|
||||
'show_button',
|
||||
'image_path',
|
||||
'sort_order',
|
||||
'is_active',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'show_title' => 'boolean',
|
||||
'show_subtitle' => 'boolean',
|
||||
'show_button' => 'boolean',
|
||||
'sort_order' => 'integer',
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
}
|
||||
|
||||
public function scopeActive($query)
|
||||
{
|
||||
return $query->where('is_active', true);
|
||||
}
|
||||
|
||||
public function scopeForZone($query, string $zone)
|
||||
{
|
||||
return $query->where('zone', $zone);
|
||||
}
|
||||
|
||||
public function scopeOrdered($query)
|
||||
{
|
||||
return $query->orderBy('sort_order')->orderBy('id');
|
||||
}
|
||||
|
||||
public function getImageUrlAttribute(): ?string
|
||||
{
|
||||
if (!$this->image_path) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Str::startsWith($this->image_path, ['http://', 'https://', '/'])) {
|
||||
return $this->image_path;
|
||||
}
|
||||
|
||||
if (Str::startsWith($this->image_path, 'uploads/')) {
|
||||
return asset($this->image_path);
|
||||
}
|
||||
|
||||
return '/storage/' . ltrim($this->image_path, '/');
|
||||
}
|
||||
}
|
||||
50
app/Models/Order.php
Normal file
50
app/Models/Order.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Order extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'status',
|
||||
'payment_method',
|
||||
'total',
|
||||
'items_count',
|
||||
'customer_name',
|
||||
'email',
|
||||
'phone',
|
||||
'address',
|
||||
'comment',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'total' => 'decimal:2',
|
||||
'items_count' => 'integer',
|
||||
];
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function items()
|
||||
{
|
||||
return $this->hasMany(OrderItem::class);
|
||||
}
|
||||
|
||||
public function getPaymentMethodLabelAttribute(): string
|
||||
{
|
||||
return match ($this->payment_method) {
|
||||
'card_transfer' => 'Перевод по реквизитам (на карту)',
|
||||
default => 'Не указан',
|
||||
};
|
||||
}
|
||||
}
|
||||
39
app/Models/OrderItem.php
Normal file
39
app/Models/OrderItem.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class OrderItem extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'order_id',
|
||||
'product_id',
|
||||
'name',
|
||||
'price',
|
||||
'quantity',
|
||||
'subtotal',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'price' => 'decimal:2',
|
||||
'subtotal' => 'decimal:2',
|
||||
'quantity' => 'integer',
|
||||
];
|
||||
}
|
||||
|
||||
public function order()
|
||||
{
|
||||
return $this->belongsTo(Order::class);
|
||||
}
|
||||
|
||||
public function product()
|
||||
{
|
||||
return $this->belongsTo(Product::class);
|
||||
}
|
||||
}
|
||||
89
app/Models/Product.php
Normal file
89
app/Models/Product.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Product extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'category_id',
|
||||
'name',
|
||||
'slug',
|
||||
'sku',
|
||||
'price',
|
||||
'old_price',
|
||||
'stock',
|
||||
'short_description',
|
||||
'description',
|
||||
'image_path',
|
||||
'gallery_paths',
|
||||
'specs',
|
||||
'is_active',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'price' => 'decimal:2',
|
||||
'old_price' => 'decimal:2',
|
||||
'stock' => 'integer',
|
||||
'gallery_paths' => 'array',
|
||||
'specs' => 'array',
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
}
|
||||
|
||||
public function category()
|
||||
{
|
||||
return $this->belongsTo(Category::class);
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'slug';
|
||||
}
|
||||
|
||||
public function getImageUrlAttribute(): ?string
|
||||
{
|
||||
return $this->resolveImagePath($this->image_path);
|
||||
}
|
||||
|
||||
public function getGalleryUrlsAttribute(): array
|
||||
{
|
||||
$paths = collect((array) ($this->gallery_paths ?? []))
|
||||
->prepend($this->image_path)
|
||||
->filter(fn ($path) => is_string($path) && trim($path) !== '')
|
||||
->map(fn (string $path) => trim($path))
|
||||
->unique()
|
||||
->values();
|
||||
|
||||
return $paths
|
||||
->map(fn (string $path) => $this->resolveImagePath($path))
|
||||
->filter()
|
||||
->values()
|
||||
->all();
|
||||
}
|
||||
|
||||
private function resolveImagePath(?string $path): ?string
|
||||
{
|
||||
$path = trim((string) $path);
|
||||
if ($path === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Str::startsWith($path, ['http://', 'https://', '/'])) {
|
||||
return $path;
|
||||
}
|
||||
|
||||
if (Str::startsWith($path, 'uploads/')) {
|
||||
return asset($path);
|
||||
}
|
||||
|
||||
return '/storage/' . ltrim($path, '/');
|
||||
}
|
||||
}
|
||||
60
app/Models/User.php
Normal file
60
app/Models/User.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
/** @use HasFactory<\Database\Factories\UserFactory> */
|
||||
use HasFactory, Notifiable;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'email',
|
||||
'password',
|
||||
'is_admin',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for serialization.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'email_verified_at' => 'datetime',
|
||||
'password' => 'hashed',
|
||||
'is_admin' => 'boolean',
|
||||
];
|
||||
}
|
||||
|
||||
public function orders()
|
||||
{
|
||||
return $this->hasMany(Order::class);
|
||||
}
|
||||
|
||||
public function chatConversations()
|
||||
{
|
||||
return $this->hasMany(ChatConversation::class);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user