Zhouzhendong 4 лет назад
Родитель
Сommit
4edc5d5f5c

+ 0 - 1
app/Http/Controllers/StorageController.php

@@ -183,7 +183,6 @@ sql;
         $result = app("ForeignHaiRoboticsService")->paddingCacheShelf(Station::query()->whereIn("code",$boxes)->get());
         if ($result===null)$this->error("任务下发错误,检查日志");
         if ($result===false)$this->error("已无可用料箱,部分库位填充失败");
-        app("StationService")->locationOccupyMulti($boxes);
         $this->success(["data"=>$data,"boxes"=>$boxes]);
     }
 

+ 61 - 3
app/Http/Controllers/TestController.php

@@ -88,9 +88,67 @@ class TestController extends Controller
 
     public function test()
     {
-        $a = new StorageService();
-        $b = Station::query()->where("station_type_id",5)->whereNotNull("parent_id")->get();
-        $a->clearTask(array_column($b->toArray(),"code"));
+        $code1 = "";
+        $code2 = "";
+        Station::query()->where("station_type_id",5)->whereNotNull("parent_id")
+            ->where("id","!=",11)->update(["status"=>1]);
+        Cache::forget("CACHE_SHELF_AVAILABLE");
+        Cache::forget("CACHE_SHELF_MAPPING");
+
+        $dateTime = date("Y-m-d H:i:s");
+        $materialBox1 = MaterialBox::query()->where("code",$code1)->first();
+        $materialBox2 = MaterialBox::query()->where("code",$code2)->first();
+        $task1 = StationTaskMaterialBox::query()->create([
+            'station_id'=>11,
+            'material_box_id'=>$materialBox1->id,
+            'station_task_batch_id'=>1,
+            'status'=>'待处理'
+        ]);
+        $task2=StationTaskMaterialBox::query()->create([
+            'station_id'=>6,
+            'material_box_id'=>$materialBox2->id,
+            'station_task_batch_id'=>1,
+            'status'=>'待处理'
+        ]);
+        TaskTransaction::query()->insert([[
+            "doc_code" => "test",
+            "bar_code" => "test",
+            "to_station_id" => 11,
+            "material_box_id" => $materialBox1->id,
+            "task_id" => $task1->id,
+            "commodity_id" => 505012,//XUNI03
+            "amount" => 1,
+            "type" => "出库",
+            "status" => 0,
+            "mark" => 2,
+            "bin_number"=>1,
+            "created_at"=>$dateTime,
+            "updated_at"=>$dateTime,
+        ],[
+            "doc_code" => "test",
+            "bar_code" => "test",
+            "to_station_id" => 6,
+            "material_box_id" => $materialBox2->id,
+            "task_id" => $task2->id,
+            "commodity_id" => 505012,//XUNI03
+            "amount" => 1,
+            "type" => "出库",
+            "status" => 3,
+            "mark" => 2,
+            "bin_number"=>1,
+            "created_at"=>$dateTime,
+            "updated_at"=>$dateTime,
+        ]]);
+        $foreignHaiRoboticsService = new ForeignHaiRoboticsService();
+        $toLocation = collect(["HAIB1-01-01"]);
+        $taskMaterialBoxes = collect([$task1]);
+        $foreignHaiRoboticsService->
+        fetchGroup_multiLocation($toLocation, $taskMaterialBoxes, '', '立架出至缓存架',20);
+        foreach ($toLocation as $value){
+            app("CacheShelfService")->lightUp($value,'3','0',["title"=>"机器人取箱中,禁止操作"]);
+            Cache::forever("CACHE_SHELF_OCCUPANCY_11",true);
+        }
+        app("StationService")->locationOccupyMulti($toLocation->toArray());
     }
     public function _stationCacheLightOff($locCode)
     {

+ 34 - 26
app/Jobs/CacheShelfTaskJob.php

@@ -46,11 +46,15 @@ class CacheShelfTaskJob implements ShouldQueue
         switch ($this->key){
             case "CACHE_SHELF_AVAILABLE"://缓存架释放呼叫
                 //等待一定时间来合并同类请求至此
-                $available = Cache::get($this->key,function (){return [];});
-                if ($this->count!==count($available))return;
+                $available = Cache::get($this->key,0);
+                if ($this->count!==$available)return;
+                Cache::forget($this->key); //无论是否开始分发 都清除本次缓存架的计数器
+                //获取可用缓存架
+                $stations = app("StationService")->getCacheShelf(true);
+                if ($stations->count()==0)break;
                 //检查事务 尝试分发任务 改变下方序列来控制分发顺序 逐级分发 一次成功就终止
-                if ($this->dispatchOutTask($available,$service))break; //首先尝试向出库事务分发 分发成功跳出
-                if ($this->dispatchInTask($available,$service))break;  //尝试向入库事务分发
+                if ($this->dispatchOutTask($stations,$service))break; //首先尝试向出库事务分发 分发成功跳出
+                if ($this->dispatchInTask($stations,$service))break;  //尝试向入库事务分发
                 break;
             default://入库呼叫
                 if (!Cache::has($this->key))return;
@@ -61,10 +65,10 @@ class CacheShelfTaskJob implements ShouldQueue
                 $controlSuccess = $service->controlHaiRobot($dataToPost,$task,'缓存架入立架');
                 $tIds = [];
                 $task->each(function ($t)use(&$tIds){$tIds[] = $t->id;});
-                StationTaskMaterialBox::query()->where("id",$tIds)
+                StationTaskMaterialBox::query()->whereIn("id",$tIds)
                     ->where("status","待处理")->update(['status' => $controlSuccess ? '处理中' : '异常']);
                 Cache::forget($this->key);
-                if ($controlSuccess)$this->materialBoxMappingCacheShelf($task,$location);
+                //if ($controlSuccess)$this->materialBoxMappingCacheShelf($task,$location);
         }
     }
 
