StationService.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. <?php
  2. namespace App\Services;
  3. use App\Events\BroadcastToStation;
  4. use App\Station;
  5. use App\StationTask;
  6. use App\StationTaskMaterialBox;
  7. use App\StationType;
  8. use Exception;
  9. use Illuminate\Database\Eloquent\Collection;
  10. use Illuminate\Database\Eloquent\Model;
  11. use Illuminate\Support\Facades\Cache;
  12. use App\Traits\ServiceAppAop;
  13. use Illuminate\Support\Facades\DB;
  14. class StationService
  15. {
  16. use ServiceAppAop;
  17. protected $modelClass=Station::class;
  18. /** @var $stationTaskService StationTaskService */
  19. protected $stationTaskService;
  20. /**
  21. * @param string $typeName
  22. * @return Station
  23. * @throws Exception
  24. */
  25. function getStation_byType(string $typeName):Station{
  26. $station= Cache::remember('Station_typeName_'.$typeName,
  27. config('cache.expirations.rarelyChange'),
  28. function ()use($typeName) {
  29. $stationType= StationType::query()->where('name',$typeName)->orderBy('id')->get('id')->first();
  30. if(!$stationType) throw new Exception('指定站类型获取不到');
  31. return Station::query()->where('station_type_id',$stationType['id'])->first();
  32. });
  33. if(!$station)throw new Exception('默认站获取不到');
  34. return $station;
  35. }
  36. function getULineEntrance(Station $station):?Station{
  37. $station->loadMissing(['stationType','child']);
  38. if (($station['stationType']['name']??'')=='料箱出货口'){
  39. return $station;
  40. }
  41. if (($station['child']['stationType']['name']??'')=='料箱出货口'){
  42. return $station['child'];
  43. }
  44. return null;
  45. }
  46. function getULineExit(Station $station):?Station{
  47. $station->loadMissing(['stationType','child']);
  48. if ($station['stationType']['name']??''=='料箱入货口'){
  49. return $station;
  50. }
  51. if ($station['child']['stationType']['name']??''=='料箱入货口'){
  52. return $station['child'];
  53. }
  54. return null;
  55. }
  56. function broadcast($station_id, ?StationTask $stationTask){
  57. LogService::log('海柔请求in2','broadcast',
  58. $station_id.'|'.json_encode($stationTask));
  59. if($stationTask)
  60. $json = $stationTask->toJson();
  61. else
  62. $json =[];
  63. LogService::log('海柔请求done2','broadcast',
  64. $station_id.'|'.$json);
  65. broadcast(new BroadcastToStation($station_id, $json));
  66. }
  67. function broadcastBinMonitor($station_id, ?StationTask $stationTask){
  68. LogService::log('海柔请求in1','broadcastBinMonitor',
  69. $station_id.'|'.json_encode($stationTask));
  70. if(!$stationTask)return;
  71. $this->instant($this->stationTaskService,'StationTaskService');
  72. if($stationTask['status']=='完成')
  73. $stationTask=$this->stationTaskService->getCurrent_shouldProcess_ByStationId($stationTask['station_id']);
  74. if($stationTask)
  75. $stationTask->loadMissing([
  76. "stationTaskCommodities.commodity.barcodes",
  77. "stationTaskCommodities.stationTaskMaterialBox",
  78. "stationTaskBatches.batch",
  79. "stationTaskMaterialBoxes.materialBox",
  80. ]);
  81. LogService::log('海柔请求done1','broadcastBinMonitor',
  82. $station_id.'|'.json_encode($stationTask));
  83. $this->broadcast($station_id, $stationTask);
  84. }
  85. /**
  86. * 获取镜像映射库位
  87. *
  88. * @param string $mirrorLocation
  89. *
  90. * @return Model|null
  91. */
  92. public function getMirrorMappingLocation(string $mirrorLocation):?Station
  93. {
  94. if (!$mirrorLocation)return null;
  95. return Station::query()->where("code",substr($mirrorLocation,2))->first();
  96. }
  97. /**
  98. * 是否为半箱缓存架位置
  99. *
  100. * @param Station|null|\stdClass $station
  101. * @return bool
  102. */
  103. public function isHalfBoxLocation(?Station $station):bool
  104. {
  105. if (!$station)return false;
  106. return $station->station_type_id==5 && $station->parent_id;
  107. }
  108. /**
  109. * 是否为缓存架位置
  110. *
  111. * @param Station|\stdClass $station
  112. *
  113. * @return bool
  114. */
  115. public function isCacheShelfLocation(Station $station):bool
  116. {
  117. return $station->station_type_id == 5;
  118. }
  119. /**
  120. * 获取缓存架
  121. *
  122. * @param bool $onlyAvailable
  123. *
  124. * @return Collection
  125. */
  126. public function getCacheShelf(bool $onlyAvailable = false):Collection
  127. {
  128. $stations = Station::query()->where("station_type_id",5)
  129. ->whereNotNull("parent_id")->orderByRaw("LEFT(code,5),RIGHT(code,1)");
  130. if ($onlyAvailable)$stations->where("status",0)
  131. ->whereNotIn("id",Station::query()->select("id")->whereHas("task",function ($query){
  132. $query->whereNotIn("status",["完成","取消"]);
  133. }))->lockForUpdate();
  134. return $stations->get();
  135. }
  136. /**
  137. * @param array $codes
  138. *
  139. * @return array
  140. */
  141. public function getStationMapping(array $codes):array
  142. {
  143. $mapping = [];
  144. foreach (Station::query()->whereIn("code",$codes)->get() as $station){
  145. $mapping[$station->code] = $station->id;
  146. }
  147. return $mapping;
  148. }
  149. /**
  150. * 库位占用
  151. * 为未执行的上架任务预定库位,禁止二次下发
  152. *
  153. * @param string $location
  154. * @param int|null $boxId
  155. *
  156. * @return int
  157. */
  158. public function locationOccupy(string $location, ?int $boxId=null):int
  159. {
  160. $update = ["status"=>1];
  161. if ($boxId)$update["material_box_id"]=$boxId;
  162. return Station::query()->where("code",$location)->update($update);
  163. }
  164. /**
  165. * 多库位占用
  166. * @param array $location
  167. * @return bool
  168. */
  169. public function locationOccupyMulti(array $location):bool
  170. {
  171. return !!Station::query()->whereIn("code",$location)->update(["status"=>1]);
  172. }
  173. /**
  174. * 库位释放
  175. *
  176. * @param ?string $location
  177. * @param int|null $boxId
  178. *
  179. * @return int
  180. */
  181. public function locationFreed(?string $location, ?int $boxId=null):int
  182. {
  183. if (!$location)return 0;
  184. $update = ["status"=>0,"material_box_id"=>$boxId];
  185. return Station::query()->where("code",$location)->update($update);
  186. }
  187. /**
  188. * 检查库位是否可用
  189. *
  190. * @param mixed $station
  191. *
  192. * @return bool
  193. */
  194. public function isAvailable($station):bool
  195. {
  196. if (!is_a($station,Model::class)) $station = Station::query()->where("code",$station)->first();
  197. $s = StationTaskMaterialBox::query()->selectRaw("1")->where("station_id",$station->id)->whereNotIn("status",["完成","取消"])->first();
  198. return $station && $station->status==0 && !$s;
  199. }
  200. }