From 031902091a2e250098dfd8594b88268a1289b5bb Mon Sep 17 00:00:00 2001 From: dengjun Date: Tue, 19 Dec 2023 13:33:25 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=B9=E9=87=8F=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + .../rtosc/dto/DepartureCargoVo.java | 8 +- .../haitonggauto/rtosc/dto/DepartureVo.java | 2 +- .../haitonggauto/rtosc/dto/ExportInVo.java | 4 +- .../rtosc/excel/ExportInPlanExcel.java | 10 +- .../rtosc/query/ExportInCheckQuery.java | 18 +- .../haitonggauto/rtosc/api/NuzarOpenApi.java | 8 +- .../rtosc/api/dto/ShutoutCargos.java | 5 + .../rtosc/handler/DepartureHandler.java | 80 +++++++- .../rtosc/handler/DictHandler.java | 14 +- .../rtosc/handler/ExportInHandler.java | 182 ++++++++++++------ .../rtosc/handler/ExportLoadHandler.java | 14 +- .../rtosc/handler/mapper/PoMapper.java | 2 + .../src/main/resources/templates/in_temp.xlsx | Bin 12850 -> 12881 bytes .../entity/CustomerDepartureCargo.java | 7 + .../repository/entity/CustomerExportIn.java | 8 + .../rtosc/repository/enums/AuditEnum.java | 4 +- 17 files changed, 270 insertions(+), 97 deletions(-) diff --git a/.gitignore b/.gitignore index 6797ac6..f4f2415 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ /.idea/ /logs/ /nuzar-customer-repository/nuzar-customer-repository.iml +/nuzar-customer-proxy/nuzar-customer-proxy.iml diff --git a/nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/dto/DepartureCargoVo.java b/nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/dto/DepartureCargoVo.java index 0bf64be..d7b7d83 100644 --- a/nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/dto/DepartureCargoVo.java +++ b/nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/dto/DepartureCargoVo.java @@ -24,7 +24,7 @@ public class DepartureCargoVo implements Serializable { /** * 提单号 */ - @NotBlank(groups = {ValidationGroup.insert.class, ValidationGroup.update.class}, message = "提单号不能为空") +// @NotBlank(groups = {ValidationGroup.insert.class, ValidationGroup.update.class}, message = "提单号不能为空") @ApiModelProperty(value = "提单号", required = true) private String billNo; @@ -45,8 +45,8 @@ public class DepartureCargoVo implements Serializable { /** * 货物类型 */ - @NotBlank(groups = {ValidationGroup.insert.class, ValidationGroup.update.class}, message = "货物类型不能为空") - @ApiModelProperty(value = "货物类型", required = true) +// @NotBlank(groups = {ValidationGroup.insert.class, ValidationGroup.update.class}, message = "车型不能为空") + @ApiModelProperty(value = "车型", required = true) private String cargoType; /** @@ -71,6 +71,8 @@ public class DepartureCargoVo implements Serializable { @ApiModelProperty(value = "是否退关", required = true) private Integer isShutout; + @ApiModelProperty(value = "车辆状态") + private String vinStatus; @ApiModelProperty(value = "版本号") private Integer version; diff --git a/nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/dto/DepartureVo.java b/nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/dto/DepartureVo.java index e4a32fa..c50b044 100644 --- a/nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/dto/DepartureVo.java +++ b/nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/dto/DepartureVo.java @@ -84,7 +84,7 @@ public class DepartureVo implements Serializable { * 贸易类型 */ @ApiModelProperty(value = "贸易类型", required = true) - @NotNull(groups = {ValidationGroup.insert.class, ValidationGroup.update.class}, message = "贸易类型不能为空") +// @NotNull(groups = {ValidationGroup.insert.class, ValidationGroup.update.class}, message = "贸易类型不能为空") private String tradType; /** diff --git a/nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/dto/ExportInVo.java b/nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/dto/ExportInVo.java index 18f187a..f196a90 100644 --- a/nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/dto/ExportInVo.java +++ b/nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/dto/ExportInVo.java @@ -329,8 +329,8 @@ public class ExportInVo implements Serializable { /** * 是否是二手车 */ - @ApiModelProperty(value = "是否是二手车,1是二手车,0不是二手车") - private Integer secondHand; + @ApiModelProperty(value = "是否是二手车") + private String secondHand; /** * 备注 diff --git a/nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/excel/ExportInPlanExcel.java b/nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/excel/ExportInPlanExcel.java index f9a34f3..38527d6 100644 --- a/nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/excel/ExportInPlanExcel.java +++ b/nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/excel/ExportInPlanExcel.java @@ -94,19 +94,25 @@ public class ExportInPlanExcel { @NotBlank(message = "运输方式不能为空") private String transportWay; + @ExcelProperty("*进场开始日期") + @NotBlank(message = "进场开始日期不能为空") + private String beginEnterTime; + + @ExcelProperty("*进场结束日期") + @NotBlank(message = "进场结束日期不能为空") + private String endEnterTime; + /** * 进场时间 */ // @DateTimeFormat("yyyy-MM-dd HH:mm") @ExcelProperty("进场时间") - @NotNull(message = "进场时间不能为空") private String enterTime; /** * 进场数量 */ @ExcelProperty("进场数量") - @NotNull(message = "进场数量不能为空") private Integer enterQuantity; /** diff --git a/nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/query/ExportInCheckQuery.java b/nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/query/ExportInCheckQuery.java index bbaaaac..23bc64a 100644 --- a/nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/query/ExportInCheckQuery.java +++ b/nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/query/ExportInCheckQuery.java @@ -23,6 +23,10 @@ public class ExportInCheckQuery extends BaseQuery { @ApiModelProperty(value = "船Id") private String shipId; + @ApiModelProperty(value = "批量船Id") + @DbQuery(field = "shipId", symbol = SqlSymbol.IN) + private List shipIds; + @ApiModelProperty(value = "航次ID") private String voyageId; @@ -41,13 +45,23 @@ public class ExportInCheckQuery extends BaseQuery { private List pamIds; @JsonFormat(pattern = "yyyy-MM-dd") - @ApiModelProperty(value = "开始进场时间") + @ApiModelProperty(value = "开始申请时间") @DbQuery(field = "applyTime", symbol = SqlSymbol.GTE) + private Date beginApplyTime; + + @JsonFormat(pattern = "yyyy-MM-dd") + @ApiModelProperty(value = "结束申请时间") + @DbQuery(field = "applyTime", symbol = SqlSymbol.LTE) + private Date endApplyTime; + + @JsonFormat(pattern = "yyyy-MM-dd") + @ApiModelProperty(value = "开始进场时间") + @DbQuery(field = "beginEnterTime", symbol = SqlSymbol.GTE) private Date beginEnterTime; @JsonFormat(pattern = "yyyy-MM-dd") @ApiModelProperty(value = "结束进场时间") - @DbQuery(field = "applyTime", symbol = SqlSymbol.LTE) + @DbQuery(field = "endEnterTime", symbol = SqlSymbol.LTE) private Date endEnterTime; @ApiModelProperty(value = "贸易类型") diff --git a/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/api/NuzarOpenApi.java b/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/api/NuzarOpenApi.java index 2402d90..639cd2a 100644 --- a/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/api/NuzarOpenApi.java +++ b/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/api/NuzarOpenApi.java @@ -14,8 +14,8 @@ import java.util.List; import java.util.Map; -@FeignClient(name = "https://rtops4.haitongauto.com/tos/api") -//@FeignClient(name = "rtos-openapi") +//@FeignClient(name = "https://rtops4.haitongauto.com/tos/api") +@FeignClient(name = "rtos-openapi") public interface NuzarOpenApi { // 根据港区ID获取国家 @@ -110,9 +110,9 @@ public interface NuzarOpenApi { @PostMapping("/customer/exportInspectApply/applyId/status") List getInspectStatusStatus(@RequestBody List req); - // 判断是否生成船期计划 + // 判断是否生成船期计划, 返回的是生成的计划的进港计划ID @GetMapping("/customer/shipment/shipLoad/getShipPlan") - Boolean haveShipPlan(@RequestParam("vvyId") String vvyId); + List haveShipPlan(@RequestParam("vvyId") String vvyId); // 装船审核获取国际中转备件 @PostMapping("/customer/shipment/shipLoad/transitPart") diff --git a/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/api/dto/ShutoutCargos.java b/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/api/dto/ShutoutCargos.java index 02cfc72..4d9147f 100644 --- a/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/api/dto/ShutoutCargos.java +++ b/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/api/dto/ShutoutCargos.java @@ -31,4 +31,9 @@ public class ShutoutCargos implements Serializable { @ApiModelProperty("退关货物信息主键") private String ysrId; + @ApiModelProperty("是否已经申请") + private Boolean repeat=false; + + @ApiModelProperty("货物状态") + private String vinStatus; } diff --git a/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/DepartureHandler.java b/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/DepartureHandler.java index db1ced0..732902d 100644 --- a/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/DepartureHandler.java +++ b/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/DepartureHandler.java @@ -4,14 +4,12 @@ import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.date.DateUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; -import com.alibaba.excel.util.MapUtils; import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.fill.FillConfig; import com.alibaba.excel.write.metadata.fill.FillWrapper; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; -import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.haitonggauto.rtosc.api.NuzarOpenApi; import com.haitonggauto.rtosc.api.dto.*; @@ -59,6 +57,7 @@ import com.nuzar.rtops.log.service.EsLogApprovalUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.MapUtils; import org.apache.commons.lang3.StringUtils; import org.apache.poi.util.IOUtils; import org.apache.poi.xssf.usermodel.XSSFWorkbook; @@ -119,7 +118,41 @@ public class DepartureHandler implements BaseHandler { @PostMapping("/shutout/cargo/query") public Result> getShutoutCargoList(@RequestParam(required = false) @NotNull(message = "船ID不能为空") String shipId, @RequestParam(required = false) @NotNull(message = "航次ID不能为空") String vvyId) { - return ResultUtil.success(openApi.getShutoutCargosList(shipId, vvyId)); + List rst = openApi.getShutoutCargosList(shipId, vvyId); + List existsVins = rst.stream().map(item -> item.getVinCode()).collect(Collectors.toList()); + + if (CollectionUtils.isNotEmpty(existsVins)) { + List list = departureCargoService.lambdaQuery().in(CustomerDepartureCargo::getVin, existsVins).list(); + List exists = list.stream().map(item -> item.getVin()).collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(exists)) { + rst.stream().forEach(item -> { + if (exists.contains(item.getVinCode())) { + item.setRepeat(true); + } + }); + } + + // 获取作业状态 + Map collect = null; + List vins = rst.stream().map(item -> item.getVinCode()).collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(vins)) { + VinStatusRequest req = new VinStatusRequest(); + req.setBusinessType("PICK"); + req.setImportExportType("E"); + req.setVinCodeList(vins); + req.setVvyId(vvyId); + List status = openApi.getVinStatus(req); + collect = status.stream().collect(Collectors.toMap(WorkStatusDTO::getVinCode, WorkStatusDTO::getWorkStatus)); + } + + if (MapUtils.isNotEmpty(collect)) { + for (ShutoutCargos cargo : rst) { + cargo.setVinStatus(collect.get(cargo.getVinCode())); + } + } + } + + return ResultUtil.success(rst); } /** @@ -213,7 +246,7 @@ public class DepartureHandler implements BaseHandler { } - @ApiOperation("批量验证车架号是否已经存在") + @ApiOperation("批量验证车架号是否已经存在(带航次)") @PostMapping("/check/vin/repeat") public Result>> checkVinRepeat(@RequestBody @NotNull(message = "验证列表不能为空") @Size(min = 1, message = "验证列表不能为空") ValidList form) { Map> rst = new HashMap<>(); @@ -230,6 +263,18 @@ public class DepartureHandler implements BaseHandler { return ResultUtil.success(rst); } + @ApiOperation("批量验证车架号是否已经存在(不带航次)") + @PostMapping("/check/vin/repeat/novoyage") + public Result> checkVinRepeatNoVoyage(@RequestBody @NotNull(message = "验证列表不能为空") @Size(min = 1, message = "验证列表不能为空") ValidList vins) { + List cargos = departureCargoService.query() + .select("count(*) as quantity, vin") + .in("vin", vins) + .groupBy("vin") + .having("count(quantity) > 0") + .list(); + return ResultUtil.success(cargos.stream().map(item -> item.getVin()).collect(Collectors.toList())); + } + @ApiOperation("提交审核") @PostMapping("/submit-check") public Result submitCheck(@RequestBody @@ -419,6 +464,29 @@ public class DepartureHandler implements BaseHandler { customerService.wrapperEntity(page.getRecords()); + if (CollectionUtils.isNotEmpty(page.getRecords())) { + CustomerDeparture departure = departureService.getById(page.getRecords().get(0).getDepartureId()); + + // 获取作业状态 + Map collect = null; + List vins = page.getRecords().stream().map(item -> item.getVin()).collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(vins)) { + VinStatusRequest req = new VinStatusRequest(); + req.setBusinessType("PICK"); + req.setImportExportType("E"); + req.setVinCodeList(vins); + req.setVvyId(departure.getVoyageId()); + List status = openApi.getVinStatus(req); + collect = status.stream().collect(Collectors.toMap(WorkStatusDTO::getVinCode, WorkStatusDTO::getWorkStatus)); + } + + if (MapUtils.isNotEmpty(collect)) { + for (CustomerDepartureCargo cargo : page.getRecords()) { + cargo.setVinStatus(collect.get(cargo.getVin())); + } + } + } + return ResultUtil.success(page); } @@ -565,7 +633,7 @@ public class DepartureHandler implements BaseHandler { excelWriter.fill(new FillWrapper("plan", before), writeSheet); excelWriter.fill(new FillWrapper("plan", after), fillConfig, writeSheet); - Map map = MapUtils.newHashMap(); + Map map = new HashMap<>(); map.put("batchNo", departures.get(i).getBatchNo()); // {batchNo} map.put("receiveCompany", departures.get(i).getReceiveCompany()); // {receiveCompany} //{applicant} @@ -672,7 +740,7 @@ public class DepartureHandler implements BaseHandler { cargos.stream().forEach(cargo -> { cargoTable.addCell(new Paragraph(cargo.getBillNo()).setFont(font)); cargoTable.addCell(new Paragraph(cargo.getBrand()).setFont(font)); - cargoTable.addCell(new Paragraph(StringUtils.equals(cargo.getCargoType(), "0") ? "车辆" : "备件").setFont(font)); + cargoTable.addCell(new Paragraph(cargo.getCargoType()).setFont(font)); cargoTable.addCell(cargo.getVin()); cargoTable.addCell(String.valueOf(cargo.getQuantity())); }); diff --git a/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/DictHandler.java b/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/DictHandler.java index cbbe786..8972944 100644 --- a/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/DictHandler.java +++ b/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/DictHandler.java @@ -121,7 +121,7 @@ public class DictHandler implements BaseHandler { } if (StringUtils.isNotEmpty(q)) { - rst = rst.stream().filter(item -> StringUtils.equalsIgnoreCase(item.getText(), q) || StringUtils.equalsAnyIgnoreCase(item.getExtra1(), q)).collect(Collectors.toList()); + rst = rst.stream().filter(item -> StringUtils.containsIgnoreCase(item.getText(), q) || StringUtils.containsIgnoreCase(item.getExtra1(), q)).collect(Collectors.toList()); } return ResultUtil.success(rst); @@ -149,7 +149,7 @@ public class DictHandler implements BaseHandler { } if (StringUtils.isNotEmpty(q)) { - rst = rst.stream().filter(item -> StringUtils.equalsIgnoreCase(item.getText(), q) || StringUtils.equalsAnyIgnoreCase(item.getExtra1(), q)).collect(Collectors.toList()); + rst = rst.stream().filter(item -> StringUtils.containsIgnoreCase(item.getText(), q) || StringUtils.equalsAnyIgnoreCase(item.getExtra1(), q)).collect(Collectors.toList()); } return ResultUtil.success(rst); @@ -193,7 +193,7 @@ public class DictHandler implements BaseHandler { } if (StringUtils.isNotEmpty(q)) { - rst = rst.stream().filter(item -> StringUtils.equalsIgnoreCase(item.getText(), q) || StringUtils.equalsAnyIgnoreCase(item.getExtra1(), q)).collect(Collectors.toList()); + rst = rst.stream().filter(item -> StringUtils.containsIgnoreCase(item.getText(), q) || StringUtils.equalsAnyIgnoreCase(item.getExtra1(), q)).collect(Collectors.toList()); } return ResultUtil.success(rst); @@ -258,7 +258,7 @@ public class DictHandler implements BaseHandler { } if (StringUtils.isNotEmpty(q)) { - rst = rst.stream().filter(item -> StringUtils.equalsIgnoreCase(item.getText(), q) || StringUtils.equalsAnyIgnoreCase(item.getExtra1(), q)).collect(Collectors.toList()); + rst = rst.stream().filter(item -> StringUtils.containsIgnoreCase(item.getText(), q) || StringUtils.equalsAnyIgnoreCase(item.getExtra1(), q)).collect(Collectors.toList()); } return ResultUtil.success(rst); @@ -285,7 +285,7 @@ public class DictHandler implements BaseHandler { } if (StringUtils.isNotEmpty(q)) { - rst = rst.stream().filter(item -> StringUtils.equalsIgnoreCase(item.getText(), q) || StringUtils.equalsAnyIgnoreCase(item.getExtra1(), q)).collect(Collectors.toList()); + rst = rst.stream().filter(item -> StringUtils.containsIgnoreCase(item.getText(), q) || StringUtils.equalsAnyIgnoreCase(item.getExtra1(), q)).collect(Collectors.toList()); } return ResultUtil.success(rst); @@ -311,7 +311,7 @@ public class DictHandler implements BaseHandler { } if (StringUtils.isNotEmpty(q)) { - rst = rst.stream().filter(item -> StringUtils.equalsIgnoreCase(item.getText(), q) || StringUtils.equalsAnyIgnoreCase(item.getExtra1(), q)).collect(Collectors.toList()); + rst = rst.stream().filter(item -> StringUtils.containsIgnoreCase(item.getText(), q) || StringUtils.equalsAnyIgnoreCase(item.getExtra1(), q)).collect(Collectors.toList()); } return ResultUtil.success(rst); @@ -337,7 +337,7 @@ public class DictHandler implements BaseHandler { } if (StringUtils.isNotEmpty(q)) { - rst = rst.stream().filter(item -> StringUtils.equalsIgnoreCase(item.getText(), q) || StringUtils.equalsAnyIgnoreCase(item.getExtra1(), q)).collect(Collectors.toList()); + rst = rst.stream().filter(item -> StringUtils.containsIgnoreCase(item.getText(), q) || StringUtils.containsIgnoreCase(item.getExtra1(), q)).collect(Collectors.toList()); } return ResultUtil.success(rst); diff --git a/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/ExportInHandler.java b/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/ExportInHandler.java index 043d9b1..9f9535e 100644 --- a/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/ExportInHandler.java +++ b/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/ExportInHandler.java @@ -286,6 +286,19 @@ public class ExportInHandler implements BaseHandler { }.changeBaseQueryToWrapper(CustomerExportIn.class, query); Page page = customerExportInService.page(new Page<>(query.getPage(), query.getRows()), queryWrapper); customerService.wrapperEntity(page.getRecords()); + // 处理是否生成装船计划 + if(CollectionUtils.isNotEmpty(page.getRecords())) { + Map> map = new HashMap<>(); + List collect = page.getRecords().stream().map(item -> item.getVoyageId()).distinct().collect(Collectors.toList()); + for (String v : collect) { + List list = openApi.haveShipPlan(v); + map.put(v, CollectionUtils.isNotEmpty(list) ? list : Collections.emptyList()); + } + page.getRecords().stream().forEach(item -> { + item.setShipPlan(map.get(item.getVoyageId()).contains(item.getId())); + }); + } + return ResultUtil.success(page); } @@ -295,13 +308,17 @@ public class ExportInHandler implements BaseHandler { if (query.getEndEnterTime() != null) { query.setEndEnterTime(DateUtils.getDayEnd(query.getEndEnterTime())); } - if (query.getCheckStatus() == null) { - query.setCheckStatusList(Arrays.asList(AuditEnum.AUDIT, AuditEnum.AUDIT_PASS, AuditEnum.AUDIT_REJECT)); - } - String vin = query.getVin(); - if (StringUtils.isNotEmpty(vin)) { - query.setVin(null); - } +// if (query.getCheckStatus() == null) { +// query.setCheckStatusList(Arrays.asList(AuditEnum.AUDIT, AuditEnum.AUDIT_PASS, AuditEnum.AUDIT_REJECT)); +// } +// String vin = query.getVin(); +// if (StringUtils.isNotEmpty(vin)) { +// query.setVin(null); +// } + + query.setBillNum(null); + query.setCheckStatus(AuditEnum.AUDIT_PASS); + QueryWrapper queryWrapper = (QueryWrapper) new WrapperKit() { }.changeBaseQueryToWrapper(CustomerExportIn.class, query); @@ -309,9 +326,9 @@ public class ExportInHandler implements BaseHandler { queryWrapper.select("sum(quantity) as quantity, port_area_id, ship_id, voyage_id, max(update_date) as update_date"); queryWrapper.groupBy("port_area_id, ship_id, voyage_id"); - if (StringUtils.isNotEmpty(vin)) { - queryWrapper.exists("select id from customer_export_in_cargo where customer_export_in_cargo.export_in_id=customer_export_in.id and customer_export_in_cargo.vin={0}", vin); - } +// if (StringUtils.isNotEmpty(vin)) { +// queryWrapper.exists("select id from customer_export_in_cargo where customer_export_in_cargo.export_in_id=customer_export_in.id and customer_export_in_cargo.vin={0}", vin); +// } Page page = customerExportInService.page(new Page<>(query.getPage(), query.getRows()), queryWrapper); @@ -425,6 +442,7 @@ public class ExportInHandler implements BaseHandler { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper(); queryWrapper.eq(query.getId() != null, CustomerExportInCargo::getExportInId, query.getId()); + queryWrapper.like(StringUtils.isNotEmpty(query.getVin()), CustomerExportInCargo::getVin, query.getVin()); queryWrapper.in(CollectionUtils.isNotEmpty(query.getIds()), CustomerExportInCargo::getExportInId, query.getIds()); if (query.getCargoType() != null) { queryWrapper.eq(CustomerExportInCargo::getCargoType, query.getCargoType()); @@ -1079,13 +1097,12 @@ public class ExportInHandler implements BaseHandler { return ResultUtil.failure(ErrorType.PROGRAM_ERROR.id(), "id:" + id + "不存在"); } - // 有装船审核通过的 - Long count = customerExportLoadService.lambdaQuery().eq(CustomerExportLoad::getShipId, ei.getShipId()) - .eq(CustomerExportLoad::getVoyageId, ei.getVoyageId()) - .eq(CustomerExportLoad::getBillNo, ei.getBillNum()) - .eq(CustomerExportLoad::getBrandId, ei.getBrandId()).eq(CustomerExportLoad::getCheckStatus, AuditEnum.AUDIT_PASS).count(); - if (count > 0) { - return ResultUtil.failure(ErrorType.PROGRAM_ERROR.id(), "装船审核通过,不允许取消审核"); + List havePlans = openApi.haveShipPlan(ei.getVoyageId()); + if (CollectionUtils.isNotEmpty(havePlans)) { + Boolean c = havePlans.contains(ei.getId()); + if (c) { + return ResultUtil.failure(ErrorType.PARAMS_ERROR.id(), "已生成装船计划,不允许取消审核"); + } } CustomerExportIn exportIn = PoMapper.instance.exportInCheckVo2Entity(check); @@ -1108,11 +1125,6 @@ public class ExportInHandler implements BaseHandler { @Transactional(rollbackFor = {Exception.class}) @PostMapping("/batch-update/shipVoyage") public Result shipVoyageUpdate(@RequestBody @Validated(ValidationGroup.insert.class) BatchUpdateShipVo form) { - Boolean havePlan = openApi.haveShipPlan(form.getVoyageId()); - if (havePlan) { - return ResultUtil.failure(ErrorType.PARAMS_ERROR.id(), "已生成装船计划,不支持批量修改航次"); - } - // 船名,航次必须相同才能修改 long count = customerExportInService.query() .select("distinct(voyage_id)") @@ -1129,6 +1141,14 @@ public class ExportInHandler implements BaseHandler { .eq(CustomerExportIn::getShipId, form.getShipId()) .eq(CustomerExportIn::getCheckStatus, AuditEnum.AUDIT).list(); + List havePlans = openApi.haveShipPlan(form.getVoyageId()); + if (CollectionUtils.isNotEmpty(exportInList) && CollectionUtils.isNotEmpty(havePlans)) { + long c = exportInList.stream().filter(item -> havePlans.contains(item.getId())).count(); + if (c > 0) { + return ResultUtil.failure(ErrorType.PARAMS_ERROR.id(), "已生成装船计划,不支持批量修改航次"); + } + } + exportInList.stream().filter(item -> StringUtils.equals("备件", item.getCartType()) && StringUtils.equalsAnyIgnoreCase(item.getVoyage(), "HT6", "HTTC", "HTLG")) .forEach(item -> { String vvyId = item.getVoyageId(); @@ -1183,15 +1203,18 @@ public class ExportInHandler implements BaseHandler { return ResultUtil.failure(ErrorType.PARAMS_ERROR.id(), "所选船名航次不同,不支持批量修改航次"); } - Boolean havePlan = openApi.haveShipPlan(exportIns.get(0).getVoyageId()); - if (havePlan) { - return ResultUtil.failure(ErrorType.PARAMS_ERROR.id(), "已生成装船计划,不支持批量修改航次"); - } - // 判断是不是备件,如果是备件,则需要重新生成 List exportInList = customerExportInService.lambdaQuery() .in(CustomerExportIn::getId, form.getIds()).list(); + List havePlans = openApi.haveShipPlan(exportIns.get(0).getVoyageId()); + if (CollectionUtils.isNotEmpty(exportInList) && CollectionUtils.isNotEmpty(havePlans)) { + long c = exportInList.stream().filter(item -> havePlans.contains(item.getId())).count(); + if (c > 0) { + return ResultUtil.failure(ErrorType.PARAMS_ERROR.id(), "已生成装船计划,不支持批量修改航次"); + } + } + exportInList.stream().filter(item -> StringUtils.equals("备件", item.getCartType()) && StringUtils.equalsAnyIgnoreCase(item.getVoyage(), "HT6", "HTTC", "HTLG")) .forEach(item -> { String vvyId = item.getVoyageId(); @@ -1395,11 +1418,11 @@ public class ExportInHandler implements BaseHandler { return v; }).collect(Collectors.toList()); List rst = shpApi.checkVinRepeat(req); + existVins.clear(); if (CollectionUtils.isNotEmpty(rst)) { // 再次过滤出重复的 List sCollect = rst.stream().filter(ss -> ss.getIsRepetition()).collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(sCollect)) { - existVins.clear(); existVins.addAll(sCollect.stream().map(ss -> ss.getVinCode()).collect(Collectors.toList())); } } @@ -1497,11 +1520,14 @@ public class ExportInHandler implements BaseHandler { @PostMapping("/import-vin") public Result> importVin(@RequestParam(required = false) @NotNull(message = "出口进场ID不能为空") Long id, MultipartFile file) throws IOException { CustomerExportIn exportIn = customerExportInService.getById(id); - Boolean havePlan = openApi.haveShipPlan(exportIn.getVoyageId()); - if (havePlan) { - return ResultUtil.failure(ErrorType.PARAMS_ERROR.id(), "已生成装船计划,不能导入"); - } + List havePlans = openApi.haveShipPlan(exportIn.getVoyageId()); + if (exportIn != null && CollectionUtils.isNotEmpty(havePlans)) { + Boolean c = havePlans.contains(exportIn.getId()); + if (c) { + return ResultUtil.failure(ErrorType.PARAMS_ERROR.id(), "已生成装船计划,不能导入"); + } + } // 有错误的数据 List errorDataList = new ArrayList<>(); @@ -1603,11 +1629,11 @@ public class ExportInHandler implements BaseHandler { return v; }).collect(Collectors.toList()); List rst = shpApi.checkVinRepeat(req); + existVins.clear(); if (CollectionUtils.isNotEmpty(rst)) { // 再次过滤出重复的 List sCollect = rst.stream().filter(ss -> ss.getIsRepetition()).collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(sCollect)) { - existVins.clear(); existVins.addAll(sCollect.stream().map(ss -> ss.getVinCode()).collect(Collectors.toList())); } } @@ -1829,11 +1855,11 @@ public class ExportInHandler implements BaseHandler { return v; }).collect(Collectors.toList()); List rst = shpApi.checkVinRepeat(req); + existVins.clear(); // 先清空 if (CollectionUtils.isNotEmpty(rst)) { // 再次过滤出重复的 List sCollect = rst.stream().filter(ss -> ss.getIsRepetition()).collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(sCollect)) { - existVins.clear(); existVins.addAll(sCollect.stream().map(ss -> ss.getVinCode()).collect(Collectors.toList())); } } @@ -1841,20 +1867,27 @@ public class ExportInHandler implements BaseHandler { List existData = item.getValue().stream().filter(p -> existVins.contains(p.getVin())).collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(existData)) { - errorDataList.addAll(item.getValue().stream().map(p -> { + errorDataList.addAll(item.getValue().stream().filter(p -> existVins.contains(p.getVin())).map(p -> { JSONObject o = JSONObject.from(p); o.put("status", "数据已存在, 未导入"); return o; }).collect(Collectors.toList())); + errorDataList.addAll(item.getValue().stream().filter(p -> !existVins.contains(p.getVin())) + .map(p -> { + JSONObject o = JSONObject.from(p); + o.put("status", "验证通过"); + return o; + }).collect(Collectors.toList())); return; + } else { + errorDataList.addAll(item.getValue().stream().filter(p -> !existVins.contains(p.getVin())) + .map(p -> { + JSONObject o = JSONObject.from(p); + o.put("status", "导入成功"); + return o; + }).collect(Collectors.toList())); } - errorDataList.addAll(item.getValue().stream().filter(p -> !existVins.contains(p.getVin())) - .map(p -> { - JSONObject o = JSONObject.from(p); - o.put("status", "导入成功"); - return o; - }).collect(Collectors.toList())); // 删除原有的车架号 customerExportInCargoService.lambdaUpdate().eq(CustomerExportInCargo::getExportInId, exportIn.getId()).remove(); List saveCargos = cargos.stream().filter(p -> !existVins.contains(p.getVin())).collect(Collectors.toList()); @@ -1888,6 +1921,19 @@ public class ExportInHandler implements BaseHandler { return ResultUtil.success("success"); } + @ApiOperation("通过车架号查询进港信息") + @PostMapping("/query/exportIn/vin") + public Result queryExportInByVin(@RequestParam(required = false) @NotBlank(message = "车架号不能为空") String vin) { + List list = customerExportInService.lambdaQuery() + .exists("select id from customer_export_in_cargo where customer_export_in.id = customer_export_in_cargo.export_in_id and vin={0}", vin) + .list(); + if (CollectionUtils.isNotEmpty(list)) { + return ResultUtil.success(list.get(0)); + } + + return ResultUtil.success(null); + } + @ApiOperation("出口进场导出") @GetMapping("/exportExecl") public void exportExecl( @@ -2196,12 +2242,6 @@ public class ExportInHandler implements BaseHandler { // 港区、船名、港口、品牌、车型 validData.stream().forEach(item -> { - if (item.getEnterQuantity() != item.getQuantity()) { - JSONObject o = JSONObject.from(item); - o.put("status", "数量和进场数量不一致"); - errorDataList.add(o); - return; - } if (portList.stream().filter(p -> StringUtils.equalsIgnoreCase(p.getText(), item.getPortName())).count() == 0) { JSONObject o = JSONObject.from(item); o.put("status", "港口不存在"); @@ -2260,7 +2300,7 @@ public class ExportInHandler implements BaseHandler { return; } // 运输方式必须是“板车运输、商品车自开、驳船,否则导入不成功,提示“运输方式错误” - if (!StringUtils.equalsAnyIgnoreCase(item.getTransportWay(), "板车运输", "商品车自开", "驳船") || transportWayList.stream().filter(p -> StringUtils.equalsIgnoreCase(p.getText(), item.getTransportWay())).count() == 0) { + if (transportWayList.stream().filter(p -> StringUtils.equalsIgnoreCase(p.getText(), item.getTransportWay())).count() == 0) { JSONObject o = JSONObject.from(item); o.put("status", "运输方式错误"); errorDataList.add(o); @@ -2278,9 +2318,7 @@ public class ExportInHandler implements BaseHandler { return; } // 车型如果是车辆操作模式必须为“港机作业,客户自开”,如果是备件操作模式必须为“铲车、吊车、浮吊”,否则导入不成功,提示“操作模式错误” - if ((StringUtils.equals("车辆", item.getCartType()) && !StringUtils.equalsAny(item.getOperateType(), "港机作业", "自开")) || - (StringUtils.equals("备件", item.getCartType()) && !StringUtils.equalsAny(item.getOperateType(), "铲车", "吊车", "浮吊")) - || operateTypeList.stream().filter(p -> StringUtils.equalsIgnoreCase(p.getText(), item.getOperateType())).count() == 0) { + if (operateTypeList.stream().filter(p -> StringUtils.equalsIgnoreCase(p.getText(), item.getOperateType())).count() == 0) { JSONObject o = JSONObject.from(item); o.put("status", "操作模式错误"); errorDataList.add(o); @@ -2292,15 +2330,31 @@ public class ExportInHandler implements BaseHandler { errorDataList.add(o); return; } - // 验证进场日期是否正确 - Date d = DateUtils.parseDate(StringUtils.trim(item.getEnterTime()), "yyyy/MM/dd"); - - if (d == null) { + Date bDate = DateUtils.parseDate(StringUtils.trim(item.getBeginEnterTime()), "yyyy/MM/dd"); + if (bDate == null) { JSONObject o = JSONObject.from(item); - o.put("status", "日期格式不正确yyyy/MM/dd"); + o.put("status", "进场开始日期格式为2023/09/08"); errorDataList.add(o); return; } + Date eDate = DateUtils.parseDate(StringUtils.trim(item.getEndEnterTime()), "yyyy/MM/dd"); + if (eDate == null) { + JSONObject o = JSONObject.from(item); + o.put("status", "进场结束日期格式为2023/09/08"); + errorDataList.add(o); + return; + } + if (StringUtils.isNotEmpty(item.getEnterTime())) { + // 验证进场时间是否正确 + Date d = DateUtils.parseDate(StringUtils.trim(item.getEnterTime()), "yyyy/MM/dd HH:mm"); + + if (d == null) { + JSONObject o = JSONObject.from(item); + o.put("status", "进场时间格式必须为2023/09/08 13:00"); + errorDataList.add(o); + return; + } + } saveData.add(item); // JSONObject o = JSONObject.from(item); @@ -2329,8 +2383,11 @@ public class ExportInHandler implements BaseHandler { in.setCountry(portCountryList.get(in.getPortId()).getText()); } - in.setBeginEnterTime(DateUtils.parseDate(StringUtils.trim(item.getEnterTime()), "yyyy/MM/dd")); - in.setEndEnterTime(in.getBeginEnterTime()); + if (StringUtils.isNotEmpty(item.getEnterTime())) { + // 验证进场时间是否正确 + Date d = DateUtils.parseDate(StringUtils.trim(item.getEnterTime()), "yyyy/MM/dd HH:mm"); + in.setTmpEnterDate(d); + } in.setShipId(shipList.stream().filter(p -> StringUtils.equalsIgnoreCase(p.getText(), item.getShipName())).findFirst().get().getId()); in.setShipEnName(shipList.stream().filter(p -> StringUtils.equalsIgnoreCase(p.getText(), item.getShipName())).findFirst().get().getExtra1()); @@ -2346,7 +2403,10 @@ public class ExportInHandler implements BaseHandler { in.setFreightId(companyMap.get(item.getFreight())); in.setApplicantId(UserContext.getUser().getUserId()); in.setTermcd(in.getPortAreaId()); - in.setVolume(in.getLength().multiply(in.getWeight()).multiply(in.getHeight()).setScale(4, RoundingMode.HALF_UP)); // 计算体积 + in.setVolume(in.getLength().multiply(in.getWidth()).multiply(in.getHeight()).setScale(4, RoundingMode.HALF_UP)); // 计算体积 + if (in.getEnterQuantity() == null) { + in.setEnterQuantity(in.getQuantity()); + } if (StringUtils.equals("1", type)) { in.setCheckStatus(AuditEnum.AUDIT); @@ -2451,7 +2511,7 @@ public class ExportInHandler implements BaseHandler { List times = new ArrayList<>(); CustomerExportInTimes time = new CustomerExportInTimes(); time.setEnterQuantity(ss.getQuantity()); - time.setEnterTime(ss.getBeginEnterTime()); + time.setEnterTime(ss.getTmpEnterDate() == null ? ss.getBeginEnterTime() : ss.getTmpEnterDate()); times.add(time); ss.setEachVolume(lastE.getEachVolume()); @@ -2466,7 +2526,7 @@ public class ExportInHandler implements BaseHandler { List times = new ArrayList<>(); CustomerExportInTimes time = new CustomerExportInTimes(); time.setEnterQuantity(ss.getQuantity()); - time.setEnterTime(ss.getBeginEnterTime()); + time.setEnterTime(ss.getTmpEnterDate() == null ? ss.getBeginEnterTime() : ss.getTmpEnterDate()); times.add(time); ss.setEachVolume(lastE.getEachVolume()); diff --git a/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/ExportLoadHandler.java b/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/ExportLoadHandler.java index 7a83dfe..3016c14 100644 --- a/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/ExportLoadHandler.java +++ b/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/ExportLoadHandler.java @@ -857,8 +857,8 @@ public class ExportLoadHandler implements BaseHandler { return ResultUtil.failure(ErrorType.PARAMS_ERROR.id(), "所选船名航次不同,不支持批量修改航次"); } - Boolean havePlan = openApi.haveShipPlan(exportLoads.get(0).getVoyageId()); - if (havePlan) { + List havePlans = openApi.haveShipPlan(exportLoads.get(0).getVoyageId()); + if (CollectionUtils.isNotEmpty(havePlans)) { return ResultUtil.failure(ErrorType.PARAMS_ERROR.id(), "已生成装船计划,不支持批量修改航次"); } @@ -874,8 +874,8 @@ public class ExportLoadHandler implements BaseHandler { @ApiOperation("批量修改船名航次") @PostMapping("/batch-update/shipVoyage") public Result shipVoyageUpdate(@RequestBody @Validated(ValidationGroup.update.class) BatchUpdateShipVo form) { - Boolean havePlan = openApi.haveShipPlan(form.getVoyageId()); - if (havePlan) { + List havePlans = openApi.haveShipPlan(form.getVoyageId()); + if (CollectionUtils.isNotEmpty(havePlans)) { return ResultUtil.failure(ErrorType.PARAMS_ERROR.id(), "已生成装船计划,不支持批量修改航次"); } @@ -1009,7 +1009,7 @@ public class ExportLoadHandler implements BaseHandler { if (exportIn == null || exportIn.getCheckStatus() != AuditEnum.AUDIT_PASS) { errorDataList.addAll(item.getValue().stream().map(p -> { JSONObject o = JSONObject.from(p); - o.put("status", "未找到审核通过的出口进港申请"); + o.put("status", "本船名航次下未找到审核通过的出口进港申请"); return o; }).collect(Collectors.toList())); return; @@ -1217,7 +1217,7 @@ public class ExportLoadHandler implements BaseHandler { if (exportIn == null || exportIn.getCheckStatus() != AuditEnum.AUDIT_PASS) { errorDataList.addAll(item.getValue().stream().map(p -> { JSONObject o = JSONObject.from(p); - o.put("status", "未找到审核通过的出口进港申请"); + o.put("status", "本船名航次下未找到审核通过的出口进港申请"); return o; }).collect(Collectors.toList())); return; @@ -1648,7 +1648,7 @@ public class ExportLoadHandler implements BaseHandler { if (exportIn == null || exportIn.getCheckStatus() != AuditEnum.AUDIT_PASS) { errorDataList.addAll(item.getValue().stream().map(p -> { JSONObject o = JSONObject.from(p); - o.put("status", "未找到审核通过的出口进港申请"); + o.put("status", "本船名航次下未找到审核通过的出口进港申请"); return o; }).collect(Collectors.toList())); return; diff --git a/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/mapper/PoMapper.java b/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/mapper/PoMapper.java index 67c3bcf..d653ffc 100644 --- a/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/mapper/PoMapper.java +++ b/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/mapper/PoMapper.java @@ -58,6 +58,8 @@ public interface PoMapper { @Mapping(source = "createDate", target = "createDate", dateFormat="yyyy-MM-dd HH:mm:ss") FreeTradeExportExcel entity2Excel(CustomerFreeTrade entity); + @Mapping(source = "endEnterTime", target = "endEnterTime", dateFormat="yyyy/MM/dd") + @Mapping(source = "beginEnterTime", target = "beginEnterTime", dateFormat="yyyy/MM/dd") CustomerExportIn excel2Entity(ExportInPlanExcel excel); CustomerImportUnload importUnloadCheckVo2Entity(ImportUnloadCheckVo vo); diff --git a/nuzar-customer-controller/src/main/resources/templates/in_temp.xlsx b/nuzar-customer-controller/src/main/resources/templates/in_temp.xlsx index a24744598618b59eae49630b235f664b384985ab..084feb75fce5c8892bb690fdd703ed82e5fdcf71 100644 GIT binary patch literal 12881 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