| | |
| | | package com.vincent.rsf.server.api.service.impl; |
| | | |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | import com.fasterxml.jackson.core.JsonProcessingException; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import com.fasterxml.jackson.databind.cfg.CoercionAction; |
| | | import com.fasterxml.jackson.databind.cfg.CoercionInputShape; |
| | | import com.vincent.rsf.framework.common.Cools; |
| | | import com.vincent.rsf.framework.common.R; |
| | | import com.vincent.rsf.framework.exception.CoolException; |
| | | import com.vincent.rsf.server.api.config.RemotesInfoProperties; |
| | | import com.vincent.rsf.server.api.entity.CommonResponse; |
| | | import com.vincent.rsf.server.api.entity.constant.RcsConstant; |
| | | import com.vincent.rsf.server.api.entity.dto.InTaskMsgDto; |
| | | import com.vincent.rsf.server.api.entity.dto.LocTypeDto; |
| | | import com.vincent.rsf.server.api.controller.erp.params.TaskInParam; |
| | | import com.vincent.rsf.server.api.entity.dto.SyncLocsDto; |
| | | import com.vincent.rsf.server.api.entity.params.CommonRequest; |
| | | import com.vincent.rsf.server.api.entity.params.WcsTaskParams; |
| | | import com.vincent.rsf.server.manager.enums.*; |
| | | import com.vincent.rsf.server.api.service.WcsService; |
| | | import com.vincent.rsf.server.api.utils.LocUtils; |
| | |
| | | import com.vincent.rsf.server.system.constant.SerialRuleCode; |
| | | import com.vincent.rsf.server.manager.enums.LocStsType; |
| | | import com.vincent.rsf.server.system.utils.SerialRuleUtils; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.http.HttpEntity; |
| | | import org.springframework.http.HttpHeaders; |
| | | import org.springframework.http.HttpMethod; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.web.client.RestTemplate; |
| | | |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | import java.util.concurrent.Executors; |
| | | import java.util.concurrent.ScheduledExecutorService; |
| | | import java.util.concurrent.TimeUnit; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @Slf4j |
| | | @Service |
| | | public class WcsServiceImpl implements WcsService { |
| | | @Autowired |
| | |
| | | private WaitPakinItemService waitPakinItemService; |
| | | @Autowired |
| | | private BasStationService basStationService; |
| | | @Autowired |
| | | private RestTemplate restTemplate; |
| | | @Autowired |
| | | private RemotesInfoProperties.RcsApi rcsApi; |
| | | |
| | | |
| | | @Override |
| | |
| | | //根据立库类型获取获取库位 |
| | | if (warehouseArea.getType().equals(WarehType.WAREHOUSE_TYPE_CRN.val)) { |
| | | //堆垛机 |
| | | dto = getLocNoCrn(param.getOrgLoc(),deviceBind, warehouseArea.getId(), param.getSourceStaNo(), matnr, batch, locTypeDto, 0, param.getIoType()); |
| | | dto = getLocNoCrn(param.getOrgLoc(), deviceBind, warehouseArea.getId(), param.getSourceStaNo(), matnr, batch, locTypeDto, 0, param.getIoType()); |
| | | |
| | | } else if (warehouseArea.getType().equals(WarehType.WAREHOUSE_TYPE_FOUR_DIRECTIONS.val)) { |
| | | //四向库 |
| | | } else { |
| | | } else { |
| | | //CTU 库以及其它 |
| | | dto = getLocNoCtu(deviceBind, warehouseArea.getId(), param.getSourceStaNo(), matnr, batch, locTypeDto, 0, param.getIoType()); |
| | | } |
| | | return dto; |
| | | } |
| | | |
| | | private InTaskMsgDto getLocNoCrn(String orgLoc,DeviceBind deviceBind, Long area, Integer sourceStaNo, String matnr, String batch, LocTypeDto locTypeDto, int times, Integer ioType) { |
| | | /** |
| | | * @author Ryan |
| | | * @date 2025/8/28 |
| | | * @description: Wcs库位同步 |
| | | * @version 1.0 |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public R syncLocsToWms() { |
| | | /**RCS基础配置链接*/ |
| | | CommonRequest params = new CommonRequest(); |
| | | params.setPageSize(100); |
| | | ScheduledExecutorService scheduled = Executors.newScheduledThreadPool(1); |
| | | scheduled.scheduleWithFixedDelay(new Runnable() { |
| | | int current = 1; |
| | | @Override |
| | | public void run() { |
| | | params.setCurrent(current); |
| | | List<SyncLocsDto> dtos = syncLocs(params); |
| | | if (dtos.isEmpty()) { |
| | | scheduled.shutdown(); |
| | | } |
| | | dtos.forEach(dto -> { |
| | | Loc loc = new Loc(); |
| | | loc.setCode(dto.getLocNo()) |
| | | .setBarcode(dto.getBarcode()) |
| | | .setRow(dto.getRow()) |
| | | .setLev(dto.getLev()) |
| | | .setId(null) |
| | | .setAreaId(41L) |
| | | .setWarehouseId(27L) |
| | | .setCol(dto.getBay()) |
| | | .setType(dto.getLocType()) |
| | | .setStatus(dto.getStatusBool()) |
| | | .setUseStatus(LocStsType.getLocSts(dto.getLocSts())); |
| | | if (!locService.save(loc)) { |
| | | scheduled.shutdown(); |
| | | throw new CoolException("WCS库位同步失败!!"); |
| | | } |
| | | }); |
| | | current++; |
| | | } |
| | | }, 1, 1, TimeUnit.SECONDS); |
| | | |
| | | return R.ok(); |
| | | } |
| | | |
| | | private List<SyncLocsDto> syncLocs(CommonRequest params) { |
| | | String rcsUrl = rcsApi.getHost() + ":" + rcsApi.getPort() + RcsConstant.syncLocs; |
| | | log.info("任务下发,请求地址: {}, 请求参数: {}", rcsUrl, JSONObject.toJSONString(params)); |
| | | HttpHeaders headers = new HttpHeaders(); |
| | | headers.add("Content-Type", "application/json"); |
| | | headers.add("api-version", "v2.0"); |
| | | HttpEntity httpEntity = new HttpEntity(params, headers); |
| | | ResponseEntity<String> exchange = restTemplate.exchange(rcsUrl, HttpMethod.POST, httpEntity, String.class); |
| | | log.info("任务下发后,响应结果: {}", exchange); |
| | | if (Objects.isNull(exchange.getBody())) { |
| | | throw new CoolException("任务下发失败!!"); |
| | | } else { |
| | | ObjectMapper objectMapper = new ObjectMapper(); |
| | | objectMapper.coercionConfigDefaults() |
| | | .setCoercion(CoercionInputShape.EmptyString, CoercionAction.AsEmpty); |
| | | try { |
| | | CommonResponse result = objectMapper.readValue(exchange.getBody(), CommonResponse.class); |
| | | if (result.getCode() == 200) { |
| | | JSONObject jsonObject = JSONObject.parseObject(exchange.getBody()).getJSONObject("data"); |
| | | return JSONArray.parseArray(jsonObject.getJSONArray("records").toJSONString(), SyncLocsDto.class); |
| | | } else { |
| | | throw new CoolException("任务下发失败!!"); |
| | | } |
| | | } catch (JsonProcessingException e) { |
| | | throw new CoolException(e.getMessage()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private InTaskMsgDto getLocNoCrn(String orgLoc, DeviceBind deviceBind, Long area, Integer sourceStaNo, String matnr, String batch, LocTypeDto locTypeDto, int times, Integer ioType) { |
| | | if (Cools.isEmpty(matnr)) { //物料号 |
| | | matnr = ""; |
| | | } |
| | |
| | | ); |
| | | |
| | | if (!Cools.isEmpty(locMast2)) { |
| | | if (null != orgMoveLoc){ |
| | | if (null != orgMoveLoc) { |
| | | if (!locMast2.getChannel().equals(orgMoveLoc.getChannel())) { |
| | | break; |
| | | } |
| | |
| | | ); |
| | | |
| | | if (!Cools.isEmpty(locMast2)) { |
| | | if (null != orgMoveLoc){ |
| | | if (null != orgMoveLoc) { |
| | | if (!locMast2.getChannel().equals(orgMoveLoc.getChannel())) { |
| | | break; |
| | | } |
| | |
| | | ); |
| | | |
| | | if (!Cools.isEmpty(locMast2)) { |
| | | if (null != orgMoveLoc){ |
| | | if (null != orgMoveLoc) { |
| | | if (!locMast2.getChannel().equals(orgMoveLoc.getChannel())) { |
| | | break; |
| | | } |
| | |
| | | ); |
| | | |
| | | if (!Cools.isEmpty(locMast2)) { |
| | | if (null != orgMoveLoc){ |
| | | if (null != orgMoveLoc) { |
| | | if (!locMast2.getChannel().equals(orgMoveLoc.getChannel())) { |
| | | break; |
| | | } |
| | |
| | | ); |
| | | |
| | | if (!Cools.isEmpty(locMast2)) { |
| | | if (null != orgMoveLoc){ |
| | | if (null != orgMoveLoc) { |
| | | if (!locMast2.getChannel().equals(orgMoveLoc.getChannel())) { |
| | | break; |
| | | } |
| | |
| | | // 当前巷道无空库位时,递归调整至下一巷道,检索全部巷道无果后,跳出递归 |
| | | if (times < rowCount * 2) { |
| | | times = times + 1; |
| | | return getLocNoCrn(orgLoc,deviceBind, area, sourceStaNo, matnr, batch, locTypeDto, times, ioType); |
| | | return getLocNoCrn(orgLoc, deviceBind, area, sourceStaNo, matnr, batch, locTypeDto, times, ioType); |
| | | |
| | | } |
| | | // 2.库位当前所属尺寸无空库位时,调整尺寸参数,向上兼容检索库位 |
| | | if (locTypeDto.getLocType1() < 3) { |
| | | int i = locTypeDto.getLocType1() + 1; |
| | | locTypeDto.setLocType1(i); |
| | | return getLocNoCrn(orgLoc,deviceBind, area, sourceStaNo, matnr, batch, locTypeDto, 0, ioType); |
| | | return getLocNoCrn(orgLoc, deviceBind, area, sourceStaNo, matnr, batch, locTypeDto, 0, ioType); |
| | | } |
| | | throw new CoolException("没有空库位"); |
| | | } |