Browse Source

1.场站api接口

纪新园 3 months ago
parent
commit
ae88811539

+ 41 - 0
blade-service/blade-los/src/main/java/org/springblade/los/ftp/controller/ApiController.java

@@ -0,0 +1,41 @@
+package org.springblade.los.ftp.controller;
+
+import io.swagger.annotations.Api;
+import lombok.AllArgsConstructor;
+import lombok.SneakyThrows;
+import org.springblade.core.tool.api.R;
+import org.springblade.los.ftp.dto.ApiRequest;
+import org.springblade.los.ftp.dto.FtpDto;
+import org.springblade.los.ftp.service.CyFtpService;
+import org.springblade.los.ftp.service.FtpService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.constraints.NotNull;
+
+/**
+ * @author :jixinyuan
+ * @date : 2024/3/5
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/apicyctnr")
+public class ApiController {
+
+	@Autowired
+	private final CyFtpService cyFtpService;
+
+	/**
+	 * 场站api
+	 */
+	@SneakyThrows
+	@ApiIgnore
+	@RequestMapping(value = "/cyctnrItem", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
+	public R cyctnrItem(@RequestBody ApiRequest apiRequest) {
+		return cyFtpService.cyctnrItem(apiRequest);
+	}
+}

+ 47 - 0
blade-service/blade-los/src/main/java/org/springblade/los/ftp/dto/ApiItem.java

@@ -0,0 +1,47 @@
+package org.springblade.los.ftp.dto;
+
+import lombok.Data;
+
+/**
+ * @author :jixinyuan
+ * @date : 2025/9/24
+ */
+@Data
+public class ApiItem {
+
+	/**
+	 * 放箱号
+	 */
+	private String releaseNo;
+
+	/**
+	 * 箱号
+	 */
+	private String ctnrNo;
+
+	/**
+	 * 箱型
+	 */
+	private String ctnrType;
+
+	/**
+	 * 提单号:进场可以为空 出场不能为空
+	 */
+	private String mblno;
+
+	/**
+	 * 进出场日期
+	 */
+	private String approachExitDate;
+
+	/**
+	 * 进出场目的
+	 */
+	private String objective;
+
+	/**
+	 * 箱  好:0坏:1
+	 */
+	private String boxStatus;
+
+}

+ 39 - 0
blade-service/blade-los/src/main/java/org/springblade/los/ftp/dto/ApiRequest.java

@@ -0,0 +1,39 @@
+package org.springblade.los.ftp.dto;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author :jixinyuan
+ * @date : 2025/9/24
+ */
+@Data
+public class ApiRequest {
+
+	/**
+	 * 港口代码
+	 */
+	private String portNo;
+
+	/**
+	 * 场站代码
+	 */
+	private String stationCode;
+
+	/**
+	 * 进场JC,出场CC类型
+	 */
+	private String approachExit;
+
+	/**
+	 * 导入时间
+	 */
+	private String importDate;
+
+	/**
+	 * 箱明细
+	 */
+	private List<ApiItem> item;
+
+}

+ 5 - 0
blade-service/blade-los/src/main/java/org/springblade/los/ftp/service/CyFtpService.java

@@ -1,9 +1,12 @@
 package org.springblade.los.ftp.service;
 
 import org.springblade.core.tool.api.R;
