Files
water_new/modules/Mall/Models/Order.php
2023-03-09 11:54:13 +08:00

300 lines
7.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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\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,
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(),
];
}
}