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.

235 lines
8.0 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
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
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 Hyperf\HttpMessage\Stream\SwooleStream;
  22. use Symfony\Component\HttpFoundation\Request;
  23. class NotifyController extends BaseController
  24. {
  25. /**
  26. * @Inject
  27. * @var MqttServiceInterface
  28. */
  29. protected $mqttSpeakerService;
  30. /**
  31. * @Inject
  32. * @var DeviceServiceInterface
  33. */
  34. protected $deviceService;
  35. /**
  36. * @Inject
  37. * @var MiniprogramService
  38. */
  39. protected $miniprogramService;
  40. /**
  41. * @Inject
  42. * @var FeiePrintServiceInterface
  43. */
  44. protected $feiePrintService;
  45. public function wxminiOnline()
  46. {
  47. $config = config('wxpay');
  48. $app = Factory::payment($config);
  49. $app['guzzle_handler'] = CoroutineHandler::class;
  50. $get = $this->request->getQueryParams();
  51. $post = $this->request->getParsedBody();
  52. $cookie = $this->request->getCookieParams();
  53. $files = $this->request->getUploadedFiles();
  54. $server = $this->request->getServerParams();
  55. $xml = $this->request->getBody()->getContents();
  56. $app['request'] = new Request($get,$post,[],$cookie,$files,$server,$xml);
  57. // 通知回调,进行业务处理
  58. $response = $app->handlePaidNotify(function ($message, $fail) use ($app) {
  59. var_dump('message',$message);
  60. Db::beginTransaction();
  61. try {
  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. Db::rollBack();
  74. $fail('Unknown error but FAIL');
  75. }
  76. // 查询订单
  77. $orderMain = OrderMain::query()
  78. ->where([
  79. 'global_order_id' => $message['out_trade_no'],
  80. 'type' => OrderMain::ORDER_TYPE_ONLINE
  81. ])
  82. ->first();
  83. // 订单不存在
  84. if (empty($orderMain)) {
  85. $this->log->event(
  86. LogLabel::PAY_NOTIFY_WXMINI,
  87. ['global_order_id_fail' => $message['out_trade_no']]
  88. );
  89. Db::rollBack();
  90. return true;
  91. }
  92. // 修改订单、子订单状态
  93. $currentTime = time();
  94. $orderMain->state = OrderMain::ORDER_STATE_UNTAKE;
  95. $orderMain->time_pay = $currentTime;
  96. $orderMain->pay_time = date('Y-m-d H:i:s', $currentTime);
  97. $orderMain->save();
  98. $upOrder = Order::query()
  99. ->where(['order_main_id' => $orderMain->id])
  100. ->update(['state' => OrderMain::ORDER_STATE_UNTAKE, 'pay_time' => $orderMain->pay_time]);
  101. // 更新商户销量
  102. $upStoreScore = Store::query()
  103. ->whereIn('id', explode(',', $orderMain->store_ids))
  104. ->update(['score' => Db::raw('score+1')]);
  105. // 更新商品库存和销量
  106. $orders = Order::query()->select(['id', 'money', 'user_id', 'store_id', 'pay_time'])
  107. ->where(['order_main_id' => $orderMain->id])
  108. ->get()
  109. ->toArray();
  110. $orderGoods = OrderGoods::query()->select(['good_id AS id', 'number', 'combination_id'])
  111. ->whereIn('order_id', array_values(array_column($orders, 'id')))
  112. ->get()
  113. ->toArray();
  114. foreach ($orderGoods as $key => &$goodsItem) {
  115. $goods = Goods::find($goodsItem['id']);
  116. // 库存处理,有规格
  117. if ($goodsItem['combination_id']) {
  118. $combination = SpecCombination::find($goodsItem['combination_id']);
  119. $combination->number = $combination->number - $goodsItem['number'];
  120. $combination->save();
  121. } else {
  122. $goods->inventory = $goods->inventory - $goodsItem['number'];
  123. }
  124. $goods->sales = $goods->sales - $goodsItem['number'];
  125. $goods->save();
  126. }
  127. // 月销流水
  128. $statistics = [];
  129. foreach ($orders as $key => &$order) {
  130. $statistics[] = [
  131. 'money' => $order['money'],
  132. 'user_id' => $order['user_id'],
  133. 'store_id' => $order['store_id'],
  134. 'market_id' => $orderMain->market_id,
  135. 'order_id' => $order['id'],
  136. 'createtime' => strtotime($order['pay_time']),
  137. ];
  138. }
  139. if (is_array($statistics) && !empty($statistics)) {
  140. $inSalesStatistics = OrderSalesStatistic::query()->insert($statistics);
  141. }
  142. // 喇叭通知,兼容旧音响,MQTT+IOT
  143. $res = $this->mqttSpeakerService->speakToStore($orderMain->id);
  144. $res = $this->deviceService->pubMsgToStoreByOrderMainId($orderMain->id);
  145. // 公众号模板消息
  146. // $res = $this->miniprogramService->sendTemMsgForOnlineOrder($orderMain->id);
  147. // 打印订单,自动打印 TODO 后续优化调用逻辑
  148. $res = $this->feiePrintService->feiePrint($orderMain->global_order_id);
  149. Db::commit();
  150. return true;
  151. } catch (Exception $e) {
  152. $this->log->event(
  153. LogLabel::PAY_NOTIFY_WXMINI,
  154. ['exception_fail' => $e->getMessage()]
  155. );
  156. Db::rollBack();
  157. $fail('Exception');
  158. }
  159. });
  160. var_dump('reponse',$response->getContent());
  161. return $this->response
  162. ->withHeader('Content-Type', 'text/xml')
  163. ->withStatus(200)
  164. ->withBody(new SwooleStream($response->getContent()));
  165. }
  166. public function wxminiOffline()
  167. {
  168. $config = config('wxpay');
  169. $app = Factory::payment($config);
  170. $app['guzzle_handler'] = CoroutineHandler::class;
  171. // 通知回调,进行业务处理
  172. $response = $app->handlePaidNotify(function ($message, $fail) use ($app) {
  173. $this->log->event(
  174. LogLabel::PAY_NOTIFY_WXMINI,
  175. $message
  176. );
  177. // 查询订单
  178. $orderMain = OrderMain::query()
  179. ->where(['global_order_id' => $message['out_trade_no'], 'type' => OrderMain::ORDER_TYPE_OFFLINE, 'state' => OrderMain::ORDER_STATE_UNPAY])
  180. ->where('time', '>=', date('Y-m-d H:i:s', (time()-900)))
  181. ->first();
  182. if (empty($orderMain)) {
  183. // 去查一下微信订单
  184. $wxOrder = $app->order->queryByOutTradeNumber($orderMain->global_order_id);
  185. $this->log->event(
  186. LogLabel::PAY_NOTIFY_WXMINI,
  187. $wxOrder
  188. );
  189. // return true;
  190. }
  191. });
  192. $response->send();
  193. }
  194. }