Jelajahi Sumber

Merge branch 'master' into work_order_version_7.8.1

# Conflicts:
#	config/octane.php
loustwo 4 tahun lalu
induk
melakukan
2dcc8d8eff

+ 1 - 0
.gitignore

@@ -37,3 +37,4 @@ yarn-error.log
 /database/data
 /bootstrap/cache/*
 /public/vendor/horizon
+/start_for_win.bat

+ 47 - 0
app/Console/Commands/LoginListenerCommand.php

@@ -0,0 +1,47 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\Log;
+use Workerman\Worker;
+
+class LoginListenerCommand extends Command
+{
+    protected $signature = 'workman {action} {--d}';
+
+    protected $description = 'Start a Workerman server.';
+
+    public function handle()
+    {
+        global $argv;
+        $action = $this->argument('action');
+
+        $argv[0] = 'wk';
+        $argv[1] = $action;
+        $argv[2] = $this->option('d') ? '-d' : '';
+        $ws_worker = new Worker('websocket://0.0.0.0:2346');
+
+        // Emitted when new connection come
+        /*$ws_worker->onConnect = function ($connection) {
+        };*/
+
+        // Emitted when data received
+        $ws_worker->onMessage = function ($connection, $data) {
+            try {
+                $data = json_decode($data);
+                $_SERVER['HTTP_USER_AGENT'] = $data->userAgent;
+                $connection->send(app("UserService")->verifySingleTag($data->user, $data->token) ? "true" : "false");
+            }catch (\Exception $e){
+                Log::error("SOCKET连接恶意信息",[$e->getMessage(),$data]);
+            }
+        };
+
+        // Emitted when connection closed
+        $ws_worker->onClose = function ($connection) {
+        };
+
+        // Run worker
+        Worker::runAll();
+    }
+}

+ 6 - 2
app/Http/ApiControllers/LoginController.php

