CacheShelfTaskJob.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. <?php
  2. namespace App\Jobs;
  3. use App\Components\ErrorPush;
  4. use App\Services\ForeignHaiRoboticsService;
  5. use App\Station;
  6. use App\StationTaskMaterialBox;
  7. use App\TaskTransaction;
  8. use Illuminate\Bus\Queueable;
  9. use Illuminate\Contracts\Queue\ShouldQueue;
  10. use Illuminate\Foundation\Bus\Dispatchable;
  11. use Illuminate\Queue\InteractsWithQueue;
  12. use Illuminate\Support\Collection;
  13. use Illuminate\Support\Facades\Cache;
  14. use Illuminate\Support\Facades\DB;
  15. class CacheShelfTaskJob implements ShouldQueue
  16. {
  17. use Dispatchable, InteractsWithQueue, Queueable, ErrorPush;
  18. protected $key;
  19. protected $count;
  20. /**
  21. * Create a new job instance.
  22. *
  23. * @return void
  24. */
  25. public function __construct(string $key,int $count)
  26. {
  27. $this->count = $count;
  28. $this->key = $key;
  29. }
  30. /**
  31. * Execute the job.
  32. *
  33. * @return void
  34. * @throws
  35. */
  36. public function handle()
  37. {
  38. /** @var ForeignHaiRoboticsService $service */
  39. $service = app("ForeignHaiRoboticsService");
  40. switch ($this->key){
  41. case "CACHE_SHELF_AVAILABLE"://出库呼叫
  42. DB::beginTransaction();
  43. try {
  44. $available = Cache::get($this->key,function (){return [];});
  45. if ($this->count!==count($available))return;
  46. $tasks = TaskTransaction::query()->selectRaw("task_id,GROUP_CONCAT(id) AS ids,id")->with("task")
  47. ->where("type","出库")->whereHas("task",function ($query){
  48. $query->where("status","待处理");
  49. })->where("status",3)->lockForUpdate()
  50. ->where("mark",2)->groupBy("task_id")->get(); //检索等待的队列事务来获取对应任务
  51. if (!$tasks->count())return;
  52. $tasks = $tasks->where("task.station_task_batch_id",$tasks[0]->task->station_task_batch_id);//仅处理同波次
  53. if ($tasks->count()>count($available))$tasks = $tasks->slice(0,count($available));//事务过多切割部分处理
  54. $toLocation = collect();
  55. $task = collect();
  56. $availableTemp = array_keys($available);
  57. $map = app("StationService")->getStationMapping($availableTemp);//获取库位映射信息
  58. $updateTask = [["id","station_id","updated_at"]];
  59. $updateTransaction = [["id","to_station_id","status","updated_at"]];
  60. $time = date("Y-m-d H:i:s");
  61. foreach ($tasks as $index=>$obj){
  62. $loc = $availableTemp[$index];
  63. $toLocation->push($loc);
  64. $obj->task->station_id = $map[$loc];
  65. $task->push($obj->task);
  66. unset($available[$loc]);
  67. $updateTask[] = ["id"=>$obj->task->id,"station_id"=>$map[$loc],"updated_at"=>$time];
  68. if ($obj->ids!=$obj->id){
  69. $ids = explode(",",$obj->ids);
  70. foreach ($ids as $id)$updateTransaction[] = ["id"=>$id,"to_station_id"=>$map[$loc],"status"=>0,"updated_at"=>$time];
  71. }else $updateTransaction[] = ["id"=>$obj->id,"to_station_id"=>$map[$loc],"status"=>0,"updated_at"=>$time];
  72. }
  73. app("BatchUpdateService")->batchUpdate("station_task_material_boxes",$updateTask);
  74. app("BatchUpdateService")->batchUpdate("task_transactions",$updateTransaction);
  75. $result = $service->fetchGroup_multiLocation($toLocation,$task,$tasks[0]->station_task_batch_id,'立架出至缓存架',20);
  76. if ($result){
  77. Cache::forever($this->key,$available);
  78. foreach ($toLocation as $value){
  79. app("CacheShelfService")->lightUp($value,'3','0');
  80. Cache::forever("CACHE_SHELF_OCCUPANCY_{$map[$value]}",true);
  81. }
  82. app("StationService")->locationOccupyMulti($toLocation->toArray());
  83. DB::commit();
  84. }else{
  85. DB::rollBack();
  86. $this->push(__METHOD__."->".__LINE__,"出库队列执行失败","库位信息:".json_encode($toLocation)." 任务信息:".json_encode($task));
  87. }
  88. }catch (\Exception $e){
  89. DB::rollBack();
  90. $this->push(__METHOD__."->".__LINE__,"出库队列执行错误",$e->getMessage()." | 当前任务数:".$this->count." | 缓存信息:".(isset($available) ? json_encode($available) : ''));
  91. }
  92. break;
  93. default://入库呼叫
  94. if (!Cache::has($this->key))return;
  95. /** @var Collection $task */
  96. list($task,$location) = Cache::get($this->key);
  97. if ($this->count!==$task->count())return;
  98. $dataToPost = $service->makeJson_move_multi($task, '缓存架入立架', $location);
  99. $controlSuccess = $service->controlHaiRobot($dataToPost,$task,'缓存架入立架');
  100. $tIds = [];
  101. $task->each(function ($t)use(&$tIds){$tIds[] = $t->id;});
  102. StationTaskMaterialBox::query()->where("id",$tIds)
  103. ->where("status","待处理")->update(['status' => $controlSuccess ? '处理中' : '异常']);
  104. Cache::forget($this->key);
  105. if ($controlSuccess)$this->materialBoxMappingCacheShelf($task,$location);
  106. }
  107. }
  108. /**
  109. * 料箱映射缓存架,因为建立的入立架任务源库位是立库,无法获取真实源库位,所以在此拿到映射库位
  110. * 在料箱被取走时通过任务料箱号获取对应库位,来标记该缓存架库位可以被执行任务了 StationTaskMaterialBoxService:markHasTaken
  111. * 出库会启用库位占用逻辑 入库分为:人工入库与系统自动入库 人工控制入库由人工自己辨识库位可用度,而系统入库只能通过此映射来拿到可用库位信息
  112. *
  113. * @param Collection $task
  114. * @param Collection $location
  115. *
  116. * @return void
  117. */
  118. public function materialBoxMappingCacheShelf(Collection $task,Collection $location)
  119. {
  120. $map = Cache::get("CACHE_SHELF_MAPPING",function (){return [];});
  121. foreach ($task as $key=>$obj)$map[$obj->material_box_id] = $location[$key];
  122. Cache::forever("CACHE_SHELF_MAPPING",$map);
  123. }
  124. }