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\Di\Annotation\Inject;
use PhpAmqpLib\Message\AMQPMessage;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
#[Consumer(exchange: 'RefundOrder', routingKey: 'RefundOrder', queue: 'RefundOrder.direct', name: "RefundOrderConsumer", nums: 1)]
class RefundOrderConsumer extends ConsumerMessage
@@ -40,22 +42,29 @@ class RefundOrderConsumer extends ConsumerMessage
protected Order $orderModel;
/**
* @param $data
* @param AMQPMessage $message
* @return Result
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
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));
return Result::ACK;
}
$orderId = (int)$data['order_id'];
$orderType = (int)$data['type'];
$amount = $data['amount'];
try {
$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) {
$this->log->error('RefundOrderConsumer:error:'.$e->getMessage().':data:'.json_encode($data));

View File

@@ -24,4 +24,10 @@ class RefundCode
* @Message("退款失败")
*/
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 $notify_json
* @property string $remark
* @property string $reason
* @property string $create_time
* @property string $update_time
*/

View File

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

View File

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

View File

@@ -18,6 +18,7 @@ use App\Constants\ApiCode;
use App\Constants\Common\GoodCode;
use App\Constants\Common\OrderCode;
use App\Constants\Common\PayCode;
use App\Constants\Common\RefundCode;
use App\Constants\ConfigCode;
use App\Exception\ErrException;
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

View File

@@ -46,16 +46,18 @@ trait OrderChangeStatusTrait
* @param int $orderId
* @param int $type
* @param float|int $amount amount = 0 全部 amount > 0 部分
* @param string $reason
* @return void
* @throws ContainerExceptionInterface
* @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([
'order_id' => $orderId,
'type' => $type,
'amount' => $amount,
'reason' => $reason
]);
$producer = ApplicationContext::getContainer()->get(Producer::class);
$producer->produce($message);