HdDeliveryOrderClass.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. <?php
  2. namespace bizHd\express\classes;
  3. use bizHd\base\classes\BaseClass;
  4. use bizHd\order\classes\OrderClass;
  5. use common\components\delivery\services\DispatchService;
  6. use common\components\dict;
  7. use common\components\noticeUtil;
  8. use common\components\push;
  9. use mikemadisonweb\rabbitmq\components\ConsumerInterface;
  10. use Yii;
  11. class HdDeliveryOrderClass extends BaseClass
  12. {
  13. public static $baseFile = HdDeliveryOrderAR::class;
  14. public static function payAfter($order)
  15. {
  16. if (empty($order)) {
  17. return false;
  18. }
  19. if ($order->sendType != 2) {
  20. return false;
  21. }
  22. if ($order->payStatus != 1) {
  23. return false;
  24. }
  25. $orderId = $order->id;
  26. $shopId = $order->shopId;
  27. try {
  28. $cacheKey = 'hd_pt_cacheData:' . $orderId;
  29. $cachedData = Yii::$app->redis->get($cacheKey);
  30. if (!empty($cachedData)) {
  31. noticeUtil::push('零售,付款成功之后要发跑腿的订单:' . $orderId, '15280215347');
  32. $cachedData = json_decode($cachedData, true);
  33. $data = [
  34. 'orderId' => $orderId,
  35. 'shopId' => $order->shopId,
  36. 'mainId' => $order->mainId,
  37. 'platform' => $cachedData['deliveryPlatform'],
  38. 'ip' => '127.0.0.1',
  39. 'deliveryPrice' => $cachedData['deliveryPrice'],
  40. 'deliveryDistance' => $cachedData['deliveryDistance'],
  41. 'deliveryBracketContent' => $cachedData['deliveryBracketContent'],
  42. 'pickupTime' => $cachedData['pickupTime'],
  43. 'allParams' => $cachedData['deliveryAllParams'],
  44. 'weight' => $cachedData['weight'] ?? 1,
  45. 'remark' => $cachedData['deliveryRemark'] ?? '',
  46. 'price' => $order->actPrice,
  47. ];
  48. self::askCreateOrder($data);
  49. } else {
  50. //noticeUtil::push("零售-缓存数据不存在或已过期,cacheKey:{$cacheKey}");
  51. // 发送 app 通知
  52. // $title = '发跑腿失败';
  53. // $msg = "零售-缓存数据不存在或已过期,cacheKey:{$cacheKey}";
  54. // $allDevices = \bizHd\device\classes\HdDeviceClass::getAllByCondition(['shopId' => $shopId, 'status' => 1]);
  55. // $cids = array_column($allDevices, 'clientId');
  56. // $push = new push('hd', push::MSG_TYPE_WORK);
  57. // $push->pushByCloud($cids, $title, $msg, []);
  58. return false;
  59. }
  60. } catch (\Exception $e) {
  61. $msg = $e->getMessage();
  62. $remind = "零售,付款成功之后要发跑腿的订单,报错 {$orderId} {$msg}";
  63. noticeUtil::push($remind);
  64. }
  65. }
  66. //发跑腿准备数据
  67. public static function prepareAskData($post, $order)
  68. {
  69. try {
  70. //跑腿订单生产者创建订单
  71. $orderId = $order->id ?? 0;
  72. $callErrand = $post['callErrand'] ?? 0; // 是否立即发跑腿 1:是 0:否
  73. if ($callErrand == 1) {
  74. $hasPay = $post['hasPay'] ?? dict::getDict('hasPay', 'unPay'); //收款方式 0:扫码付 1:线下(已付款) 2:赊账(欠款)3:现金 4:余额
  75. if ($hasPay == dict::getDict('hasPay', 'unPay')) { // 0:扫码付
  76. $deliveryPlatform = $post['deliveryPlatform'];
  77. $expireTime = 0;
  78. if ($deliveryPlatform == 'shansong') {
  79. $expireTime = 1800 - 60;
  80. } elseif ($deliveryPlatform == 'didi') {
  81. $expireTime = 7200;
  82. } else {
  83. $expireTime = 7200; // 默认缓存时长2小时
  84. }
  85. $cacheKey = 'hd_pt_cacheData:' . $orderId;
  86. Yii::$app->redis->set($cacheKey, json_encode($post, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
  87. Yii::$app->redis->expire($cacheKey, $expireTime);
  88. } else {
  89. $sendType = $post['sendType'];
  90. if ($order->payStatus == 1 && $sendType == dict::getDict('sendType', 'thirdSend')) { // $post 中有 pickupTime,则说明是要立即发跑腿 或者 callErrand == 1
  91. $platform = $post['deliveryPlatform'];
  92. $deliveryPrice = $post['deliveryPrice'];
  93. $deliveryDistance = $post['deliveryDistance'];
  94. $deliveryBracketContent = $post['deliveryBracketContent'];
  95. $pickupTime = $post['pickupTime'];
  96. $allParams = $post['deliveryAllParams'];
  97. $data = [
  98. 'orderId' => $orderId,
  99. 'mainId' => $order->mainId,
  100. 'shopId' => $order->shopId,
  101. 'platform' => $platform,
  102. 'ip' => Yii::$app->request->userIP,
  103. 'deliveryPrice' => $deliveryPrice,
  104. 'deliveryDistance' => $deliveryDistance,
  105. 'deliveryBracketContent' => $deliveryBracketContent,
  106. 'pickupTime' => $pickupTime,
  107. 'allParams' => $allParams,
  108. //-----------------------
  109. 'weight' => $post['weight'] ?? 1,
  110. 'remark' => $post['deliveryRemark'] ?? '',
  111. 'price' => $order->actPrice,
  112. ];
  113. self::askCreateOrder($data);
  114. }
  115. }
  116. }
  117. } catch (\Exception $e) {
  118. $msg = $e->getMessage();
  119. $remind = "零售,跑腿下单,准备数据报错 {$orderId} {$msg}";
  120. noticeUtil::push($remind);
  121. }
  122. }
  123. //生产者创建下单指令逻辑
  124. public static function askCreateOrder($data)
  125. {
  126. try {
  127. $orderId = $data['orderId'];
  128. $allParams = $data['allParams'];
  129. $producer = Yii::$app->rabbitmq->getProducer('ptProducer');
  130. $msg = serialize([
  131. 'type' => 'hd_pt_create_order',
  132. 'orderId' => $orderId,
  133. 'mainId' => $data['mainId'],
  134. 'shopId' => $data['shopId'],
  135. 'pickupTime' => $data['pickupTime'],
  136. 'ip' => $data['ip'],
  137. 'allParams' => $allParams,
  138. 'weight' => $data['weight'],
  139. 'remark' => $data['remark'],
  140. 'price' => $data['price']
  141. ]);
  142. Yii::info('hd askCreateOrder == ' . $msg);
  143. $producer->publish($msg, 'ptExchange', 'ptRoute', ['delivery_mode' => 2, 'content_type' => 'application/octet-stream']);
  144. } catch (\Exception $e) {
  145. $msg = $e->getMessage();
  146. $remind = "零售花店,跑腿下单,生产消息端报错 {$orderId} {$msg}";
  147. noticeUtil::push($remind, '15280215347');
  148. }
  149. }
  150. //消费者消费下单指令逻辑
  151. public static function beginCreateOrder($data)
  152. {
  153. try {
  154. //花店,进行下单流程处理
  155. $dataStr = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
  156. //noticeUtil::push('已消费hd -- ' . $dataStr);
  157. Yii::info('hd消费者收到下单指令 -- ' . $dataStr);
  158. $orderId = $data['orderId']; // xhOrder.id
  159. $params = $data['allParams'];
  160. $platform = $params['en_name'];// 平台英文名,$post['platform'] 是中文
  161. $errMsg = '';
  162. if (empty($platform)) {
  163. Yii::error('platform为空');
  164. $errMsg = 'platform参数为空';
  165. }
  166. $shopId = $data['shopId'];
  167. $mainId = $data['mainId'];
  168. $params['mainId'] = $mainId;
  169. $params['ip'] = $data['ip'];
  170. $params['weight'] = $data['weight'];
  171. $params['remark'] = $data['remark'] ?? '';
  172. $params['total_price_fen'] = $data['price'];
  173. $params['pickupTime'] = $data['pickupTime'];
  174. $Order = OrderClass::getById($orderId, true);
  175. if (empty($Order)) {
  176. $errMsg = "没有找到订单 hd-orderId={$orderId}";
  177. }
  178. if ($Order->mainId != $mainId) {
  179. $errMsg = "hd-orderId={$orderId} 不是 mainId={$mainId} 的订单";
  180. }
  181. if (!in_array($Order['sendStatus'], [-4, -2, -1])) {
  182. $errMsg = "订单 hd-orderId={$orderId} 已经发过跑腿";
  183. }
  184. if ($errMsg != '') {
  185. Yii::error($errMsg);
  186. noticeUtil::push($errMsg);
  187. return ConsumerInterface::MSG_REJECT;
  188. }
  189. $ds = new DispatchService($mainId, $platform);
  190. $ret = $ds->createOrder($Order, 'xhOrder', $shopId, $params);
  191. if (isset($ret['code']) && $ret['code'] == 0) {
  192. $hdo = HdDeliveryOrderClass::getByCondition(['mainId' => $mainId, 'orderId' => $ret['data']['orderId']]);
  193. if (empty($hdo)) {
  194. $data = [
  195. 'mainId' => $mainId,
  196. 'shopId' => $shopId,
  197. 'deliveryId' => $ret['platform'],
  198. 'hdOrderId' => $orderId,
  199. 'orderId' => $ret['data']['orderId'],
  200. 'distance' => $ret['data']['distance'],
  201. 'fee' => $ret['data']['fee'],
  202. 'orderStatus' => 0
  203. ];
  204. // createdAt 中保存了滴滴跑腿订单的后半截数据
  205. if ($platform == 'didi') {
  206. $data['createdAt'] = date('Y-m-d H:i:s', $ret['data']['timeStamp']);
  207. }
  208. HdDeliveryOrderClass::add($data);
  209. } else {
  210. Yii::info('重复创建订单');
  211. noticeUtil::push('重复创建订单:' . json_encode($hdo, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
  212. }
  213. //更新订单
  214. $Order->sendDistance = $ret['data']['distance'];
  215. $Order->sendStatus = 0;
  216. $Order->deliveryId = $platform;
  217. $Order->sendType = 2;// 2指跑腿
  218. $Order->status = 3;// 3配送中
  219. $save = $Order->save();
  220. if ($save) {
  221. noticeUtil::push("hd-orderId={$orderId}, 创建跑腿成功"); //. json_encode($Order->toArray(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES
  222. } else {
  223. noticeUtil::push("hd-orderId={$orderId}, 创建跑腿失败"); // . json_encode($Order->toArray(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES
  224. }
  225. return ConsumerInterface::MSG_ACK;
  226. } else {
  227. if (isset($ret['msg'])) {
  228. Yii::error("hd-orderId={$orderId}, 创建跑腿失败:" . $ret['msg']);
  229. noticeUtil::push("零售订单号:{$orderId}, 原因:" . $ret['msg']);
  230. self::sendAppNotice($shopId, $orderId, "订单号:{$orderId},原因:" . $ret['msg']); // 发 App 通知
  231. return ConsumerInterface::MSG_REJECT;
  232. }
  233. Yii::error("hd-orderId={$orderId}, 创建跑腿失败");
  234. noticeUtil::push("订单号:{$orderId}, 创建跑腿失败");
  235. self::sendAppNotice($shopId, $orderId, '创建跑腿失败'); // 发 App 通知
  236. return ConsumerInterface::MSG_REJECT;
  237. }
  238. } catch (\Exception $e) {
  239. $orderId = $data['orderId'];
  240. Yii::error("hd-orderId={$orderId} 创建跑腿失败:" . $e->getMessage());
  241. noticeUtil::push("零售订单号:{$orderId} 原因:" . $e->getMessage());
  242. $shopId = $data['shopId'];
  243. // 发 App 通知
  244. self::sendAppNotice($shopId, $orderId, "订单号:{$orderId},原因:" . $e->getMessage());
  245. return ConsumerInterface::MSG_REJECT;
  246. }
  247. }
  248. // 发 App 通知
  249. public static function sendAppNotice($shopId, $orderId, $msg)
  250. {
  251. $title = '发跑腿失败';
  252. $msg = "零售订单创建跑腿失败," . $msg;
  253. $allDevices = \bizHd\device\classes\HdDeviceClass::getAllByCondition(['shopId' => $shopId, 'status' => 1]);
  254. $cids = array_column($allDevices, 'clientId');
  255. $payload = [
  256. "page" => "admin/order/detail",
  257. "params" => ["id" => $orderId]
  258. ];
  259. $push = new push('hd', push::MSG_TYPE_WORK);
  260. $push->pushByCloud($cids, $title, $msg, $payload);
  261. }
  262. }
  263. // 在同文件末尾追加一个内联的 AR 类
  264. class HdDeliveryOrderAR extends \bizHd\base\models\Base
  265. {
  266. public static function tableName()
  267. {
  268. return 'xhHdDeliveryOrder';
  269. }
  270. }
  271. // 可选:为了兼容历史直接引用 models 的代码(如果存在),做一个别名映射
  272. if (!class_exists('\bizHd\express\models\HdDeliveryOrder')) {
  273. class_alias(\bizHd\express\classes\HdDeliveryOrderAR::class, '\bizHd\express\models\HdDeliveryOrder');
  274. }