Pārlūkot izejas kodu

Merge remote-tracking branch 'origin/master'

gogs 1 gadu atpakaļ
vecāks
revīzija
9909c6e1f9

+ 67 - 0
app/Http/Controllers/Api/InOutOptionController.php

@@ -0,0 +1,67 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+use App\Service\InOutOptionService;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Redis;
+
+class InOutOptionController extends BaseController
+{
+    public function setOrderNumber(Request $request){
+        $service = new InOutOptionService();
+        list($status,$data) = $service->setOrderNumber($request->all());
+
+        echo 'ok';die;
+    }
+
+    public function getOrderNumber(Request $request){
+        $service = new InOutOptionService();
+        list($status,$data) = $service->getOrderNumber($request->all(),$request->header('Site'));
+
+        if($status){
+            return $this->json_return(200,'',$data);
+        }else{
+            return $this->json_return(201,$data);
+        }
+    }
+
+    public function setFhMessage(Request $request){
+        $service = new InOutOptionService();
+        $service->setFhMessage($request->all(),$request->header('Site'));
+
+        echo 'ok';
+    }
+
+    public function inout(){
+        $i = 'inout_key_state';
+        $s = Redis::get($i);
+        if($s){
+            $key = 'inout_key';
+            $a = Redis::get($key);
+            if(empty($a)){
+                $a = 1;
+            } else{
+                if($a == 1) $a = 2;
+                else $a = 1;
+            }
+            Redis::set($key,$a);
+
+            if($a == 1) $type = '出库';
+            else $type = '入库';
+
+            $detail = [
+                'project'=>'南京福猴建材有限公司',
+                'type'=>$type,
+                'num'=>'2',
+                'order_no'=>'PG2023101900818',
+                '时间'=>date('Y-m-d H:i:s'),
+            ];
+            Redis::del($i);
+            return $this->json_return(200,'',$detail);
+        }
+
+        return $this->json_return(200,'',[]);
+
+    }
+}

+ 3 - 1
app/Http/Controllers/Api/TestController.php