@@ -88,11 +92,11 @@ class CacheShelfTaskJob implements ShouldQueue
     /**
      * 分发出库任务
      *
-     * @param array $available
+     * @param $stations
      * @param $service
      * @return bool
      */
-    private function dispatchOutTask(array $available, $service):bool
+    private function dispatchOutTask(&$stations,$service):bool
     {
         DB::beginTransaction();
         try {
@@ -101,14 +105,14 @@ class CacheShelfTaskJob implements ShouldQueue
                     $query->where("status","待处理");
                 })->where("status",3)->lockForUpdate()
                 ->where("mark",2)->groupBy("task_id")->get(); //检索等待的队列事务来获取对应任务
-            if ($this->dispatchTask($tasks,$available,$service,function ($obj,$stationId,$time,&$updateTransaction){
+            if ($this->dispatchTask($tasks,$stations,$service,function ($obj,$stationId,$time,&$updateTransaction){
                 if ($obj->ids!=$obj->id){
                     $ids = explode(",",$obj->ids);
                     foreach ($ids as $id)$updateTransaction[] = ["id"=>$id,"to_station_id"=>$stationId,"status"=>0,"updated_at"=>$time];
                 }else $updateTransaction[] = ["id"=>$obj->id,"to_station_id"=>$stationId,"status"=>0,"updated_at"=>$time];
             },function ($service,$toLocation,$task,$prefix){
                 return $service->fetchGroup_multiLocation($toLocation,$task,$prefix,'立架出至缓存架',20);
-            },"to_station_id")){DB::commit();return true;}
+            },"to_station_id")){DB::commit();return $stations->count()==0;} //缓存架用完 跳出,否则接着分发
             DB::rollBack();
         }catch (\Exception $e){
             DB::rollBack();
@@ -120,11 +124,11 @@ class CacheShelfTaskJob implements ShouldQueue
     /**
      * 分发入库任务
      *
-     * @param array $available
+     * @param $stations
      * @param $service
      * @return bool
      */
-    private function dispatchInTask(array $available, $service):bool
+    private function dispatchInTask(&$stations,$service):bool
     {
         DB::beginTransaction();
         try {
@@ -133,11 +137,14 @@ class CacheShelfTaskJob implements ShouldQueue
                     $query->where("status","待处理");
                 })->where("status",3)->lockForUpdate()
                 ->where("mark",1)->get(); //检索等待的队列事务来获取对应任务
-            if ($this->dispatchTask($tasks,$available,$service,function ($obj,$stationId,$time,&$updateTransaction){
+            if (!$tasks->count())return false;
+            if ($this->dispatchTask($tasks,$stations,$service,function ($obj,$stationId,$time,&$updateTransaction){
                 $updateTransaction[] = ["id"=>$obj->id,"fm_station_id"=>$stationId,"status"=>0,"updated_at"=>$time];
             },function ($service,$toLocation,$task,$prefix){
                 return $service->fetchGroup_multiLocation($toLocation,$task,'','立架出至缓存架');
-            },"fm_station_id")){DB::commit();return true;}
+            },"fm_station_id")){
+                DB::commit();return $stations->count()==0; //缓存架用完 跳出,否则接着分发
+            }
             DB::rollBack();
         }catch (\Exception $e){
             DB::rollBack();
@@ -146,31 +153,32 @@ class CacheShelfTaskJob implements ShouldQueue
         return false;
     }
 
