StationService.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  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. * @param bool $desc
  124. *
  125. * @return Collection
  126. */
  127. public function getCacheShelf(bool $onlyAvailable = false, bool $desc = false):Collection
  128. {
  129. $stations = Station::query()->where("station_type_id",5)
  130. ->whereNotNull("parent_id");
  131. if ($onlyAvailable)$stations->where("status",0)
  132. ->whereNotIn("id",Station::query()->select("id")->whereHas("task",function ($query){
  133. $query->whereNotIn("status",["完成","取消"]);
  134. }))->lockForUpdate();
  135. if ($desc)$stations->orderByDesc("code");
  136. return $stations->get();
  137. }
  138. /**
  139. * @param array $codes
  140. *
  141. * @return array
  142. */
  143. public function getStationMapping(array $codes):array
  144. {
  145. $mapping = [];
  146. foreach (Station::query()->whereIn("code",$codes)->get() as $station){
  147. $mapping[$station->code] = $station->id;
  148. }
  149. return $mapping;
  150. }
  151. /**
  152. * 库位占用
  153. * 为未执行的上架任务预定库位,禁止二次下发
  154. *
  155. * @param string $location
  156. * @param int|null $boxId
  157. *
  158. * @return int
  159. */
  160. public function locationOccupy(string $location, ?int $boxId=null):int
  161. {
  162. $update = ["status"=>1];
  163. if ($boxId)$update["material_box_id"]=$boxId;
  164. return Station::query()->where("code",$location)->update($update);
  165. }
  166. /**
  167. * 多库位占用
  168. * @param array $location
  169. * @return bool
  170. */
  171. public function locationOccupyMulti(array $location):bool
  172. {
  173. return !!Station::query()->whereIn("code",$location)->update(["status"=>1]);
  174. }
  175. /**
  176. * 库位释放
  177. *
  178. * @param ?string $location
  179. * @param int|null $boxId
  180. *
  181. * @return int
  182. */
  183. public function locationFreed(?string $location, ?int $boxId=null):int
  184. {
  185. if (!$location)return 0;
  186. $update = ["status"=>0];
  187. if ($boxId)$update["material_box_id"]=$boxId;
  188. return Station::query()->where("code",$location)->update($update);
  189. }
  190. /**
  191. * 检查库位是否可用
  192. *
  193. * @param mixed $station
  194. *
  195. * @return bool
  196. */
  197. public function isAvailable($station):bool
  198. {
  199. if (!is_a($station,Model::class)) $station = Station::query()->where("code",$station)->first();
  200. $s = StationTaskMaterialBox::query()->selectRaw("1")->where("station_id",$station->id)->whereNotIn("status",["完成","取消"])->first();
  201. return $station && $station->status==0 && !$s;
  202. }
  203. }