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.

251 lines
8.7 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. <?php
  2. namespace App\Controller;
  3. use App\Constants\LogLabel;
  4. use App\Model\Goods;
  5. use App\Model\Order;
  6. use App\Model\OrderGoods;
  7. use App\Model\OrderMain;
  8. use App\Model\OrderSalesStatistic;
  9. use App\Model\SpecCombination;
  10. use App\Model\Store;
  11. use App\Model\SystemConfig;
  12. use App\Service\DeviceServiceInterface;
  13. use App\Service\FeiePrintServiceInterface;
  14. use App\Service\MiniprogramService;
  15. use App\Service\MqttServiceInterface;
  16. use EasyWeChat\Factory;
  17. use Hyperf\DbConnection\Db;
  18. use Hyperf\Guzzle\CoroutineHandler;
  19. use Exception;
  20. use Hyperf\Di\Annotation\Inject;
  21. use Symfony\Component\HttpFoundation\Request;
  22. class NotifyController extends BaseController
  23. {
  24. /**
  25. * @Inject
  26. * @var MqttServiceInterface
  27. */
  28. protected $mqttSpeakerService;
  29. /**
  30. * @Inject
  31. * @var DeviceServiceInterface
  32. */
  33. protected $deviceService;
  34. /**
  35. * @Inject
  36. * @var MiniprogramService
  37. */
  38. protected $miniprogramService;
  39. /**
  40. * @Inject
  41. * @var FeiePrintServiceInterface
  42. */
  43. protected $feiePrintService;
  44. public function wxminiOnline()
  45. {
  46. $config = config('wxpay');
  47. $app = Factory::payment($config);
  48. $app['guzzle_handler'] = CoroutineHandler::class;
  49. $get = $this->request->getQueryParams();
  50. $post = $this->request->getParsedBody();
  51. $cookie = $this->request->getCookieParams();
  52. $files = $this->request->getUploadedFiles();
  53. $server = $this->request->getServerParams();
  54. $xml = $this->request->getBody()->getContents();
  55. $app['request'] = new Request($get,$post,[],$cookie,$files,$server,$xml);
  56. var_dump('inside');
  57. // 通知回调,进行业务处理
  58. Db::beginTransaction();
  59. try {
  60. $response = $app->handlePaidNotify(function ($message, $fail) use ($app) {
  61. var_dump('message', $message);
  62. // 支付失败或者通知失败
  63. if (
  64. empty($message)
  65. || $message['return_code'] != 'SUCCESS'
  66. || !isset($message['result_code'])
  67. || $message['result_code'] != 'SUCCESS'
  68. ) {
  69. $this->log->event(
  70. LogLabel::PAY_NOTIFY_WXMINI,
  71. $message
  72. );
  73. $fail('Unknown error but FAIL');
  74. }
  75. // 查询订单
  76. $orderMain = OrderMain::query()
  77. ->where([
  78. 'global_order_id' => $message['out_trade_no'],
  79. 'type' => OrderMain::ORDER_TYPE_ONLINE,
  80. 'state' => OrderMain::ORDER_STATE_UNPAY
  81. ])
  82. ->where('time', '>=', date('Y-m-d H:i:s', (time() - 900)))
  83. ->first();
  84. var_dump('$orderMain', $orderMain);
  85. // 订单不存在
  86. if (empty($orderMain)) {
  87. $this->log->event(
  88. LogLabel::PAY_NOTIFY_WXMINI,
  89. $orderMain
  90. );
  91. // 去查一下微信订单,只处理未支付的情况 TODO 其他情况处理
  92. $wxOrder = $app->order->queryByOutTradeNumber($message['out_trade_no']);
  93. // 查询成功
  94. if ($wxOrder['return_code'] == 'SUCCESS') {
  95. if ($wxOrder['result_code'] == 'SUCCESS') {
  96. // 看订单支付状态,处理未支付的情况,把订单处理成未支付
  97. if ($wxOrder['trade_state'] != 'NOTPAY') {
  98. OrderMain::query()
  99. ->where(['global_order_id' => $message['out_trade_no']])
  100. ->update(['state' => OrderMain::ORDER_STATE_UNPAY]);
  101. $fail('Order not paid');
  102. }
  103. }
  104. }
  105. return true;
  106. }
  107. // 修改订单、子订单状态
  108. $currentTime = time();
  109. $orderMain->state = OrderMain::ORDER_STATE_UNTAKE;
  110. $orderMain->time_pay = $currentTime;
  111. $orderMain->pay_time = date('Y-m-d H:i:s', $currentTime);
  112. $orderMain->save();
  113. $upOrder = Order::query()
  114. ->where(['order_main_id' => $orderMain->id])
  115. ->update(['state' => OrderMain::ORDER_STATE_UNTAKE, 'pay_time' => $orderMain->pay_time]);
  116. // 更新商户销量
  117. $upStoreScore = Store::query()
  118. ->whereIn('id', explode(',', $orderMain->store_ids))
  119. ->update(['score' => Db::raw('score+1')]);
  120. // 更新商品库存和销量
  121. $orders = Order::query()->select(['id', 'money', 'user_id', 'store_id', 'pay_time'])
  122. ->where(['order_main_id' => $orderMain->id])
  123. ->get()
  124. ->toArray();
  125. $orderGoods = OrderGoods::query()->select(['good_id AS id', 'number', 'combination_id'])
  126. ->whereIn('order_id', array_values(array_column($orders, 'id')))
  127. ->get()
  128. ->toArray();
  129. foreach ($orderGoods as $key => &$goodsItem) {
  130. $goods = Goods::find($goodsItem['id']);
  131. // 库存处理,有规格
  132. if ($goodsItem['combination_id']) {
  133. $combination = SpecCombination::find($goodsItem['combination_id']);
  134. $combination->number = $combination->number - $goodsItem['number'];
  135. $combination->save();
  136. } else {
  137. $goods->inventory = $goods->inventory - $goodsItem['number'];
  138. }
  139. $goods->sales = $goods->sales - $goodsItem['number'];
  140. $goods->save();
  141. }
  142. // 月销流水
  143. $statistics = [];
  144. foreach ($orders as $key => &$order) {
  145. $statistics[] = [
  146. 'money' => $order['money'],
  147. 'user_id' => $order['user_id'],
  148. 'store_id' => $order['store_id'],
  149. 'market_id' => $orderMain->market_id,
  150. 'order_id' => $order['id'],
  151. 'createtime' => strtotime($order['pay_time']),
  152. ];
  153. }
  154. if (is_array($statistics) && !empty($statistics)) {
  155. $inSalesStatistics = OrderSalesStatistic::query()->insert($statistics);
  156. }
  157. // 喇叭通知,兼容旧音响,MQTT+IOT
  158. $res = $this->mqttSpeakerService->speakToStore($orderMain->id);
  159. var_dump($res);
  160. $res = $this->deviceService->pubMsgToStoreByOrderMainId($orderMain->id);
  161. var_dump($res);
  162. // 公众号模板消息
  163. $res = $this->miniprogramService->sendTemMsgForOnlineOrder($orderMain->id);
  164. var_dump($res);
  165. // 打印订单,自动打印 TODO 后续优化调用逻辑
  166. $res = $this->feiePrintService->feiePrint($orderMain->order_num);
  167. var_dump($res);
  168. return true;
  169. });
  170. var_dump('$response', $response);
  171. Db::rollBack();
  172. $response->send();
  173. } catch (\EasyWeChat\Kernel\Exceptions\Exception $e) {
  174. var_dump($e->getMessage());
  175. Db::rollBack();
  176. }
  177. }
  178. public function wxminiOffline()
  179. {
  180. $config = config('wxpay');
  181. $app = Factory::payment($config);
  182. $app['guzzle_handler'] = CoroutineHandler::class;
  183. // 通知回调,进行业务处理
  184. $response = $app->handlePaidNotify(function ($message, $fail) use ($app) {
  185. $this->log->event(
  186. LogLabel::PAY_NOTIFY_WXMINI,
  187. $message
  188. );
  189. // 查询订单
  190. $orderMain = OrderMain::query()
  191. ->where(['global_order_id' => $message['out_trade_no'], 'type' => OrderMain::ORDER_TYPE_OFFLINE, 'state' => OrderMain::ORDER_STATE_UNPAY])
  192. ->where('time', '>=', date('Y-m-d H:i:s', (time()-900)))
  193. ->first();
  194. if (empty($orderMain)) {
  195. // 去查一下微信订单
  196. $wxOrder = $app->order->queryByOutTradeNumber($orderMain->global_order_id);
  197. $this->log->event(
  198. LogLabel::PAY_NOTIFY_WXMINI,
  199. $wxOrder
  200. );
  201. // return true;
  202. }
  203. });
  204. $response->send();
  205. }
  206. }