268 lines
6.3 KiB
PHP
268 lines
6.3 KiB
PHP
<?php
|
|
|
|
namespace Modules\Mall\Models;
|
|
|
|
use App\Models\Model;
|
|
use App\Traits\HasClicks;
|
|
use App\Traits\HasCovers;
|
|
use App\Traits\HasStatus;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Modules\Mall\Models\Traits\BelongsToShop;
|
|
use Overtrue\LaravelVersionable\Versionable;
|
|
|
|
class Goods extends Model
|
|
{
|
|
|
|
use BelongsToShop,
|
|
HasStatus,
|
|
HasClicks,
|
|
HasCovers,
|
|
Versionable,
|
|
SoftDeletes;
|
|
|
|
/**
|
|
* 规格,支持单规格和多规格
|
|
*/
|
|
const TYPE_SINGLE = 1;
|
|
const TYPE_MULTIPLE = 2;
|
|
const TYPE_MAP = [
|
|
self::TYPE_SINGLE => '单规格',
|
|
// self::TYPE_MULTIPLE => '多规格',
|
|
];
|
|
/**
|
|
* 状态
|
|
*/
|
|
const STATUS_AUDIT = 0;
|
|
const STATUS_UP = 1;
|
|
const STATUS_REJECT = 2;
|
|
const STATUS_DOWN = 3;
|
|
const STATUS_MAP = [
|
|
self::STATUS_AUDIT => '审核中',
|
|
self::STATUS_UP => '上架',
|
|
self::STATUS_REJECT => '驳回',
|
|
self::STATUS_DOWN => '下架',
|
|
];
|
|
/**
|
|
* 库存的扣减方式
|
|
*/
|
|
const DEDUCT_STOCK_ORDER = 1;
|
|
const DEDUCT_STOCK_PAID = 2;
|
|
const DEDUCT_STOCK_MAP = [
|
|
self::DEDUCT_STOCK_ORDER => '下单减库存',
|
|
self::DEDUCT_STOCK_PAID => '付款减库存',
|
|
];
|
|
/**
|
|
* 支付方式
|
|
*/
|
|
const PAY_TYPE_ONLINE = 1;
|
|
const PAY_TYPE_OFFLINE = 2;
|
|
const PAY_TYPE_ALL = 3;
|
|
const PAY_TYPE_MAP = [
|
|
self::PAY_TYPE_ONLINE => '在线支付',
|
|
self::PAY_TYPE_OFFLINE => '货到付款',
|
|
self::PAY_TYPE_ALL => '在线支付/货到付款',
|
|
];
|
|
|
|
/**
|
|
* 商品类型
|
|
*/
|
|
const CHANNEL_NORMAL = 1;
|
|
const CHANNEL_SCORE = 2;
|
|
const CHANNEL_FREE = 3;
|
|
|
|
const Channels = [
|
|
self::CHANNEL_NORMAL => '正常',
|
|
self::CHANNEL_SCORE => '积分兑换',
|
|
self::CHANNEL_FREE => '赠送',
|
|
];
|
|
|
|
/**
|
|
* 展示列表,从数据库查询的字段
|
|
*/
|
|
const LIST_SELECT_FIELDS = [
|
|
'id',
|
|
'name',
|
|
'description',
|
|
'cover',
|
|
'shop_id',
|
|
'original_price',
|
|
'sales',
|
|
'clicks',
|
|
];
|
|
|
|
protected $table = 'mall_goods';
|
|
|
|
protected $casts = [
|
|
'pictures' => 'json',
|
|
];
|
|
|
|
protected $with = [
|
|
'specs',
|
|
'skus',
|
|
];
|
|
|
|
/**
|
|
* 不参与版本记录的字段
|
|
*
|
|
* @var array|string[]
|
|
*/
|
|
protected array $dontVersionable = ['clicks', 'updated_at'];
|
|
|
|
/**
|
|
* Notes : 商品分类
|
|
*
|
|
* @Date : 2021/5/12 9:48 上午
|
|
* @Author : < Jason.C >
|
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
|
*/
|
|
public function category(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Category::class);
|
|
}
|
|
|
|
/**
|
|
* Notes : 标签
|
|
*
|
|
* @Date : 2021/5/12 10:14 上午
|
|
* @Author : < Jason.C >
|
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
|
*/
|
|
public function tags(): BelongsToMany
|
|
{
|
|
return $this->belongsToMany(Tag::class, 'mall_goods_tag');
|
|
}
|
|
|
|
/**
|
|
* Notes : 所属品牌
|
|
*
|
|
* @Date : 2021/5/11 11:00 上午
|
|
* @Author : < Jason.C >
|
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
|
*/
|
|
public function brand(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Brand::class);
|
|
}
|
|
|
|
/**
|
|
* Notes : 运费模板
|
|
*
|
|
* @Date : 2021/5/11 11:04 上午
|
|
* @Author : < Jason.C >
|
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
|
*/
|
|
public function delivery(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Delivery::class);
|
|
}
|
|
|
|
/**
|
|
* Notes : 商品属性
|
|
*
|
|
* @Date : 2021/5/12 11:31 上午
|
|
* @Author : < Jason.C >
|
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
|
*/
|
|
public function specs(): HasMany
|
|
{
|
|
return $this->hasMany(GoodsSpec::class);
|
|
}
|
|
|
|
/**
|
|
* Notes : 商品SKU
|
|
*
|
|
* @Date : 2021/5/11 1:47 下午
|
|
* @Author : < Jason.C >
|
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
|
*/
|
|
public function skus(): HasMany
|
|
{
|
|
return $this->hasMany(GoodsSku::class);
|
|
}
|
|
|
|
/**
|
|
* Notes : 获取规格的价格区间
|
|
*
|
|
* @Date : 2021/5/13 11:49 上午
|
|
* @Author : < Jason.C >
|
|
* @return string
|
|
*/
|
|
public function getPriceAttribute(): string
|
|
{
|
|
if ($this->type === self::TYPE_SINGLE) {
|
|
return $this->price_min;
|
|
} else {
|
|
return $this->price_min.'|'.$this->price_max;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Notes : 返回最低积分
|
|
*
|
|
* @Date : 2021/5/20 11:26 上午
|
|
* @Author : < Jason.C >
|
|
* @return float
|
|
*/
|
|
public function getScoreAttribute(): float
|
|
{
|
|
return $this->skus->min('score') ?? 0;
|
|
}
|
|
|
|
/**
|
|
* Notes : 最低价格
|
|
*
|
|
* @Date : 2021/5/13 11:50 上午
|
|
* @Author : < Jason.C >
|
|
* @return float
|
|
*/
|
|
public function getPriceMinAttribute(): float
|
|
{
|
|
return $this->skus->min('price') ?? 0;
|
|
}
|
|
|
|
/**
|
|
* Notes : 最高价格
|
|
*
|
|
* @Date : 2021/5/13 11:51 上午
|
|
* @Author : < Jason.C >
|
|
* @return float
|
|
*/
|
|
public function getPriceMaxAttribute(): float
|
|
{
|
|
return $this->skus->max('price') ?? 0;
|
|
}
|
|
|
|
/**
|
|
* Notes : 按价格排序
|
|
*
|
|
* @Date : 2021/5/17 14:18
|
|
* @Author : Mr.wang
|
|
* @param Builder $query
|
|
* @param string $direction
|
|
* @return Builder
|
|
*/
|
|
public function scopeOrderByPrice(Builder $query, string $direction = 'asc'): Builder
|
|
{
|
|
if ($direction) {
|
|
$price = DB::raw('MIN(price) as min_price');
|
|
} else {
|
|
$price = DB::raw('MAX(price) as min_price');
|
|
}
|
|
|
|
$minPrice = DB::table('mall_goods_skus')
|
|
->select('goods_id', $price)
|
|
->whereNull('deleted_at')
|
|
->groupBy('goods_id');
|
|
|
|
return $query->joinSub($minPrice, 'min_price', function ($join) {
|
|
$join->on('mall_goods.id', '=', 'min_price.goods_id');
|
|
})->orderBy('min_price', $direction);
|
|
}
|
|
|
|
}
|