OrderStatusCallBack.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. <?php
  2. namespace common\components\delivery\platform\shansong;
  3. use biz\common\classes\GhsNotifyClass;
  4. use biz\common\classes\HdNotifyClass;
  5. use bizGhs\express\classes\GhsDeliveryOrderClass;
  6. use bizGhs\order\classes\OrderClass;
  7. use bizHd\express\classes\HdDeliveryOrderClass;
  8. use bizHd\order\classes\OrderClass as HdOrderClass;
  9. use bizHd\purchase\classes\PurchaseClass;
  10. use common\components\noticeUtil;
  11. use common\components\util;
  12. use Yii;
  13. /**
  14. * 闪送订单状态回调处理类
  15. * Class OrderStatusCallBack
  16. * @package common\components\delivery\platform\shanSong
  17. */
  18. class OrderStatusCallBack
  19. {
  20. /**
  21. * 处理闪送订单状态回调
  22. *
  23. * @param array $data 回调数据
  24. * @return bool 处理结果
  25. */
  26. public function handle($data)
  27. {
  28. try {
  29. // 记录回调原始数据
  30. //Yii::info('闪送订单状态回调 - 原始数据: ' . json_encode($data, JSON_UNESCAPED_UNICODE), 'shansong-callback');
  31. // 验证必要参数
  32. if (empty($data['issOrderNo']) || !isset($data['status'])) {
  33. Yii::error('闪送回调参数不完整: ' . json_encode($data, JSON_UNESCAPED_UNICODE), 'shansong-callback');
  34. return false;
  35. }
  36. // 将闪送平台的订单状态转换为系统内的 orderStatus
  37. $status = $data['status'];
  38. $subStatus = isset($data['subStatus']) ? $data['subStatus'] : null;
  39. $sendStatus = SendStatusUtil::convertOrderStatus($status, $subStatus);
  40. $orderStatus = OrderStatusUtil::convertStatus($status, $subStatus);
  41. // 查找配送订单
  42. $deliveryOrder = $this->getDeliveryOrder($data['issOrderNo']);
  43. if ($deliveryOrder === null) {
  44. if($status == 20 && $subStatus == 1){
  45. Yii::info('闪送订单暂未创建 -- issOrderNo=' . $data['issOrderNo'], 'shansong-callback');
  46. return true;
  47. }
  48. Yii::error('闪送订单不存在: issOrderNo=' . $data['issOrderNo'], 'shansong-callback');
  49. return false;
  50. }
  51. // 处理骑手信息
  52. $this->handleCourierInfo($data, $deliveryOrder);
  53. // 处理取消信息
  54. $this->handleCancelInfo($data, $deliveryOrder);
  55. // 处理费用信息
  56. $this->handleFeeInfo($data, $deliveryOrder);
  57. // 处理密码信息
  58. $this->handlePasswordInfo($data, $deliveryOrder);
  59. // 更新配送订单状态
  60. $deliveryOrder->orderStatus = $sendStatus;
  61. $deliveryOrder->save();
  62. // 区分类别,然后更新主订单状态
  63. if(isset($deliveryOrder->ghsOrderId)){ // 批发
  64. $type = '批发';
  65. util::checkRepeatCommit('ghs_pt_'.$deliveryOrder->ghsOrderId.'_'.$data['status'].'_'.$subStatus, 2);// 防止重复回调
  66. $order = OrderClass::getById($deliveryOrder->ghsOrderId, true, 'id,sendType,sendStatus,deliveryId,purchaseId,customId,status');
  67. $cg = PurchaseClass::getById($order->purchaseId, true, 'id,status,sendStatus');
  68. if ($order) {
  69. // 确认送达或取消订单,更新主订单状态
  70. if ($sendStatus == 5) {
  71. if($cg->status == 3){
  72. OrderClass::confirmReach($order, ['staffId' => 0, 'staffName' => '']);
  73. }else{
  74. Yii::warning('进行确认送达时,采购单状态不为3,无法进行确认送达。orderId='.$order->id);
  75. noticeUtil::push('进行确认送达时,采购单状态不为3,无法进行确认送达。orderId='.$order->id.', purchaseId='.$cg->id);
  76. }
  77. }
  78. if (!in_array($order->sendStatus, [-2, -1]) && ($sendStatus == -1 || $sendStatus == -2)) {
  79. OrderClass::cancelOrderSend($order, ['staffId' => 0, 'staffName' => '']);
  80. $abortType = $data['abortType'] ?? null;
  81. $event = $this->cancelFrom($sendStatus, $abortType);
  82. GhsNotifyClass::ptErrorNotify($order->id, $event);
  83. }
  84. $cg->sendStatus = $sendStatus;
  85. $cg->save();
  86. $order->sendStatus = $sendStatus;
  87. $order->save();
  88. }
  89. }elseif(isset($deliveryOrder->hdOrderId)){ // 零售
  90. $type = '零售';
  91. util::checkRepeatCommit('hd_pt_'.$deliveryOrder->hdOrderId.'_'.$data['status'].'_'.$subStatus, 2);// 防止重复回调
  92. $order = HdOrderClass::getById($deliveryOrder->hdOrderId, true, 'id,sendType,sendStatus,deliveryId,customId,status');
  93. $order->status = $orderStatus;
  94. if ($order) {
  95. if (!in_array($order->sendStatus, [-1, -2]) && ($sendStatus == -1 || $sendStatus == -2)) {
  96. $abortType = $data['abortType'] ?? null;
  97. $event = $this->cancelFrom($sendStatus, $abortType);
  98. HdNotifyClass::ptErrorNotify($order->id, $event);
  99. }
  100. $order->sendStatus = $sendStatus;
  101. $order->save();
  102. }
  103. }
  104. Yii::info("闪送({$type})订单状态更新成功: issOrderNo={$data['issOrderNo']}, status={$data['status']} , sendStatus={$sendStatus}", 'shansong-callback');
  105. return true;
  106. } catch (\Exception $e) {
  107. Yii::error('闪送回调处理异常: ' . $e->getMessage() .
  108. ' | Trace: ' . $e->getTraceAsString(), 'shansong-callback');
  109. return false;
  110. }
  111. }
  112. /**
  113. * 处理骑手信息
  114. *
  115. * @param array $data 回调数据
  116. * @param object $deliveryOrder 配送订单对象
  117. */
  118. private function handleCourierInfo($data, $deliveryOrder)
  119. {
  120. if (isset($data['courier']) && is_array($data['courier'])) {
  121. $courier = $data['courier'];
  122. Yii::info($data['issOrderNo'] . '-闪送骑手信息: ' . json_encode([
  123. 'name' => $courier['name'] ?? '',
  124. 'mobile' => $courier['mobile'] ?? '',
  125. 'id' => $courier['id'] ?? '',
  126. 'headIcon' => $courier['headIcon'] ?? '',
  127. 'latitude' => $courier['latitude'] ?? '',
  128. 'longitude' => $courier['longitude'] ?? '',
  129. 'time' => $courier['time'] ?? '',
  130. 'orderCount' => $courier['orderCount'] ?? 0,
  131. 'estimateDeliveryTimeTip' => $courier['estimateDeliveryTimeTip'] ?? '',
  132. ], JSON_UNESCAPED_UNICODE), 'shansong-callback');
  133. // 保存到数据库字段
  134. // $deliveryOrder->courierName = $courier['name'] ?? '';
  135. // $deliveryOrder->courierPhone = $courier['mobile'] ?? '';
  136. // $deliveryOrder->courierId = $courier['id'] ?? '';
  137. // $deliveryOrder->courierHeadIcon = $courier['headIcon'] ?? '';
  138. // $deliveryOrder->courierLatitude = $courier['latitude'] ?? '';
  139. // $deliveryOrder->courierLongitude = $courier['longitude'] ?? '';
  140. // $deliveryOrder->courierTime = $courier['time'] ?? '';
  141. // $deliveryOrder->estimateDeliveryTimeTip = $courier['estimateDeliveryTimeTip'] ?? '';
  142. // 处理配送轨迹(如需要)
  143. if (isset($courier['deliveryProcessTrail']) && is_array($courier['deliveryProcessTrail'])) {
  144. Yii::info('闪送配送轨迹: ' . json_encode($courier['deliveryProcessTrail'], JSON_UNESCAPED_UNICODE), 'shansong-callback');
  145. }
  146. }
  147. }
  148. /**
  149. * 处理取消信息
  150. *
  151. * @param array $data 回调数据
  152. * @param object $deliveryOrder 配送订单对象
  153. */
  154. private function handleCancelInfo($data, $deliveryOrder)
  155. {
  156. // 订单取消时(status=60)会返回取消相关信息
  157. if (isset($data['status']) && $data['status'] == 60) {
  158. $abortType = $data['abortType'] ?? null;
  159. $punishType = $data['punishType'] ?? null;
  160. $abortReason = $data['abortReason'] ?? '';
  161. Yii::info($data['issOrderNo'] . '-闪送取消信息: ' . json_encode([
  162. 'abortType' => $abortType,
  163. 'abortTypeDesc' => $abortType ? SendStatusUtil::getAbortTypeDesc($abortType) : '',
  164. 'punishType' => $punishType,
  165. 'punishTypeDesc' => $punishType ? SendStatusUtil::getPunishTypeDesc($punishType) : '',
  166. 'abortReason' => $abortReason,
  167. ], JSON_UNESCAPED_UNICODE), 'shansong-callback');
  168. // 保存到数据库字段
  169. // $deliveryOrder->abortType = $abortType;
  170. // $deliveryOrder->punishType = $punishType;
  171. // $deliveryOrder->abortReason = $abortReason;
  172. }
  173. }
  174. /**
  175. * 处理费用信息
  176. *
  177. * @param array $data 回调数据
  178. * @param object $deliveryOrder 配送订单对象
  179. */
  180. private function handleFeeInfo($data, $deliveryOrder)
  181. {
  182. $deductAmount = $data['deductAmount'] ?? 0;
  183. $drawback = $data['drawback'] ?? 0;
  184. $sendBackFee = $data['sendBackFee'] ?? 0;
  185. // 记录费用信息(金额单位:分)
  186. if ($deductAmount > 0 || $drawback > 0 || $sendBackFee > 0) {
  187. Yii::info($data['issOrderNo'] . '-闪送费用信息: ' . json_encode([
  188. 'deductAmount' => $deductAmount, // 扣款金额
  189. 'drawback' => $drawback, // 退款金额
  190. 'sendBackFee' => $sendBackFee, // 送回费
  191. ], JSON_UNESCAPED_UNICODE), 'shansong-callback');
  192. // 保存到数据库字段 | 扣款金额 + 送回费
  193. $deliveryOrder->cancelCost = $deductAmount + $sendBackFee;
  194. }
  195. }
  196. /**
  197. * 处理密码信息
  198. *
  199. * @param array $data 回调数据
  200. * @param object $deliveryOrder 配送订单对象
  201. */
  202. private function handlePasswordInfo($data, $deliveryOrder)
  203. {
  204. $pickupPassword = $data['pickupPassword'] ?? '';
  205. $deliveryPassword = $data['deliveryPassword'] ?? '';
  206. if (!empty($pickupPassword) || !empty($deliveryPassword)) {
  207. Yii::info($data['issOrderNo'] . '-闪送密码信息: ' . json_encode([
  208. 'pickupPassword' => $pickupPassword,
  209. 'deliveryPassword' => $deliveryPassword,
  210. ], JSON_UNESCAPED_UNICODE), 'shansong-callback');
  211. // 保存到数据库字段
  212. // $deliveryOrder->pickupPassword = $pickupPassword;
  213. // $deliveryOrder->deliveryPassword = $deliveryPassword;
  214. }
  215. }
  216. /**
  217. * 根据订单号查找配送订单
  218. *
  219. * @param string $orderId
  220. * @return object|null
  221. */
  222. private function getDeliveryOrder($orderId)
  223. {
  224. // 查找批发配送订单
  225. $deliveryOrder = GhsDeliveryOrderClass::getByCondition([
  226. 'deliveryId' => 'shansong',
  227. 'orderId' => $orderId
  228. ], true, 'id DESC');
  229. if ($deliveryOrder) {
  230. return $deliveryOrder;
  231. }
  232. // 查找零售配送订单
  233. return HdDeliveryOrderClass::getByCondition([
  234. 'deliveryId' => 'shansong',
  235. 'orderId' => $orderId
  236. ], true, 'id DESC');
  237. }
  238. private function cancelFrom($sendStatus, $abortType)
  239. {
  240. if($sendStatus == -1){
  241. switch($abortType){
  242. case 1:
  243. $which = '客户发起取消';
  244. break;
  245. case 3:
  246. $which = '闪送员发起取消';
  247. break;
  248. case 10:
  249. $which = '系统自动发起取消';
  250. break;
  251. default:
  252. $which = '未知';
  253. }
  254. return $which;
  255. }
  256. if($sendStatus == -2){
  257. return '异常';
  258. }
  259. }
  260. }