This commit is contained in:
2023-03-08 09:16:04 +08:00
commit e78454540f
1318 changed files with 210569 additions and 0 deletions

View File

@@ -0,0 +1,301 @@
<?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(),
];
}
}