-    private function dispatchTask(\Illuminate\Database\Eloquent\Collection $tasks, array $available, $service,
+    private function dispatchTask(\Illuminate\Database\Eloquent\Collection $tasks,&$stations, $service,
                                   \Closure $update, \Closure $execute, string $stationName):bool
     {
-        if (!$tasks->count())return false;
-        if ($tasks->count()>count($available))$tasks = $tasks->slice(0,count($available));//事务过多切割部分处理
+        $locations = $stations;
+        if ($tasks->count()>$locations->count())$tasks = $tasks->slice(0,$locations->count());//事务过多切割部分处理
+        if ($tasks->count()<$locations->count()){
+            $stations = $stations->slice($tasks->count());
+            $stations = $stations->values($stations);
+        }
         $toLocation = collect();
         $task = collect();
-        $availableTemp = array_keys($available);
-        $map = app("StationService")->getStationMapping($availableTemp);//获取库位映射信息
         $updateTask = [["id","station_id","updated_at"]];
         $updateTransaction = [["id",$stationName,"status","updated_at"]];
         $time = date("Y-m-d H:i:s");
+        $map = [];
         foreach ($tasks as $index=>$obj){
-            $loc = $availableTemp[$index];
-            $toLocation->push($loc);
-            $obj->task->station_id = $map[$loc];
+            $toLocation->push($stations[$index]->code);
+            $map[$stations[$index]->code] = $stations[$index]->id;
+            $obj->task->station_id = $stations[$index]->id;
             $task->push($obj->task);
-            unset($available[$loc]);
-            $updateTask[] = ["id"=>$obj->task->id,"station_id"=>$map[$loc],"updated_at"=>$time];
-            $update($obj,$map[$loc],$time,$updateTransaction);
+            $updateTask[] = ["id"=>$obj->task->id,"station_id"=>$stations[$index]->id,"updated_at"=>$time];
+            $update($obj,$stations[$index]->id,$time,$updateTransaction);
         }
         app("BatchUpdateService")->batchUpdate("station_task_material_boxes",$updateTask);
         app("BatchUpdateService")->batchUpdate("task_transactions",$updateTransaction);
         if ($execute($service,$toLocation,$task,$tasks[0]->station_task_batch_id)){
-            Cache::forever($this->key,$available);
             foreach ($toLocation as $value){
                 app("CacheShelfService")->lightUp($value,'3','0',["title"=>"机器人取箱中,禁止操作"]);
                 Cache::forever("CACHE_SHELF_OCCUPANCY_{$map[$value]}",true);

+ 14 - 0
app/Services/CacheShelfService.php

@@ -4,6 +4,7 @@ namespace App\Services;
 
 use App\Events\BroadcastToStation;
 use App\Exceptions\ErrorException;
+use App\Jobs\CacheShelfTaskJob;
 use App\Station;
 use App\StationTaskMaterialBox;
 use App\Traits\ServiceAppAop;
@@ -202,4 +203,17 @@ class   CacheShelfService
 
         return ['success' => true];
     }
+
+    /**
+     * 料箱被取走
+     *
+     * @param Station|\stdClass $station
+     */
+    public function boxHasBeenTaken($station)
+    {
+        app("StationService")->locationFreed($station); //释放库位,解除绑定料箱
+        $available=Cache::get("CACHE_SHELF_AVAILABLE",0)+1;//获取可用缓存架数量 plus当前
+        Cache::forever("CACHE_SHELF_AVAILABLE",$available);
+        CacheShelfTaskJob::dispatch("CACHE_SHELF_AVAILABLE",$available)->delay(now()->addSeconds(config("haiRou.cacheShelf.outBinAwait")));
+    }
 }

+ 4 - 0
app/Services/ForeignHaiRoboticsService.php

@@ -496,6 +496,10 @@ class ForeignHaiRoboticsService
         }
         if ($stationCollection->count()>0){
             if (!$this->fetchGroup_multiLocation($stationCollection,$collection,'','立架出至缓存架')) return null;
+            app("StationService")->locationOccupyMulti($stationCollection->toArray());
+            $stationCollection->each(function ($code){
+                app("CacheShelfService")->lightUp($code,'3','0',["title"=>"机器人取箱中,禁止操作"]);
+            });
         }
         return $stations->count()==$stationCollection->count();
     }

