Browse Source
Merge branch 'phoenix' of http://120.24.33.109:11081/hyzjshwo/lanzu_api_hyperf into phoenix
master
Merge branch 'phoenix' of http://120.24.33.109:11081/hyzjshwo/lanzu_api_hyperf into phoenix
master
6 changed files with 376 additions and 275 deletions
-
330app/JsonRpc/OrderOnlineService.php
-
8app/JsonRpc/OrderOnlineServiceInterface.php
-
308app/JsonRpc/OrderService.php
-
2app/Service/v3/Implementations/FeiePrintService.php
-
2app/Service/v3/Implementations/StoreService.php
-
1config/autoload/dependencies.php
@ -0,0 +1,330 @@ |
|||
<?php |
|||
|
|||
namespace App\JsonRpc; |
|||
|
|||
use App\Commons\Log; |
|||
use App\Constants\v3\ErrorCode; |
|||
use App\Constants\v3\LogLabel; |
|||
use App\Constants\v3\OrderState; |
|||
use App\Exception\ErrorCodeException; |
|||
use App\Model\v3\Order; |
|||
use App\Model\v3\OrderGoods; |
|||
use App\Model\v3\OrderMain; |
|||
use App\Service\v3\Interfaces\FinancialRecordServiceInterface; |
|||
use App\Service\v3\Interfaces\OrderOnlineServiceInterface; |
|||
use App\Service\v3\Interfaces\SeparateAccountsServiceInterface; |
|||
use EasyWeChat\Factory; |
|||
use EasyWeChat\Kernel\Exceptions\InvalidConfigException; |
|||
use Hyperf\DbConnection\Db; |
|||
use Hyperf\Guzzle\CoroutineHandler; |
|||
use Hyperf\RpcServer\Annotation\RpcService; |
|||
use Hyperf\Di\Annotation\Inject; |
|||
use App\JsonRpc\OrderOnlineServiceInterface as OrderOnlineRpcService; |
|||
use function AlibabaCloud\Client\json; |
|||
|
|||
/** |
|||
* @RpcService(name="OrderOnlineService", protocol="jsonrpc-http", server="jsonrpc-http", publishTo="") |
|||
*/ |
|||
class OrderOnlineService implements OrderOnlineRpcService |
|||
{ |
|||
|
|||
/** |
|||
* @Inject |
|||
* @var Log |
|||
*/ |
|||
protected $log; |
|||
|
|||
/** |
|||
* @Inject |
|||
* @var OrderOnlineServiceInterface |
|||
*/ |
|||
protected $orderOnlineService; |
|||
|
|||
/** |
|||
* @Inject |
|||
* @var SeparateAccountsServiceInterface |
|||
*/ |
|||
protected $separateAccountsService; |
|||
|
|||
/** |
|||
* @Inject |
|||
* @var FinancialRecordServiceInterface |
|||
*/ |
|||
protected $financialRecordService; |
|||
|
|||
/** |
|||
* 订单完成 |
|||
* @param $global_order_id |
|||
* @param $user_id |
|||
* @return array |
|||
*/ |
|||
public function onlineComplete($global_order_id, $user_id) |
|||
{ |
|||
Db::beginTransaction(); |
|||
try { |
|||
|
|||
$this->orderOnlineService->doComplete($global_order_id, $user_id); |
|||
$this->separateAccountsService->orderOnlineCompleted($global_order_id, $user_id); |
|||
|
|||
Db::commit(); |
|||
return [ |
|||
"status" => 200, |
|||
"code" => 0, |
|||
"result" => [], |
|||
"message" => '处理成功' |
|||
]; |
|||
} catch (\Exception $e) { |
|||
|
|||
Db::rollBack(); |
|||
$this->log->event(LogLabel::ORDER_COMPLETE_LOG, ['jsonrpc_order_service_exception_onlineComplete' => $e->getMessage(), 'params' => json([$global_order_id, $user_id])]); |
|||
return [ |
|||
"status" => 200, |
|||
"code" => $e->getCode() ?? ErrorCode::ORDER_COMPLETE_FAIL, |
|||
"result" => [], |
|||
"message" => $e->getMessage() |
|||
]; |
|||
} |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 线上订单退款,整个订单退,这个是专门用于处理用户的申请退款的同意退款操作 |
|||
* @param $global_order_id |
|||
* @param $user_id |
|||
* @return array |
|||
*/ |
|||
public function onlineRefund($global_order_id, $user_id) |
|||
{ |
|||
try { |
|||
$this->orderOnlineService->doRefund($global_order_id, $user_id); |
|||
return [ |
|||
"status" => 200, |
|||
"code" => 0, |
|||
"result" => [], |
|||
"message" => '处理成功' |
|||
]; |
|||
} catch (\Exception $e) { |
|||
return [ |
|||
"status" => 200, |
|||
"code" => $e->getCode(), |
|||
"result" => [], |
|||
"message" => $e->getMessage() |
|||
]; |
|||
} |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 线上订单单笔退款,主要用于后台强行操作退单退款 |
|||
* 支持单商品、单店、整单 |
|||
* 按比例计算红包进行退款 |
|||
* 比如:两个子订单和子订单商品,分别是2元,98元,使用了10元优惠券 |
|||
* 退2元商品时,退款金额为 |
|||
* 红包 :(2/(98+2))*10 = 0.2 |
|||
* 退款:2-0.2=1.8元 |
|||
* @param $user_id *用户ID |
|||
* @param $global_order_id *全局总订单ID |
|||
* @param $order_child_id *主订单ID, |
|||
* @param $order_goods_id *订单商品ID |
|||
* @param $note |
|||
* @return array |
|||
*/ |
|||
public function onlineSingleRefund($user_id, $note, $global_order_id, $order_child_id=null, $order_goods_id=null) |
|||
{ |
|||
|
|||
Db::beginTransaction(); |
|||
try { |
|||
|
|||
$params = [ |
|||
'user_id' => $user_id, |
|||
'note' => $note, |
|||
'global_order_id' => $global_order_id, |
|||
'order_child_id' => $order_child_id, |
|||
'order_goods_id' => $order_goods_id, |
|||
]; |
|||
|
|||
if (!$user_id || !$global_order_id || !$note) { |
|||
$this->log->event(LogLabel::ORDER_REFUND_LOG, [ |
|||
'jsonrpc_order_service_exception_onlineSingleRefund' => '参数不对', |
|||
'params' => json_encode($params) |
|||
]); |
|||
throw new ErrorCodeException(ErrorCode::ORDER_REFUND_FAIL); |
|||
} |
|||
|
|||
// 主订单
|
|||
$orderMain = OrderMain::query() |
|||
->where(['global_order_id' => $global_order_id, 'user_id' => $user_id]) |
|||
->whereIn('state', OrderState::CAN_REFUND_DIRECT) |
|||
->first(); |
|||
|
|||
if (is_null($orderMain)) { |
|||
$this->log->event(LogLabel::ORDER_REFUND_LOG, [ |
|||
'jsonrpc_order_service_exception_onlineSingleRefund' => '订单不存在', |
|||
'params' => json_encode($params) |
|||
]); |
|||
throw new ErrorCodeException(ErrorCode::ORDER_REFUND_FAIL); |
|||
} |
|||
|
|||
// 子订单
|
|||
$orderChild = null; |
|||
if ($order_child_id) { |
|||
$orderChild = Order::query()->with('store:user_id')->where(['order_main_id' => $orderMain->global_order_id, 'id' => $order_child_id])->first(); |
|||
} |
|||
|
|||
// 订单商品
|
|||
$orderGoods = null; |
|||
if ($order_goods_id) { |
|||
if (!$order_child_id || is_null($orderChild)) { |
|||
$this->log->event(LogLabel::ORDER_REFUND_LOG, [ |
|||
'jsonrpc_order_service_exception_onlineSingleRefund' => '子订单参数异常[单品]', |
|||
'params' => json_encode($params) |
|||
]); |
|||
throw new ErrorCodeException(ErrorCode::ORDER_REFUND_FAIL); |
|||
} |
|||
|
|||
$orderGoods = OrderGoods::query()->where(['order_id' => $orderChild->id, 'id' => $order_goods_id])->first(); |
|||
|
|||
if (is_null($orderGoods)) { |
|||
$this->log->event(LogLabel::ORDER_REFUND_LOG, [ |
|||
'jsonrpc_order_service_exception_onlineSingleRefund' => '订单商品参数异常[单品]', |
|||
'params' => json_encode($params) |
|||
]); |
|||
throw new ErrorCodeException(ErrorCode::ORDER_REFUND_FAIL); |
|||
} |
|||
|
|||
} |
|||
$totalAmount = $orderMain->total_money; // 订单可退款金额,总订单金额不含配送费和服务费
|
|||
$preRefundAmount = 0; // 预退款金额
|
|||
$refundAmount = 0; // 实际退款金额
|
|||
$refundType = 'main'; // 退款类型, Main整单 Sub子单 Goods单品
|
|||
if ($orderGoods) { // 1. 如果订单商品存在则说明要退单品
|
|||
$preRefundAmount = bcmul($orderGoods->price, $orderGoods->number, 2); |
|||
$refundType = 'goods'; |
|||
} elseif ($orderChild) { // 2. 否则如果存在子订单说明退子订单
|
|||
$preRefundAmount = $orderChild->money; |
|||
$refundType = 'sub'; |
|||
} else { // 3. 再则如果存在主订单说明退主订单
|
|||
$preRefundAmount = $orderMain->total_money; |
|||
$refundType = 'main'; |
|||
} |
|||
|
|||
// 占订单金额的比例
|
|||
$rate = bcdiv($preRefundAmount, $totalAmount, 6); |
|||
// 计算优惠券所占金额
|
|||
$couponMoney = bcmul($orderMain->coupon_money, $rate, 6); |
|||
// 计算本次退款实际退款金额
|
|||
$refundAmount = bcsub($preRefundAmount, $couponMoney, 2); |
|||
|
|||
if ($refundAmount <= 0) { |
|||
$this->log->event(LogLabel::ORDER_REFUND_LOG, [ |
|||
'jsonrpc_order_service_exception_onlineSingleRefund' => '没有可退款金额[实际退款金额]', |
|||
'params' => json_encode($params) |
|||
]); |
|||
throw new ErrorCodeException(ErrorCode::ORDER_REFUND_FAIL); |
|||
} |
|||
// 开始退款
|
|||
$config = config('wxpay'); |
|||
$app = Factory::payment($config); |
|||
$app['guzzle_handler'] = CoroutineHandler::class; |
|||
$result = $app->refund->byOutTradeNumber( |
|||
$orderMain->global_order_id, |
|||
$orderMain->global_order_id, |
|||
bcmul($orderMain->money, 100, 0), |
|||
bcmul($refundAmount, 100, 0), |
|||
[ |
|||
'refund_desc' => '订单协商退款[' . $refundType . ']', |
|||
'notify_url' => config('wechat.notify_url.refund_single'), |
|||
] |
|||
); |
|||
|
|||
if ($result['return_code'] == 'FAIL') { |
|||
$this->log->event(LogLabel::ORDER_REFUND_LOG, [ |
|||
'jsonrpc_order_service_exception_onlineSingleRefund' => $result['return_msg'] . '[微信退款失败]', |
|||
'params' => json_encode($result) |
|||
]); |
|||
throw new ErrorCodeException(ErrorCode::ORDER_REFUND_FAIL); |
|||
} |
|||
|
|||
if ($result['result_code'] == 'FAIL') { |
|||
$this->log->event(LogLabel::ORDER_REFUND_LOG, [ |
|||
'jsonrpc_order_service_exception_onlineSingleRefund' => $result['err_code_des'] . '[微信退款失败]' . $result['err_code'], |
|||
'params' => json_encode($result) |
|||
]); |
|||
throw new ErrorCodeException(ErrorCode::ORDER_REFUND_FAIL); |
|||
} |
|||
|
|||
// 退款申请成功,查询退款状态,此处暂时无法传递和记录单品退的信息,所以直接查询退款状态处理,不做回调
|
|||
$refundResult = $app->refund->queryByRefundId($result['refund_id']); |
|||
$this->log->event(LogLabel::ORDER_REFUND_LOG, [ |
|||
'jsonrpc_order_service_exception_onlineSingleRefund' => '[微信退款查询]', |
|||
'params' => json_encode($refundResult) |
|||
]); |
|||
|
|||
// 退款成功
|
|||
if ( |
|||
!($refundResult['return_code'] == 'SUCCESS' |
|||
&& isset($refundResult['result_code']) |
|||
&& $refundResult['result_code'] == 'SUCCESS') |
|||
) { |
|||
throw new ErrorCodeException(ErrorCode::ORDER_REFUND_FAIL); |
|||
} |
|||
|
|||
$currentTime = time(); |
|||
// 处理订单状态
|
|||
$orderMain->state = OrderState::REFUNDED; |
|||
$orderMain->total_refund_note = $note; |
|||
$orderMain->refund_time = $currentTime; |
|||
$orderMain->save(); |
|||
|
|||
if ($refundType == 'sub') { |
|||
$orderChild->status = 3; |
|||
$orderChild->refund_note = $note; |
|||
$orderChild->refund_time = $currentTime; |
|||
$orderChild->save(); |
|||
} elseif ($refundType == 'goods') { |
|||
$orderGoods->status = 3; |
|||
$orderGoods->refund_note = $note; |
|||
$orderGoods->refund_time = $currentTime; |
|||
$orderGoods->save(); |
|||
} |
|||
|
|||
// 处理用户和商户流水
|
|||
if ($refundType == 'main') { # 整单退的话还得处理所有子订单的商户
|
|||
|
|||
$orderChildren = Order::query()->with('store:user_id')->where(['order_main_id' => $orderMain->global_order_id])->get(); |
|||
foreach ($orderChildren as $key => &$order) { |
|||
// 占订单金额的比例
|
|||
$rate = bcdiv($order->money, $totalAmount, 6); |
|||
// 计算优惠券所占金额
|
|||
$couponMoney = bcmul($orderMain->coupon_money, $rate, 6); |
|||
// 计算本次退款实际退款金额
|
|||
$refundStoreAmount = bcsub($order->money, $couponMoney, 2); |
|||
$this->financialRecordService->storeRefundDirect($order->store->user_id, $order->id, $refundStoreAmount); |
|||
} |
|||
|
|||
} elseif ($refundType == 'sub') { # 退子订单或者退单品的话,商户只有一个
|
|||
$this->financialRecordService->storeRefundDirect($orderChild->store->user_id, $orderChild->id, $refundAmount); |
|||
} |
|||
|
|||
$this->financialRecordService->userRefundDirect($orderMain->user_id, $orderMain->global_order_id, $refundAmount); |
|||
|
|||
Db::commit(); |
|||
return [ |
|||
"status" => 200, |
|||
"code" => 0, |
|||
"result" => [], |
|||
"message" => '处理成功' |
|||
]; |
|||
|
|||
} catch (\Exception $e) { |
|||
Db::rollBack(); |
|||
return [ |
|||
"status" => 200, |
|||
"code" => $e->getCode(), |
|||
"result" => [], |
|||
"message" => '[退款失败]'.$e->getMessage() |
|||
]; |
|||
} |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
<?php |
|||
|
|||
namespace App\JsonRpc; |
|||
|
|||
interface OrderOnlineServiceInterface |
|||
{ |
|||
|
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue