|
|
@@ -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) {
|