You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

222 lines
5.7 KiB

  1. <?php
  2. namespace App\Controller\v3;
  3. use App\Constants\v3\OrderState;
  4. use App\Controller\BaseController;
  5. use App\Model\v3\Order;
  6. use App\Model\v3\OrderMain;
  7. use Hyperf\DbConnection\Db;
  8. use Psr\Http\Message\ResponseInterface;
  9. /**
  10. * 顺丰同城回调
  11. */
  12. class SfExpressController extends BaseController
  13. {
  14. private string $dev_id;
  15. private string $dev_key;
  16. // private string $shop_id;
  17. public function __construct()
  18. {
  19. parent::__construct(); //此句不能少,否则$this->request和$this->response获取不到
  20. $this->dev_id = env('SF_EXPRESS_DEV_ID');
  21. $this->dev_key = env('SF_EXPRESS_DEV_KEY');
  22. // $this->shop_id = env('SF_EXPRESS_SHOP_ID');
  23. }
  24. /**
  25. * 配送状态更改回调
  26. */
  27. public function riderStatus(): ResponseInterface
  28. {
  29. if (!$this->checkSign($this->request->query('sign'))) {
  30. return $this->response->json([
  31. 'error_code' => 500,
  32. 'error_msg' => '签名错误',
  33. ]);
  34. }
  35. $formData = $this->request->all();
  36. if (empty($formData['shop_order_id'])) {
  37. return $this->response->json([
  38. 'error_code' => 500,
  39. 'error_msg' => '无效的shop_order_id',
  40. ]);
  41. }
  42. # 主订单表
  43. $orderMain = OrderMain::whereIn('state', [OrderState::PAID, OrderState::DELIVERY])
  44. ->where('global_order_id', $formData['shop_order_id'])
  45. ->first();
  46. if (!$orderMain) {
  47. return $this->response->json([
  48. 'error_code' => 500,
  49. 'error_msg' => '订单不存在',
  50. ]);
  51. }
  52. DB::beginTransaction();
  53. try {
  54. # 主订单表
  55. $orderMain->state = OrderState::DELIVERY;
  56. //order_status 订单状态 10-配送员确认;12:配送员到店;15:配送员配送中
  57. if (!empty($formData['order_status'])) {
  58. if ($formData['order_status'] == 10 && $orderMain->receive_time == 0) {
  59. $orderMain->receive_time = time(); // 接单时间
  60. } else if ($formData['order_status'] == 12 && $orderMain->delivery_start_time == 0) {
  61. $orderMain->delivery_start_time = time(); // 开始配送时间
  62. }
  63. }
  64. $orderMain->save();
  65. # 子订单表
  66. Order::where('order_main_id', $formData['shop_order_id'])
  67. ->update(['state' => $orderMain->state]);
  68. DB::commit();
  69. } catch (\Exception $exception) {
  70. DB::rollBack();
  71. return $this->response->json([
  72. 'error_code' => 500,
  73. 'error_msg' => $exception->getMessage(),
  74. ]);
  75. }
  76. return $this->response->json([
  77. 'error_code' => 0,
  78. 'error_msg' => 'success',
  79. ]);
  80. }
  81. /**
  82. * 骑士撤单状态回调
  83. */
  84. public function riderRecall(): ResponseInterface
  85. {
  86. if (!$this->checkSign($this->request->query('sign'))) {
  87. return $this->response->json([
  88. 'error_code' => 500,
  89. 'error_msg' => '签名错误',
  90. ]);
  91. }
  92. $formData = $this->request->all();
  93. if (empty($formData['shop_order_id'])) {
  94. return $this->response->json([
  95. 'error_code' => 500,
  96. 'error_msg' => '无效的shop_order_id',
  97. ]);
  98. }
  99. //order_status 22-配送员撤单
  100. //TODO 因目前订单表没有相关撤单的字段,故目前不做处理,仅仅返回成功给顺丰
  101. return $this->response->json([
  102. 'error_code' => 0,
  103. 'error_msg' => 'success',
  104. ]);
  105. }
  106. /**
  107. * 订单完成回调
  108. */
  109. public function orderComplete(): ResponseInterface
  110. {
  111. if (!$this->checkSign($this->request->query('sign'))) {
  112. return $this->response->json([
  113. 'error_code' => 500,
  114. 'error_msg' => '签名错误',
  115. ]);
  116. }
  117. $formData = $this->request->all();
  118. if (empty($formData['shop_order_id'])) {
  119. return $this->response->json([
  120. 'error_code' => 500,
  121. 'error_msg' => '无效的shop_order_id',
  122. ]);
  123. }
  124. # 主订单表
  125. $orderMain = OrderMain::where('state', '>', OrderState::UNPAID)
  126. ->where('global_order_id', $formData['shop_order_id'])
  127. ->first();
  128. if (!$orderMain) {
  129. return $this->response->json([
  130. 'error_code' => 500,
  131. 'error_msg' => '订单不存在',
  132. ]);
  133. }
  134. DB::beginTransaction();
  135. try {
  136. # 主订单表
  137. $orderMain->state = OrderState::COMPLETED;
  138. $orderMain->complete_time = time();
  139. $orderMain->delivery_time = time();
  140. $orderMain->save();
  141. # 子订单表
  142. Order::where('order_main_id', $formData['shop_order_id'])
  143. ->update(['state' => $orderMain->state]);
  144. DB::commit();
  145. } catch (\Exception $exception) {
  146. DB::rollBack();
  147. return $this->response->json([
  148. 'error_code' => 500,
  149. 'error_msg' => $exception->getMessage(),
  150. ]);
  151. }
  152. return $this->response->json([
  153. 'error_code' => 0,
  154. 'error_msg' => 'success',
  155. ]);
  156. }
  157. /**
  158. * 顺丰原因订单取消回调
  159. */
  160. public function sfCancel(): ResponseInterface
  161. {
  162. //TODO 因目前订单表没有相关撤单的字段,故目前不做处理,仅仅返回成功给顺丰
  163. return $this->riderRecall();
  164. }
  165. /**
  166. * 订单异常回调
  167. */
  168. public function riderException(): ResponseInterface
  169. {
  170. /** ex_id枚举值:
  171. 4003:托寄物丢失或损坏
  172. 1001:商家出货慢
  173. 2010:顾客拒绝实名认证
  174. 3004:实名认证校验失败
  175. 1007:更改取货地址
  176. 2001:顾客电话无法接通
  177. 2004:更改期望送达时间
  178. 2005:顾客拒收
  179. 2008:顾客不在家
  180. 2009:更改送货地址
  181. 4001:配送地址错误
  182. 4002:其他
  183. */
  184. //TODO 因目前订单表没有相关撤单的字段,故目前不做处理,仅仅返回成功给顺丰
  185. return $this->riderRecall();
  186. }
  187. /**
  188. * 回调签名校验
  189. */
  190. private function checkSign(?string $checkSign): bool
  191. {
  192. $post_data = $this->request->getBody()->getContents();
  193. echo PHP_EOL, '$post_data', PHP_EOL;
  194. print_r($post_data);
  195. $sign_char = $post_data . "&{$this->dev_id}&{$this->dev_key}";
  196. return $checkSign == base64_encode(md5($sign_char));
  197. }
  198. }