From d6d23fdce496f1e1bdf703acf65e9cdf73e3945c Mon Sep 17 00:00:00 2001 From: weigang Date: Thu, 13 Aug 2020 21:32:37 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BA=BF=E4=B8=8A=E6=94=AF=E4=BB=98=E5=9B=9E?= =?UTF-8?q?=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Amqp/Consumer/DevicOrderConsumer.php | 4 +- app/Controller/DeviceController.php | 4 +- app/Controller/NotifyController.php | 179 ++++++++-- app/Controller/OrderController.php | 10 + app/Controller/PaymentController.php | 1 - app/Controller/TestController.php | 35 +- app/Libs/FeiePrintClient.php | 307 ++++++++++++++++++ app/Model/OrderMain.php | 1 + app/Model/OrderSalesStatistic.php | 29 ++ app/Model/SystemConfig.php | 10 + app/Request/OrderOfflineRequest.php | 42 +++ app/Service/CouponService.php | 2 +- ...terface.php => CouponServiceInterface.php} | 2 +- app/Service/DeviceServiceImp.php | 45 ++- ...terFace.php => DeviceServiceInterface.php} | 3 +- app/Service/FeiePrintService.php | 226 +++++++++++++ app/Service/FeiePrintServiceInterface.php | 10 + app/Service/MiniprogramService.php | 147 +++++++++ app/Service/MiniprogramServiceInterface.php | 9 + app/Service/MqttServiceInterface.php | 21 ++ app/Service/MqttSpeakerService.php | 48 +++ app/Service/OrderService.php | 107 +++++- app/Service/OrderServiceInterface.php | 2 +- app/TaskWorker/MQTTClientTask.php | 40 ++- config/autoload/dependencies.php | 7 +- config/config.php | 5 +- config/routes.php | 1 + 27 files changed, 1240 insertions(+), 57 deletions(-) create mode 100644 app/Libs/FeiePrintClient.php create mode 100644 app/Model/OrderSalesStatistic.php create mode 100644 app/Model/SystemConfig.php create mode 100644 app/Request/OrderOfflineRequest.php rename app/Service/{CoupnoServiceInterface.php => CouponServiceInterface.php} (93%) rename app/Service/{DeviceServiceInterFace.php => DeviceServiceInterface.php} (68%) create mode 100644 app/Service/FeiePrintService.php create mode 100644 app/Service/FeiePrintServiceInterface.php create mode 100644 app/Service/MiniprogramService.php create mode 100644 app/Service/MiniprogramServiceInterface.php create mode 100644 app/Service/MqttServiceInterface.php create mode 100644 app/Service/MqttSpeakerService.php diff --git a/app/Amqp/Consumer/DevicOrderConsumer.php b/app/Amqp/Consumer/DevicOrderConsumer.php index f6e58bc..08a2d1c 100644 --- a/app/Amqp/Consumer/DevicOrderConsumer.php +++ b/app/Amqp/Consumer/DevicOrderConsumer.php @@ -6,7 +6,7 @@ namespace App\Amqp\Consumer; use App\Model\Order; use App\Model\SpeakerDevic; -use App\Service\DeviceServiceInterFace; +use App\Service\DeviceServiceInterface; use Hyperf\Amqp\Result; use Hyperf\Amqp\Annotation\Consumer; use Hyperf\Amqp\Message\ConsumerMessage; @@ -21,7 +21,7 @@ class DevicOrderConsumer extends ConsumerMessage { /** * @Inject - * @var DeviceServiceInterFace + * @var DeviceServiceInterface */ protected $deviceService; diff --git a/app/Controller/DeviceController.php b/app/Controller/DeviceController.php index ee315b3..d7ec213 100644 --- a/app/Controller/DeviceController.php +++ b/app/Controller/DeviceController.php @@ -4,7 +4,7 @@ namespace App\Controller; use Hyperf\Di\Annotation\Inject; use App\Exception\BusinessException; -use App\Service\DeviceServiceInterFace; +use App\Service\DeviceServiceInterface; use Hyperf\Validation\ValidationException; class DeviceController extends BaseController @@ -12,7 +12,7 @@ class DeviceController extends BaseController /** * @Inject - * @var DeviceServiceInterFace + * @var DeviceServiceInterface */ protected $deviceService; diff --git a/app/Controller/NotifyController.php b/app/Controller/NotifyController.php index 289c578..3ac5cd3 100644 --- a/app/Controller/NotifyController.php +++ b/app/Controller/NotifyController.php @@ -3,46 +3,114 @@ namespace App\Controller; use App\Constants\LogLabel; +use App\Model\Goods; +use App\Model\Order; +use App\Model\OrderGoods; use App\Model\OrderMain; +use App\Model\OrderSalesStatistic; +use App\Model\SpecCombination; +use App\Model\Store; +use App\Model\SystemConfig; +use App\Service\DeviceServiceInterface; +use App\Service\FeiePrintServiceInterface; +use App\Service\MiniprogramService; +use App\Service\MqttServiceInterface; use EasyWeChat\Factory; use Hyperf\DbConnection\Db; use Hyperf\Guzzle\CoroutineHandler; use Exception; +use Hyperf\Di\Annotation\Inject; class NotifyController extends BaseController { + + /** + * @Inject + * @var MqttServiceInterface + */ + protected $mqttSpeakerService; + + /** + * @Inject + * @var DeviceServiceInterface + */ + protected $deviceService; + + /** + * @Inject + * @var MiniprogramService + */ + protected $miniprogramService; + + /** + * @Inject + * @var FeiePrintServiceInterface + */ + protected $feiePrintService; + public function wxminiOnline() { + $config = config('wxpay'); $app = Factory::payment($config); $app['guzzle_handler'] = CoroutineHandler::class; - + var_dump('inside'); // 通知回调,进行业务处理 - $response = $app->handlePaidNotify(function ($message, $fail) use ($app) { - - Db::beginTransaction(); - try { - - $this->log->event( - LogLabel::PAY_NOTIFY_WXMINI, - $message - ); + Db::beginTransaction(); + try { + $response = $app->handlePaidNotify(function ($message, $fail) use ($app) { + + var_dump('message', $message); + // 支付失败或者通知失败 + if ( + empty($message) + || $message['return_code'] != 'SUCCESS' + || !isset($message['result_code']) + || $message['result_code'] != 'SUCCESS' + ) { + $this->log->event( + LogLabel::PAY_NOTIFY_WXMINI, + $message + ); + $fail('Unknown error but FAIL'); + } // 查询订单 $orderMain = OrderMain::query() - ->where(['global_order_id' => $message['out_trade_no'], 'type' => OrderMain::ORDER_TYPE_ONLINE, 'state' => OrderMain::ORDER_STATE_UNPAY]) - ->where('time', '>=', date('Y-m-d H:i:s', (time()-900))) + ->where([ + 'global_order_id' => $message['out_trade_no'], + 'type' => OrderMain::ORDER_TYPE_ONLINE, + 'state' => OrderMain::ORDER_STATE_UNPAY + ]) + ->where('time', '>=', date('Y-m-d H:i:s', (time() - 900))) ->first(); - + var_dump('$orderMain', $orderMain); + // 订单不存在 if (empty($orderMain)) { - // 去查一下微信订单 - $wxOrder = $app->order->queryByOutTradeNumber($orderMain->global_order_id); $this->log->event( LogLabel::PAY_NOTIFY_WXMINI, - $wxOrder + $orderMain ); + // 去查一下微信订单,只处理未支付的情况 TODO 其他情况处理 + $wxOrder = $app->order->queryByOutTradeNumber($message['out_trade_no']); + // 查询成功 + if ($wxOrder['return_code'] == 'SUCCESS') { + if ($wxOrder['result_code'] == 'SUCCESS') { + // 看订单支付状态,处理未支付的情况,把订单处理成未支付 + if ($wxOrder['trade_state'] != 'NOTPAY') { + OrderMain::query() + ->where(['global_order_id' => $message['out_trade_no']]) + ->update(['state' => OrderMain::ORDER_STATE_UNPAY]); + + $fail('Order not paid'); + } + } + } + + + // return true; } @@ -53,25 +121,86 @@ class NotifyController extends BaseController $orderMain->pay_time = date('Y-m-d H:i:s', $currentTime); $orderMain->save(); - // 更新销量、商品库存,新增月销数据 + $upOrder = Order::query() + ->where(['order_main_id' => $orderMain->id]) + ->update(['state' => OrderMain::ORDER_STATE_UNTAKE, 'pay_time' => $orderMain->pay_time]); + + // 更新商户销量 + $upStoreScore = Store::query() + ->whereIn('id', $orderMain->order_ids) + ->update(['score' => Db::raw('score+1')]); + + // 更新商品库存和销量 + $orders = Order::query()->select(['id', 'money', 'user_id', 'store_id', 'createtime']) + ->where(['order_main_id' => $orderMain->id]) + ->get() + ->toArray(); + $orderGoods = OrderGoods::query()->select(['good_id AS id', 'number', 'combination_id']) + ->whereIn('order_id', array_values(array_column($orders, 'id'))) + ->get() + ->toArray(); + foreach ($orderGoods as $key => &$goodsItem) { + + $goods = Goods::find($goodsItem['id']); + + // 库存处理,有规格 + if ($goodsItem->combination_id) { + $combination = SpecCombination::find($goodsItem['combination_id']); + $combination->number = $combination->number - $goodsItem['number']; + $combination->save(); + } else { + $goods->inventory = $goods->inventory - $goodsItem['number']; + } + + $goods->sales = $goods->sales - $goodsItem['number']; + $goods->save(); + + } + + // 月销流水 + $statistics = []; + foreach ($orders as $key => & $order) { + $statistics[] = [ + 'money' => $order->money, + 'user_id' => $order->user_id, + 'store_id' => $order->store_id, + 'market_id' => $orderMain->market_id, + 'order_id' => $order->id, + 'createtime' => strtotime($order->pay_time), + ]; + } + + if (is_array($statistics) && !empty($statistics)) { + $inSalesStatistics = OrderSalesStatistic::query()->insert($statistics); + } // 喇叭通知,兼容旧音响,MQTT+IOT + $res = $this->mqttSpeakerService->speakToStore($orderMain->id); + var_dump($res); + $res = $this->deviceService->pubMsgToStoreByOrderMainId($orderMain->id); + var_dump($res); // 公众号模板消息 + $res = $this->miniprogramService->sendTemMsgForOnlineOrder($orderMain->id); + var_dump($res); - // 打印订单 + // 打印订单,自动打印 TODO 后续优化调用逻辑 + $res = $this->feiePrintService->feiePrint($orderMain->order_num); + var_dump($res); - Db::commit(); - return true; + }); - } catch (Exception $e) { + var_dump('$response', $response); + Db::rollBack(); + $response->send(); - Db::rollBack(); - } + } catch (\EasyWeChat\Kernel\Exceptions\Exception $e) { - }); + var_dump($e->getMessage()); + Db::rollBack(); + + } - $response->send(); } public function wxminiOffline() diff --git a/app/Controller/OrderController.php b/app/Controller/OrderController.php index ff18506..f26045d 100644 --- a/app/Controller/OrderController.php +++ b/app/Controller/OrderController.php @@ -3,6 +3,7 @@ namespace App\Controller; use App\Constants\ErrorCode; +use App\Request\OrderOfflineRequest; use App\Request\OrderOnlineRequest; use Hyperf\Di\Annotation\Inject; use App\Service\OrderServiceInterface; @@ -25,4 +26,13 @@ class OrderController extends BaseController } return $this->success(['order_id' => $orderMainId]); } + + public function addOfflineOrder(OrderOfflineRequest $request) + { + $orderMainId = $this->orderService->addOfflineOrder($request->validated()); + if (!is_int($orderMainId)) { + return $this->result(ErrorCode::ORDER_FAILURE, '', $orderMainId); + } + return $this->success(['order_id' => $orderMainId]); + } } \ No newline at end of file diff --git a/app/Controller/PaymentController.php b/app/Controller/PaymentController.php index a3ffbd6..5047f27 100644 --- a/app/Controller/PaymentController.php +++ b/app/Controller/PaymentController.php @@ -65,7 +65,6 @@ class PaymentController extends BaseController // 待支付的,未超时(15min,900sec)的订单 $orderMain = OrderMain::query() ->where(['dm_state' => OrderMain::ORDER_STATE_UNPAY, 'id' => $data['order_id']]) - ->where('time', '>=', date('Y-m-d H:i:s', (time()-900))) ->first(); if (empty($orderMain)) { diff --git a/app/Controller/TestController.php b/app/Controller/TestController.php index f69cea8..10fe872 100644 --- a/app/Controller/TestController.php +++ b/app/Controller/TestController.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace App\Controller; +use App\Libs\FeiePrintClient; use Hyperf\HttpServer\Contract\RequestInterface; use Hyperf\HttpServer\Annotation\AutoController; use Hyperf\Utils\Coroutine; @@ -22,6 +23,7 @@ class TestController extends AbstractController { private $name = 'default action'; + protected $client = null; public function index1(RequestInterface $request) { @@ -37,14 +39,33 @@ class TestController extends AbstractController // $result = $client->handle("set"); - //$log = ApplicationContext::getContainer()->get(Log::class); - $log = $this->log; - - $log->push(['test'=>1,'user_id'=>290,'msg'=>'order']); - $log->event('t1',['test'=>1,'user_id'=>290,'msg'=>'order']); + // //$log = ApplicationContext::getContainer()->get(Log::class); + // $log = $this->log; + // + // $log->push(['test'=>1,'user_id'=>290,'msg'=>'order']); + // $log->event('t1',['test'=>1,'user_id'=>290,'msg'=>'order']); + // + // //$this->name = 'index1 action '. $result; + // return $this->name; - //$this->name = 'index1 action '. $result; - return $this->name; + $time = time(); + $msgInfo = array( + 'user' => '13161443713@163.com', + 'stime' => $time, + 'sig' => sha1('13161443713@163.com' . 'XsaHzgePdyWTfcMX' . $time), + 'apiname' => 'Open_printMsg', + 'sn' => '920527381', + 'content' => '1111', + 'times' => 1//打印次数 + ); + $this->client = new FeiePrintClient('api.feieyun.cn', 80); + if (!$this->client->post('/Api/Open/', $msgInfo)) { + return '12'; + } else { + //服务器返回的JSON字符串,建议要当做日志记录起来 + $result = $this->client->getContent(); + return $result; + } } public function index2(RequestInterface $request) diff --git a/app/Libs/FeiePrintClient.php b/app/Libs/FeiePrintClient.php new file mode 100644 index 0000000..a1b4789 --- /dev/null +++ b/app/Libs/FeiePrintClient.php @@ -0,0 +1,307 @@ +host = $host; + $this->port = $port; + } + function get($path, $data = false) { + $this->path = $path; + $this->method = 'GET'; + if ($data) { + $this->path .= '?'.$this->buildQueryString($data); + } + return $this->doRequest(); + } + function post($path, $data) { + $this->path = $path; + $this->method = 'POST'; + $this->postdata = $this->buildQueryString($data); + return $this->doRequest(); + } + function buildQueryString($data) { + $querystring = ''; + if (is_array($data)) { + foreach ($data as $key => $val) { + if (is_array($val)) { + foreach ($val as $val2) { + $querystring .= urlencode($key).'='.urlencode($val2).'&'; + } + } else { + $querystring .= urlencode($key).'='.urlencode($val).'&'; + } + } + $querystring = substr($querystring, 0, -1); // Eliminate unnecessary & + } else { + $querystring = $data; + } + return $querystring; + } + function doRequest() { + if (!$fp = @fsockopen($this->host, $this->port, $errno, $errstr, $this->timeout)) { + switch($errno) { + case -3: + $this->errormsg = 'Socket creation failed (-3)'; + case -4: + $this->errormsg = 'DNS lookup failure (-4)'; + case -5: + $this->errormsg = 'Connection refused or timed out (-5)'; + default: + $this->errormsg = 'Connection failed ('.$errno.')'; + $this->errormsg .= ' '.$errstr; + $this->debug($this->errormsg); + } + return false; + } + socket_set_timeout($fp, $this->timeout); + $request = $this->buildRequest(); + $this->debug('Request', $request); + fwrite($fp, $request); + $this->headers = array(); + $this->content = ''; + $this->errormsg = ''; + $inHeaders = true; + $atStart = true; + while (!feof($fp)) { + $line = fgets($fp, 4096); + if ($atStart) { + $atStart = false; + if (!preg_match('/HTTP\/(\\d\\.\\d)\\s*(\\d+)\\s*(.*)/', $line, $m)) { + $this->errormsg = "Status code line invalid: ".htmlentities($line); + $this->debug($this->errormsg); + return false; + } + $http_version = $m[1]; + $this->status = $m[2]; + $status_string = $m[3]; + $this->debug(trim($line)); + continue; + } + if ($inHeaders) { + if (trim($line) == '') { + $inHeaders = false; + $this->debug('Received Headers', $this->headers); + if ($this->headers_only) { + break; + } + continue; + } + if (!preg_match('/([^:]+):\\s*(.*)/', $line, $m)) { + continue; + } + $key = strtolower(trim($m[1])); + $val = trim($m[2]); + if (isset($this->headers[$key])) { + if (is_array($this->headers[$key])) { + $this->headers[$key][] = $val; + } else { + $this->headers[$key] = array($this->headers[$key], $val); + } + } else { + $this->headers[$key] = $val; + } + continue; + } + $this->content .= $line; + } + fclose($fp); + if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] == 'gzip') { + $this->debug('Content is gzip encoded, unzipping it'); + $this->content = substr($this->content, 10); + $this->content = gzinflate($this->content); + } + if ($this->persist_cookies && isset($this->headers['set-cookie']) && $this->host == $this->cookie_host) { + $cookies = $this->headers['set-cookie']; + if (!is_array($cookies)) { + $cookies = array($cookies); + } + foreach ($cookies as $cookie) { + if (preg_match('/([^=]+)=([^;]+);/', $cookie, $m)) { + $this->cookies[$m[1]] = $m[2]; + } + } + $this->cookie_host = $this->host; + } + if ($this->persist_referers) { + $this->debug('Persisting referer: '.$this->getRequestURL()); + $this->referer = $this->getRequestURL(); + } + if ($this->handle_redirects) { + if (++$this->redirect_count >= $this->max_redirects) { + $this->errormsg = 'Number of redirects exceeded maximum ('.$this->max_redirects.')'; + $this->debug($this->errormsg); + $this->redirect_count = 0; + return false; + } + $location = isset($this->headers['location']) ? $this->headers['location'] : ''; + $uri = isset($this->headers['uri']) ? $this->headers['uri'] : ''; + if ($location || $uri) { + $url = parse_url($location.$uri); + return $this->get($url['path']); + } + } + return true; + } + function buildRequest() { + $headers = array(); + $headers[] = "{$this->method} {$this->path} HTTP/1.0"; + $headers[] = "Host: {$this->host}"; + $headers[] = "User-Agent: {$this->user_agent}"; + $headers[] = "Accept: {$this->accept}"; + if ($this->use_gzip) { + $headers[] = "Accept-encoding: {$this->accept_encoding}"; + } + $headers[] = "Accept-language: {$this->accept_language}"; + if ($this->referer) { + $headers[] = "Referer: {$this->referer}"; + } + if ($this->cookies) { + $cookie = 'Cookie: '; + foreach ($this->cookies as $key => $value) { + $cookie .= "$key=$value; "; + } + $headers[] = $cookie; + } + if ($this->username && $this->password) { + $headers[] = 'Authorization: BASIC '.base64_encode($this->username.':'.$this->password); + } + if ($this->postdata) { + $headers[] = 'Content-Type: application/x-www-form-urlencoded'; + $headers[] = 'Content-Length: '.strlen($this->postdata); + } + $request = implode("\r\n", $headers)."\r\n\r\n".$this->postdata; + return $request; + } + function getStatus() { + return $this->status; + } + function getContent() { + return $this->content; + } + function getHeaders() { + return $this->headers; + } + function getHeader($header) { + $header = strtolower($header); + if (isset($this->headers[$header])) { + return $this->headers[$header]; + } else { + return false; + } + } + function getError() { + return $this->errormsg; + } + function getCookies() { + return $this->cookies; + } + function getRequestURL() { + $url = 'https://'.$this->host; + if ($this->port != 80) { + $url .= ':'.$this->port; + } + $url .= $this->path; + return $url; + } + function setUserAgent($string) { + $this->user_agent = $string; + } + function setAuthorization($username, $password) { + $this->username = $username; + $this->password = $password; + } + function setCookies($array) { + $this->cookies = $array; + } + function useGzip($boolean) { + $this->use_gzip = $boolean; + } + function setPersistCookies($boolean) { + $this->persist_cookies = $boolean; + } + function setPersistReferers($boolean) { + $this->persist_referers = $boolean; + } + function setHandleRedirects($boolean) { + $this->handle_redirects = $boolean; + } + function setMaxRedirects($num) { + $this->max_redirects = $num; + } + function setHeadersOnly($boolean) { + $this->headers_only = $boolean; + } + function setDebug($boolean) { + $this->debug = $boolean; + } + function quickGet($url) { + $bits = parse_url($url); + $host = $bits['host']; + $port = isset($bits['port']) ? $bits['port'] : 80; + $path = isset($bits['path']) ? $bits['path'] : '/'; + if (isset($bits['query'])) { + $path .= '?'.$bits['query']; + } + $client = new HttpClient($host, $port); + if (!$client->get($path)) { + return false; + } else { + return $client->getContent(); + } + } + function quickPost($url, $data) { + $bits = parse_url($url); + $host = $bits['host']; + $port = isset($bits['port']) ? $bits['port'] : 80; + $path = isset($bits['path']) ? $bits['path'] : '/'; + $client = new HttpClient($host, $port); + if (!$client->post($path, $data)) { + return false; + } else { + return $client->getContent(); + } + } + function debug($msg, $object = false) { + if ($this->debug) { + print '
HttpClient Debug: '.$msg; + if ($object) { + ob_start(); + print_r($object); + $content = htmlentities(ob_get_contents()); + ob_end_clean(); + print '
'.$content.'
'; + } + print '
'; + } + } +} \ No newline at end of file diff --git a/app/Model/OrderMain.php b/app/Model/OrderMain.php index ee3840c..4972484 100644 --- a/app/Model/OrderMain.php +++ b/app/Model/OrderMain.php @@ -75,6 +75,7 @@ class OrderMain extends Model 'coupon_id2', 'uniacid', 'state', + 'dm_state', 'time', 'time_add', 'pay_time', diff --git a/app/Model/OrderSalesStatistic.php b/app/Model/OrderSalesStatistic.php new file mode 100644 index 0000000..a20edf8 --- /dev/null +++ b/app/Model/OrderSalesStatistic.php @@ -0,0 +1,29 @@ + 'required|nonempty|integer', + 'user_id' => 'required|nonempty|integer', + 'money' => 'required|nonempty', + ]; + } + + public function messages(): array + { + return [ + '*.*' => ':attribute 参数异常' + ]; + } + + public function attributes(): array + { + return [ + + ]; + } +} diff --git a/app/Service/CouponService.php b/app/Service/CouponService.php index f4f8af9..227d79b 100644 --- a/app/Service/CouponService.php +++ b/app/Service/CouponService.php @@ -6,7 +6,7 @@ use Hyperf\DbConnection\Db; use Hyperf\Redis\Redis; use Hyperf\Utils\ApplicationContext; -class CouponService implements CoupnoServiceInterface +class CouponService implements CouponServiceInterface { /** diff --git a/app/Service/CoupnoServiceInterface.php b/app/Service/CouponServiceInterface.php similarity index 93% rename from app/Service/CoupnoServiceInterface.php rename to app/Service/CouponServiceInterface.php index 4e3d9a4..943eb38 100644 --- a/app/Service/CoupnoServiceInterface.php +++ b/app/Service/CouponServiceInterface.php @@ -4,7 +4,7 @@ namespace App\Service; -interface CoupnoServiceInterface +interface CouponServiceInterface { /** * 当前订单可用优惠券列表 diff --git a/app/Service/DeviceServiceImp.php b/app/Service/DeviceServiceImp.php index 2b4962c..16c9110 100644 --- a/app/Service/DeviceServiceImp.php +++ b/app/Service/DeviceServiceImp.php @@ -4,13 +4,14 @@ namespace App\Service; use App\Commons\Log; use App\Constants\LogLabel; +use App\Model\Order; use App\Model\SpeakerDevic; use App\Model\Store; use Hyperf\Di\Annotation\Inject; use Hyperf\Utils\ApplicationContext; use App\TaskWorker\AliIotTask; -class DeviceServiceImp implements DeviceServiceInterFace +class DeviceServiceImp implements DeviceServiceInterface { /** * @Inject @@ -54,13 +55,6 @@ class DeviceServiceImp implements DeviceServiceInterFace // 获取市场ID $market_id = Store::query()->where(['id' => $store_id])->value('market_id'); - // $sd = new SpeakerDevic; - // $sd->store_id = $store_id; - // $sd->device_name = $dev_name; - // $sd->market_id = $market_id; - // $sd->bind_time = time(); - // $sd->saveOrFail(); - $sd = SpeakerDevic::query()->updateOrCreate( ['store_id' => $store_id, 'device_name' => $dev_name], ['market_id' => $market_id, 'bind_time' => time(), 'is_bind' => SpeakerDevic::IS_BIND_YES] @@ -84,8 +78,9 @@ class DeviceServiceImp implements DeviceServiceInterFace /** * 发布语音消息 - * @param $store_id + * @param $dev_names * @param $msg + * @return bool */ public function pubMsgToStoreByDevName($dev_names, $msg) { @@ -96,6 +91,38 @@ class DeviceServiceImp implements DeviceServiceInterFace return true; } + public function pubMsgToStoreByOrderMainId($order_id, $is_main = true) + { + + // 获取订单 + $orders = Order::query()->select(['id','order_num','money', 'pay_type', 'store_id', 'type']); + if ($is_main) { + $orders = $orders->where(['order_main_id' => $order_id])->get()->toArray(); + } else { + $orders = $orders->where(['id' => $order_id])->get()->toArray(); + } + + if(empty($orders)) return; + + // 循环发送 + foreach ($orders as $k => &$order) { + + $device_names = SpeakerDevic::query() + ->select(['device_name']) + ->where(['store_id' => $order['store_id'], 'is_bind' => SpeakerDevic::IS_BIND_YES]) + ->get() + ->toArray(); + + $msg = "{\"msg\":\"到账".$order['money']."元\"}"; + foreach ($device_names as $key => $dev_name) { + $this->IOTService->pub($dev_name['device_name'], $msg); + } + } + + return true; + + } + /** * 当前设备是否已经被绑定 * @param $dev_name diff --git a/app/Service/DeviceServiceInterFace.php b/app/Service/DeviceServiceInterface.php similarity index 68% rename from app/Service/DeviceServiceInterFace.php rename to app/Service/DeviceServiceInterface.php index 15aa23b..68cd47c 100644 --- a/app/Service/DeviceServiceInterFace.php +++ b/app/Service/DeviceServiceInterface.php @@ -2,10 +2,11 @@ namespace App\Service; -interface DeviceServiceInterFace +interface DeviceServiceInterface { public function getListByStoreId($store_id); public function bindByStoreId($dev_name,$store_id); public function unbindById($bind_id); public function pubMsgToStoreByDevName($dev_names,$msg); + public function pubMsgToStoreByOrderMainId($order_id, $is_main = true); } \ No newline at end of file diff --git a/app/Service/FeiePrintService.php b/app/Service/FeiePrintService.php new file mode 100644 index 0000000..b822175 --- /dev/null +++ b/app/Service/FeiePrintService.php @@ -0,0 +1,226 @@ +join('ims_cjdc_order as o','o.order_main_id', '=', 'm.id','inner') + ->join('ims_cjdc_order_goods as g','o.id','=', 'g.order_id','inner') + ->join('ims_cjdc_feprint as f','m.market_id','=', 'f.market_id','inner') + ->join('ims_cjdc_store as s','s.id','=', 'o.store_id','inner') + ->where('m.order_num', $order_num) + ->select("o.note as o_note,g.name,g.number,g.money,g.good_unit,m.delivery_time as ps_time,m.address,m.note,m.name as user_name,m.dada_fee,m.money as m_money,m.yhq_money2,m.box_money,f.sn,m.tel,m.order_num,g.id,g.spec,s.name as shopname") + ->order('s.id') + ->get(); + + $content = $this->printFormat($data, 14, 6, 3, 6); + $res = $this->printMsg($data[0]['sn'], $content, 1); + return ($res); + } + + /** + * [打印订单接口 Open_printMsg] + * @param [string] $sn [打印机编号sn] + * @param [string] $content [打印内容] + * @param [string] $times [打印联数] + * @return [string] [接口返回值] + */ + protected function printMsg($sn, $content, $times = 1) + { + $time = time(); //请求时间 + $msgInfo = array( + 'user' => self::USER, + 'stime' => $time, + 'sig' => sha1(self::USER . self::UKEY . $time), + 'apiname' => 'Open_printMsg', + 'sn' => $sn, + 'content' => $content, + 'times' => $times//打印次数 + ); + + $client = new FeiePrintClient(self::IP, self::PORT); + if (!$client->post(self::PATH, $msgInfo)) { + echo 'error'; + } else { + // 服务器返回的JSON字符串,建议要当做日志记录起来 + $result = $client->getContent(); + return $result; + } + } + + protected function printFormat($arr, $A, $B, $C, $D) + { + $orderInfo = '懒族生活
'; + $orderInfo .= '名称 单价 数量 金额
'; + $orderInfo .= '--------------------------------
'; + $shopname = ""; + $shopnum = 0; + foreach ($arr as $k5 => $v5) { + if ($shopname != $v5['shopname']) { + if ($shopname != "") { + $orderInfo .= '
'; + } + $shopnum++; + $orderInfo .= "(" . $shopnum . ")" .$v5['shopname'] . '
'; + $shopname = $v5['shopname']; + } + $name = $v5['name']; + if(!empty($v5['spec'])) { + $name .= "(规格:". $v5['spec'].")"; + }elseif (!empty($v5['good_unit'])){ + $name .= "(规格:". $v5['good_unit'].")"; + } + $price = $v5['money']; + $num = $v5['number']; + $prices = sprintf("%.2f",$v5['money']*$v5['number']); + $kw3 = ''; + $kw1 = ''; + $kw2 = ''; + $kw4 = ''; + $str = $name; + $blankNum = $A;//名称控制为14个字节 + $lan = mb_strlen($str,'utf-8'); + $m = 0; + $j=1; + $blankNum++; + $result = array(); + if(strlen($price) < $B){ + $k1 = $B - strlen($price); + for($q=0;$q<$k1;$q++){ + $kw1 .= ' '; + } + $price = $kw1.$price; + } + if(strlen($num) < $C){ + $k2 = $C - strlen($num); + for($q=0;$q<$k2;$q++){ + $kw2 .= ' '; + } + $num = $kw2.$num; + } + if(strlen($prices) < $D){ + $k3 = $D - strlen($prices); + for($q=0;$q<$k3;$q++){ + $kw4 .= ' '; + } + $prices = $kw4.$prices; + } + for ($i=0;$i<$lan;$i++){ + $new = mb_substr($str,$m,$j,'utf-8'); + $j++; + if(mb_strwidth($new,'utf-8')<$blankNum) { + if($m+$j>$lan) { + $m = $m+$j; + $tail = $new; + $lenght = iconv("UTF-8", "GBK//IGNORE", $new); + $k = $A - strlen($lenght); + for($q=0;$q<$k;$q++){ + $kw3 .= ' '; + } + if($m==$j){ + $tail .= $kw3.' '.$price.' '.$num.' '.$prices; + }else{ + $tail .= $kw3.'
'; + } + break; + }else{ + $next_new = mb_substr($str,$m,$j,'utf-8'); + if(mb_strwidth($next_new,'utf-8')<$blankNum) continue; + else{ + $m = $i+1; + $result[] = $new; + $j=1; + } + } + } + } + $head = ''; + foreach ($result as $key=>$value) { + if($key < 1){ + $v_lenght = iconv("UTF-8", "GBK//IGNORE", $value); + $v_lenght = strlen($v_lenght); + if($v_lenght == 13) $value = $value." "; + $head .= $value.' '.$price.' '.$num.' '.$prices; + }else{ + $head .= $value.'
'; + } + } + $orderInfo .= $head.$tail; + if(!empty($v5['o_note'])){ + $orderInfo .= '备注:'.$v5['o_note'].'
'; + } + } + // $time = date('Y-m-d H:i:s', time()); + $orderInfo .= '--------------------------------
'; + if ($arr[0]['box_money'] > 0) { + $kw5 = ''; + $len = 24 - strlen($arr[0]['box_money']); + for ($q = 0; $q < $len; $q++) { + $kw5 .= ' '; + } + $orderInfo .= '包装费:' . $kw5 . $arr[0]['box_money'] . '
'; + } + if($arr[0]['dada_fee'] > 0){ + $kw5 = ''; + $len = 24 - strlen($arr[0]['dada_fee']); + for ($q = 0; $q < $len; $q++) { + $kw5 .= ' '; + } + $orderInfo .= '配送费:'.$kw5.$arr[0]['dada_fee'].'
'; + } + if($arr[0]['yhq_money2'] > 0){ + $yhq_money2 = sprintf("%.2f",$arr[0]['yhq_money2']); + $kw6 = ''; + $len = 25 - strlen($yhq_money2); + for ($q = 0; $q < $len; $q++) { + $kw6 .= ' '; + } + $orderInfo .= '红包:'.$kw6.'-'.$yhq_money2.'
'; + } + $total = '合计:'.$arr[0]['m_money']; + $user_name = $arr[0]['user_name']; + if(strlen($user_name)>18){ + $user_name=substr($user_name,0,18).'...'; + } + $str = $user_name . $total; + $kw5 = ''; + $lenght = iconv("UTF-8", "GBK//IGNORE", $str); + $total_len = 32 - strlen($lenght); + for ($q = 0; $q < $total_len; $q++) { + $kw5 .= ' '; + } + $total_str = $user_name.$kw5.$total; + $orderInfo .= $total_str.'
'; + $orderInfo .= '送货地点:' . $arr[0]['address'] . '
'; + $tel = substr_replace( $arr[0]['tel'], '****', 3, 4); + $orderInfo .= '联系电话:' . $tel . '
'; + $orderInfo .= '配送时间:' . $arr[0]['ps_time'] . '
'; + if(!empty($arr[0]['note'])){ + $orderInfo .= '备注:'.$arr[0]['note'].'

'; + } + //$orderInfo .= 'http://www.feieyun.com';//把解析后的二维码生成的字符串用标签套上即可自动生成二维码 + return $orderInfo; + } +} \ No newline at end of file diff --git a/app/Service/FeiePrintServiceInterface.php b/app/Service/FeiePrintServiceInterface.php new file mode 100644 index 0000000..5e67cdc --- /dev/null +++ b/app/Service/FeiePrintServiceInterface.php @@ -0,0 +1,10 @@ + '微信支付', '2' => '余额支付', '3' => '积分支付', '4' => '货到付款']; + $address_store = $order['address'] . ';' .$order['name']. ';'. substr_replace($order['tel'],'****',3,4); + $address = $order['address'] . ';' .$order['name']. ';'. $order['tel']; + + // 查询子订单,用于发消息给商户 + $order_children = Order::query()->select(['id', 'order_num', 'store_id', 'money', 'time']) + ->where(['order_main_id' => $order_main_id]) + ->get() + ->toArray(); + + $goods_temp_all = []; + foreach ($order_children as $key => &$item) { + + $item = (array)$item; + + // 订单商品 + $order_goods = OrderGoods::query()->select(['name', 'number', 'spec', 'good_unit']) + ->where(['order_id' => $item['id']]) + ->get() + ->toArray(); + + $goods_temp = []; + foreach ($order_goods as $k => &$goods) { + array_push($goods_temp, $goods['name']."*".$goods['number']."/".($goods['spec']?:$goods['good_unit'])); + array_push($goods_temp_all, $goods['name']."*".$goods['number']."/".($goods['spec']?:$goods['good_unit'])); + } + + // 商户/门店的openid + $store = Store::query()->select(['id', 'name']) + ->where(['id' => $item['store_id']]) + ->first()->toArray(); + $store['openid'] = Users::query() + ->where(['id' => $store['user_id']]) + ->value('openid'); + + // 模板数据 + $data_store = [ + 'first' => ['您有新的外卖订单!订单编号:'.$item['order_num'], '#ff0000'], + 'keyword' => [ + ["您的外卖订单详情:\r\n".implode(";\r\n",$goods_temp), '#ff0000'], + $item['money'], + $payTypes[$order['pay_type']], + $item['time']?:'', + $address_store, + ], + 'remark' => [$order['note'], '#4e6ef2'] + ]; + + $ret_store = $this->sendTempMsg($store['openid'], '-M7DG_ACwJxqdAvyvJuAnPpx4xaLf3VkkN0fckno71c',$data_store); + } + + // 模板数据发送消息给用户 + $data_user = [ + 'first' => '您好,下单成功!订单编号:'.$order['order_num'], + 'keyword' => [ + implode(";\r\n", $goods_temp_all), + $order['money'], + $payTypes[$order['pay_type']], + date('Y-m-d H:i:s', $order['time_add']), + $address, + ], + 'remark' => '感谢您的光临,欢迎下次再来!' + ]; + + // 获取用户openid,发送给用户 + $user_openid = Users::query()->where(['id' => $order['user_id']])->value('openid'); + $ret_user = $this->sendTempMsg($user_openid,'-M7DG_ACwJxqdAvyvJuAnPpx4xaLf3VkkN0fckno71c', $data_user); + + } + + public function sendTempMsg($openid, $template_id, $data, $redirect_url = '', $applet_config = ['appid' => '', 'pagepath' => '']) + { + // 先拼个基础的 + $template = [ + 'touser' => $openid, + 'mp_template_msg' => [ + 'appid' => env('OFFICIAL_APP_ID'), + 'template_id' => $template_id, + 'url' => $redirect_url, + ] + ]; + + // 看看有没有小程序跳转的要求 + if ( is_array($applet_config)&&!empty($applet_config)&&!empty($applet_config['appid']) ) { + $template['mp_template_msg']['miniprogram'] = $applet_config; + } + + // 重点来了,拼接关键数据data + if (!is_array($data)) { # 数组都不是,请回去 + return false; + } + + if (is_array($data['first'])) { + $template['mp_template_msg']['data']['first']['value'] = $data['first'][0] ?? ''; + $template['mp_template_msg']['data']['first']['color'] = $data['first'][1] ?? ''; + } else { + $template['mp_template_msg']['data']['first']['value'] = $data['first']; + } + + if (isset($data['keyword'])&&is_array($data['keyword'])) { + foreach ($data['keyword'] as $key => &$keyword) { + $index = $key+1; + + if (is_array($keyword)) { + $template['mp_template_msg']['data']['keyword'.$index]['value'] = $keyword[0] ?? ''; + $template['mp_template_msg']['data']['keyword'.$index]['color'] = $keyword[1] ?? ''; + } else { + $template['mp_template_msg']['data']['keyword'.$index]['value'] = $keyword; + } + + } + } + + if (is_array($data['remark'])) { + $template['mp_template_msg']['data']['remark']['value'] = $data['remark'][0] ?? ''; + $template['mp_template_msg']['data']['remark']['color'] = $data['remark'][1] ?? ''; + } else { + $template['mp_template_msg']['data']['remark']['value'] = $data['remark']; + } + + $app = Factory::miniProgram(config('wxtempmsg')); + $app->uniform_message->send($template); + } + +} \ No newline at end of file diff --git a/app/Service/MiniprogramServiceInterface.php b/app/Service/MiniprogramServiceInterface.php new file mode 100644 index 0000000..b1ebe72 --- /dev/null +++ b/app/Service/MiniprogramServiceInterface.php @@ -0,0 +1,9 @@ + '', 'pagepath' => '']); +} \ No newline at end of file diff --git a/app/Service/MqttServiceInterface.php b/app/Service/MqttServiceInterface.php new file mode 100644 index 0000000..203b908 --- /dev/null +++ b/app/Service/MqttServiceInterface.php @@ -0,0 +1,21 @@ +select(['id','order_num','money', 'pay_type', 'store_id', 'type']); + if ($isMain) { + $orders = $orders->where(['order_main_id' => $orderId])->get()->toArray(); + } else { + $orders = $orders->where(['id' => $orderId])->get()->toArray(); + } + + if(empty($orders)) return; + + // 循环发送 + foreach ($orders as $k => &$order) { + $order['template'] = "懒族生活支付到账".floatval($order['money'])."元"; + // 获取终端ID + $order['to_client_id'] = Store::query()->where(['id' => $order['store_id']])->value('loudspeaker_imei'); + // 发布订阅消息 + $this->pubToMqtt($order['template'], self::TOPIC, $order['to_client_id']); + } + } + + /** + * @inheritDoc + */ + public function pubToMqtt($message, $topic, $toClientId) + { + $task = ApplicationContext::getContainer()->get(MQTTClientTask::class); + $task->publish($message, $topic, $toClientId); + } +} \ No newline at end of file diff --git a/app/Service/OrderService.php b/app/Service/OrderService.php index 54468a9..2efb470 100644 --- a/app/Service/OrderService.php +++ b/app/Service/OrderService.php @@ -22,7 +22,7 @@ class OrderService implements OrderServiceInterface /** * @Inject - * @var CoupnoServiceInterface + * @var CouponServiceInterface */ protected $couponService; @@ -349,9 +349,110 @@ class OrderService implements OrderServiceInterface /** * @inheritDoc */ - public function addOfflineOrder() + public function addOfflineOrder($data) { - // TODO: Implement addOfflineOrder() method. + Db::beginTransaction(); + try { + // 主订单数据 + $dataMain = []; + + // 获取分布式全局ID + $generator = ApplicationContext::getContainer()->get(IdGeneratorInterface::class); + $globalRrderId = $generator->generate(); + + // 主订单插入数据 + $currentTime = time(); + $dataMain = [ + 'delivery_no' => '', + 'dada_fee' => 0, + 'market_id' => 0, + 'box_money' => 0, + 'ps_money' => 0, + 'mj_money' => 0, + 'xyh_money' => 0, + 'yhq_money' => 0, + 'yhq_money2' => 0, + 'zk_money' => 0, + 'tel' => '', + 'name' => '', + 'address' => '', + 'area' => '', + 'lat' => '', + 'lng' => '', + 'note' => '', + 'form_id' => '', + 'form_id2' => '', + 'delivery_time' => '', + 'order_type' => 0, + 'coupon_id' => 0, + 'coupon_id2' => 0, + 'store_list' => '', + 'receive_coupon_ids' => '', + 'type' => OrderMain::ORDER_TYPE_OFFLINE, + 'time' => date('Y-m-d H:i:s', $currentTime), + 'time_add' => $currentTime, + 'pay_time' => '', + 'pay_type' => OrderMain::ORDER_PAY_WX, + 'state' => OrderMain::ORDER_STATE_UNPAY, + 'dm_state' => OrderMain::ORDER_STATE_UNPAY, + 'code' => $globalRrderId, + 'jj_note' => '', + 'uniacid' => 2, + 'order_num' => 'dm'.date('YmdHis', time()) . rand(1111, 9999), + 'money' => $data['money'], + 'user_id' => $data['user_id'], + 'store_ids' => $data['store_id'], + 'global_order_id' => $globalRrderId, + ]; + + // 主订单模型保存 + $orderMain = OrderMain::create($dataMain); + $orderMainId = $orderMain->id; + + // 子订单模型保存 + $dataChild = [ + 'uniacid' => 1, + 'order_num' => 's'.date('YmdHis', time()) . rand(1111, 9999), + 'user_id' => $orderMain->user_id, + 'store_id' => $data['store_id'], + 'order_main_id' => $orderMainId, + 'state' => OrderMain::ORDER_STATE_UNPAY, + 'tel' => $orderMain->tel, + 'name' => $orderMain->name, + 'address' => $orderMain->address, + 'area' => $orderMain->area, + 'time' => date("Y-m-d H:i:s"), + 'note' => '', + 'delivery_time' => $orderMain->delivery_time, + 'type' => $orderMain->type, + 'lat' => $orderMain->lat, + 'lng' => $orderMain->lng, + 'pay_type' => $orderMain->pay_type, + 'order_type' => $orderMain->order_type, + 'money' => 0, + 'box_money' => 0, + 'mj_money' => 0, + 'yhq_money' => 0, + 'yhq_money2' => 0, + 'zk_money' => 0, + 'coupon_id' => 0, + 'coupon_id2' => 0, + 'xyh_money' => 0, + 'time_add' => date("Y-m-d H:i:s"), + 'jj_note' => '', + 'form_id' => '', + 'form_id2' => '', + 'code' => '', + ]; + + $orderChildId = Order::query()->insertGetId($dataChild); + + Db::commit(); + return $orderMainId; + } catch (Exception $e) { + Db::rollBack(); + return '购买失败'; + } } diff --git a/app/Service/OrderServiceInterface.php b/app/Service/OrderServiceInterface.php index 08ee815..0d5e0a2 100644 --- a/app/Service/OrderServiceInterface.php +++ b/app/Service/OrderServiceInterface.php @@ -17,7 +17,7 @@ interface OrderServiceInterface * 扫码支付 * @return mixed */ - public function addOfflineOrder(); + public function addOfflineOrder($data); /** * 订单是否已经存在 diff --git a/app/TaskWorker/MQTTClientTask.php b/app/TaskWorker/MQTTClientTask.php index 6119690..f751cdc 100644 --- a/app/TaskWorker/MQTTClientTask.php +++ b/app/TaskWorker/MQTTClientTask.php @@ -12,8 +12,46 @@ class MQTTClientTask /** * @Task + * @param string|number $message 消息内容 + * @param string $topic 发布消息到主题,主题名 + * @param string $type 消息类型,cash或tts + * @param string $payId 支付方式,如“支付宝”、“微信”等 + * @param string $toClientId 终端id,如IMEI码 + * @param string $curClientId 当前客户端id */ - public function getClient() + public function publish( + $message, + $topic, + $toClientId = '', + $type = '', + $payId = '', + $curClientId = '' + ) { + $this->getClient(); + + $msgArr = []; + if ( (empty($type)&&is_numeric($message)) || 'cash' === $type ) { + $msgArr['cash'] = $message; + $payId AND $msgArr['payid'] = $payId; + } else { + $msgArr['message'] = $message; + } + + if (!empty($toClientId)) { + $topic .= '/'.$toClientId; + } + + $curClientId OR $curClientId = rand(1,999999999); + $success = $this->mqttClient->sendConnect($curClientId); + + if ($success) { + $this->mqttClient->sendPublish($topic, json_encode($msgArr), MQTTClient::MQTT_QOS2); + $this->mqttClient->sendDisconnect(); + } + $this->mqttClient->close(); + } + + protected function getClient() { $this->mqttClient = new MQTTClient(env('MQTT_HOST'), env('MQTT_PORT')); $this->mqttClient->setAuthentication(env('MQTT_NAME'), env('MQTT_PASS')); diff --git a/config/autoload/dependencies.php b/config/autoload/dependencies.php index 411bb9f..1557ca3 100644 --- a/config/autoload/dependencies.php +++ b/config/autoload/dependencies.php @@ -9,13 +9,16 @@ declare(strict_types=1); * @contact group@hyperf.io * @license https://github.com/hyperf/hyperf/blob/master/LICENSE */ + return [ \App\Service\ServiceEvaluateServiceInterface::class => \App\Service\ServiceEvaluateService::class, \App\Service\AttachmentServiceInterface::class => \App\Service\AttachmentService::class, \App\Service\ParamsTokenServiceInterface::class => \App\Service\ParamsTokenSsdbService::class, - \App\Service\DeviceServiceInterFace::class =>\App\Service\DeviceServiceImp::class, + \App\Service\DeviceServiceInterface::class =>\App\Service\DeviceServiceImp::class, \App\Commons\Log::class => \App\Commons\Log::class, \App\Service\IOTServiceInterface::class => \App\Service\IOTAliService::class, \App\Service\OrderServiceInterface::class => \App\Service\OrderService::class, - \App\Service\CoupnoServiceInterface::class => \App\Service\CouponService::class, + \App\Service\CouponServiceInterface::class => \App\Service\CouponService::class, + \App\Service\MqttServiceInterface::class => \App\Service\MqttSpeakerService::class, + \App\Service\FeiePrintServiceInterface::class => \App\Service\FeiePrintService::class, ]; diff --git a/config/config.php b/config/config.php index 7e8d490..ba75ad6 100644 --- a/config/config.php +++ b/config/config.php @@ -36,6 +36,9 @@ return [ 'cert_path' => env('CERT_PATH',''), 'key_path' => env('KEY_PATH',''), 'notify_url' => env('NOTIFY_URL',''), + ], + 'wxtempmsg' => [ + 'app_id' => env('APP_ID',''), + 'secret' => env('APP_SECRET',''), ] - ]; diff --git a/config/routes.php b/config/routes.php index 266122f..7902ff0 100644 --- a/config/routes.php +++ b/config/routes.php @@ -39,6 +39,7 @@ Router::addGroup('/v1/',function (){ //订单相关 Router::post('Order/addOnline', 'App\Controller\OrderController@addOnlineOrder'); + Router::post('Order/addOffline', 'App\Controller\OrderController@addOfflineOrder'); //小程序支付相关 Router::post('wxminipay/online', 'App\Controller\PaymentController@wxminiPayOnline');