ForeignHaiRoboticsService.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. <?php
  2. namespace App\Services;
  3. use App\Exceptions\ErrorException;
  4. use App\Exceptions\Exception;
  5. use App\MaterialBox;
  6. use App\Station;
  7. use App\StationTask;
  8. use App\StationTaskMaterialBox;
  9. use Carbon\Carbon;
  10. use Illuminate\Support\Collection;
  11. use Illuminate\Support\Facades\DB;
  12. use Illuminate\Support\Facades\Http;
  13. use App\Traits\ServiceAppAop;
  14. class ForeignHaiRoboticsService
  15. {
  16. use ServiceAppAop;
  17. // protected $modelClass=ForeignHaiRobotics::class;
  18. /** @var $stationTaskMaterialBoxService StationTaskMaterialBoxService */
  19. private $stationTaskMaterialBoxService;
  20. /** @var $stationTaskBatchService StationTaskBatchService */
  21. private $stationTaskBatchService;
  22. /** @var $stationTaskCommoditiesService StationTaskCommodityService */
  23. private $stationTaskCommoditiesService;
  24. /** @var $materialBoxService MaterialBoxService */
  25. private $materialBoxService;
  26. /** @var $stationTaskService StationTaskService */
  27. private $stationTaskService;
  28. /** @var $stationService StationService */
  29. private $stationService;
  30. public function __construct()
  31. {
  32. $this->stationTaskMaterialBoxService=null;
  33. $this->materialBoxService=null;
  34. $this->stationService=null;
  35. }
  36. /**
  37. * @param string $modeName '输送线入立架'|'立架出至输送线'|'移动立架内位置'|'缓存架入立架'|'立架出至缓存架'
  38. * @param string $fromLocation
  39. * @param string $toLocation
  40. * @param Collection $taskMaterialBoxes
  41. * @param string $groupId
  42. * @param int $priority
  43. * @param int $isSequenced
  44. * @return array
  45. */
  46. private function makeJson_move(
  47. Collection $taskMaterialBoxes,
  48. string $modeName,
  49. string $fromLocation='',
  50. string $toLocation='',
  51. $groupId=''
  52. , $priority=10
  53. , $isSequenced=1
  54. ): array
  55. {
  56. $timestampSuffix = microtime(true);
  57. $taskMode=$this->getTaskMode($modeName);
  58. $bins=$taskMaterialBoxes->map(function (StationTaskMaterialBox $taskMaterialBox)use($timestampSuffix,$fromLocation,$toLocation){
  59. return [
  60. "taskCode" =>$taskMaterialBox['id'].'_'.$timestampSuffix,
  61. "binCode" => $taskMaterialBox['materialBox']['code'],
  62. "fromLocCode" => $fromLocation??'',
  63. "toLocCode" => $toLocation??'',
  64. ];
  65. });
  66. return [[
  67. "taskMode" =>$taskMode,
  68. "bins"=>$bins,
  69. "groupCode"=>$groupId.'_'.$timestampSuffix,
  70. "priority"=>$priority,
  71. "sequenceFlag"=>$isSequenced,
  72. ]];
  73. }
  74. private function makeJson_move_multi(
  75. Collection $taskMaterialBoxes,
  76. string $modeName,
  77. string $fromLocation='',
  78. Collection $toLocations=null,
  79. $groupId=''
  80. , $priority=10
  81. , $isSequenced=1
  82. ): array
  83. {
  84. if(!$toLocations||($toLocations->count()!=$taskMaterialBoxes->count()))throw new Exception('toLocation中的元素数量必须和料箱任务一致');
  85. $timestampSuffix = microtime(true);
  86. $taskMode=$this->getTaskMode($modeName);
  87. $bins=$taskMaterialBoxes->map(function (StationTaskMaterialBox $taskMaterialBox,$i)use($timestampSuffix,$fromLocation,$toLocations){
  88. return [
  89. "taskCode" =>$taskMaterialBox['id'].'_'.$timestampSuffix,
  90. "binCode" => $taskMaterialBox['materialBox']['code'],
  91. "fromLocCode" => $fromLocation??'',
  92. "toLocCode" => $toLocations[$i],
  93. ];
  94. });
  95. return [[
  96. "taskMode" =>$taskMode,
  97. "bins"=>$bins,
  98. "groupCode"=>$groupId.'_'.$timestampSuffix,
  99. "priority"=>$priority,
  100. "sequenceFlag"=>$isSequenced,
  101. ]];
  102. }
  103. private function getTaskMode($modeName){
  104. switch ($modeName){
  105. case '输送线入立架': return 1;
  106. case '立架出至输送线': return 2;
  107. case '立架出至缓存架':
  108. case '移动立架内位置': return 3;
  109. case '缓存架入立架':return 6;
  110. default: throw new \Exception('发至海柔的移料箱请求,模式不存在');
  111. }
  112. }
  113. public function fetchGroup($toLocation, Collection $taskMaterialBoxes, $groupIdPrefix='',$mode='立架出至输送线'): bool
  114. {
  115. $dataToPost=$this->makeJson_move(
  116. $taskMaterialBoxes,
  117. $mode,
  118. '',
  119. $toLocation??'',
  120. $groupIdPrefix
  121. );
  122. return $this->controlHaiRobot($dataToPost,$taskMaterialBoxes,$mode);
  123. }
  124. /**
  125. * @param Collection $toLocations //库位和料箱任务一一对应,一个库位对应一个料箱
  126. * @param Collection $taskMaterialBoxes
  127. * @param string $groupIdPrefix
  128. * @param string $mode
  129. * @return bool
  130. * @throws ErrorException
  131. */
  132. public function fetchGroup_multiLocation(Collection $toLocations, Collection $taskMaterialBoxes, $groupIdPrefix='',$mode='立架出至输送线'): bool
  133. {
  134. $dataToPost=$this->makeJson_move_multi(
  135. $taskMaterialBoxes,
  136. $mode,
  137. '',
  138. $toLocations,
  139. $groupIdPrefix
  140. );
  141. return $this->controlHaiRobot($dataToPost,$taskMaterialBoxes,$mode);
  142. }
  143. public function moveBin(){
  144. }
  145. public function markBinProcessed(
  146. $workStation,
  147. $binCode,
  148. $success,
  149. $created_at,
  150. $exception,
  151. $is_in_plan
  152. ): bool
  153. {
  154. LogService::log('海柔请求','markBinProcessed1.1',
  155. '');
  156. $this->instant($this->stationService,'StationService');
  157. $this->instant($this->materialBoxService,'MaterialBoxService');
  158. $this->instant($this->stationTaskMaterialBoxService,'StationTaskMaterialBoxService');
  159. $this->instant($this->stationTaskCommoditiesService,'StationTaskCommodityService');
  160. $this->instant($this->stationTaskBatchService,'StationTaskBatchService');
  161. try{
  162. LogService::log('海柔请求','markBinProcessed1.2',
  163. json_encode([$binCode,$success,$exception,$is_in_plan]));
  164. if($failed
  165. =!$success)
  166. throw new ErrorException('海柔任务失败:'.$exception);
  167. LogService::log('海柔请求','markBinProcessed1.3',
  168. $failed);
  169. // if($NotInPlan
  170. // =!$is_in_plan)
  171. // throw new ErrorException('海柔认为是计划外的料箱:'.$exception);
  172. LogService::log('海柔请求','markBinProcessed1.4',
  173. '$NotInPlan');
  174. $materialBox=
  175. $this->materialBoxService->get(['code'=>$binCode])->first();
  176. LogService::log('海柔请求','markBinProcessed1.5',
  177. json_encode($materialBox));
  178. /** @var StationTaskMaterialBox $stationTaskMaterialBox */
  179. $stationTaskMaterialBox
  180. =(function()use($materialBox){
  181. return $stationTaskMaterialBox=
  182. StationTaskMaterialBox::query()
  183. ->where('material_box_id',$materialBox['id'])
  184. ->where('created_at','>',Carbon::now()->subDay())
  185. ->whereIn('status',['处理中','待处理','异常','处理队列'])
  186. ->orderBy('id','desc')
  187. ->first();
  188. })();
  189. LogService::log('海柔请求','markBinProcessed1.6',
  190. json_encode($stationTaskMaterialBox));
  191. if(!$stationTaskMaterialBox){
  192. throw new ErrorException($binCode.'该料箱没有安排在处理队列中.');
  193. }
  194. LogService::log('海柔请求','markBinProcessed1.7',
  195. json_encode($stationTaskMaterialBox));
  196. DB::transaction(function ()use($stationTaskMaterialBox){
  197. $stationTaskMaterialBox_next=
  198. $this->stationTaskMaterialBoxService
  199. ->processNextQueued($stationTaskMaterialBox); //找到队列中下一个料箱,并标记为处理中
  200. $this->stationTaskCommoditiesService
  201. ->markProcessed($stationTaskMaterialBox['stationTaskCommodities']);
  202. LogService::log('海柔请求','markBinProcessed1.8',
  203. json_encode($stationTaskMaterialBox));
  204. if($stationTaskMaterialBox_next)
  205. $this->stationTaskCommoditiesService
  206. ->markProcessing($stationTaskMaterialBox_next['stationTaskCommodities']);//因为上边商品任务被标记完成了,所以这里要将队列中找出正在处理的料箱对应的标记为“处理中”
  207. $this->stationTaskMaterialBoxService
  208. ->markProcessed($stationTaskMaterialBox);
  209. $notProcessedBoxTasks = $this->stationTaskMaterialBoxService->getNotProcessedSiblings($stationTaskMaterialBox);
  210. if($notProcessedBoxTasks->isEmpty()){
  211. $this->instant($this->stationTaskService,'StationTaskService');
  212. LogService::log('海柔请求','markBinProcessed1.81',
  213. json_encode($stationTaskMaterialBox['stationTaskBatch']));
  214. $stationTaskMaterialBox->loadMissing('stationTaskBatch');
  215. $this->stationTaskBatchService->markProcessed($stationTaskMaterialBox['stationTaskBatch']);
  216. LogService::log('海柔请求','markBinProcessed1.82',
  217. json_encode($stationTaskMaterialBox['stationTaskBatch']));
  218. $this->stationTaskService->markProcessed($stationTaskMaterialBox['stationTask']);
  219. }
  220. $this->storeBox($stationTaskMaterialBox)
  221. ?true
  222. :(function(){throw new ErrorException('呼叫机器人回收U型线料箱失败');})();
  223. LogService::log('海柔请求','markBinProcessed1.9',
  224. json_encode($stationTaskMaterialBox));
  225. $this->stationService->broadcastBinMonitor($stationTaskMaterialBox['station_id'],$stationTaskMaterialBox['stationTask']);
  226. LogService::log('海柔请求','markBinProcessed1.99',
  227. json_encode($stationTaskMaterialBox));
  228. });
  229. return true;
  230. }catch (\Exception $e){
  231. $this->instant($this->stationTaskMaterialBoxService,'StationTaskMaterialBoxService');
  232. $this->instant($this->materialBoxService,'MaterialBoxService');
  233. $box=$this->materialBoxService->firstOrCreate(['code'=>$binCode]);
  234. $stationTaskMaterialBox_toStore=
  235. $this->stationTaskMaterialBoxService->create([
  236. 'station_id' => $this->stationService->getStation_byType('立库')['id'],
  237. 'material_box_id' => $box['id'],
  238. 'status' => '处理中'
  239. ] );
  240. $dataToPost=$this->makeJson_move(
  241. collect([$stationTaskMaterialBox_toStore]),
  242. '输送线入立架',
  243. 'BIN-IN1',//TODO:这里应该是动态取得,参考出立架getULineExit()方法,不然不能从站获得对应的出口,而且要改Station的child为children
  244. '',
  245. $stationTaskMaterialBox_toStore['stationTaskBatch']['id']
  246. );
  247. $this->controlHaiRobot($dataToPost,collect([$stationTaskMaterialBox_toStore]),'输送线入立架');
  248. $stationTaskMaterialBox = $stationTaskMaterialBox_toStore??$materialBox??null;
  249. if($stationTaskMaterialBox && get_class($stationTaskMaterialBox)==MaterialBox::class){
  250. $stationTaskMaterialBox = StationTaskMaterialBox::query()
  251. ->where('material_box_id',$stationTaskMaterialBox['id'])
  252. ->where('status','<>','完成')
  253. ->where('created_at','>',now()->format('Y-m-d'))
  254. ->first();
  255. }
  256. if($stationTaskMaterialBox)
  257. $this->stationTaskMaterialBoxService
  258. ->excepted($stationTaskMaterialBox);
  259. return $e->getMessage();
  260. }
  261. }
  262. public function storeBox(?StationTaskMaterialBox $stationTaskMaterialBox): bool
  263. {
  264. LogService::log('海柔请求','putBinToStore1',
  265. '');
  266. $this->instant($this->stationService,'StationService');
  267. $this->instant($this->stationTaskMaterialBoxService,'StationTaskMaterialBoxService');
  268. $stationTaskMaterialBox_toStore=
  269. $this->stationTaskMaterialBoxService->firstOrCreate([
  270. 'station_id' => $this->stationService->getStation_byType('立库')['id'],
  271. 'material_box_id' => $stationTaskMaterialBox['materialBox']['id'],
  272. 'status' => '处理中',
  273. 'type' => '放',
  274. ]);
  275. LogService::log('海柔请求','putBinToStore2',
  276. json_encode($stationTaskMaterialBox));
  277. $dataToPost=$this->makeJson_move(
  278. collect([$stationTaskMaterialBox_toStore]),
  279. '输送线入立架',
  280. 'BIN-IN1',//TODO:这里应该是动态取得,参考出立架getULineExit()方法,不然不能从站获得对应的出口,而且要改Station的child为children
  281. '',
  282. $stationTaskMaterialBox['stationTaskBatch']['id']
  283. );
  284. LogService::log('海柔请求','putBinToStore3',
  285. json_encode($dataToPost));
  286. $controlSuccess = $this->controlHaiRobot($dataToPost,collect([$stationTaskMaterialBox_toStore]),'输送线入立架');
  287. return $controlSuccess;
  288. }
  289. /** 缓存架入立架 料箱 任务
  290. * @param StationTaskMaterialBox|null $stationTaskMaterialBox
  291. * @param string|null $formLocation
  292. * @return bool
  293. * @throws ErrorException
  294. */
  295. public function putBinToStore_fromCacheShelf(?StationTaskMaterialBox $stationTaskMaterialBox,
  296. string $formLocation): bool
  297. {
  298. LogService::log('海柔请求','putBinToStore_fromCacheShelf1', '');
  299. LogService::log('海柔请求','putBinToStore_fromCacheShelf2', json_encode($stationTaskMaterialBox));
  300. $dataToPost=$this->makeJson_move(
  301. collect([$stationTaskMaterialBox]),
  302. '缓存架入立架',
  303. $formLocation,
  304. ''
  305. );
  306. LogService::log('海柔请求','putBinToStore_fromCacheShelf3', json_encode($dataToPost));
  307. $controlSuccess = $this->controlHaiRobot($dataToPost,collect([$stationTaskMaterialBox]),'缓存架入立架');
  308. LogService::log('海柔请求','putBinToStore_fromCacheShelf4', 'controlHaiRobot '. json_encode($controlSuccess));
  309. if($controlSuccess){
  310. $this->instant($this->stationTaskMaterialBoxService,'StationTaskMaterialBoxService');
  311. $this->stationTaskMaterialBoxService->set($stationTaskMaterialBox,[
  312. 'status' => '处理中',
  313. ]);
  314. LogService::log('海柔请求','putBinToStore_fromCacheShelf5', 'controlHaiRobot '. json_encode($stationTaskMaterialBox));
  315. }
  316. return $controlSuccess;
  317. }
  318. public function taskUpdate(
  319. // $groupCode,
  320. $stationTaskMaterialBox_id, //实际对应传入的字段 taskCode, 这里用料箱任务号做taskCode
  321. $updateEventType, //0:task_begin(取货)1:task_end(放货)
  322. $status, //0:任务成功1:任务失败
  323. $binCode
  324. ):bool{
  325. LogService::log('海柔请求','taskUpdateIn',
  326. json_encode([
  327. $stationTaskMaterialBox_id,
  328. $updateEventType,
  329. $status,
  330. $binCode
  331. ]));
  332. $this->instant($this->stationTaskMaterialBoxService,'StationTaskMaterialBoxService');
  333. try{
  334. if(($failed
  335. =$status)==1){
  336. throw new ErrorException('海柔任务失败');
  337. }
  338. if($料箱不匹配=
  339. !$stationTaskMaterialBox
  340. =(function()use($stationTaskMaterialBox_id,$binCode){
  341. $stationTaskMaterialBox=StationTaskMaterialBox::query()->find($id=$stationTaskMaterialBox_id);
  342. if($stationTaskMaterialBox['materialBox']['code']==$binCode)return $stationTaskMaterialBox;
  343. return null;
  344. })()){
  345. throw new ErrorException('发回的料箱和任务号(ID)不匹配:$stationTaskMaterialBox_id:'
  346. .$stationTaskMaterialBox_id.' $binCode:'.$binCode. ' '.
  347. StationTaskMaterialBox::query()
  348. ->where('id', $id=$stationTaskMaterialBox_id)
  349. ->get()
  350. ->toJson());
  351. }
  352. if(($标记已放置=
  353. function()use($updateEventType,$stationTaskMaterialBox){
  354. if(($isPut
  355. =$updateEventType)==1){
  356. $this->stationTaskMaterialBoxService->markHasPut($stationTaskMaterialBox);
  357. return true;
  358. }return false;
  359. })())
  360. return true;
  361. ($标记已取出=
  362. function()use($updateEventType,$stationTaskMaterialBox){
  363. if(($isGet
  364. =$updateEventType)==0){
  365. $this->stationTaskMaterialBoxService->markHasTaken($stationTaskMaterialBox);
  366. }
  367. })();
  368. }catch (\Exception $e){
  369. $this->excepted($stationTaskMaterialBox_id, $binCode, $e->getMessage());
  370. return false;
  371. }
  372. return true;
  373. }
  374. // public function markHasPut($taskCode,$binCode):bool{
  375. // try{
  376. // //标记料箱进入位置
  377. //// $taskMaterialBoxesService->markDone();//
  378. // }catch (\Exception $e){
  379. // switch ($e->getCode()){
  380. // case 'taskBinNotMatch';
  381. // case 'taskGetFailed';
  382. // }
  383. // }
  384. //
  385. // }
  386. public function excepted($taskCode='',$binCode='', $msg=''):bool{
  387. try{
  388. throw new ErrorException(
  389. "taskCode任务号:$taskCode , binCode箱号:$binCode 海柔运行报错: $msg"
  390. );
  391. }catch (\Exception $e){
  392. return true;
  393. }
  394. }
  395. /**
  396. * @param array $dataToPost
  397. * @return bool
  398. */
  399. public function controlHaiRobot(array $dataToPost,Collection $taskMaterialBoxes,$modeName): bool
  400. {
  401. LogService::log('海柔请求','runMany','波次任务分配6.r5f2c1:'.json_encode($dataToPost));
  402. try{
  403. LogService::log('海柔请求','runMany','波次任务分配6.r5f2c1.51:');
  404. $response = Http::post(config('api.haiq.storage.moveBin'), $dataToPost);
  405. if(isset($response->json()['code'])&&$response->json()['code']==500)
  406. throw new ErrorException('机器人500错误:'.json_encode($response->json()));
  407. LogService::log('海柔请求','runMany','波次任务分配6.r5f2c1.52:');
  408. LogService::log(__METHOD__,'runMany','波次任务分配6.r5f2c1.53:'.json_encode($response->json()));
  409. }catch (\Exception $e){
  410. LogService::log('海柔请求','runMany','波次任务分配6.r5f2c1.54:'.json_encode($dataToPost).$e->getMessage());
  411. throw new ErrorException('海柔机器人任务执行失败:'.json_encode($dataToPost).$e->getMessage());
  412. }
  413. LogService::log('海柔请求','runMany','波次任务分配6.r5f2c2:'.json_encode($dataToPost));
  414. $errMsg = (function () use ($response) {
  415. if ($response->ok()) return '';
  416. $errMsg = '错误: ';
  417. if (!$response) {
  418. return $errMsg . '没有返回内容,检查连接或目标服务器';
  419. }
  420. switch (((string)$response["code"])[0]) {
  421. case 5:
  422. $errMsg .= '目标服务器代码错误,请联系对方';
  423. break;
  424. case 4:
  425. $errMsg .= '权限不足以请求资源,请检查对方服务器规范';
  426. break;
  427. default:
  428. $errMsg .= '出现未知请求错误';
  429. break;
  430. }
  431. $responseDetails = ' code:' . $response["code"]
  432. . ' header:' . $response->body()
  433. . ' response:' . json_encode($response->headers());
  434. return $errMsg . $responseDetails;
  435. })();
  436. LogService::log('海柔请求','runMany','波次任务分配6.r5f2c3:'.json_encode($errMsg));
  437. LogService::log(__METHOD__, __FUNCTION__,
  438. $errMsg ?? ''
  439. . '请求:' . json_encode($dataToPost)
  440. . '调用堆栈c:' . json_encode(array_slice(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), 0, 3))
  441. );
  442. $isSuccess = !$errMsg;
  443. $标记料箱状态=(function() use ($taskMaterialBoxes,$modeName){
  444. foreach ($taskMaterialBoxes as $taskMaterialBox){
  445. switch ($modeName){
  446. case '缓存架入立架':
  447. case '输送线入立架':
  448. case '移动立架内位置':
  449. $taskMaterialBox->materialBox['status']='在入库中';break;
  450. case '立架出至输送线':
  451. case '立架出至缓存架':
  452. $taskMaterialBox->materialBox['status']='在出库中';break;
  453. default:
  454. $taskMaterialBox->materialBox['status']='未知';break;
  455. }
  456. $taskMaterialBox->materialBox->update();
  457. }
  458. })();
  459. return $isSuccess;
  460. }
  461. /**
  462. * put cache rack box to warehousing(将缓存架料箱入库)
  463. *
  464. * @param string $fromLocation
  465. * @param integer $boxId
  466. *
  467. * @return int
  468. */
  469. public function putWareHousing(string $fromLocation, $boxId):?int
  470. {
  471. $station = Station::query()->select("id")->where("code",$fromLocation)->first();
  472. if (!$station)return null;
  473. if (StationTask::query()->select("id")->where("status","!=",'完成')->where("station_id",$station->id)->first())return null;
  474. /** @var StationTaskMaterialBox|\stdClass $stmb */
  475. $stmb = app("StorageService")->createWarehousingTask($station->id,$boxId);
  476. return $stmb->id;
  477. }
  478. /**
  479. * 填充缓存架
  480. *
  481. * @param \Illuminate\Database\Eloquent\Collection $stations
  482. */
  483. public function paddingCacheShelf($stations)
  484. {
  485. $collection = new Collection();
  486. $stationCollection = new Collection();
  487. $blacklist = [];
  488. foreach ($stations as $station){
  489. $box = app("MaterialBoxService")->getAnEmptyBox($blacklist);
  490. if (!$box)continue;
  491. $task = StationTask::query()->create([
  492. 'status' => "待处理",
  493. 'station_id' => $station->id,
  494. ]);
  495. $collection->add(StationTaskMaterialBox::query()->create([
  496. 'station_id' => $station->id,
  497. 'material_box_id'=>$box->id,
  498. 'status'=>"待处理",
  499. 'type' => '取',
  500. 'station_task_id' => $task->id,
  501. ]));
  502. $stationCollection->add($station->code);
  503. $blacklist[] = $box->id;
  504. }
  505. app("ForeignHaiRoboticsService")->fetchGroup_multiLocation($stationCollection,$collection,'','立架出至缓存架');
  506. }
  507. }