@@ -11,7 +11,9 @@ use Illuminate\Http\Request;
 
 class TestController extends BaseController
 {
-
+    public function deviceCallback(Request $request){
+        echo 'ok';die;
+    }
 
 
     public function boxInsert(){

+ 4 - 1
app/Jobs/DesktopDeviceJob.php

@@ -112,9 +112,11 @@ class DesktopDeviceJob implements ShouldQueue
         if(! $status) return;
 
         //组织数据
+        $total = 0;
         $completion_orders_dtl = [];
         $first = $data['content'][0]['dispatch_orders'];
         foreach ($data['content'] as $value){
+            $total += $value['dispatch_num'];
             $completion_orders_dtl[] = [
                 "item_num" => $value['item_num'],
                 "product_no" => $value['product_no'],
@@ -181,7 +183,8 @@ class DesktopDeviceJob implements ShouldQueue
             "employee_id_show" => $first['employee_id_show'],
             "tag" => $tag,
             "completion_type" => 'COMPLETION_AFTER_QUALITY',
-            "completion_type_show" => '完工扫码'
+            "completion_type_show" => '完工扫码',
+            "finished_num_total" => $total,
         ];
         $post = [
             "bizTypeEk" => "LOWCODE",

+ 232 - 0
app/Jobs/DoorDeviceJob.php

@@ -0,0 +1,232 @@
+<?php
+
+namespace App\Jobs;
+
+use App\Service\ClearDataService;
+use App\Service\InOutOptionService;
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Foundation\Bus\Dispatchable;
+use Illuminate\Queue\InteractsWithQueue;
+use Illuminate\Queue\SerializesModels;
+use Illuminate\Support\Facades\Redis;
+use Symfony\Component\Console\Output\ConsoleOutput;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class DoorDeviceJob implements ShouldQueue
+{
+    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
+
+    protected $data;
+    protected $type;
+    protected $site;
+    protected $device_id;
+
+    /**
+     * Create a new job instance
+     *
+     * @return void
+     */
+    public function __construct($data,$type,$site,$device_id)
+    {
+        $this->data = $data;
+        $this->type = $type;
+        $this->site = $site ?? '91451322MA5P9JNKXA';
+        $this->device_id = $device_id;
+    }
+
+    /**
+     * Execute the job.
+     *
+     * @return void
+     */
+    public function handle()
+    {
+        try{
+            $epc = $this->data;
+            $type = $this->type;//1 入库 2 出库
+            $order_number = [];
+            foreach ($epc as $value){
+                $str = @hex2bin($value);
+                $str = ltrim($str, "\x00");
+                if(! empty($str) && substr($str, 0, 2) === "BZ"){
+                    if(! in_array($str, $order_number)) $order_number[] = $str; // 十六进制字符串转回原来字符串
+                }
+//                $order_number[] = hex2bin($value); //十六进制字符串转回 原来字符串
+            }
+            file_put_contents('record_door_result.txt',date("Y-m-d H:i:s",time())."原数据:".json_encode($epc) . "解析后:" . json_encode($order_number) .PHP_EOL.'start'.PHP_EOL,8);
+            if(empty($order_number)) {
+                file_put_contents('record_door_result.txt',date("Y-m-d H:i:s",time()).'start_end'.PHP_EOL,8);
+                return;
+            }
+
+            //获取包装单产品
+            $dispatchList = $this->getDispatchList($order_number);
+            if(empty($dispatchList) || empty($dispatchList['data'])) {
+                file_put_contents('record_door_result.txt',date("Y-m-d H:i:s",time()).'getlist_end'.PHP_EOL,8);
+                return;
+            }
+            $this->completionOrders($dispatchList['data'],$type);
+
+            //输出信息 测试
+            $this->echoMessage(new ConsoleOutput());
+        }catch (\Exception $exception){
+            file_put_contents('record_door_error.txt',date("Y-m-d H:i:s",time()).json_encode($this->data) . PHP_EOL.$exception->getMessage().PHP_EOL,8);
+        }
+    }
+
+    public function getDispatchList($data){
+        if(empty($data)) return [];
+        list($status,$token) = ClearDataService::getTokenCs();
+        if(! $status) return [];
+
+        $site = $this->site;
+        $url = "http://121.36.142.167:7774/jbl/api/module-data/box_orders/box_orders/diy/defective_order_no_list";
+        $post = [
+            'defective_order_no_list' => $data,
+        ];
+        $header = ["Authorization: Bearer {$token}","Content-Type:application/json","Site:{$site}"];
+        $json = str_replace('"workflowSearchBean":[]','"workflowSearchBean":{}',json_encode($post));
+
+        $curl = curl_init();
+        curl_setopt_array($curl, array(
+            CURLOPT_URL => $url,
+            CURLOPT_RETURNTRANSFER => true,
+            CURLOPT_ENCODING => '',
+            CURLOPT_MAXREDIRS => 10,
+            CURLOPT_TIMEOUT => 0,
+            CURLOPT_FOLLOWLOCATION => true,
+            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
+            CURLOPT_CUSTOMREQUEST => 'POST',
+            CURLOPT_POSTFIELDS => $json,
+            CURLOPT_HTTPHEADER => $header,
+        ));
+        $response = curl_exec($curl);
+        curl_close($curl);
+
+        file_put_contents('record_door_result.txt',date('Y-m-d H:i:s'). PHP_EOL . $response .PHP_EOL.'getlist'.PHP_EOL,8);
+
+        return json_decode($response,true);
+    }
+
+    public function completionOrders($data,$type){
+        list($status,$token) = ClearDataService::getTokenCs();
+        if(! $status) return;
+
+        $site = $this->site;
+        $device_id = $this->device_id;
+        //组织数据
+        $main_dtl = $orderNo = [];
+        if($type == 1){
+            $opt = InOutOptionService::OrderKeyQueueIn;
+            $url = 'http://121.36.142.167:7774/jbl/api/module-data/production_receipt/production_receipt';
+            $dynamicFormId = "473758926009479168";
+            $showModelId = "473761325902147584";
+            foreach ($data as $value){
+                if(empty($value['box_orders']['delivery_status'])){
+                    $main_dtl[] = [
+                        "product_code"=> $value['brand_code'],
+                        "product_title"=> $value['product_title'],
+                        "product_size"=> $value['product_size'],
+                        "color"=> $value['color'],
+                        "color_two"=> $value['color_two'],
+                        "product_unit_title"=> $value['product_unit_title'],
+                        "product_unit"=> $value['product_unit'],
+                        "color_code"=> $value['color_code'],
+                        "color_code_two"=> $value['color_code_two'],
+                        "in_num"=> $value['box_num'],
+                    ];
+                    if(! in_array($value['box_orders']['defective_order_no'], $orderNo)) $orderNo[] = $value['box_orders']['defective_order_no'];
+                }
+            }
+            $datas = [
+                'production_receipt' => [
+                    'production_receipt_no' => null,
+                    'in_out_type' => 'RK007',
+                    'box_title' => 'WH05001',
+                    'in_time' => gmdate("Y-m-d\TH:i:s.000\Z"),
+                    'status' => "NOT_APPROVED",
+                ],
+                'production_receipt_dtl' => $main_dtl
+            ];
+        }else{
+            $opt = InOutOptionService::OrderKeyQueueOut;
+            $url = 'http://121.36.142.167:7774/jbl/api/module-data/picking_out/picking_out';
+            $dynamicFormId = "473763313217908736";
+            $showModelId = "473771977253269504";
+            foreach ($data as $value){
+                if(empty($value['box_orders']['delivery_status'])){
+                    $main_dtl[] = [
+                        "product_code"=> $value['brand_code'],
+                        "product_title"=> $value['product_title'],
+                        "product_size"=> $value['product_size'],
+                        "color"=> $value['color'],
+                        "color_two"=> $value['color_two'],
+                        "product_unit_title"=> $value['product_unit_title'],
+                        "product_unit"=> $value['product_unit'],
+                        "color_code"=> $value['color_code'],
+                        "color_code_two"=> $value['color_code_two'],
+                        "in_num"=> $value['box_num'],
+                    ];
+                    if(! in_array($value['box_orders']['defective_order_no'], $orderNo)) $orderNo[] = $value['box_orders']['defective_order_no'];
+                }
+            }
+            $datas = [
+                'picking_out' => [
+                    'picking_out_no' => null,
+                    'in_out_type' => 'CK010',
+                    'box_title' => 'WH05001',
+                    'out_time' => gmdate("Y-m-d\TH:i:s.000\Z"),
+                    'status' => "NOT_APPROVED",
+                ],
+                'picking_out_product' => $main_dtl
+            ];
+        }
+
+        if(! empty($main_dtl)){
+            //有产品
+            $post = [
+                "bizTypeEk" => "LOWCODE",
+                "bizId" => -1,
+                "data" => $datas,
+                "dynamicFormId" => $dynamicFormId,
+                "showModelId" => $showModelId
+            ];
+        }
+        //组织数据------
+        file_put_contents('record_door_result.txt',date('Y-m-d H:i:s'). PHP_EOL . json_encode($post) .PHP_EOL.'post'.PHP_EOL,8);
+
+        $header = ["Authorization: Bearer {$token}","Content-Type:application/json","Site:{$site}"];
+
+        $curl = curl_init();
+        curl_setopt_array($curl, array(
+            CURLOPT_URL => $url,
+            CURLOPT_RETURNTRANSFER => true,
+            CURLOPT_ENCODING => '',
+            CURLOPT_MAXREDIRS => 10,
+            CURLOPT_TIMEOUT => 0,
+            CURLOPT_FOLLOWLOCATION => true,
+            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
+            CURLOPT_CUSTOMREQUEST => 'POST',
+            CURLOPT_POSTFIELDS => json_encode($post),
+            CURLOPT_HTTPHEADER => $header,
+        ));
+        $response = curl_exec($curl);
+        curl_close($curl);
+
+        $result = json_decode($response,true);
+        if(! empty($result['createdDate'])) {
+            $expire_time = 10;
+            $key = $device_id . $opt;
+            Redis::set($key, json_encode($orderNo));
+            Redis::expire($key, $expire_time);
+        }
+
+        file_put_contents('record_door_result.txt',date('Y-m-d H:i:s'). PHP_EOL . $response .PHP_EOL.'create'.PHP_EOL,8);
+    }
+
+    protected function echoMessage(OutputInterface $output)
+    {
+        $output->writeln($this->data);
+    }
+}

+ 35 - 13
app/Jobs/ProcessDataJob.php

@@ -60,21 +60,43 @@ class ProcessDataJob implements ShouldQueue
         if(! $status) return;
 
         $url = $this->url . "api/module-data/device_machine_record/device_machine_record";
-        $post = [
-            'bizId' => -1,
-            'bizTypeEk' => 'LOWCODE',
-            'data' => [
-                'device_machine_record' => [
-                    'machine_code' => $data['dev_eui'],
-                    'param_value' => $data['value'],
-                    'record_time' => $this->getNowDay()
-                ]
-            ],
-            'dynamicFormId' => '477743923368955904',
-            'showModelId' => '477745421456904192'
-        ];
         $header = ["Authorization: Bearer {$token}","Content-Type:application/json"];
+        if(! empty($data['multiple'])){
+            foreach ($data['multiple'] as $key => $value){
+                $post = [
+                    'bizId' => -1,
+                    'bizTypeEk' => 'LOWCODE',
+                    'data' => [
+                        'device_machine_record' => [
+                            'machine_code' => $key,
+                            'param_value' => $value,
+                            'record_time' => $this->getNowDay()
+                        ]
+                    ],
+                    'dynamicFormId' => '477743923368955904',
+                    'showModelId' => '477745421456904192'
+                ];
+                $this->sendData($url,$post,$header);
+            }
+        } else{
+            $post = [
+                'bizId' => -1,
+                'bizTypeEk' => 'LOWCODE',
+                'data' => [
+                    'device_machine_record' => [
+                        'machine_code' => $data['dev_eui'],
+                        'param_value' => $data['value'],
+                        'record_time' => $this->getNowDay()
+                    ]
+                ],
+                'dynamicFormId' => '477743923368955904',
+                'showModelId' => '477745421456904192'
+            ];
+            $this->sendData($url,$post,$header);
+        }
+    }
 
+    public function sendData($url, $post, $header){
         $curl = curl_init();
         curl_setopt_array($curl, array(
             CURLOPT_URL => $url,

+ 76 - 12
app/Service/ClearDataService.php

@@ -86,20 +86,41 @@ class ClearDataService extends Service
 
     public static function saveData($data){
         try{
+            $dev_eui = $data['obj']['devEUI'];
+            $device_name = $data['obj']['deviceName'];
+            $source_ip = self::getIP();
             //保存数据
-            $model = new DeviceData();
+            if(isset($data['temperature']) && isset($data['humidity'])){
+                $insert[] = [
+                    'dev_eui' => $dev_eui . '1',
+                    'device_name' => $device_name,
+                    'source_ip' => $source_ip,
+                    'data_type' => 4,
+                    'happening_data' => $data['temperature']
+                ];
+                $insert[] = [
+                    'dev_eui' => $dev_eui . '2',
+                    'device_name' => $device_name,
+                    'source_ip' => $source_ip,
+                    'data_type' => 4,
+                    'happening_data' => $data['humidity']
+                ];
+                DeviceData::insert($insert);
+            }else{
+                $model = new DeviceData();
 //            $model->data = json_encode($data);//源数据
-            $model->dev_eui = $data['obj']['devEUI'];
-            $model->device_name = $data['obj']['deviceName'];
-            $model->source_ip = self::getIP();
-            if(isset($data['temperature'])){
-                $model->data_type = 1;
-                $model->happening_data = $data['temperature'];
-            }elseif (isset($data['pressure'])){
-                $model->data_type = 2;
-                $model->happening_data = $data['pressure'];
+                $model->dev_eui = $dev_eui;
+                $model->device_name = $device_name;
+                $model->source_ip = $source_ip;
+                if(isset($data['temperature'])){
+                    $model->data_type = 1;
+                    $model->happening_data = $data['temperature'];
+                }elseif (isset($data['pressure'])){
+                    $model->data_type = 2;
+                    $model->happening_data = $data['pressure'];
+                }
+                $model->save();
             }
-            $model->save();
         }catch (\Exception $exception){
             file_put_contents('record_errors.txt',json_encode($data) . PHP_EOL . $exception->getFile().$exception->getLine().$exception->getCode(),8);
         }
@@ -108,7 +129,12 @@ class ClearDataService extends Service
     public static function clearData($data){
         $return['is_clear_data'] = 1;
         $return['dev_eui'] = $data['obj']['devEUI'] ?? '';
-        if(isset($data['temperature'])){
+        if(isset($data['temperature']) && isset($data['humidity'])){
+            $return['multiple'] = [
+                $return['dev_eui'] . '1' => $data['temperature'],
+                $return['dev_eui'] . '2' => $data['humidity'],
+            ];
+        }elseif(isset($data['temperature'])){
             $return['value'] = $data['temperature'];
         }elseif (isset($data['pressure'])){
             $return['value'] = round($data['pressure'] / 1000,2);
@@ -190,4 +216,42 @@ class ClearDataService extends Service
 
         return [true,$token];
     }
+
+    public static function getTokenCs(){
+        $token_key = 'big_king_login_token_cs';
+        $token = Redis::get($token_key);
+        if(! $token){
+            $url = config('ip.cs');
+            $post = array("name" => "admin","password"=>"admin","rememberMe"=>true);
+            $header = ['Content-Type:application/json'];
+            $curl = curl_init();
+            curl_setopt_array($curl, array(
+                CURLOPT_URL => $url . 'jbl/api/mes/login',
+                CURLOPT_RETURNTRANSFER => true,
+                CURLOPT_ENCODING => '',
+                CURLOPT_MAXREDIRS => 10,
+                CURLOPT_TIMEOUT => 0,
+                CURLOPT_FOLLOWLOCATION => true,
+                CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
+                CURLOPT_CUSTOMREQUEST => 'POST',
+                CURLOPT_POSTFIELDS => json_encode($post),
+                CURLOPT_HTTPHEADER =>  $header,
+            ));
+            $response = curl_exec($curl);
+            curl_close($curl);
+            $result = json_decode($response,true);
+            if(empty($result['token'])) {
+                file_put_contents('big_king_token_error_cs.txt',date('Y-m-d H:i:s'). PHP_EOL . $response .PHP_EOL,8);
+                return [false,''];
+            }else{
+                $token = $result['token'];
+                $expire_time = 1728000; //20天
+                Redis::set($token_key,$token);
+                Redis::expire($token_key, $expire_time);
+                return [true,$token];
+            }
+        }
+
+        return [true,$token];
+    }
 }

+ 117 - 0
app/Service/InOutOptionService.php

@@ -0,0 +1,117 @@
+<?php
+
+namespace App\Service;
+
+use App\Jobs\DoorDeviceJob;
+use Illuminate\Support\Facades\Redis;
+
+class InOutOptionService extends Service
+{
+    const OrderKeyQueueIn = 'InOrderNumber';
+    const OrderKeyQueueOut = 'OutOrderNumber';
+    const OrderKeyQueueInOut = 'InOutOrderNumber';
+    const Key = 'FHCK';
+
+    //通道门传来的数据  正常出入库 直接生成单据 (放入队列生成)
+    //发货出库数据 出库以后存到缓存 前端自取  发货出库会有可能这次不发了 所以也有入回来
+    public function setOrderNumber($data){
+        if(! empty($data['data']['tagList'])){
+            $in = $out = [];
+            $device_id = $data['data']['id'] ?? 0; //设备id
+            $site = $data['data']['devMark'] ?? ""; //站点
+            foreach ($data['data']['tagList'] as $value){
+                if($value['direction'] == '1'){
+                    //(判断到有发货出库的入库标识 存入缓存)
+                    if(Redis::exists($device_id . self::Key)){
+                        Redis::lpush($device_id . self::Key . self::OrderKeyQueueInOut, json_encode($value));
+                    }else{
+                        //入库 直接生成入库单
+                        if(! in_array($value['epc'],$in)) $in[] = $value['epc'];
+                    }
+                }elseif ($value['direction'] == '2'){
+                    //(判断到有发货出库的出库标识 存入缓存)
+                    if(Redis::exists($device_id . self::Key)){
+                        Redis::lpush($device_id . self::Key . self::OrderKeyQueueInOut, json_encode($value));
+                    }else{
+                        //出库 直接生成出库单
+                        if(! in_array($value['epc'],$out)) $out[] = $value['epc'];
+                    }
+                }
+            }
+            if(! empty($in)) dispatch(new DoorDeviceJob($in,1,$site,$device_id))->onQueue('door_device');
+            if(! empty($out)) dispatch(new DoorDeviceJob($out,2,$site,$device_id))->onQueue('door_device');
+        }
+    }
+
+    //获取单号 包括成功的出入库数据(生成单据成功 返回成功的包装单号)  和   发货出库(包装单号)
+    public function getOrderNumber($data,$site){
+        //获取某个站点的数据
+        $tmp = [];
+        $result = [];
+
+        //发货出库
+        $key = $data['device_id'] . self::Key . self::OrderKeyQueueInOut;
+        if(Redis::exists($key)) {
+            //发货
+            while ($item = Redis::lpop($key)) {
+                $order = json_decode($item, true);
+                $order_it = $order['epc'] . $order['direction'];
+                if(! in_array($order_it, $tmp)){
+                    $str = @hex2bin($order['epc']);
+                    $str = ltrim($str, "\x00");
+                    if(! empty($str) && substr($str, 0, 2) === "BZ"){
+                        $order['epc'] = $str;
+                        $order['site'] = $site;
+                        $result[] = $order;
+                    }
+                }
+            }
+
+            return [true, $result];
+        }
+
+        //入库
+        $key = $data['device_id'] . self::OrderKeyQueueIn;
+        $res = Redis::get($key);
+        if(! empty($res)){
+            $return  = json_decode($res,true);
+            foreach ($return as $value){
+                $result[] = [
+                    'epc' => $value,
+                    'direction' => '1',
+                ];
+            }
+            Redis::del($key);
+            return [true, $result];
+        }
+
+        //发货
+        $key = $data['device_id'] . self::OrderKeyQueueOut;
+        $res = Redis::get($key);
+        if(! empty($res)){
+            $return  = json_decode($res,true);
+            foreach ($return as $value){
+                $result[] = [
+                    'epc' => $value,
+                    'direction' => '2',
+                ];
+            }
+            Redis::del($key);
+            return [true, $result];
+        }
+
+        return [true, $result];
+    }
+
+    //设置通道门是 正常出入库 还是  发货出库
+    public function setFhMessage($data,$site){
+        $key = $data['device_id'] . self::Key;
+        if(empty($data['fh'])){
+            //通道门处在出入库屏 删除通道门在发货出库屏下的标识(如果存在)
+            if(Redis::exists($key)) Redis::del($key);
+        }else{
+            //通道门处在发货出库屏 设置55秒过期  前端50秒请求一次 更新标识时间
+            if (Redis::setnx($key, 1)) Redis::expire($key, 55); //多少秒后过期
+        }
+    }
+}

+ 7 - 0
routes/api.php

@@ -21,6 +21,12 @@ Route::any('login', 'Api\LoginController@login');
 Route::any('job', 'Api\JobController@processDataJobAdd');
 Route::any('job_device', 'Api\JobController@processDataJobAddDevice');
 Route::any('man_device', 'Api\JobController@processDataJobAddDeviceMan');
+//通道门传输的数据保存单号
+Route::any('setOrderNumber', 'Api\InOutOptionController@setOrderNumber');
+//获取单号
+Route::any('getOrderNumber', 'Api\InOutOptionController@getOrderNumber');
+//设置发货出库标识
+Route::any('setFhMessage', 'Api\InOutOptionController@setFhMessage');
 Route::any('del', 'Api\JobController@delKey');
 Route::any('oee', 'Api\ScreenController@oee');
 Route::any('wyOee', 'Api\ScreenController@wyOee');
@@ -33,6 +39,7 @@ Route::any('inout', 'Api\ScreenController@inout');
 Route::any('upInout', 'Api\ScreenController@upInout');
 Route::any('gzEchart', 'Api\ScreenController@gzEchart');
 Route::any('t', 'Api\ScreenController@t');
+Route::any('deviceCallback', 'Api\TestController@deviceCallback');
 
 Route::group(['middleware'=> []],function ($route){
     $route->any('menuAdd', 'Api\SysMenuController@add');