| | |
| | | package com.vincent.rsf.server.api.service.impl; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | 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.controller.erp.params.SyncOrderParams; |
| | | import com.vincent.rsf.server.api.controller.erp.params.SyncOrdersItem; |
| | | import com.vincent.rsf.server.api.service.AgvService; |
| | | import com.vincent.rsf.server.api.service.ReceiveMsgService; |
| | | import com.vincent.rsf.server.manager.controller.params.WaitPakinParam; |
| | | import com.vincent.rsf.server.manager.entity.*; |
| | | import com.vincent.rsf.server.manager.entity.param.AgvBindAndInTParam; |
| | | import com.vincent.rsf.server.manager.enums.LocStsType; |
| | | import com.vincent.rsf.server.manager.enums.PakinIOStatus; |
| | | import com.vincent.rsf.server.manager.enums.StationTypeEnum; |
| | | import com.vincent.rsf.server.manager.enums.TaskType; |
| | | import com.vincent.rsf.server.manager.service.*; |
| | | import com.vincent.rsf.server.manager.service.impl.DeviceSiteServiceImpl; |
| | | import com.vincent.rsf.server.manager.service.impl.MatnrServiceImpl; |
| | | import com.vincent.rsf.server.manager.utils.LocManageUtil; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.time.Instant; |
| | | import java.time.LocalDateTime; |
| | | import java.time.ZoneId; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | import java.util.concurrent.CompletableFuture; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @Slf4j |
| | | @Service |
| | | public class AgvServiceImpl implements AgvService { |
| | | |
| | | private static final String AGV_MISC_ORDER_PREFIX = "AGVT"; |
| | | private static final DateTimeFormatter BATCH_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); |
| | | |
| | | @Autowired |
| | | private ReceiveMsgService receiveMsgService; |
| | | |
| | | @Autowired |
| | | private WaitPakinService waitPakinService; |
| | |
| | | @Autowired |
| | | private WarehouseAreasService warehouseAreasService; |
| | | @Autowired |
| | | private LocService locService; |
| | | @Autowired |
| | | private TaskService taskService; |
| | | @Autowired |
| | | private BasContainerService basContainerService; |
| | | @Autowired |
| | | private DeviceSiteServiceImpl deviceSiteService; |
| | | @Autowired |
| | | private MatnrServiceImpl matnrService; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public R AGVBindAndInTaskStart(WaitPakinParam waitPakinPda, Long loginUserId) { |
| | | //先绑定 |
| | | getAGVStaBind(waitPakinPda); |
| | | try{ |
| | | getAGVStaBind(waitPakinPda); |
| | | } catch (CoolException e) { |
| | | log.error(e.getMessage()); |
| | | } |
| | | //生成任务 |
| | | AGVInTaskStart(waitPakinPda, loginUserId); |
| | | return R.ok(); |
| | |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public R AGVBindAndInTaskStartT(AgvBindAndInTParam param, Long loginUserId) { |
| | | if (Objects.isNull(param)) { |
| | | throw new CoolException("参数不能为空!!"); |
| | | } |
| | | if (Cools.isEmpty(param.getMatNr())) { |
| | | throw new CoolException("物料编码不能为空!!"); |
| | | } |
| | | if (Cools.isEmpty(param.getPalletBarcode())) { |
| | | throw new CoolException("托盘码不能为空!!"); |
| | | } |
| | | if (Cools.isEmpty(param.getPalletSta())) { |
| | | throw new CoolException("操作站点不能为空!!"); |
| | | } |
| | | |
| | | checkPalletBarcodeAvailable(param.getPalletBarcode()); |
| | | |
| | | Matnr matnr = matnrService.getOne(new LambdaQueryWrapper<Matnr>() |
| | | .eq(Matnr::getCode, param.getMatNr()) |
| | | .last("limit 1")); |
| | | if (Objects.isNull(matnr)) { |
| | | throw new CoolException("物料编码不存在:" + param.getMatNr()); |
| | | } |
| | | |
| | | long nowMillis = System.currentTimeMillis(); |
| | | long nowSeconds = nowMillis / 1000; |
| | | String orderNo = buildAgvMiscOrderNo(param.getPalletBarcode(), nowMillis); |
| | | SyncOrderParams syncOrder = new SyncOrderParams() |
| | | .setWkType(SyncOrderParams.BusinessType.STK_MISCELLANEOUS) |
| | | .setType("in") |
| | | .setOrderNo(orderNo) |
| | | .setOrderInternalCode(nowMillis) |
| | | .setCreateTime(nowSeconds) |
| | | .setBusinessTime(nowSeconds) |
| | | .setAnfme(1.0) |
| | | .setOrderItems(Collections.singletonList(buildOrderItem(param, matnr, nowMillis, nowSeconds).setBarcode(param.getPalletBarcode()))); |
| | | syncOrder.setStationId(param.getPalletSta()); |
| | | R r = receiveMsgService.syncCheckOrder(Collections.singletonList(syncOrder), loginUserId); |
| | | if (!Objects.isNull(r) && Objects.equals(String.valueOf(r.get("code")), "200")) { |
| | | autoCallAgvInTask(param, loginUserId); |
| | | } |
| | | return R.ok(Cools.add("orderNo", orderNo).add("palletBarcode", param.getPalletBarcode())); |
| | | } |
| | | |
| | | private void autoCallAgvInTask(AgvBindAndInTParam param, Long loginUserId) { |
| | | CompletableFuture.runAsync(() -> { |
| | | int retry = 0; |
| | | while (retry < 5) { |
| | | retry++; |
| | | try { |
| | | Thread.sleep(3000); |
| | | WaitPakin waitPakin = waitPakinService.getOne(new LambdaQueryWrapper<WaitPakin>() |
| | | .eq(WaitPakin::getBarcode, param.getPalletBarcode()) |
| | | .eq(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_DONE.val) |
| | | .last("limit 1")); |
| | | if (Objects.isNull(waitPakin)) { |
| | | continue; |
| | | } |
| | | |
| | | BasStation basStation = basStationService.getOne(new LambdaQueryWrapper<BasStation>() |
| | | .eq(BasStation::getStationName, param.getPalletSta()) |
| | | .last("limit 1")); |
| | | if (Objects.isNull(basStation)) { |
| | | return; |
| | | } |
| | | // if (Objects.isNull(basStation) || Objects.isNull(basStation.getArea())) { |
| | | // return; |
| | | // } |
| | | |
| | | WaitPakinParam waitPakinPda = new WaitPakinParam() |
| | | .setBarcode(param.getPalletBarcode()) |
| | | .setStaNo(param.getPalletSta()) |
| | | .setArea(param.getArea()); |
| | | AGVBindAndInTaskStart(waitPakinPda, loginUserId); |
| | | return; |
| | | } catch (Exception ignored) { |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | |
| | | private SyncOrdersItem buildOrderItem(AgvBindAndInTParam param, Matnr matnr, long uniqueSeed, long nowSeconds) { |
| | | String suffix = String.valueOf(uniqueSeed); |
| | | String batch = LocalDateTime.ofInstant(Instant.ofEpochSecond(nowSeconds), ZoneId.systemDefault()) |
| | | .format(BATCH_FORMATTER); |
| | | SyncOrdersItem syncOrdersItem = new SyncOrdersItem() |
| | | .setModel(matnr.getModel()) |
| | | .setAnfme(1.0) |
| | | .setUnit(matnr.getUnit()) |
| | | .setBaseUnitId(matnr.getUnit()) |
| | | .setPriceUnitId(matnr.getUnit()) |
| | | .setBatch(batch) |
| | | .setPlanNo(AGV_MISC_ORDER_PREFIX + "-PLAN-" + suffix) |
| | | .setLineId(AGV_MISC_ORDER_PREFIX + "-LINE-" + suffix) |
| | | .setPlatItemId("1") |
| | | .setPalletId(param.getPalletBarcode()); |
| | | syncOrdersItem.setMatnr(matnr.getCode()); |
| | | syncOrdersItem.setMaktx(matnr.getName()); |
| | | syncOrdersItem.setSpec(matnr.getSpec()); |
| | | return syncOrdersItem; |
| | | } |
| | | |
| | | private String buildAgvMiscOrderNo(String palletBarcode, long uniqueSeed) { |
| | | String cleanBarcode = palletBarcode.replaceAll("[^A-Za-z0-9]", ""); |
| | | if (cleanBarcode.length() > 24) { |
| | | cleanBarcode = cleanBarcode.substring(cleanBarcode.length() - 24); |
| | | } |
| | | return AGV_MISC_ORDER_PREFIX + cleanBarcode + uniqueSeed; |
| | | } |
| | | |
| | | private void checkPalletBarcodeAvailable(String palletBarcode) { |
| | | WaitPakin waitPakin = waitPakinService.getOne(new LambdaQueryWrapper<WaitPakin>() |
| | | .eq(WaitPakin::getBarcode, palletBarcode) |
| | | .last("limit 1")); |
| | | if (!Objects.isNull(waitPakin)) { |
| | | throw new CoolException("托盘码:" + palletBarcode + "已被组托单:" + waitPakin.getCode() + "使用!!"); |
| | | } |
| | | |
| | | BasStation basStation = basStationService.getOne(new LambdaQueryWrapper<BasStation>() |
| | | .eq(BasStation::getBarcode, palletBarcode) |
| | | .last("limit 1")); |
| | | if (!Objects.isNull(basStation)) { |
| | | throw new CoolException("托盘码:" + palletBarcode + "已被站点:" + basStation.getStationName() + "绑定!!"); |
| | | } |
| | | |
| | | Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>() |
| | | .eq(Loc::getBarcode, palletBarcode) |
| | | .last("limit 1")); |
| | | if (!Objects.isNull(loc)) { |
| | | throw new CoolException("托盘码:" + palletBarcode + "已被库位:" + loc.getCode() + "使用!!"); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public R getStaMsgSelect(Map<String, Object> params) { |
| | | String sta = params.get("sta").toString(); |
| | | if (Cools.isEmpty(sta)) { |