319 lines
8.0 KiB
PHP
319 lines
8.0 KiB
PHP
<?php
|
|
|
|
namespace Modules\Mall\Models\Traits;
|
|
|
|
use Encore\Admin\Facades\Admin;
|
|
use Exception;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Modules\Mall\Events\RefundAgreed;
|
|
use Modules\Mall\Events\RefundCompleted;
|
|
use Modules\Mall\Events\RefundRefused;
|
|
use Modules\Payment\Models\Payment;
|
|
|
|
trait RefundActions
|
|
{
|
|
|
|
public $operator;
|
|
|
|
/**
|
|
* Notes: 设置操作人
|
|
*
|
|
* @Author: 玄尘
|
|
* @Date : 2021/5/17 16:12
|
|
* @param $operator
|
|
* @return $this
|
|
*/
|
|
public function setOperator($operator)
|
|
{
|
|
$this->operator = $operator;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Notes: 设置备注
|
|
*
|
|
* @Author: 玄尘
|
|
* @Date : 2021/5/17 16:12
|
|
* @param $remark
|
|
* @return $this
|
|
*/
|
|
public function setRemark($remark)
|
|
{
|
|
$this->remark = $remark;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Notes: 同意退款
|
|
*
|
|
* @Author: 玄尘
|
|
* @Date : 2021/5/17 11:59
|
|
* @param $remark
|
|
* @return bool
|
|
* @throws \Exception
|
|
*/
|
|
public function agree($remark = null): bool
|
|
{
|
|
if (! $this->can('agree')) {
|
|
throw new Exception("退款单状态不可以同意退款");
|
|
}
|
|
|
|
DB::transaction(function () use ($remark) {
|
|
$this->actual_total = $this->refund_total;
|
|
$this->save();
|
|
|
|
$this->apply('agree');
|
|
$this->setOrderApply($this->order, 'agree');
|
|
|
|
if ($this->order->express) {
|
|
$this->express()->create();
|
|
}
|
|
|
|
$this->setLogs($remark);
|
|
|
|
//订单已经进入发货流程,需要客户退货
|
|
if ($this->order->express && $this->order->express->deliver_at) {
|
|
$this->apply('deliver');
|
|
$this->setOrderApply($this->order, 'user_deliver');
|
|
} else {
|
|
//未发货设置为退款中
|
|
$this->apply('process');
|
|
$this->setOrderApply($this->order, 'process');
|
|
}
|
|
|
|
event(new RefundAgreed($this));
|
|
});
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Notes: 拒绝退款
|
|
*
|
|
* @Author: 玄尘
|
|
* @Date : 2021/5/17 12:01
|
|
* @param string|null $remark
|
|
* @return bool
|
|
* @throws \Exception
|
|
*/
|
|
public function refuse(string $remark = null): bool
|
|
{
|
|
if (! $this->can('refuse')) {
|
|
throw new Exception("退款单状态不可以拒绝退款");
|
|
}
|
|
|
|
DB::transaction(function () use ($remark) {
|
|
|
|
$this->apply('refuse');
|
|
$this->setOrderApply($this->order, 'refuse');
|
|
|
|
$this->setLogs($remark);
|
|
|
|
event(new RefundRefused($this));
|
|
});
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Notes: 退货退款中
|
|
*
|
|
* @Author: 玄尘
|
|
* @Date : 2021/5/17 14:29
|
|
* @param $company
|
|
* @param string $number
|
|
* @return bool
|
|
* @throws \Exception
|
|
*/
|
|
public function deliver($company, string $number): bool
|
|
{
|
|
if ($this->can('delivered')) {
|
|
DB::transaction(function () use ($company, $number) {
|
|
$this->express()->update([
|
|
'company' => $company,
|
|
'number' => $number,
|
|
'deliver_at' => now(),
|
|
]);
|
|
|
|
// 修改状态机
|
|
$this->apply('delivered');
|
|
$this->setOrderApply($this->order, 'user_deliverd');
|
|
|
|
$this->setLogs('客户退货');
|
|
|
|
});
|
|
|
|
return true;
|
|
} else {
|
|
throw new Exception('订单状态不可发货');
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Notes: 确认收货
|
|
*
|
|
* @Author: 玄尘
|
|
* @Date : 2021/5/17 14:30
|
|
* @return bool
|
|
* @throws \Exception
|
|
*/
|
|
public function receive(): bool
|
|
{
|
|
if (! $this->can('sign')) {
|
|
throw new Exception('退款单状态不可以确认收货');
|
|
}
|
|
|
|
$this->express->receive_at = now();
|
|
$this->express->save();
|
|
|
|
$this->apply('sign');
|
|
//设置为退款中
|
|
$this->apply('process');
|
|
$this->setOrderApply($this->order, 'process');
|
|
|
|
$this->setLogs('店家签收');
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Notes: 标记退款完成
|
|
*
|
|
* @Author: 玄尘
|
|
* @Date : 2021/5/17 14:32
|
|
* @return bool
|
|
* @throws \Exception
|
|
*/
|
|
public function complete(): bool
|
|
{
|
|
if (! $this->can('completed')) {
|
|
throw new Exception("订单状态不对,不可设置完成");
|
|
}
|
|
|
|
DB::transaction(function () {
|
|
$this->apply('completed');
|
|
//设置时间
|
|
$this->refunded_at = now();
|
|
$this->save();
|
|
|
|
$this->setLogs('订单标记完成');
|
|
|
|
event(new RefundCompleted($this));
|
|
});
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Notes: 退款
|
|
*
|
|
* @Author: 玄尘
|
|
* @Date : 2021/5/17 14:52
|
|
* @throws \Exception
|
|
*/
|
|
public function returns(): bool
|
|
{
|
|
try {
|
|
$payment = $this->order->payment;
|
|
if (! $payment) {
|
|
throw new Exception("退款失败,未找到支付信息");
|
|
}
|
|
//微信支付
|
|
if ($payment->driver == Payment::DRIVER_WECHAT) {
|
|
$order = [
|
|
'out_trade_no' => $payment->trade_id,
|
|
'out_refund_no' => $this->refund_no,
|
|
'total_fee' => $payment->total * 100,
|
|
'refund_fee' => $this->actual_total * 100,
|
|
];
|
|
$result = app('pay.wechat')->refund($order);
|
|
|
|
if ($result->result_code != 'SUCCESS') {
|
|
throw new Exception("退款失败,".$result->return_msg);
|
|
}
|
|
|
|
$this->setLogs('退款完成');
|
|
|
|
return true;
|
|
} elseif ($payment->driver == Payment::DRIVER_ALIPAY) {//支付宝支付
|
|
|
|
$order = [
|
|
'out_trade_no' => $this->order->order_no,
|
|
'refund_amount' => $this->actual_total,
|
|
];
|
|
|
|
$result = app('pay.alipay')->refund($order);
|
|
|
|
if ($result->code != '10000') {
|
|
throw new Exception("退款失败,".$result->msg);
|
|
}
|
|
|
|
return true;
|
|
} elseif ($payment->driver == Payment::DRIVER_SCORE) {//水滴支付
|
|
|
|
$this->user->account->rule('score_buy_refund', $this->actual_total, false, [
|
|
'order_no' => $this->order->order_no,
|
|
'refund_no' => $this->refund_no,
|
|
]);
|
|
|
|
return true;
|
|
} else {
|
|
throw new Exception("退款失败,未找到支付路径");
|
|
}
|
|
} catch (Exception $exception) {
|
|
throw new Exception($exception->getMessage());
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Notes: 记录日志
|
|
*
|
|
* @Author: 玄尘
|
|
* @Date : 2021/5/17 16:03
|
|
* @param null $remark
|
|
* @param null $title
|
|
* @param null $pictures
|
|
*/
|
|
public function setLogs($remark = null, $title = null, $pictures = null)
|
|
{
|
|
if (empty($this->operator)) {
|
|
$this->operator = $this->user;
|
|
}
|
|
|
|
if (empty($this->operator)) {
|
|
$this->operator = Admin::user();
|
|
}
|
|
|
|
$refund = $this->refresh();
|
|
$logs = [
|
|
'userable_type' => get_class($this->operator),
|
|
'userable_id' => $this->operator->id,
|
|
'remark' => $remark,
|
|
'title' => $title,
|
|
'pictures' => $pictures,
|
|
'state' => $refund->state,
|
|
];
|
|
|
|
$refund->logs()->create($logs);
|
|
}
|
|
|
|
/**
|
|
* Notes: 修改订单状态机
|
|
*
|
|
* @Author: 玄尘
|
|
* @Date : 2021/6/17 9:22
|
|
*/
|
|
public function setOrderApply($order, $status)
|
|
{
|
|
//如果都已经退款/货
|
|
if ($order->refund_items_count == $order->items()->count()) {
|
|
$order->apply($status);
|
|
}
|
|
}
|
|
|
|
}
|