zory 1 mês atrás
pai
commit
2ccff52580

+ 2 - 2
app/controller/api/Goods.php

@@ -31,8 +31,8 @@ class Goods extends Base
             ],$request->method());
             if (!is_array($param)) return error($param);
             $data = $this->model->where("id",$param['spm'])->with(['poi' => function ($query) {
-                $query->field("poi_id,poi_name,poi_address,longitude,latitude");
-            }])->findOrEmpty();
+                $query->field("poi_id,poi_name,poi_address,longitude,latitude,poi_id");
+            },'skuSpecs'])->findOrEmpty();
             if ($data->isEmpty()) return errorTrans("empty.data");
             return $this->encode("success",$data->toArray());
         } catch (\Throwable $th) {

+ 2 - 2
app/controller/api/Home.php

@@ -37,8 +37,8 @@ class Home extends Base
                     "cover" => "https://washmy.oss-cn-guangzhou.aliyuncs.com/storage/dc7fd761c2e2af9c340f20677f8f115d942f0bde.png"
                 ]
             ];
-            $store = (new SaasStore)->where("poi_id",$param['store'])->field("poi_name,start_at,end_at,longitude,latitude,service_mobile")->findOrEmpty();
-            $goods = (new SaasGoods)->where("poi_id",$param['store'])->field("product_id,product_name,image_list,category,price,line_price,sale_stock,id")->select()->toArray();
+            $store = (new SaasStore)->where("poi_id",$param['store'])->field("poi_name,start_at,end_at,longitude,latitude,service_mobile,poi_id")->findOrEmpty();
+            $goods = (new SaasGoods)->where("poi_id",$param['store'])->field("product_id,product_name,image_list,category,price,line_price,sale_stock,id")->limit(10)->select()->toArray();
             return success("ok",compact('banner','store','goods'));
         } catch (\Throwable $th) {
             return error($th->getMessage());

+ 33 - 0
app/controller/api/Service.php

@@ -0,0 +1,33 @@
+<?php
+
+namespace app\controller\api;
+
+use app\extra\basic\Base;
+use app\middleware\AuthMiddleware;
+use LinFly\Annotation\Attributes\Route\Controller;
+use LinFly\Annotation\Attributes\Route\Middleware;
+use LinFly\Annotation\Attributes\Route\PostMapping;
+use support\Request;
+use support\Response;
+
+
+#[Controller("/dy/service"),Middleware(AuthMiddleware::class)]
+class Service extends Base
+{
+
+
+    /**
+     * 分配客服
+     * @param Request $request
+     * @return Response
+     */
+    #[PostMapping("shareout")]
+    public function shareUser2Mer(Request $request)
+    {
+        try {
+            $param = $request->all();
+        } catch (\Throwable $throwable) {
+            return error($throwable->getMessage());
+        }
+    }
+}

+ 2 - 1
composer.json

@@ -54,7 +54,8 @@
     "qcloud/cos-sdk-v5": "^2.6",
     "qiniu/php-sdk": "^7.14",
     "luckycmc/webman-province-city-area": "^1.0",
-    "tinywan/captcha": "^0.0.4"
+    "tinywan/captcha": "^0.0.4",
+    "webman/push": "^1.1"
   },
   "suggest": {
     "ext-event": "For better performance. "

+ 10 - 0
config/plugin/webman/push/app.php

@@ -0,0 +1,10 @@
+<?php
+return [
+    'enable'       => true,
+    'websocket'    => 'websocket://0.0.0.0:3131',
+    'api'          => 'http://0.0.0.0:3232',
+    'app_key'      => '265c33b73d5c04f918978577df2c48d2',
+    'app_secret'   => '25774aa8461dcd54e5a318ba1e58f75b',
+    'channel_hook' => 'http://127.0.0.1:8787/plugin/webman/push/hook',
+    'auth'         => '/plugin/webman/push/auth'
+];

+ 21 - 0
config/plugin/webman/push/process.php

@@ -0,0 +1,21 @@
+<?php
+
+use Webman\Push\Server;
+
+return [
+    'server' => [
+        'handler'     => Server::class,
+        'listen'      => config('plugin.webman.push.app.websocket'),
+        'count'       => 1, // 必须是1
+        'reloadable'  => false, // 执行reload不重启
+        'constructor' => [
+            'api_listen' => config('plugin.webman.push.app.api'),
+            'app_info'   => [
+                config('plugin.webman.push.app.app_key') => [
+                    'channel_hook' => config('plugin.webman.push.app.channel_hook'),
+                    'app_secret'   => config('plugin.webman.push.app.app_secret'),
+                ],
+            ]
+        ]
+    ]
+];

+ 87 - 0
config/plugin/webman/push/route.php

@@ -0,0 +1,87 @@
+<?php
+/**
+ * This file is part of webman.
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the MIT-LICENSE.txt
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @author    walkor<walkor@workerman.net>
+ * @copyright walkor<walkor@workerman.net>
+ * @link      http://www.workerman.net/
+ * @license   http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+
+use support\Request;
+use Webman\Route;
+use Webman\Push\Api;
+
+/**
+ * 推送js客户端文件
+ */
+Route::get('/plugin/webman/push/push.js', function (Request $request) {
+    return response()->file(base_path().'/vendor/webman/push/src/push.js');
+});
+
+/**
+ * 私有频道鉴权,这里应该使用session辨别当前用户身份,然后确定该用户是否有权限监听channel_name
+ */
+Route::post(config('plugin.webman.push.app.auth'), function (Request $request) {
+    $pusher = new Api(str_replace('0.0.0.0', '127.0.0.1', config('plugin.webman.push.app.api')), config('plugin.webman.push.app.app_key'), config('plugin.webman.push.app.app_secret'));
+    $channel_name = $request->post('channel_name');
+    $session = $request->session();
+    // 这里应该通过session和channel_name判断当前用户是否有权限监听channel_name
+    $has_authority = true;
+    if ($has_authority) {
+        return response($pusher->socketAuth($channel_name, $request->post('socket_id')));
+    } else {
+        return response('Forbidden', 403);
+    }
+});
+
+/**
+ * 当频道上线以及下线时触发的回调
+ * 频道上线:是指某个频道从没有连接在线到有连接在线的事件
+ * 频道下线:是指某个频道的所有连接都断开触发的事件
+ */
+Route::post(parse_url(config('plugin.webman.push.app.channel_hook'), PHP_URL_PATH), function (Request $request) {
+
+    // 没有x-pusher-signature头视为伪造请求
+    if (!$webhook_signature = $request->header('x-pusher-signature')) {
+        return response('401 Not authenticated', 401);
+    }
+
+    $body = $request->rawBody();
+
+    // 计算签名,$app_secret 是双方使用的密钥,是保密的,外部无从得知
+    $expected_signature = hash_hmac('sha256', $body, config('plugin.webman.push.app.app_secret'), false);
+
+    // 安全校验,如果签名不一致可能是伪造的请求,返回401状态码
+    if ($webhook_signature !== $expected_signature) {
+        return response('401 Not authenticated', 401);
+    }
+
+    // 这里存储这上线 下线的channel数据
+    $payload = json_decode($body, true);
+
+    $channels_online = $channels_offline = [];
+
+    foreach ($payload['events'] as $event) {
+        if ($event['name'] === 'channel_added') {
+            $channels_online[] = $event['channel'];
+        } else if ($event['name'] === 'channel_removed') {
+            $channels_offline[] = $event['channel'];
+        }
+    }
+
+    // 业务根据需要处理上下线的channel,例如将在线状态写入数据库,通知其它channel等
+    // 上线的所有channel
+    echo 'online channels: ' . implode(',', $channels_online) . "\n";
+    // 下线的所有channel
+    echo 'offline channels: ' . implode(',', $channels_offline) . "\n";
+
+    return 'OK';
+});
+
+
+