+import org.springblade.los.ftp.dto.ApiRequest;
 import org.springblade.los.ftp.dto.FtpDto;
 import org.springframework.web.multipart.MultipartFile;
 
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import java.util.List;
 
 /**
@@ -18,4 +21,6 @@ public interface CyFtpService {
 	R ftpFilescopy(Long corpId,List<String> filesName, String type);
 
 	R ftpFileImport(MultipartFile file, Long corpId, String type);
+
+	R cyctnrItem(ApiRequest apiRequest);
 }

+ 245 - 0
blade-service/blade-los/src/main/java/org/springblade/los/ftp/service/impl/CyFtpServiceImpl.java

@@ -22,7 +22,13 @@ import org.springblade.los.box.dynamics.entity.BoxDynamicsRecord;
 import org.springblade.los.box.dynamics.entity.BoxDynamicsRecordItems;
 import org.springblade.los.box.dynamics.mapper.BoxDynamicsRecordItemsMapper;
 import org.springblade.los.box.dynamics.mapper.BoxDynamicsRecordMapper;
+import org.springblade.los.box.entity.PutBox;
 import org.springblade.los.box.excel.EmptyContainerAppearanceAnalysis;
+import org.springblade.los.box.service.IPutBoxService;
+import org.springblade.los.business.sea.entity.Bills;
+import org.springblade.los.business.sea.mapper.BillsMapper;
+import org.springblade.los.ftp.dto.ApiItem;
+import org.springblade.los.ftp.dto.ApiRequest;
 import org.springblade.los.ftp.dto.ContainerMovement;
 import org.springblade.los.ftp.service.CyFtpService;
 import org.springblade.resource.feign.IOssClient;
@@ -62,6 +68,10 @@ public class CyFtpServiceImpl implements CyFtpService {
 
 	private final BoxDynamicsRecordMapper boxDynamicsRecordService;
 
+	private final IPutBoxService putBoxService;
+
+	private final BillsMapper billsMapper;
+
 	@Override
 	public R ftpFilesHandle(Long corpId, String type) {
 		BCorps bCorps = bCorpsService.getById(corpId);
@@ -431,6 +441,241 @@ public class CyFtpServiceImpl implements CyFtpService {
 		return R.data(new ArrayList<>());
 	}
 
+	@Override
+	public R cyctnrItem(ApiRequest apiRequest) {
+		StringBuilder msg = new StringBuilder();
+		// 1. 执行基础参数校验
+		validateBasicParams(apiRequest, msg);
+		// 2. 场站代码有效性校验
+		BCorps bCorps = bCorpsService.getOne(new LambdaQueryWrapper<BCorps>()
+			.eq(BCorps::getTenantId, AuthUtil.getTenantId())
+			.eq(BCorps::getIsDeleted, 0)
+			.eq(BCorps::getCode, apiRequest.getStationCode())
+			.last("LIMIT 1"));
+		if (bCorps == null) {
+			msg.append("场站代码:").append(apiRequest.getStationCode()).append("不正确,请联系相关人员!");
+		}
+		// 3. 港口代码有效性校验
+		BPorts ports = bPortsService.getOne(new LambdaQueryWrapper<BPorts>()
+			.eq(BPorts::getTenantId, AuthUtil.getTenantId())
+			.eq(BPorts::getIsDeleted, 0)
+			.in(BPorts::getUnCode, apiRequest.getPortNo())
+			.last("LIMIT 1"));
+		if (ports == null) {
+			msg.append("港口代码:").append(apiRequest.getPortNo()).append("不正确,请联系相关人员!");
+		}
+		// 4. 箱型代码有效性校验
+		List<String> boxType = apiRequest.getItem().stream().map(ApiItem::getCtnrType).filter(Objects::nonNull)
+			.distinct().collect(Collectors.toList());
+		List<BCntrTypes> boxTypeList = new ArrayList<>();
+		if (!boxType.isEmpty()) {
+			boxTypeList = cntrTypesService.list(new LambdaQueryWrapper<BCntrTypes>()
+				.eq(BCntrTypes::getTenantId, AuthUtil.getTenantId())
+				.eq(BCntrTypes::getIsDeleted, 0)
+				.in(BCntrTypes::getCode95, boxType));
+			if (boxTypeList.isEmpty()) {
+				msg.append("箱型不正确,请联系相关人员!");
+			}
+		}
+		List<String> boxCodeList = apiRequest.getItem().stream().map(ApiItem::getCtnrNo).filter(Objects::nonNull)
+			.distinct().collect(Collectors.toList());
+		// 5. 放箱号有效性校验
+		List<String> releaseNoList = apiRequest.getItem().stream().map(ApiItem::getReleaseNo).filter(Objects::nonNull)
+			.distinct().collect(Collectors.toList());
+		List<PutBox> putBoxList = new ArrayList<>();
+		if (!releaseNoList.isEmpty()) {
+			putBoxList = putBoxService.list(new LambdaQueryWrapper<PutBox>()
+				.eq(PutBox::getTenantId, AuthUtil.getTenantId())
+				.eq(PutBox::getIsDeleted, 0)
+				.in(PutBox::getContainerNumber, releaseNoList));
+			if (putBoxList.isEmpty()) {
+				msg.append("放箱号不存在!");
+			}
+		}
+		// 6.提单号有效性校验
+		List<String> mblnoList = apiRequest.getItem().stream().map(ApiItem::getMblno).filter(Objects::nonNull)
+			.distinct().collect(Collectors.toList());
+		List<Bills> billsList = new ArrayList<>();
+		if (!mblnoList.isEmpty()) {
+			billsList = billsMapper.selectList(new LambdaQueryWrapper<Bills>()
+				.eq(Bills::getTenantId, AuthUtil.getTenantId())
+				.eq(Bills::getIsDeleted, 0)
+				.apply("find_in_set(bill_type,'DD,MH')")
+				.and(i -> i.in(Bills::getHblno, mblnoList).or().in(Bills::getMblno, mblnoList)));
+			if (billsList.isEmpty()) {
+				msg.append("提单号不存在!");
+			}
+		}
+		BoxDynamicsRecord boxDynamicsRecord = new BoxDynamicsRecord();
+		// 7.设置基础信息
+		boxDynamicsRecord.setCreateTime(new Date());
+		boxDynamicsRecord.setCreateUserName(AuthUtil.getUserName());
+		boxDynamicsRecord.setCreateUser(AuthUtil.getUserId());
+		boxDynamicsRecord.setBranchId(AuthUtil.getDeptId());
+		boxDynamicsRecord.setFileType("edi");
+		boxDynamicsRecord.setImportDate(new Date());
+		// 8.处理进出场类型
+		if ("JC".equals(apiRequest.getApproachExit())) {
+			boxDynamicsRecord.setBoxDynamics("进场");
+			boxDynamicsRecord.setApproachExit("JC");
+		} else {
+			boxDynamicsRecord.setBoxDynamics("出场");
+			boxDynamicsRecord.setApproachExit("CC");
+		}
+		boxDynamicsRecord.setBoxCode(String.join(",", boxCodeList));
+		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
+		List<BoxDynamicsRecordItems> itemsList = new ArrayList<>();
+		// 9. 执行明细参数校验
+		validateBasicParamsItem(apiRequest, msg,billsList,putBoxList,boxTypeList);
+		for (ApiItem item : apiRequest.getItem()) {
+			// 10.构建明细记录对象
+			BoxDynamicsRecordItems recordItems = new BoxDynamicsRecordItems();
+			// 1).明细设置基础信息
+			recordItems.setCreateTime(new Date());
+			recordItems.setCreateUserName(AuthUtil.getUserName());
+			recordItems.setCreateUser(AuthUtil.getUserId());
+			recordItems.setBranchId(AuthUtil.getDeptId());
+			recordItems.setContainerNumber(item.getReleaseNo());
+			recordItems.setBoxCode(item.getCtnrNo());
+			recordItems.setObjective(item.getObjective());
+			// 2).明细处理箱类型
+			if ("1".equals(item.getBoxStatus())) {
+				recordItems.setBoxStatus("坏箱");
+			} else {
+				recordItems.setBoxStatus("好箱");
+			}
+			// 3).明细港口数据赋值
+			if (ports != null) {
+				recordItems.setPortCode(ports.getCode());
+				recordItems.setPortCname(ports.getCnName());
+				recordItems.setPortEname(ports.getEnName());
+				recordItems.setPortId(ports.getId());
+			}
+			// 4).明细箱型数据赋值
+			if (!boxTypeList.isEmpty()) {
+                boxTypeList.stream().filter(e -> e.getCode95().equals(item.getCtnrType())).findFirst().ifPresent(cntrTypes -> recordItems.setBoxType(cntrTypes.getCnName()));
+            }
+			// 5).明细场站数据赋值
+			if (bCorps != null) {
+				recordItems.setStationCname(bCorps.getCnName());
+				recordItems.setStationEname(bCorps.getEnName());
+				recordItems.setStationCode(bCorps.getCode());
+				recordItems.setStationId(bCorps.getId());
+			}
+			recordItems.setHblno(item.getMblno());
+			// 6).明细日期字段处理
+			try {
+				formatter.parse(item.getApproachExitDate());
+			} catch (ParseException e) {
+				msg.append("进出场日期格式不正确,请传入格式为‘yyyy-MM-dd’正确格式日期");
+			}
+            itemsList.add(recordItems);
+		}
+		// 11.主表港口数据赋值
+		if (ports != null) {
+			boxDynamicsRecord.setPortCode(ports.getCode());
+			boxDynamicsRecord.setPortCname(ports.getCnName());
+			boxDynamicsRecord.setPortEname(ports.getEnName());
+			boxDynamicsRecord.setPortId(ports.getId());
+		}
+		// 12.主表场站数据赋值
+		if (bCorps != null) {
+			boxDynamicsRecord.setStationCname(bCorps.getCnName());
+			boxDynamicsRecord.setStationEname(bCorps.getEnName());
+			boxDynamicsRecord.setStationCode(bCorps.getCode());
+			boxDynamicsRecord.setStationId(bCorps.getId());
+		}
+		// 13. 错误处理:如果有错误信息则直接返回
+		if (ObjectUtils.isNotNull(msg.toString())) {
+			return R.fail(500, msg.toString());
+		} else {
+			// 14. 数据保存处理
+			boxDynamicsRecordService.insert(boxDynamicsRecord);
+			for (BoxDynamicsRecordItems item : itemsList) {
+				item.setPid(boxDynamicsRecord.getId());
+				boxDynamicsRecordItemsService.insert(item);
+			}
+			return R.success("成功");
+		}
+	}
+	/**
+	 * 明细参数校验方法
+	 * @param apiRequest 请求对象
+	 * @param msg 错误信息收集器
+	 */
+	private void validateBasicParamsItem(ApiRequest apiRequest, StringBuilder msg,List<Bills> billsList,
+										 List<PutBox> putBoxList ,List<BCntrTypes> boxTypeList) {
+		for (ApiItem item : apiRequest.getItem()) {
+			if (ObjectUtils.isNull(item.getReleaseNo())) {
+				msg.append("放箱号不能为空");
+			}
+			if (ObjectUtils.isNull(item.getCtnrNo())) {
+				msg.append("箱号不能为空");
+			}
+			if (ObjectUtils.isNull(item.getCtnrType())) {
+				msg.append("箱型不能为空");
+			}
+			if (ObjectUtils.isNull(item.getApproachExitDate())) {
+				msg.append("进出场日期不能为空");
+			}
+			if (ObjectUtils.isNull(item.getObjective())) {
+				msg.append("进出场目的不能为空");
+			}
+			if ("CC".equals(apiRequest.getApproachExit())) {
+				if (ObjectUtils.isNull(item.getMblno())) {
+					msg.append("提单号不能为空");
+				}
+				if (!billsList.isEmpty()) {
+					List<Bills> bills = billsList.stream().filter(e -> e.getMblno().equals(item.getMblno()) ||
+						e.getHblno().equals(item.getMblno())).collect(Collectors.toList());
+					if (bills.isEmpty()) {
+						msg.append("提单号:").append(item.getMblno()).append("不存在!");
+					}
+				}
+			}
+			if (!boxTypeList.isEmpty()) {
+				BCntrTypes cntrTypes = boxTypeList.stream().filter(e -> e.getCode95().equals(item.getCtnrType())).findFirst().orElse(null);
+				if (cntrTypes == null) {
+					msg.append("箱型:").append(item.getCtnrType()).append("不正确,请联系相关人员!");
+				}
+			}
+			if (!putBoxList.isEmpty()) {
+				PutBox putBox = putBoxList.stream().filter(e -> e.getContainerNumber().equals(item.getReleaseNo())).findFirst().orElse(null);
+				if (putBox == null) {
+					msg.append("放箱号:").append(item.getReleaseNo()).append("不存在!");
+				}
+			}
+		}
+	}
+
+	/**
+	 * 基础参数校验方法
+	 * @param apiRequest 请求对象
+	 * @param msg 错误信息收集器
+	 */
+	private void validateBasicParams(ApiRequest apiRequest, StringBuilder msg) {
+		// 校验明细数据不能为空
+		if (apiRequest.getItem() == null || apiRequest.getItem().isEmpty()) {
+			msg.append("集装箱明细不能为空;");
+		}
+		// 校验港口代码不能为空
+		if (apiRequest.getPortNo() == null) {
+			msg.append("港口代码不能为空;");
+		}
+		// 校验场站代码不能为空
+		if (ObjectUtils.isNull(apiRequest.getStationCode())) {
+			msg.append("场站代码不能为空");
+		}
+		// 校验进出场类型不能为空
+		if (ObjectUtils.isNull(apiRequest.getApproachExit())) {
+			msg.append("进出场类型不能为空");
+		}
+		// 校验推送时间不能为空
+		if (ObjectUtils.isNull(apiRequest.getImportDate())) {
+			msg.append("推送时间不能为空");
+		}
+	}
+
 	public static List<ContainerMovement> parseEdifactMessage(InputStream inputStream) throws IOException {
 		List<ContainerMovement> movements = new ArrayList<>();
 		if (inputStream == null) {