248 lines
5.7 KiB
PHP
248 lines
5.7 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use App\Constants\OrderStatus;
|
|
use App\Helpers\Numeric;
|
|
use Dcat\Admin\Traits\HasDateTimeFormatter;
|
|
use EloquentFilter\Filterable;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
|
|
class Order extends Model
|
|
{
|
|
use Filterable;
|
|
use HasDateTimeFormatter;
|
|
|
|
public const STATUS_PENDING = 0; // 待付款
|
|
public const STATUS_PAID = 1; // 已付款
|
|
public const STATUS_COMPLETED = 9; // 已完成
|
|
public const STATUS_CANCELLED = 10; // 已取消
|
|
|
|
public const SHIPPING_STATE_PENDING = 0; // 待发货
|
|
public const SHIPPING_STATE_PROCESSING = 1; // 发货中
|
|
public const SHIPPING_STATE_PROCESSED = 2; // 已完成
|
|
|
|
public const PAY_WAY_ALIPAY = 'alipay';
|
|
public const PAY_WAY_WXPAY = 'wxpay';
|
|
public const PAY_WAY_BALANCE = 'balance';
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected $attributes = [
|
|
'reduced_amount' => 0,
|
|
'status' => self::STATUS_PENDING,
|
|
];
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected $casts = [
|
|
'completed_at' => 'datetime',
|
|
'status' => 'int',
|
|
];
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected $fillable = [
|
|
'user_id',
|
|
'sn',
|
|
'user_coupon_id',
|
|
'coupon_discount_amount',
|
|
'vip_discount_amount',
|
|
'reduced_amount',
|
|
'shipping_fee',
|
|
'products_total_amount',
|
|
'total_amount',
|
|
'note',
|
|
'remark',
|
|
'pay_sn',
|
|
'pay_way',
|
|
'pay_at',
|
|
'consignee_name',
|
|
'consignee_telephone',
|
|
'consignee_zone',
|
|
'consignee_address',
|
|
'shipping_state',
|
|
'status',
|
|
'completed_at',
|
|
];
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
public static $payWayTexts = [
|
|
self::PAY_WAY_ALIPAY => '支付宝',
|
|
self::PAY_WAY_WXPAY => '微信支付',
|
|
self::PAY_WAY_BALANCE => '余额',
|
|
];
|
|
|
|
/**
|
|
* 下单人
|
|
*
|
|
* @return void
|
|
*/
|
|
public function user()
|
|
{
|
|
return $this->belongsTo(User::class, 'user_id');
|
|
}
|
|
|
|
/**
|
|
* 使用的优惠券
|
|
*
|
|
* @return void
|
|
*/
|
|
public function userCoupon()
|
|
{
|
|
return $this->hasOne(UserCoupon::class, 'id', 'user_coupon_id');
|
|
}
|
|
|
|
/**
|
|
* 仅查询支付过期的订单
|
|
*/
|
|
public function scopeExpired()
|
|
{
|
|
return $this->where('status', static::STATUS_PENDING)->where('created_at', '<=', now()->subSeconds(1800));
|
|
}
|
|
|
|
/**
|
|
* 属于此订单的商品
|
|
*/
|
|
public function products()
|
|
{
|
|
return $this->hasMany(OrderProduct::class);
|
|
}
|
|
|
|
/**
|
|
* 确认此订单是否可以被确认
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function isConfirmable(): bool
|
|
{
|
|
return $this->status === static::STATUS_PAID;
|
|
}
|
|
|
|
/**
|
|
* 确认此订单是否可以被取消
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function isCancelable(): bool
|
|
{
|
|
return in_array($this->status, [static::STATUS_PENDING, static::STATUS_PAID])
|
|
&& $this->shipping_state === static::SHIPPING_STATE_PENDING;
|
|
}
|
|
|
|
/**
|
|
* 获取订单券优惠金额
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getCouponDiscountAmountFormatAttribute()
|
|
{
|
|
return Numeric::trimTrailingZero(bcdiv($this->attributes['coupon_discount_amount'], 100, 2));
|
|
}
|
|
|
|
/**
|
|
* 获取订单会员折扣金额
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getVipDiscountAmountFormatAttribute()
|
|
{
|
|
return Numeric::trimTrailingZero(bcdiv($this->attributes['vip_discount_amount'], 100, 2));
|
|
}
|
|
|
|
/**
|
|
* 获取订单减免金额
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getReducedAmountFormatAttribute()
|
|
{
|
|
return Numeric::trimTrailingZero(bcdiv($this->attributes['reduced_amount'], 100, 2));
|
|
}
|
|
|
|
/**
|
|
* 获取订单邮费
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getShippingFeeFormatAttribute()
|
|
{
|
|
return Numeric::trimTrailingZero(bcdiv($this->attributes['shipping_fee'], 100, 2));
|
|
}
|
|
|
|
/**
|
|
* 获取订单支付金额
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getTotalAmountFormatAttribute()
|
|
{
|
|
return Numeric::trimTrailingZero(bcdiv($this->attributes['total_amount'], 100, 2));
|
|
}
|
|
|
|
/**
|
|
* 获取订单商品总额
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getProductsTotalAmountFormatAttribute()
|
|
{
|
|
return Numeric::trimTrailingZero(bcdiv($this->attributes['products_total_amount'], 100, 2));
|
|
}
|
|
|
|
/**
|
|
* 待支付订单过期时间
|
|
*
|
|
* @return int
|
|
*/
|
|
public function getExpiresAtAttribute()
|
|
{
|
|
if (! $this->isPending()) {
|
|
return 0;
|
|
}
|
|
|
|
return now()->diffInSeconds(
|
|
$this->created_at->addSeconds(1800), false
|
|
);
|
|
}
|
|
|
|
/**
|
|
* 获取订单状态
|
|
*
|
|
* @return int
|
|
*/
|
|
public function getOrderStatusAttribute(): int
|
|
{
|
|
$status = OrderStatus::UNKNOWN;
|
|
|
|
if ($this->status === static::STATUS_PENDING) {
|
|
$status = OrderStatus::PENDING;
|
|
} elseif ($this->status === static::STATUS_PAID) {
|
|
switch ($this->shipping_state) {
|
|
case static::SHIPPING_STATE_PENDING:
|
|
$status = OrderStatus::PAID;
|
|
break;
|
|
|
|
case static::SHIPPING_STATE_PROCESSING:
|
|
$status = OrderStatus::SHIPPING;
|
|
break;
|
|
|
|
case static::SHIPPING_STATE_PROCESSED:
|
|
$status = OrderStatus::SHIPPED;
|
|
break;
|
|
}
|
|
} elseif ($this->status === static::STATUS_COMPLETED) {
|
|
$status = OrderStatus::COMPLETED;
|
|
} elseif ($this->status === static::STATUS_CANCELLED) {
|
|
$status = OrderStatus::CANCELLED;
|
|
}
|
|
|
|
return $status;
|
|
}
|
|
}
|