feat : refund

This commit is contained in:
2025-02-24 15:30:58 +08:00
parent d0409088a6
commit c14901de4a
7 changed files with 105 additions and 24 deletions

View File

@@ -15,6 +15,8 @@ use Hyperf\Amqp\Annotation\Consumer;
use Hyperf\Amqp\Message\ConsumerMessage; use Hyperf\Amqp\Message\ConsumerMessage;
use Hyperf\Di\Annotation\Inject; use Hyperf\Di\Annotation\Inject;
use PhpAmqpLib\Message\AMQPMessage; use PhpAmqpLib\Message\AMQPMessage;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
#[Consumer(exchange: 'RefundOrder', routingKey: 'RefundOrder', queue: 'RefundOrder.direct', name: "RefundOrderConsumer", nums: 1)] #[Consumer(exchange: 'RefundOrder', routingKey: 'RefundOrder', queue: 'RefundOrder.direct', name: "RefundOrderConsumer", nums: 1)]
class RefundOrderConsumer extends ConsumerMessage class RefundOrderConsumer extends ConsumerMessage
@@ -40,22 +42,29 @@ class RefundOrderConsumer extends ConsumerMessage
protected Order $orderModel; protected Order $orderModel;
/**
* @param $data
* @param AMQPMessage $message
* @return Result
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function consumeMessage($data, AMQPMessage $message): Result public function consumeMessage($data, AMQPMessage $message): Result
{ {
if (!$data['order_id'] || !$data['type'] || !$data['amount']) { if (!$data['order_id'] || !$data['type'] || !$data['amount'] || !$data['reason']) {
$this->log->error('CancelOrderConsumer:error:NoData:'.json_encode($data)); $this->log->error('CancelOrderConsumer:error:NoData:'.json_encode($data));
return Result::ACK; return Result::ACK;
} }
$orderId = (int)$data['order_id'];
$orderType = (int)$data['type'];
$amount = $data['amount'];
try { try {
$service = new RefundService(); $service = new RefundService();
$service->orderId = (int)$data['order_id'];
$service->type = (int)$data['type'];
$service->refundAmount = $data['amount'];
$service->reason = $data['reason'];
$service->handle();
} catch (Exception $e) { } catch (Exception $e) {
$this->log->error('RefundOrderConsumer:error:'.$e->getMessage().':data:'.json_encode($data)); $this->log->error('RefundOrderConsumer:error:'.$e->getMessage().':data:'.json_encode($data));

View File

@@ -24,4 +24,10 @@ class RefundCode
* @Message("退款失败") * @Message("退款失败")
*/ */
CONST INT REFUND_FAIL = 99; CONST INT REFUND_FAIL = 99;
/**
* @var string 订单类型前缀
*/
const string ORDER_TYPE_GOOD_PREFIX = 'RG';
const string ORDER_TYPE_BALANCE_PREFIX = 'RB';
} }

View File

@@ -24,6 +24,7 @@ use Hyperf\DbConnection\Model\Model;
* @property string $wx_transaction_id * @property string $wx_transaction_id
* @property string $notify_json * @property string $notify_json
* @property string $remark * @property string $remark
* @property string $reason
* @property string $create_time * @property string $create_time
* @property string $update_time * @property string $update_time
*/ */

View File

