0, 'is_settle' => false, 'is_change' => false, 'status' => self::STATUS_PENDING, ]; /** * @var array */ protected $casts = [ 'pay_at' => 'datetime', 'completed_at' => 'datetime', 'auto_complete_at' => 'datetime', 'status' => 'int', 'is_settle' => 'bool', 'is_change' => 'bool', ]; /** * @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', 'out_trade_no', 'consignee_name', 'consignee_telephone', 'consignee_zone', 'consignee_address', 'shipping_state', 'status', 'completed_at', 'auto_complete_at', 'is_change', 'is_settle', 'sales_value', ]; public static $payWayText = [ self::PAY_WAY_WXPAY => '微信支付', self::PAY_WAY_ALIPAY => '支付宝', self::PAY_WAY_WALLET => '钱包', self::PAY_WAY_BALANCE => '余额', self::PAY_WAY_OFFLINE => '线下支付', ]; /** * 仅查询支付过期的订单 */ public function scopeExpired($query) { return $query->where('status', static::STATUS_PENDING) ->where('created_at', '<=', now()->subSeconds(app_settings('app.order_payment_expires_at'))); } /** * 仅查询可自动完成的订单 */ public function scopeCompletable($query) { return $query->where('status', static::STATUS_PAID) ->where('shipping_state', static::SHIPPING_STATE_PROCESSED) ->where('auto_complete_at', '<=', now()); } /** * 仅查询可结算的订单 */ public function scopeSettlable($query) { return $query->where('status', static::STATUS_COMPLETED) ->where('completed_at', '<=', now()->subDays(app_settings('distribution.settle_days', 7))) ->where('is_settle', false); } /** * 仅查询待发货的订单 */ public function scopeNeedShipping($query) { return $query->where('status', static::STATUS_PAID) ->where('shipping_state', '<', static::SHIPPING_STATE_PROCESSED); } /** * 下单人 * * @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 products() { return $this->hasMany(OrderProduct::class); } /** * 属于此订单的发货包裹 */ public function packages() { return $this->hasMany(OrderPackage::class); } /** * 此订单的最新包裹 * */ public function lastPackage() { return $this->hasOne(OrderPackage::class)->where('is_failed', false)->latestOfMany(); } /** * 属于此订单的退款任务 */ public function refundLogs() { return $this->hasMany(OrderRefundLog::class); } /** * 属于此订单的标签 */ public function tags() { return $this->belongsToMany(Tag::class, 'taggables', 'taggable_id', 'tag_id')->wherePivot('taggable_type', self::class)->withTimestamps(); } /** * 属于此订单的支付记录 */ public function payLogs() { return $this->morphMany(PayLog::class, 'payable'); } /** * 属于此订单的售后单 */ public function afterSales() { return $this->hasMany(AfterSale::class, 'order_id'); } /** * 属于此订单的预收益任务 */ public function distributionPreIncomeJobs() { return $this->morphMany(DistributionPreIncomeJob::class, 'jobable'); } /** * 此订单是否待付款 * * @return boolean */ public function isPending(): bool { return $this->status === static::STATUS_PENDING; } /** * 确认此订单是否已付款 * * @return bool */ public function isPaid(): bool { return $this->status === static::STATUS_PAID; } /** * 确认此订单是否是待发货 * * @return bool */ public function isWaitShipping(): bool { return $this->status === static::STATUS_PAID && $this->shipping_state === static::SHIPPING_STATE_PENDING; } /** * 确认此订单是否是发货中 * * @return bool */ public function isShipping(): bool { return $this->status === static::STATUS_PAID && $this->shipping_state === static::SHIPPING_STATE_PROCESSING; } /** * 确认此订单是否是已发货 * * @return bool */ public function isShipped(): bool { return $this->status === static::STATUS_PAID && $this->shipping_state === static::SHIPPING_STATE_PROCESSED; } /** * 确认此订单是否是已完成 * * @return bool */ public function isCompleted(): bool { return $this->status === static::STATUS_COMPLETED; } /** * 确认此订单是否是已取消 * * @return bool */ public function isCancelled(): bool { return $this->status === static::STATUS_CANCELLED; } /** * 将订单标记为已完成 * * @return void */ public function markAsCompleted() { $this->update([ 'status' => static::STATUS_COMPLETED, 'completed_at' => now(), ]); } /** * 获取订单券优惠金额 * * @return string */ public function getCouponDiscountAmountFormatAttribute() { return trim_trailing_zeros(bcdiv($this->attributes['coupon_discount_amount'], 100, 2)); } /** * 获取订单会员折扣金额 * * @return string */ public function getVipDiscountAmountFormatAttribute() { return trim_trailing_zeros(bcdiv($this->attributes['vip_discount_amount'], 100, 2)); } /** * 获取订单减免金额 * * @return string */ public function getReducedAmountFormatAttribute() { return trim_trailing_zeros(bcdiv($this->attributes['reduced_amount'], 100, 2)); } /** * 获取订单邮费 * * @return string */ public function getShippingFeeFormatAttribute() { return trim_trailing_zeros(bcdiv($this->attributes['shipping_fee'], 100, 2)); } /** * 获取订单支付金额 * * @return string */ public function getTotalAmountFormatAttribute() { return trim_trailing_zeros(bcdiv($this->attributes['total_amount'], 100, 2)); } /** * 获取订单商品总额 * * @return string */ public function getProductsTotalAmountFormatAttribute() { return trim_trailing_zeros(bcdiv($this->attributes['products_total_amount'], 100, 2)); } /** * 待支付订单过期时间 * * @return int */ public function getExpiresAtAttribute() { $seconds = 0; if ($this->isPending()) { $seconds = now()->diffInSeconds( $this->created_at->addSeconds(app_settings('app.order_payment_expires_at', 1800)), false ); } return $seconds > 0 ? $seconds : 0; } /** * 获取订单状态 * * @return int */ public function getOrderStatusAttribute(): int { // 待付款 if ($this->isPending()) { return OrderStatus::PENDING; } // 待发货 if ($this->isWaitShipping()) { return OrderStatus::WAIT_SHIPPING; } // 发货中 if ($this->isShipping()) { return OrderStatus::SHIPPING; } // 已发货 if ($this->isShipped()) { return OrderStatus::SHIPPED; } // 已完成 if ($this->isCompleted()) { return OrderStatus::COMPLETED; } // 已取消 if ($this->isCancelled()) { return OrderStatus::CANCELLED; } // 其它 return OrderStatus::UNKNOWN; } }