| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- <?php
- namespace common\components\delivery\platform\huolala;
- use biz\common\classes\GhsNotifyClass;
- use biz\common\classes\HdNotifyClass;
- use bizGhs\express\classes\GhsDeliveryOrderClass;
- use bizGhs\order\classes\OrderClass;
- use bizHd\express\classes\HdDeliveryOrderClass;
- use bizHd\order\classes\OrderClass as HdOrderClass;
- use bizHd\purchase\classes\PurchaseClass;
- use common\components\noticeUtil;
- use common\components\util;
- use Yii;
- class CallBackHandler
- {
- /**
- * 货拉拉状态回调入口
- *
- * @param array $data
- * @return bool
- */
- public function handler($data)
- {
- try {
- //Yii::info('货拉拉回调 - 原始数据: ' . json_encode($data, JSON_UNESCAPED_UNICODE), 'huolala-callback');
- if (empty($data) || empty($data['data']) || !is_array($data['data'])) {
- Yii::error('货拉拉回调参数异常: ' . json_encode($data, JSON_UNESCAPED_UNICODE), 'huolala-callback');
- return false;
- }
- $bizData = $data['data'];
- $eventType = $bizData['event_type'] ?? '';
- $orderDisplayId = $bizData['order_display_id'] ?? '';
- if ($eventType === '' || $orderDisplayId === '') {
- Yii::error('货拉拉回调缺少必要字段: ' . json_encode($bizData, JSON_UNESCAPED_UNICODE), 'huolala-callback');
- return false;
- }
- $sendStatus = $this->mapEventTypeToOrderSendStatus($eventType);
- if ($sendStatus === null) {
- Yii::warning(sprintf('货拉拉事件未配置状态映射: event_type=%s, order_display_id=%s', $eventType, $orderDisplayId), 'huolala-callback');
- return true;
- }
- $orderStatus = $this->mapEventTypeToOrderStatus($eventType);
- if ($orderStatus === null) {
- Yii::warning(sprintf('货拉拉事件未配置状态映射: event_type=%s, order_display_id=%s', $eventType, $orderDisplayId), 'huolala-callback');
- return true;
- }
- $deliveryOrder = $this->getDeliveryOrder($orderDisplayId);
- if (!$deliveryOrder) {
- Yii::error('货拉拉配送订单不存在: order_display_id=' . $orderDisplayId, 'huolala-callback');
- return false;
- }
- $deliveryOrder->orderStatus = $sendStatus;
- if (!$deliveryOrder->save()) {
- Yii::error('更新配送订单状态失败: ' . json_encode($deliveryOrder->getErrors(), JSON_UNESCAPED_UNICODE), 'huolala-callback');
- return false;
- }
- if(isset($deliveryOrder->ghsOrderId)){ // 批发
- util::checkRepeatCommit('ghs_pt_'.$deliveryOrder->ghsOrderId.'_'.$eventType, 2); // 防止重复回调
- $order = OrderClass::getById($deliveryOrder->ghsOrderId, true, 'id,sendStatus,deliveryId,purchaseId,customId,status');
- if ($order) {
- $cg = PurchaseClass::getById($order->purchaseId, true, 'id,status,sendStatus');
- // 确认送达或取消订单,更新主订单状态
- if ($sendStatus == 5) { // 添加 $cg->status == 3 条件是为了避免报错,而没往下执行
- if($cg->status == 3){
- OrderClass::confirmReach($order, ['staffId' => 0, 'staffName' => '']);
- }else{
- Yii::warning('进行确认送达时,采购单状态不为3,无法进行确认送达。orderId='.$order->id);
- noticeUtil::push('进行确认送达时,采购单状态不为3,无法进行确认送达。orderId='.$order->id.', purchaseId='.$cg->id);
- }
- }
- if (!in_array($order->sendStatus, [-2, -1]) && ($sendStatus == -1 || $sendStatus == -2)) {
- OrderClass::cancelOrderSend($order, ['staffId' => 0, 'staffName' => '']);
- $event = $this->cancelFrom($sendStatus, $eventType);
- GhsNotifyClass::ptErrorNotify($order->id, $event);
- }
- $cg->sendStatus = $sendStatus;
- $cg->save();
- $order->sendStatus = $sendStatus;
- $order->status = $orderStatus;
- if (!$order->save()) {
- Yii::warning('更新主订单配送状态失败: ' . json_encode($order->getErrors(), JSON_UNESCAPED_UNICODE), 'huolala-callback');
- }
- } else {
- Yii::warning('未找到主订单: ghsOrderId=' . $deliveryOrder->ghsOrderId, 'huolala-callback');
- }
- }elseif(isset($deliveryOrder->hdOrderId)){ // 零售
- util::checkRepeatCommit('hd_pt_'.$deliveryOrder->hdOrderId.'_'.$eventType, 2); // 防止重复回调
- $order = HdOrderClass::getById($deliveryOrder->hdOrderId, true, 'id,sendType,sendStatus,deliveryId,customId,status');
- if ($order) {
- if (!in_array($order->sendStatus, [-1, -2]) && ($sendStatus == -1 || $sendStatus == -2)) {
- $event = $this->cancelFrom($sendStatus, $eventType);
- HdNotifyClass::ptErrorNotify($order->id, $event);
- }
- $order->sendStatus = $sendStatus;
- $order->status = $orderStatus;
- if (!$order->save()) {
- Yii::warning('更新主订单配送状态失败: ' . json_encode($order->getErrors(), JSON_UNESCAPED_UNICODE), 'huolala-callback');
- }
- } else {
- Yii::warning('未找到主订单: hdOrderId=' . $deliveryOrder->hdOrderId, 'huolala-callback');
- }
- }
- Yii::info(sprintf('货拉拉配送状态更新成功: order_display_id=%s, event_type=%s, orderStatus=%s', $orderDisplayId, $eventType, $sendStatus), 'huolala-callback');
- return true;
- } catch (\Throwable $e) {
- Yii::error('货拉拉回调处理异常: ' . $e->getMessage() . ' | Trace: ' . $e->getTraceAsString(), 'huolala-callback');
- return false;
- }
- }
- /**
- * 事件到系统配送状态的映射
- *
- * @param string $eventType
- * @return int|null
- */
- protected function mapEventTypeToOrderSendStatus($eventType)
- {
- $eventType = strtolower($eventType);
- $map = [
- //'order_cancelled' => -1, // 官方接口文档未更新,做下返回数据兼容
- 'order_cancel' => -1,
- 'pickup' => 20,
- 'driver_reject' => 2,
- 'order_complete' => 4, //司机完成卸货,订单运送完成
- 'set_order_abnormal' => -2, //异常完成(1、客服点击虚报订单,状态为11;2、用户或者司机申诉账单,客服修改账单为0,状态为2)
- 'loaded' => 4,
- 'auto_confirm_bill_pay' => 5, //系统自动确认账单支付,订单结束
- 'no_load_cancel' => -1,
- 'no_complete_cancel' => -1,
- 'loading' => 3,
- 'unloading' => 4,
- 'unload_finish' => 4,
- 'order_auto_complete' => 5, //司机运送完成后,48小时无操作订单自动完成
- 'order_timeout' => -1,
- 'prepay_ok' => 2,
- 'rear_pay_ok' => 5, //已支付司机账单,订单最终完成
- 'cash_received' => 5, //费用已结清,订单完成
- 'send_bill' => 4, //发送账单
- ];
- return $map[$eventType] ?? null;
- }
- /**
- * 事件到系统订单状态的映射
- *
- * @param string $eventType
- * @return int|null
- */
- protected function mapEventTypeToOrderStatus($eventType)
- {
- // 系统订单状态: 1待付款 2待配送 3配送中 4已完成 5已取消
- $map = [
- // 取消状态 (订单终态)
- 'order_cancel' => 2, // 订单取消 -> 已取消 改为 待配送(配送的取消不等于订单的取消,由于 status 带有配送状态,所以改为:待配送)
- //'order_cancelled' => 2, // 官方接口文档未更新,做下返回数据兼容
- // 回到待配送状态 (可重新派单)
- 'no_load_cancel' => 2, // 未装货取消 -> 待配送
- 'no_complete_cancel' => 2, // 未完成取消 -> 待配送
- 'order_timeout' => 2, // 订单超时 -> 待配送
- 'driver_reject' => 2, // 司机拒单 -> 待配送
- 'set_order_abnormal' => 2, // 订单异常 -> 待配送
- // 配送中状态
- 'prepay_ok' => 3, // 预付成功 -> 配送中
- 'pickup' => 3, // 已取货 -> 配送中
- 'loading' => 3, // 装货中 -> 配送中
- 'loaded' => 3, // 已装货 -> 配送中
- 'unloading' => 3, // 卸货中 -> 配送中
- 'unload_finish' => 3, // 卸货完成 -> 配送中
- 'order_complete' => 3, // 司机完成卸货,订单运送完成 -> 配送中
- 'send_bill' => 3, // 发送账单 -> 配送中
- // 完成状态
- 'order_auto_complete' => 4, // 司机运送完成后,48小时无操作订单自动完成 -> 已完成
- 'auto_confirm_bill_pay' => 4, // 系统自动确认账单支付,订单结束 -> 已完成
- 'rear_pay_ok' => 4, // 已支付司机账单,订单最终完成 -> 已完成
- 'cash_received' => 4, // 费用已结清,订单完成(收到现金) -> 已完成
- ];
- return $map[$eventType] ?? null;
- }
- /**
- * 根据订单号查找配送订单
- *
- * @param string $orderId
- * @return object|null
- */
- private function getDeliveryOrder($orderId)
- {
- // 查找批发配送订单
- $deliveryOrder = GhsDeliveryOrderClass::getByCondition([
- 'deliveryId' => 'huolala',
- 'orderId' => $orderId
- ], true, 'id DESC');
- if ($deliveryOrder) {
- return $deliveryOrder;
- }
- // 查找零售配送订单
- return HdDeliveryOrderClass::getByCondition([
- 'deliveryId' => 'huolala',
- 'orderId' => $orderId
- ], true, 'id DESC');
- }
- private function cancelFrom($sendStatus, $eventType)
- {
- if($sendStatus == -1){
- $reasons = [
- 'order_cancel' => '用户已取消订单',
- 'driver_reject' => '司机接单后拒绝,订单自动取消',
- 'no_load_cancel' => '5天内司机未操作“开始装货”,订单自动取消(测试环境40分钟)',
- 'no_complete_cancel' => '10天内未操作卸货,订单自动取消',
- 'order_timeout' => '订单无司机响应,已自动取消',
- ];
- return $reasons[$eventType] ?? '未知';
- }
- if($sendStatus == -2){
- $reasons = [
- 'set_order_abnormal' => '异常完成(1、客服点击虚报订单,状态为11;2、用户或者司机申诉账单,客服修改账单为0,状态为2)',
- ];
- return $reasons[$eventType] ?? '未知';
- }
- return '未知';
- }
- }
|