302 lines
7.9 KiB
PHP
302 lines
7.9 KiB
PHP
<?php
|
||
|
||
namespace Modules\Mall\Models;
|
||
|
||
use App\Models\Model;
|
||
use App\Traits\OrderByIdDesc;
|
||
use Carbon\Carbon;
|
||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||
use Modules\Gout\Traits\MorphManyTimeline;
|
||
use Modules\Mall\Models\Traits\BelongsToShop;
|
||
use Modules\Mall\Models\Traits\OrderActions;
|
||
use Modules\Mall\Models\Traits\OrderCando;
|
||
use Modules\Mall\Models\Traits\OrderScopes;
|
||
use Modules\Mall\Traits\WithWorkflow;
|
||
use Modules\Payment\Traits\WithPayments;
|
||
use Modules\User\Traits\BelongsToUser;
|
||
use Overtrue\LaravelVersionable\Versionable;
|
||
|
||
class Order extends Model
|
||
{
|
||
|
||
use BelongsToUser,
|
||
BelongsToShop,
|
||
OrderByIdDesc,
|
||
OrderCando,
|
||
Versionable,
|
||
WithWorkflow,
|
||
OrderActions,
|
||
WithPayments,
|
||
MorphManyTimeline,
|
||
OrderScopes,
|
||
SoftDeletes;
|
||
|
||
protected $table = 'mall_orders';
|
||
|
||
protected $dates = [
|
||
'paid_at',
|
||
'expired_at',
|
||
];
|
||
|
||
protected $casts = [
|
||
'source' => 'json',
|
||
];
|
||
protected $appends = ['total'];
|
||
/**
|
||
* 不参与版本记录的字段
|
||
*
|
||
* @var array|string[]
|
||
*/
|
||
protected array $dontVersionable = ['updated_at'];
|
||
|
||
const STATUS_INIT = 'INIT'; // 订单初始化:用户已下单,未付款
|
||
const STATUS_CANCEL = 'CANCEL'; // 订单取消:用户未支付并取消订单,超时未支付后自动取消订单
|
||
const STATUS_PAID = 'PAID'; // 已支付:用户付款完成,等待发货
|
||
const STATUS_DELIVERED = 'DELIVERED'; // 已发货:卖家已发货
|
||
const STATUS_SIGNED = 'SIGNED'; // 已签收:用户已签收
|
||
const STATUS_COMPLETED = 'COMPLETED'; // 已完成:用户签收N天后,完成订单,不再做任何操作,
|
||
|
||
const REFUND_APPLY = 'REFUND_APPLY'; // 申请退款
|
||
const REFUND_AGREE = 'REFUND_AGREE'; // 同意退款
|
||
const REFUND_DELIVER = 'REFUND_DELIVER'; // 等待客户退货
|
||
const REFUND_DELIVERD = 'REFUND_DELIVERD'; // 客户发货
|
||
const REFUND_REFUSE = 'REFUND_REFUSE'; // 拒绝退款
|
||
const REFUND_PROCESS = 'REFUND_PROCESS'; // 退款中
|
||
const REFUND_COMPLETED = 'REFUND_COMPLETED'; // 退款完成
|
||
|
||
const STATUS_MAP = [
|
||
self::STATUS_INIT => '未付款',
|
||
self::STATUS_CANCEL => '已取消',
|
||
self::STATUS_PAID => '待发货',
|
||
self::STATUS_DELIVERED => '已发货',
|
||
self::STATUS_SIGNED => '已签收',
|
||
self::STATUS_COMPLETED => '完成',
|
||
self::REFUND_APPLY => '申请退款',
|
||
self::REFUND_AGREE => '同意退款',
|
||
self::REFUND_REFUSE => '拒绝退款',
|
||
self::REFUND_DELIVER => '等待退货',
|
||
self::REFUND_DELIVERD => '客户退货',
|
||
self::REFUND_PROCESS => '退款中',
|
||
self::REFUND_COMPLETED => '退款完成',
|
||
];
|
||
|
||
const CANCEL_BY_USER = 2; // 买家取消
|
||
const CANCEL_BY_SELLER = 3; // 卖家取消
|
||
const CANCEL_BY_SYSTEM = 4; // 系统取消
|
||
|
||
const TYPE_NORMAL = 1; // 正常
|
||
const TYPE_SAMPLE = 2; // 提货
|
||
const TYPE_SCORE = 3; // 积分兑换
|
||
|
||
const TYPE_MAP = [
|
||
self::TYPE_NORMAL => '正常',
|
||
self::TYPE_SAMPLE => '提货',
|
||
self::TYPE_SCORE => '积分兑换',
|
||
];
|
||
|
||
const CHANNEL_USER = 1;
|
||
const CHANNEL_SYSTEM = 2;
|
||
|
||
const CHANNEL_MAP = [
|
||
self::CHANNEL_USER => '会员',
|
||
self::CHANNEL_SYSTEM => '公司',
|
||
];
|
||
|
||
public static function boot()
|
||
{
|
||
parent::boot();
|
||
|
||
self::creating(function ($model) {
|
||
$time = explode(' ', microtime());
|
||
|
||
$counter = $model->whereDate('created_at', Carbon::today())->count() + 1;
|
||
|
||
$len = config('mall.order_no_counter_length');
|
||
|
||
$len = $len < 6 ? 6 : $len;
|
||
$len = $len > 16 ? 16 : $len;
|
||
|
||
$model->order_no = date('YmdHis').
|
||
sprintf('%06d', $time[0] * 1e6).
|
||
sprintf('%0'.$len.'d', $counter);
|
||
|
||
$model->state = self::STATUS_INIT;
|
||
$model->expired_at = Carbon::now()->addMinutes(10);
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 获取该模型的路由的自定义键名
|
||
*
|
||
* @return string
|
||
*/
|
||
public function getRouteKeyName(): string
|
||
{
|
||
return 'order_no';
|
||
}
|
||
|
||
/**
|
||
* Notes : 获取订单总额
|
||
*
|
||
* @Date : 2021/3/16 1:48 下午
|
||
* @Author : < Jason.C >
|
||
* @return float
|
||
*/
|
||
public function getTotalAttribute(): float
|
||
{
|
||
if ($this->original) {
|
||
return sprintf("%.2f", $this->original['amount'] + $this->original['freight']);
|
||
}
|
||
|
||
return sprintf("%.2f", $this->amount + $this->freight);
|
||
}
|
||
|
||
/**
|
||
* Notes : 订单状态文本
|
||
*
|
||
* @Date : 2021/5/10 3:24 下午
|
||
* @Author : < Jason.C >
|
||
* @return string
|
||
*/
|
||
public function getStateTextAttribute(): string
|
||
{
|
||
return self::STATUS_MAP[$this->state];
|
||
}
|
||
|
||
/**
|
||
* Notes: 订单类型
|
||
*
|
||
* @Author: 玄尘
|
||
* @Date: 2022/10/13 16:53
|
||
* @return string
|
||
*/
|
||
public function getTypeTextAttribute(): string
|
||
{
|
||
return self::TYPE_MAP[$this->type];
|
||
|
||
}
|
||
|
||
/**
|
||
* Notes : 订单发货记录
|
||
*
|
||
* @Date : 2021/5/11 9:47 上午
|
||
* @Author : < Jason.C >
|
||
* @return HasOne
|
||
*/
|
||
public function express(): HasOne
|
||
{
|
||
return $this->hasOne(OrderExpress::class);
|
||
}
|
||
|
||
/**
|
||
* Notes : 订单条目
|
||
*
|
||
* @Date : 2021/5/11 9:47 上午
|
||
* @Author : < Jason.C >
|
||
* @return HasMany
|
||
*/
|
||
public function items(): HasMany
|
||
{
|
||
return $this->hasMany(OrderItem::class);
|
||
}
|
||
|
||
/**
|
||
* Notes: 获取商品
|
||
*
|
||
* @Author: 玄尘
|
||
* @Date : 2021/10/27 15:01
|
||
* @return \Illuminate\Database\Eloquent\HigherOrderBuilderProxy|mixed
|
||
*/
|
||
public function getGoodsAttribute()
|
||
{
|
||
return $this->items()->first()->source;
|
||
}
|
||
|
||
/**
|
||
* Notes : 退款单
|
||
*
|
||
* @Date : 2021/5/11 9:48 上午
|
||
* @Author : < Jason.C >
|
||
* @return HasMany
|
||
*/
|
||
public function refunds(): HasMany
|
||
{
|
||
return $this->hasMany(Refund::class);
|
||
}
|
||
|
||
/**
|
||
* Notes: 获取退款商品数
|
||
*
|
||
* @Author: 玄尘
|
||
* @Date : 2021/5/19 9:50
|
||
* @return int
|
||
*/
|
||
public function getRefundItemsCountAttribute(): int
|
||
{
|
||
$order_id = $this->id;
|
||
|
||
return RefundItem::query()
|
||
->whereHas('order_item', function ($query) use ($order_id) {
|
||
$query->where('order_id', $order_id);
|
||
})
|
||
->whereHas('refund', function ($query) {
|
||
$query->whereNotIN('state', [Refund::REFUND_APPLY]);
|
||
})
|
||
->count();
|
||
}
|
||
|
||
/**
|
||
* Notes : 工作流获取状态
|
||
*
|
||
* @Date : 2021/5/8 3:52 下午
|
||
* @Author : < Jason.C >
|
||
* @return string
|
||
*/
|
||
public function getCurrentState(): string
|
||
{
|
||
return $this->state;
|
||
}
|
||
|
||
/**
|
||
* Notes : 工作流设置状态
|
||
*
|
||
* @Date : 2021/5/8 4:01 下午
|
||
* @Author : < Jason.C >
|
||
* @param $state
|
||
*/
|
||
public function setCurrentState($state)
|
||
{
|
||
$this->state = $state;
|
||
$this->save();
|
||
}
|
||
|
||
/**
|
||
* Notes : 当前订单能不能查看物流
|
||
*
|
||
* @Date : 2021/5/19 11:55
|
||
* @Author : Mr.wang
|
||
* @return bool
|
||
*/
|
||
public function getIsLogisticShowAttribute(): bool
|
||
{
|
||
return in_array($this->state, [
|
||
self::STATUS_DELIVERED,
|
||
self::STATUS_SIGNED,
|
||
self::REFUND_COMPLETED,
|
||
]);
|
||
}
|
||
|
||
public function getCanAction(): array
|
||
{
|
||
return [
|
||
'pay' => $this->canPay(),
|
||
'cancel' => $this->canCancel(),
|
||
'sign' => $this->canSign(),
|
||
'refund' => $this->canRefund(),
|
||
];
|
||
}
|
||
|
||
}
|