+ 1 - 2
app/Services/StationService.php

@@ -199,8 +199,7 @@ class StationService
     public function locationFreed(?string $location, ?int $boxId=null):int
     {
         if (!$location)return 0;
-        $update = ["status"=>0];
-        if ($boxId)$update["material_box_id"]=$boxId;
+        $update = ["status"=>0,"material_box_id"=>$boxId];
         return Station::query()->where("code",$location)->update($update);
     }
 

+ 2 - 2
app/Services/StationTaskBatchService.php

@@ -136,7 +136,7 @@ class StationTaskBatchService
      * @return Collection|\Tightenco\Collect\Support\Collection|null 返回执行失败的记录
      * @throws ErrorException
      */
-    function runMany(?Collection $stationTaskBatches, $locationType = 'OUTBIN-U-SHAPE-LINE'):?Collection
+    function runMany(?Collection $stationTaskBatches,string $locationType = 'OUTBIN-U-SHAPE-LINE'):?Collection
     {
         LogService::log(__METHOD__,'runMany','波次任务分配6.1:'.json_encode($stationTaskBatches));
         $stationTaskBatches_failed = null;
@@ -171,7 +171,7 @@ class StationTaskBatchService
      * @return bool
      * @throws ErrorException
      */
-    function run(StationTaskBatch $stationTaskBatch, $locationType): bool
+    function run(StationTaskBatch $stationTaskBatch,string $locationType): bool
     {
         $this->instant($this->foreignHaiRoboticsService,'ForeignHaiRoboticsService');
         $this->instant($this->stationService,'StationService');

+ 13 - 4
app/Services/StationTaskMaterialBoxService.php

@@ -5,10 +5,12 @@ namespace App\Services;
 
 
 use App\Batch;
+use App\Components\ErrorPush;
 use App\Exceptions\ErrorException;
 use App\Jobs\CacheShelfTaskJob;
 use App\MaterialBox;
 use App\OrderCommodity;
+use App\Station;
 use App\StationTask;
 use App\StationTaskMaterialBox;
 use Carbon\Carbon;
@@ -20,7 +22,7 @@ use Illuminate\Support\Facades\DB;
 
 class StationTaskMaterialBoxService
 {
-    use ServiceAppAop;
+    use ServiceAppAop,ErrorPush;
     protected $modelClass=StationTaskMaterialBox::class;
     /** @var StationService $stationService */
     private $stationService;
@@ -209,9 +211,16 @@ class StationTaskMaterialBoxService
      */
     function markHasTaken($stationTaskMaterialBox)
     {
-        $stationTaskMaterialBox->loadMissing("station");
         $this->instant($this->cacheShelfService,'CacheShelfService');
-        //维护缓存架可用度
+        //$stationTaskMaterialBox->loadMissing("station");
+        $this->push("1","取出料箱通知","任务信息:".$stationTaskMaterialBox->toJson());
+
+        //判断取出料箱是否是在缓存架
+        $station = Station::query()->where("material_box_id",$stationTaskMaterialBox->material_box_id)
+            ->first();
+        if ($station && app("StationService")->isHalfBoxLocation($station))
+            app("CacheShelfService")->boxHasBeenTaken($station);
+        /*//维护缓存架可用度
         $map = Cache::get("CACHE_SHELF_MAPPING",function (){return [];});
         if (isset($map[$stationTaskMaterialBox->material_box_id])){
             $available=Cache::get("CACHE_SHELF_AVAILABLE",function (){return [];});
@@ -220,7 +229,7 @@ class StationTaskMaterialBoxService
             CacheShelfTaskJob::dispatch("CACHE_SHELF_AVAILABLE",count($available))->delay(now()->addSeconds(config("haiRou.cacheShelf.outBinAwait")));
             unset($map[$stationTaskMaterialBox->material_box_id]);
             Cache::forever("CACHE_SHELF_MAPPING",$map);
-        }
+        }*/
     }
 
     function processNextQueued(?StationTaskMaterialBox $stationTaskMaterialBox_lastProcessed){

+ 6 - 4
app/Services/StorageService.php

@@ -36,10 +36,8 @@ class StorageService
         DB::beginTransaction();
         try{
             $stationTaskMaterialBox->loadMissing("station");
-            //如果为半箱位置 清理原有任务
             if (!$stationTaskMaterialBox->station)return;
             if (app("StationService")->isHalfBoxLocation($stationTaskMaterialBox->station)){
-                app("StationService")->locationOccupy($stationTaskMaterialBox->station->code,$stationTaskMaterialBox->material_box_id);
                 //清除海柔库位信息
                 $this->clearTask([$stationTaskMaterialBox->station->code]);
                 $stationId = $stationTaskMaterialBox->station_id;
@@ -95,9 +93,13 @@ class StorageService
                             }
                             break;
                     }
-                    app("CacheShelfService")->lightUp($stationTaskMaterialBox->station->code,'2','0',$options);
                     Cache::forget("CACHE_SHELF_OCCUPANCY_{$stationTaskMaterialBox->station->id}");//关闭无限亮灯
-                }else app("StationService")->locationFreed($stationTaskMaterialBox->station->code); //释放库位占用
+                    app("StationService")->locationOccupy($stationTaskMaterialBox->station->code,$stationTaskMaterialBox->material_box_id);//料箱绑定缓存架
+                    app("CacheShelfService")->lightUp($stationTaskMaterialBox->station->code,'2','0',$options);
+                }else{
+                    app("StationService")->locationFreed($stationTaskMaterialBox->station->code); //释放库位占用
+                    app("CacheShelfService")->_stationCacheLightOff($stationTaskMaterialBox->station->code);//灭灯
+                }
             }
             DB::commit();
         }catch (\Exception $e){

+ 1 - 6
app/Station.php

@@ -23,8 +23,8 @@ class Station extends Model
      * CACHE_SHELF_OCCUPANCY_{ID}   //bool:缓存架占用标记,开启此标记后连续排灯无效
      * CACHE_SHELF_MAPPING          //array(map):缓存架映射标记,用来映射入库任务的真实库位 CacheShelfTaskJob:materialBoxMappingCacheShelf详细描述此流程
      * CACHE_SHELF_AVAILABLE        //array(map):缓存架可用标记,映射缓存架是否可以被下达出库任务
+     * CACHE_SHELF_AVAILABLE        //array(map):缓存架可用计数器,来标识这个已取出箱子的缓存架数量,这个标识用来判定缓存架一定时间内是否仍然被操作,如果缓存架停止操作则开启处理
      * */
-
     public function task()
     {
         return $this->hasOne(StationTaskMaterialBox::class,"station_id","id");
@@ -67,9 +67,4 @@ class Station extends Model
             ->where('status','=','待处理');
     }
 
-    public function storage(): HasOne
-    {
-        return $this->hasOne(Storage::class);
-    }
-
 }