@@ -12,6 +12,7 @@ use Illuminate\Support\Facades\Hash;
 
 class LoginController
 {
+
     /**
      * @api {post} /login 登录接口
      * @apiName login
@@ -72,10 +73,13 @@ class LoginController
         }
 
         try {
-            $response["data"] = ["token"=>app("UserService")->getJWTToken($user,$privateKey),
+            $token = app("UserService")->getJWTToken($user,$privateKey);
+
+            //单点登录标记
+            app("UserService")->setSingleTag($user->id,$token);
+            $response["data"] = ["token"=>$token,
                 "menu"=>$this->getMenu($user),"info"=>["id"=>$user->id,"name"=>$user->name]];
             app("UserService")->setOrRefreshCache($user);
-            Auth::logoutOtherDevices($request->input('password'));
             return response()->json($response);
         }catch (\Exception $e){
             $response["status_code"] = 409;

+ 1 - 1
app/Http/Controllers/ReceivingTaskController.php

@@ -62,7 +62,7 @@ class ReceivingTaskController extends Controller
         $ans_number_string = $delivery_appointment_car->deliveryAppointment->asn_number ?? '';
         $ans_numbers = array_filter(preg_split('/[,, ]+/is', $ans_number_string));
 
-        if (count($ans_numbers) === 0 && count($request->input('asn_no')) == 0) {
+        if (count($ans_numbers) === 0 && count($request->input('asn_no',[])) == 0) {
             return ['success' => false, 'errors' => ['appointment_number' => ['预约号没有对应的Asn号']]];
         }
 

+ 4 - 56
app/Http/Controllers/TestController.php

@@ -14,10 +14,12 @@ use Illuminate\Database\Capsule\Manager;
 use Illuminate\Database\DatabaseManager;
 use Illuminate\Foundation\Auth\AuthenticatesUsers;
 use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Hash;
 use Illuminate\Support\Facades\Log;
 use Oursdreams\Export\Export;
+use Workerman\Worker;
 
 class TestController extends Controller
 {
@@ -38,62 +40,8 @@ class TestController extends Controller
             dd("方法不存在");
         }
     }
-    public function test($main, $x)
-    {
-        return;
-        $db = DB::connection("aliyunMysql");
-        foreach ($db->select(DB::raw("select * from equipments where code like 'W4%' and info is not null and id <= 4972")) as $eq){
-            $arr = str_split ($eq->code);
-            if (strlen($main)==2){
-                $arr1 = str_split ($main);
-                $arr[4] = $arr1[0];
-                $arr[5] = $arr1[1];
-            }else{
-                $arr[5] = $main;
-            }
-            $code = implode("",$arr);
-
-            $obj = json_decode($eq->info);
-            $obj->x +=$x;
-            $db->insert("insert into equipments(code,parent_id,info,depth,width,created_at,updated_at,warehouse_detail_id)
-values(?,null,?,?,?,?,?,1)",[$code,json_encode($obj),$eq->depth,$eq->width,now()->toDateTimeString(),now()->toDateTimeString()]);
-
-            $a = $db->selectOne("select * from equipments where parent_id is null and code = ? ",[$code]);
-            foreach ($db->select("select * from equipments where parent_id = ?",[$eq->id]) as $item){
-                $arr = str_split ($item->code);
-                if (strlen($main)==2){
-                    $arr1 = str_split ($main);
-                    $arr[4] = $arr1[0];
-                    $arr[5] = $arr1[1];
-                }else{
-                    $arr[5] = $main;
-                }
-                $code = implode("",$arr);
-                $db->insert("insert into equipments(code,parent_id,info,depth,width,height,location_tab,created_at,updated_at,warehouse_detail_id)
-values(?,?,null,?,?,?,?,?,?,2)",[$code,$a->id,$item->depth,$item->width,$item->height,$item->location_tab,now()->toDateTimeString(),now()->toDateTimeString()]);
-            }
-        }
-    }
-    public function test2(){
-        return;
-        $db = DB::connection("aliyunMysql");
-        foreach ($db->select("select * from equipments where (code like 'W3%') and info is not null") as $eq){
-            $obj = json_decode($eq->info);
-            $obj->x -= 105;
-            $db->update("UPDATE equipments SET info = ? where id = ?",[json_encode($obj),$eq->id]);
-        }
-    }
-
-    public function test1(Request $request){
-        return;
-        $x = 0;
-        $a1 = 8 + 30;
-        $a2 = 80 + 30;
-        $a3 = 32 + 30;
-    }
-    use AuthenticatesUsers;
-    public function test3($request){
-        dd(Hash::make("wangyan"));
+    public function test(Request $request){
+        dd(Cache::tags(User::ANDROID_SINGLE_TAG)->get(64));
     }
 }
 

+ 11 - 1
app/Http/Middleware/AuthorizingApi.php

@@ -2,6 +2,7 @@
 
 namespace App\Http\Middleware;
 
+use App\Services\UserService;
 use Closure;
 use Firebase\JWT\ExpiredException;
 use Firebase\JWT\JWT;
@@ -21,6 +22,10 @@ class AuthorizingApi
     public function handle(Request $request, Closure $next)
     {
         $token = $request->header("token");
+        /**
+         * @var UserService $service
+         */
+        $service = app("UserService");
         if (!$token) return response()->json([
                         'message' => '没有认证,请前去认证',
                         'status_code' => 401,
@@ -37,7 +42,12 @@ class AuthorizingApi
         }
         try {
             $payload = JWT::decode($token, $publicKey, ['RS256']);
-            $user = app("UserService")->getOrRefreshCache($payload->data->id,$payload->exp);
+            $user = $service->getOrRefreshCache($payload->data->id,$payload->exp);
+            if (!$service->verifySingleTag($user->id, $token)){
+                $response["status_code"] = 407;
+                $response["message"] = "账号已在别处登录";
+                return response()->json($response);
+            }
         }catch (ExpiredException $e){
             $response["status_code"] = 401;
             $response["message"] = "token失效";

+ 1 - 1
app/Services/ReceivingTaskService.php

@@ -61,7 +61,7 @@ class ReceivingTaskService
             if ($receivingTask->id) {
                 $ans_number_string = $deliveryAppointmentCar->deliveryAppointment->asn_number ?? '';
                 $ans_numbers = array_filter(preg_split('/[,, ]+/is', $ans_number_string));
-                $ans_numbers = array_merge($ans_numbers, $params['asn_nos'] ?? []);
+                $ans_numbers = array_unique(array_merge($ans_numbers, $params['asn_nos'] ?? []));
                 $this->itemService->createItems($receivingTask, $ans_numbers);
                 $this->saveImage($receivingTask, $params['driving_license_image']);
             }

+ 16 - 0
app/Services/UserService.php

@@ -12,6 +12,7 @@ use Illuminate\Database\Eloquent\Model;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Cache;
 use App\Traits\ServiceAppAop;
+use Illuminate\Support\Facades\Log;
 
 
 class UserService
@@ -178,4 +179,19 @@ class UserService
         $this->setOrRefreshCache($user,$time>0 ? $time : 7200);
         return $user;
     }
+
+    public function setSingleTag($key, $token)
+    {
+        $val = $token."#".md5($_SERVER['HTTP_USER_AGENT']);
+        Cache::tags(User::ANDROID_SINGLE_TAG)->put($key,$val,
+            config("api.timeliness_limits.token","7200"));
+    }
+
+    public function verifySingleTag($key, $token):bool
+    {
+        $tV = Cache::tags(User::ANDROID_SINGLE_TAG)->get($key);
+        if ($tV===null)return true;
+        $userAgent = isset($_SERVER['HTTP_USER_AGENT']) ? "#".md5($_SERVER['HTTP_USER_AGENT']) : "";
+        return $tV===($token.$userAgent);
+    }
 }

+ 4 - 0
app/User.php

@@ -20,6 +20,10 @@ class User extends Authenticatable
     use Notifiable;
     use SoftDeletes;
 
+    /**
+     * 安卓单点登录记录标识
+     */
+    const ANDROID_SINGLE_TAG = "ANDROID_SINGLE";
     /**
      * The attributes that are mass assignable.
      *

+ 1 - 0
composer.json

@@ -35,6 +35,7 @@
         "predis/predis": "^1.1",
         "pusher/pusher-php-server": "^4.1",
         "te7a-houdini/laravel-trix": "^2.0",
+        "workerman/workerman": "^4.0",
         "yajra/laravel-oci8": "7.0"
     },
     "require-dev": {

+ 70 - 1
composer.lock

@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "a8a45b0f4001cb3c8e61821f0cc50383",
+    "content-hash": "ce83f90582d55cf364dba2352b7cb12d",
     "packages": [
         {
             "name": "awobaz/compoships",
@@ -7904,6 +7904,75 @@
             ],
             "time": "2020-11-12T00:07:28+00:00"
         },
+        {
+            "name": "workerman/workerman",
+            "version": "v4.0.26",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/walkor/workerman.git",
+                "reference": "27573e9f985f9ec0665b1f9924308d359bd0fdaa"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/walkor/workerman/zipball/27573e9f985f9ec0665b1f9924308d359bd0fdaa",
+                "reference": "27573e9f985f9ec0665b1f9924308d359bd0fdaa",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=5.3"
+            },
+            "suggest": {
+                "ext-event": "For better performance. "
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Workerman\\": "./"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "walkor",
+                    "email": "walkor@workerman.net",
+                    "homepage": "http://www.workerman.net",
+                    "role": "Developer"
+                }
+            ],
+            "description": "An asynchronous event driven PHP framework for easily building fast, scalable network applications.",
+            "homepage": "http://www.workerman.net",
+            "keywords": [
+                "asynchronous",
+                "event-loop"
+            ],
+            "support": {
+                "email": "walkor@workerman.net",
+                "forum": "http://wenda.workerman.net/",
+                "issues": "https://github.com/walkor/workerman/issues",
+                "source": "https://github.com/walkor/workerman",
+                "wiki": "http://doc.workerman.net/"
+            },
+            "funding": [
+                {
+                    "url": "https://opencollective.com/walkor",
+                    "type": "open_collective"
+                },
+                {
+                    "url": "https://www.patreon.com/walkor",
+                    "type": "patreon"
+                }
+            ],
+            "time": "2021-12-21T03:39:14+00:00"
+        },
         {
             "name": "yajra/laravel-oci8",
             "version": "v7.0.0",

+ 0 - 16
config/octane.php

@@ -1,16 +0,0 @@
-<?php
-return [
-    'workerman' => [
-        'transport' => 'tcp',
-        'context' => [],
-        'name' => env('APP_NAME', 'laravel-octane-workerman'),
-//        'count' => cpu_count() * 2,
-        'user' => '',
-        'group' => '',
-        'reuse_port' => true,
-        'pid_file' => storage_path('logs/webman.pid'),
-        'stdout_file' => storage_path('logs/stdout.log'),
-        'log_file' => storage_path('logs/workerman.log'),
-        'max_package_size' => 10 * 1024 * 1024,
-    ]
-];

+ 2 - 0
resources/views/order/workOrder/index.blade.php

@@ -869,11 +869,13 @@
                 },
                 groupImages(workOrder, type) {
                     let images = [];
+
                     workOrder.details.forEach(detail => {
                         let imageList = detail.images.map(item => {
                             item.issue_type_name = detail.issue_type ? detail.issue_type.name : '';
                             return item;
                         }).filter(item => {
+                            if (!item.upload_file) return false;
                             return item.type === type;
                         }).map(e => {
                             let {url, type} = e['upload_file'];

+ 1 - 0
runServes.sh

@@ -6,6 +6,7 @@ sudo ps -aux|grep laravel-echo-server |grep -v grep|awk '{print $2}'|sudo xargs
 cd /var/www/was
 nohup sudo su root -c "laravel-echo-server start" >/dev/null 2>&1 &
 nohup sudo su baoshi -c "sudo supervisord -c /var/www/was/horizon.conf" >/dev/null 2>&1 &
+nohup sudo su baoshi -c "php artisan workman start --d" >/dev/null 2>&1 &
 #nohup sudo su baoshi -c "php artisan queue:work --tries=2 --delay=2" >/dev/null 2>&1 &
 # nohup sudo ./serves/goExports >/dev/null 2>&1 &