CacheShelfService.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. <?php
  2. namespace App\Services;
  3. use App\Events\BroadcastToStation;
  4. use App\Exceptions\ErrorException;
  5. use App\MaterialBox;
  6. use App\Station;
  7. use App\StationTask;
  8. use App\StationTaskChildren;
  9. use App\StationTaskMaterialBox;
  10. use App\StationType;
  11. use App\Traits\ServiceAppAop;
  12. use Illuminate\Http\Request;
  13. use Illuminate\Support\Facades\Http;
  14. use Illuminate\Database\Eloquent\Builder;
  15. use Illuminate\Database\Eloquent\Collection;
  16. class CacheShelfService
  17. {
  18. use ServiceAppAop;
  19. protected $modelClass = Station::class;
  20. /** @var StationService $stationService */
  21. private $stationService;
  22. /** @var StationTaskMaterialBoxService $stationTaskMaterialBoxService */
  23. private $stationTaskMaterialBoxService;
  24. /** @var ForeignHaiRoboticsService $foreignHaiRoboticsService */
  25. private $foreignHaiRoboticsService;
  26. /** @var StationTaskService $stationTaskService */
  27. private $stationTaskService;
  28. /** @var StationTaskChildService $stationTaskChildService */
  29. private $stationTaskChildService;
  30. /**
  31. * 获取缓存架上子货架当前任务
  32. * @param $id
  33. * @return Builder[]|Collection
  34. */
  35. public function getChildStation($id)
  36. {
  37. return Station::query()->where('parent_id',$id)->with('parent','pendingStationTask.stationTaskMaterialBoxes.materialBox')->get();
  38. }
  39. /**
  40. * 拍灯触发任务
  41. * @param $locCode
  42. * @param $PTLAction
  43. * @return array|bool[]
  44. */
  45. public function lightOffTask($locCode, $PTLAction): array
  46. {
  47. $station = Station::query()->with('pendingStationTask.stationTaskMaterialBoxes.materialBox')->where('code', $locCode)->first();
  48. if (!app("StorageService")->checkStorage($station)){
  49. $this->stationLightUp($station->code,null,'0','1','上架任务失败');
  50. return ['success' => false,'errMsg' => '上架任务失败'];
  51. };
  52. try {
  53. $bool = $this->putBinToStore($station); // 推送任务
  54. if($bool){
  55. LogService::log(__CLASS__,'lightOffTask','code' .' true'. $locCode.json_encode($station));
  56. return ['success' => true];
  57. }else{
  58. return ['success' => false,'errMsg' => '机器人推送失败'];
  59. }
  60. } catch (ErrorException $e) {
  61. LogService::log(__FUNCTION__,'缓存架推送任务失败',json_encode($e->getMessage()));
  62. return ['success' => false,'errMsg' => $e->getMessage()];
  63. }
  64. }
  65. /**
  66. * 推任务至海柔机器人
  67. * @param $station
  68. * @return bool
  69. * @throws ErrorException
  70. */
  71. public function putBinToStore($station): bool
  72. {
  73. $this->instant($this->stationTaskMaterialBoxService, 'StationTaskMaterialBoxService');
  74. $this->instant($this->foreignHaiRoboticsService, 'ForeignHaiRoboticsService');
  75. $this->instant($this->stationService, 'StationService');
  76. $this->instant($this->stationTaskService, 'StationTaskService');
  77. $this->instant($this->stationTaskChildService, 'StationTaskChildService');
  78. /** @var StationTaskMaterialBox $takeStationTaskMaterialBox */
  79. $takeStationTaskMaterialBox = $station['pendingStationTask']['stationTaskMaterialBoxes']->first();
  80. $formStation = $this->stationService->getStation_byType('立库');
  81. // 查询是否有待处理的入库任务
  82. $putStationTaskMaterialBox = StationTaskMaterialBox::query()->where([
  83. 'station_id' => $formStation['id'],
  84. 'material_box_id' => $takeStationTaskMaterialBox['material_box_id'],
  85. 'status' => '待处理',
  86. ])->first();
  87. // 创建入立库任务
  88. if(!$putStationTaskMaterialBox){
  89. $stationTask = $this->stationTaskService->create(1); // 生成站任务
  90. $this->stationTaskService->registerStations($stationTask,[$formStation['id']]); // 注册站任务站
  91. /** @var StationTaskMaterialBox $putStationTaskMaterialBox */
  92. $putStationTaskMaterialBox = $this->stationTaskMaterialBoxService->create([
  93. 'station_id' => $formStation['id'],
  94. 'material_box_id' => $takeStationTaskMaterialBox['material_box_id'],
  95. 'status' => '待处理',
  96. ]);
  97. $putStationTaskMaterialBox['station_task_id'] = $stationTask->first()['id'];
  98. $putStationTaskMaterialBox['type'] = '放';
  99. $putStationTaskMaterialBox->update();
  100. $params = [[
  101. 'station_task_id'=>$stationTask->first()['id'],
  102. 'station_taskable_type'=>StationTaskMaterialBox::class,
  103. 'station_taskable_id'=>$putStationTaskMaterialBox['id']
  104. ]];
  105. $this->stationTaskChildService->insert($params); // 任务任务注册
  106. }
  107. // 推立库任务
  108. $isSuccess = $this->foreignHaiRoboticsService->putBinToStore_fromCacheShelf($putStationTaskMaterialBox,$station['code']);
  109. if($isSuccess) $this->stationTaskMaterialBoxService->set($takeStationTaskMaterialBox,['status' => '处理中']); // 任务推送成功 标记站任务为处理中
  110. else {
  111. $materialBoxCode = $station['pendingStationTask']['stationTaskMaterialBoxes']->first()->code ?? '';
  112. $this->_stationCacheBroadCast($station->code,0,'error');
  113. $this->_stationCacheLightOn($station->code,$materialBoxCode,'拍灯重试任务');
  114. }
  115. return $isSuccess;
  116. }
  117. /**
  118. * 创建站任务和料箱任务
  119. * @param $stationCode
  120. * @param $materialBoxCode
  121. * @return array
  122. */
  123. public function createStationTask($stationCode,$materialBoxCode): array
  124. {
  125. $this->instant($this->stationTaskService, 'StationTaskService');
  126. $this->instant($this->stationTaskMaterialBoxService,'StationTaskMaterialBoxService');
  127. $this->instant($this->stationTaskChildService,'StationTaskChildService');
  128. $station = Station::query()->where('code' , $stationCode)->first();
  129. if(!$station){
  130. $arr = [];
  131. preg_match('/^HAI([\w]+)/',$stationCode,$arr);
  132. $parentCode = $arr[1] ?? '';
  133. $stationType = StationType::query()->where('name','缓存架')->first();
  134. $parentStation = Station::query()->firstOrCreate(['code'=>$parentCode],['station_type_id'=>$stationType['id']]);
  135. $station = Station::query()->firstOrCreate(['code' => $stationCode,'parent_id'=>$parentStation['id']],['name'=>$stationCode,'station_type_id' => $stationType['id']]);
  136. }
  137. $materialBox = MaterialBox::query()->firstOrCreate(['code' => $materialBoxCode]);
  138. $station->load('pendingStationTask.stationTaskMaterialBoxes.materialBox');
  139. if($station->pendingStationTask){
  140. if($station['pendingStationTask']['stationTaskMaterialBoxes']->first()->materialBox->code == $materialBoxCode){
  141. $response = $this->_stationCacheLightOn($stationCode,$materialBoxCode,'任务重试');
  142. if($response->code) return ['success'=>true,'message' => '任务重试'];
  143. return ['success'=>true,'message' => '任务重试失败'];
  144. }
  145. return ['success' => false,'message' => '当前已有进行重的任务'];
  146. }
  147. $stationTask = $this->stationTaskService->create(1); // 生成站任务
  148. $stationTaskMaterialBox = $this->stationTaskMaterialBoxService->createByStationAndMaterialBox($station,$materialBox); // 创建料箱任务
  149. $this->stationTaskService->registerStations($stationTask,[$station['id']]); // 注册站任务站
  150. $stationTaskMaterialBox['station_task_id'] = $stationTask->first()['id'];
  151. $stationTaskMaterialBox->update();
  152. $params = [[
  153. 'station_task_id'=>$stationTask->first()['id'],
  154. 'station_taskable_type'=>StationTaskMaterialBox::class,
  155. 'station_taskable_id'=>$stationTaskMaterialBox['id']
  156. ]];
  157. $this->stationTaskChildService->insert($params); // 任务任务注册
  158. $body = $this->_stationCacheLightOn($stationCode,$materialBoxCode);
  159. if($body->code == 200)return ['success'=>true];
  160. return ['success' => false,'message' => '机器人亮灯异常'];
  161. }
  162. /**
  163. * 控制格口亮灯
  164. * @param $locCode
  165. * @param null $materialCode
  166. * @param string $title
  167. * @param string $color
  168. * @return mixed
  169. */
  170. public function _stationCacheLightOn($locCode,$materialCode = null,$title = 'title' ,string $color = '1')
  171. {
  172. $params = [
  173. "areaCode" => "1004",
  174. 'locCode' => $locCode,
  175. 'PTLAction' => 1,
  176. 'PTLSettings' => ['color'=> $color, 'frequency' =>1],
  177. "displayInfo" => [
  178. "detail01" => $materialCode,
  179. "detail02" => "detail02",
  180. "detail03" => "detail03",
  181. "qrCode" => "qrCode",
  182. "qty00" => "11",
  183. "qty01" => 1,
  184. "qty02" => 2,
  185. "title" => $title,
  186. "uomDesc01" => "uo",
  187. "uomDesc02" => "uo"
  188. ],
  189. ];
  190. $response = Http::post(config('api.haiq.storage.light'), $params);
  191. return json_decode($response->body());
  192. }
  193. /**
  194. * 站亮灯
  195. *
  196. * @param string $stationCode
  197. * @param string|null $materialCode
  198. * @param string $color explain: 0-red 1-green 2-blue 3-yellow
  199. * @param string $frequency explain: 0-常亮 1-一次 2-两次 3-三次 4-四次 5-五次 (均为/秒)
  200. * @param string $title
  201. * @return mixed
  202. */
  203. public function stationLightUp(string $stationCode,?string $materialCode = null, string $color = '1', string $frequency = '0', $title = '')
  204. {
  205. $params = [
  206. "areaCode" => "1004",
  207. 'locCode' => $stationCode,
  208. 'PTLAction' => 1,
  209. 'PTLSettings' => ['color' => $color, 'frequency' => $frequency],
  210. "displayInfo" => [
  211. "detail01" => $materialCode,
  212. "detail02" => "detail02",
  213. "detail03" => "detail03",
  214. "qrCode" => "qrCode",
  215. "qty00" => "11",
  216. "qty01" => 1,
  217. "qty02" => 2,
  218. "title" => $title,
  219. "uomDesc01" => "uo",
  220. "uomDesc02" => "uo"
  221. ],
  222. ];
  223. $response = Http::post(config('api.haiq.storage.light'), $params);
  224. return json_decode($response->body());
  225. }
  226. /**
  227. * 控制格口灭灯
  228. * @param $locCode
  229. * @return mixed
  230. */
  231. public function _stationCacheLightOff($locCode){
  232. if(!$locCode)return null;
  233. $params = [
  234. "areaCode" => "1004",
  235. 'locCode' => $locCode,
  236. 'PTLAction' => 0,
  237. ];
  238. $response = Http::post(config('api.haiq.storage.light'), $params);
  239. return json_decode($response->body());
  240. }
  241. /**
  242. * 广播 type success成功 error 异常
  243. * @param $locCode
  244. * @param $PTLAction
  245. * @param string $type
  246. */
  247. public function _stationCacheBroadCast($locCode, $PTLAction,string $type = 'success')
  248. {
  249. if($PTLAction == 0){
  250. $station = Station::query()->with('parent')->where('code',$locCode)->first();
  251. $json = json_encode( [
  252. 'station_id' => $station['parent']['id'],
  253. 'code' => $station['parent']['code'],
  254. 'gird_id' => $station['id'],
  255. 'grid_code' => $station['code'],
  256. 'type' => $type
  257. ]);
  258. broadcast(new BroadcastToStation($station['parent_id'],$json));
  259. }
  260. }
  261. /**
  262. * 根据立库任务完成 缓存架任务 和 入立架任务
  263. * @param StationTaskMaterialBox $putStationTaskMaterial
  264. */
  265. public function putStationTaskMaterialBoxProcess(StationTaskMaterialBox $putStationTaskMaterial)
  266. {
  267. $this->instant($this->stationTaskMaterialBoxService,'StationTaskMaterialBoxService');
  268. $takeStationTaskMaterialBox = StationTaskMaterialBox::query()->with('station','stationTask')->where('material_box_id',$putStationTaskMaterial['material_box_id'])->whereIn('station_id',function($query){
  269. $query->from('stations')->selectRaw('id')->whereIn('station_type_id',function($query){
  270. $query->from('station_types')->selectRaw('id')->where('name','缓存架');
  271. });
  272. })->where('status','处理中')->first();
  273. if(!$takeStationTaskMaterialBox)return ;
  274. $this->stationTaskMaterialBoxService->set($takeStationTaskMaterialBox, [
  275. 'status' => '完成'
  276. ]);
  277. // 缓存架任务
  278. if($takeStationTaskMaterialBox->stationTask)$takeStationTaskMaterialBox->stationTask->update(['status' => '完成']);
  279. // 入立架任务
  280. if($putStationTaskMaterial->stationTask)$putStationTaskMaterial->stationTask->update(['status' => '完成']);
  281. $this->_stationCacheLightOff($takeStationTaskMaterialBox->station->code ?? null); //海柔格口灭灯
  282. $this->_stationCacheBroadCast($takeStationTaskMaterialBox->station->code, 0); //通知缓存架任务完成
  283. }
  284. /**
  285. * 取消任务
  286. * @param $stationCode
  287. * @return array
  288. */
  289. public function clearTask($stationCode): array
  290. {
  291. $station = Station::query()->with(['currentStationTask.stationTaskMaterialBoxes.materialBox',
  292. 'pendingStationTask.stationTaskMaterialBoxes.materialBox'])
  293. ->where('code',$stationCode)->first();
  294. if($station->currentStationTask)return ['success' => false,'message' => '当前任务正在执行','data'=>$stationCode];
  295. if($station->pendingStationTask->stationTaskMaterialBoxes->count() == 0){
  296. $station->pendingStationTask->delete();
  297. return ['success' => true];
  298. }
  299. $taskStationTaskMaterialBox = $station->pendingStationTask->stationTaskMaterialBoxes->first() ?? null;
  300. $stationTaskMaterialBoxes = StationTaskMaterialBox::query()->with('stationTask')
  301. ->where('material_box_id',$taskStationTaskMaterialBox['material_box_id'])
  302. ->where('station_id','!=',$station->pendingStationTask['id'])
  303. ->get();
  304. foreach ($stationTaskMaterialBoxes as $stationTaskMaterialBox) {
  305. if($stationTaskMaterialBox->stationTask){
  306. StationTaskChildren::query()->where([
  307. 'station_task_id' => $stationTaskMaterialBox->stationTask['id'],
  308. 'station_taskable_type'=>StationTaskMaterialBox::class,
  309. 'station_taskable_id'=>$stationTaskMaterialBox['id']])->delete();
  310. $stationTaskMaterialBox->stationTask->delete();
  311. }
  312. $stationTaskMaterialBox->delete();
  313. }
  314. return ['success' => true];
  315. }
  316. }