@@ -10,11 +10,16 @@ use App\Model\Order;
use App\Model\PayOrder; use App\Model\PayOrder;
use App\Model\RefundOrder; use App\Model\RefundOrder;
use App\Service\Common\Pay\Wx\WxJsRechargeOrderService; use App\Service\Common\Pay\Wx\WxJsRechargeOrderService;
use App\Service\ServiceTrait\Api\OrderTrait;
use Exception; use Exception;
use Hyperf\Di\Annotation\Inject; use Hyperf\Di\Annotation\Inject;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class RefundService class RefundService
{ {
use OrderTrait;
/** /**
* @var int * @var int
*/ */
@@ -23,7 +28,12 @@ class RefundService
/** /**
* @var int * @var int
*/ */
protected int $type; public int $type;
/**
* @var string
*/
public string $reason;
/** /**
* @var PayOrder * @var PayOrder
@@ -76,7 +86,10 @@ class RefundService
protected float $isRefundMoney; protected float $isRefundMoney;
/** /**
* * @return void
* @throws Exception
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/ */
public function handle(): void public function handle(): void
{ {
@@ -93,6 +106,8 @@ class RefundService
$this->checkRefundAmount(); $this->checkRefundAmount();
$this->insertRefundOrder();
$this->refund(); $this->refund();
} catch (Exception $e) { } catch (Exception $e) {
$this->log->error('RefundOrderConsumer:RefundService:error:'.$e->getMessage()); $this->log->error('RefundOrderConsumer:RefundService:error:'.$e->getMessage());
@@ -103,6 +118,27 @@ class RefundService
$this->updateRefund($errMsg); $this->updateRefund($errMsg);
} }
/**
* @return void
* @throws Exception
*/
private function insertRefundOrder(): void
{
$this->refundInfo = new RefundOrder();
$this->refundInfo->user_id = $this->orderInfo->user_id;
$this->refundInfo->order_type = $this->type;
$this->refundInfo->order_id = $this->orderId;
$this->refundInfo->pay_id = $this->payInfo->id;
$this->refundInfo->refund_status = RefundCode::WAIT_REFUND;
$this->refundInfo->refund_money = $this->refundAmount;
$this->refundInfo->refund_type = $this->payInfo->recharge_type;
$this->refundInfo->refund_order_sno = $this->generateRefundOrderNo($this->type, $this->orderInfo->user_id);
$this->refundInfo->reason = $this->reason;
if (!$this->refundInfo->save()) throw new Exception('退款订单创建失败');
}
/** /**
* @return void * @return void
* @throws Exception * @throws Exception
@@ -111,15 +147,17 @@ class RefundService
{ {
$this->payInfo = $this->payOrderModel->getInfoByOrderIdAndType($this->orderId, $this->type); $this->payInfo = $this->payOrderModel->getInfoByOrderIdAndType($this->orderId, $this->type);
$this->refundInfo = $this->refundOrderModel->getInfoByOrderIdAndTypeWaitRefund($this->orderId,$this->type); // $this->refundInfo = $this->refundOrderModel->getInfoByOrderIdAndTypeWaitRefund($this->orderId,$this->type);
if (!$this->payInfo || !$this->refundInfo) throw new Exception('订单信息不存在'); if (!$this->payInfo) throw new Exception('订单信息不存在');
if ($this->payInfo->status != PayCode::FINISH_PAY) throw new Exception('订单支付状态不是成功');
} }
/** /**
* @return void * @return void
*/ */
protected function getOrderInfo() protected function getOrderInfo(): void
{ {
$this->orderInfo = match ($this->type) { $this->orderInfo = match ($this->type) {
OrderCode::ORDER_TYPE_GOOD => $this->orderModel->getInfoById($this->orderId), OrderCode::ORDER_TYPE_GOOD => $this->orderModel->getInfoById($this->orderId),
@@ -131,7 +169,7 @@ class RefundService
* @return void * @return void
* @throws Exception * @throws Exception
*/ */
protected function checkOrder() protected function checkOrder(): void
{ {
if (empty($orderInfo)) throw new Exception('订单信息不存在:'.json_encode(['order_id' => $this->orderId,'order_type' => $this->type])); if (empty($orderInfo)) throw new Exception('订单信息不存在:'.json_encode(['order_id' => $this->orderId,'order_type' => $this->type]));
@@ -149,10 +187,10 @@ class RefundService
$this->isRefundMoney = $this->refundOrderModel->getSuccessMoneyByOrderId($this->orderId,$this->type); $this->isRefundMoney = $this->refundOrderModel->getSuccessMoneyByOrderId($this->orderId,$this->type);
} }
protected function getUser() // protected function getUser()
{ // {
//todo 获取用户信息 // //todo 获取用户信息
} // }
/** /**
* @return void * @return void
@@ -167,9 +205,11 @@ class RefundService
} }
/** /**
* @param null $errMsg
* @return void * @return void
* @throws Exception
*/ */
protected function updateRefund($errMsg = null) protected function updateRefund($errMsg = null): void
{ {
$status = RefundCode::REFUND_FAIL; $status = RefundCode::REFUND_FAIL;
@@ -178,12 +218,17 @@ class RefundService
$errMsg = '等待支付工具退款'; $errMsg = '等待支付工具退款';
} }
$this->refundOrderModel->where('id',$this->refundInfo->id)->update([ $this->refundInfo->refund_status = $status;
'refund_status' => $status, $this->refundInfo->remark = $errMsg;
'remark' => $errMsg
]); if (!$this->refundInfo->save()) throw new Exception('退款订单更新失败');
} }
/**
* @return void
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
protected function refund(): void protected function refund(): void
{ {
$rechargeService = match ($this->refundInfo->refund_type) $rechargeService = match ($this->refundInfo->refund_type)
@@ -203,6 +248,9 @@ class RefundService
); );
} }
/**
* @return null
*/
protected function setAliPayRefund() protected function setAliPayRefund()
{ {
return null; return null;

View File

@@ -36,6 +36,7 @@ class RefundOrderService extends BaseService
*/ */
public function handle(): array public function handle(): array
{ {
//todo 考虑是否枷锁
$orderId = (int)$this->request->input('order_id'); $orderId = (int)$this->request->input('order_id');
$type = (int)$this->request->input('type'); $type = (int)$this->request->input('type');
@@ -44,7 +45,7 @@ class RefundOrderService extends BaseService
if ($orderInfo->status != OrderCode::PAYED) throw new ErrException('该订单状态已变更,请勿重复操作,刷新后无法退款请联系客服'); if ($orderInfo->status != OrderCode::PAYED) throw new ErrException('该订单状态已变更,请勿重复操作,刷新后无法退款请联系客服');
//立即取消 //立即取消
$this->joinRefundQueue($orderId, $type); $this->joinRefundQueue($orderId, $type, $orderInfo->amount, '用户主动取消订单');
return $this->return->success(); return $this->return->success();
} }

View File

@@ -18,6 +18,7 @@ use App\Constants\ApiCode;
use App\Constants\Common\GoodCode; use App\Constants\Common\GoodCode;
use App\Constants\Common\OrderCode; use App\Constants\Common\OrderCode;
use App\Constants\Common\PayCode; use App\Constants\Common\PayCode;
use App\Constants\Common\RefundCode;
use App\Constants\ConfigCode; use App\Constants\ConfigCode;
use App\Exception\ErrException; use App\Exception\ErrException;
use App\Model\Order; use App\Model\Order;
@@ -57,6 +58,19 @@ trait OrderTrait
}; };
} }
/**
* @param int $type
* @param int $userId
* @return string
*/
protected function generateRefundOrderNo(int $type,int $userId): string
{
return match ($type) {
OrderCode::ORDER_TYPE_GOOD => RefundCode::ORDER_TYPE_GOOD_PREFIX . '_' .date("YmdHis") . $userId . mt_rand(10000000, 99999999),
OrderCode::ORDER_TYPE_BALANCE => RefundCode::ORDER_TYPE_BALANCE_PREFIX. '_' .date("YmdHis"). $userId. mt_rand(10000000, 99999999),
};
}
/** /**
* 生成购物车数据 * 生成购物车数据
* @param array $data * @param array $data

View File

@@ -46,16 +46,18 @@ trait OrderChangeStatusTrait
* @param int $orderId * @param int $orderId
* @param int $type * @param int $type
* @param float|int $amount amount = 0 全部 amount > 0 部分 * @param float|int $amount amount = 0 全部 amount > 0 部分
* @param string $reason
* @return void * @return void
* @throws ContainerExceptionInterface * @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface * @throws NotFoundExceptionInterface
*/ */
protected function joinRefundQueue(int $orderId, int $type, float|int $amount = 0): void protected function joinRefundQueue(int $orderId, int $type, float|int $amount = 0, string $reason = '系统自动'): void
{ {
$message = new RefundOrderProducer([ $message = new RefundOrderProducer([
'order_id' => $orderId, 'order_id' => $orderId,
'type' => $type, 'type' => $type,
'amount' => $amount, 'amount' => $amount,
'reason' => $reason
]); ]);
$producer = ApplicationContext::getContainer()->get(Producer::class); $producer = ApplicationContext::getContainer()->get(Producer::class);
$producer->produce($message); $producer->produce($message);