From bcb588fd5d2b00762f22b49c42d1dc77b884a603 Mon Sep 17 00:00:00 2001 From: dengjun Date: Mon, 22 Jan 2024 13:21:06 +0800 Subject: [PATCH] =?UTF-8?q?BUG=E4=BF=AE=E5=A4=8D=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rtosc/excel/ExportInspectExportExcel.java | 52 ++++++ ...cel.java => ImportInspectExportExcel.java} | 2 +- .../haitonggauto/rtosc/api/NuzarOpenApi.java | 4 +- .../haitonggauto/rtosc/api/NuzarPubApi.java | 4 +- .../haitonggauto/rtosc/api/NuzarShpApi.java | 4 +- .../rtosc/handler/ExportInHandler.java | 55 +++--- .../rtosc/handler/ExportInspectHandler.java | 73 +++++--- .../rtosc/handler/ExportLoadHandler.java | 11 +- .../rtosc/handler/ImportInspectHandler.java | 43 +++-- .../handler/excel/CustomCellWriteHandler.java | 166 +++++++++--------- .../rtosc/handler/mapper/PoMapper.java | 2 +- .../src/main/resources/templates/in_temp.xlsx | Bin 13716 -> 13819 bytes .../entity/CustomerExportLoadCargo.java | 8 + 13 files changed, 265 insertions(+), 159 deletions(-) create mode 100644 nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/excel/ExportInspectExportExcel.java rename nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/excel/{InspectExportExcel.java => ImportInspectExportExcel.java} (96%) diff --git a/nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/excel/ExportInspectExportExcel.java b/nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/excel/ExportInspectExportExcel.java new file mode 100644 index 0000000..215be6c --- /dev/null +++ b/nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/excel/ExportInspectExportExcel.java @@ -0,0 +1,52 @@ +package com.haitonggauto.rtosc.excel; + +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; + + +/** + * 出口进场基本表 + * @TableName customer_export_in + */ +@Data +public class ExportInspectExportExcel { + + @ExcelProperty("序号") + private Integer serialNo; + + @ExcelProperty("船名/航次") + private String shipVoyageName; + + @ExcelProperty("港区") + private String portArea; + + @ExcelProperty("装船日期") + private String unloadDate; + + @ExcelProperty("提单号") + private String billNo; + + @ExcelProperty("报关单号") + private String passport; + + @ExcelProperty("查验日期") + private String inspectTime; + + @ExcelProperty("品牌") + private String brand; + + @ExcelProperty("车型") + private String cartType; + + @ExcelProperty("车架号") + private String vin; + + @ExcelProperty("商品项号") + private String itemNo; + + @ExcelProperty("区") + private String area; + + @ExcelProperty("公司名称") + private String company; +} \ No newline at end of file diff --git a/nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/excel/InspectExportExcel.java b/nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/excel/ImportInspectExportExcel.java similarity index 96% rename from nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/excel/InspectExportExcel.java rename to nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/excel/ImportInspectExportExcel.java index 9a583c2..e514704 100644 --- a/nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/excel/InspectExportExcel.java +++ b/nuzar-customer-client/src/main/java/com/haitonggauto/rtosc/excel/ImportInspectExportExcel.java @@ -9,7 +9,7 @@ import lombok.Data; * @TableName customer_export_in */ @Data -public class InspectExportExcel { +public class ImportInspectExportExcel { @ExcelProperty("序号") private Integer serialNo; 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 b2a2e6b..dcf6105 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获取国家 diff --git a/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/api/NuzarPubApi.java b/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/api/NuzarPubApi.java index e4ac356..f139809 100644 --- a/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/api/NuzarPubApi.java +++ b/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/api/NuzarPubApi.java @@ -7,8 +7,8 @@ import org.springframework.web.bind.annotation.*; import java.util.List; -@FeignClient(name = "https://rtops4.haitongauto.com/tos/pub") -//@FeignClient(name = "basic-service") +//@FeignClient(name = "https://rtops4.haitongauto.com/tos/pub") +@FeignClient(name = "basic-service") public interface NuzarPubApi { diff --git a/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/api/NuzarShpApi.java b/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/api/NuzarShpApi.java index 22c33f2..0424981 100644 --- a/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/api/NuzarShpApi.java +++ b/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/api/NuzarShpApi.java @@ -12,8 +12,8 @@ import org.springframework.web.bind.annotation.RequestParam; import java.util.List; -@FeignClient(name = "https://rtops4.haitongauto.com/tos/shp") -//@FeignClient(name = "shipment-service") +//@FeignClient(name = "https://rtops4.haitongauto.com/tos/shp") +@FeignClient(name = "shipment-service") public interface NuzarShpApi { @GetMapping("/vesselVoyages/queryVvyName") 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 d8b3e2b..57f6097 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 @@ -2175,19 +2175,19 @@ public class ExportInHandler implements BaseHandler { .eq(CustomerExportIn::getBrand, brand) .eq(CustomerExportIn::getModels, models) .ne(CustomerExportIn::getCartType, "备件"); // 备件的不允许整船导入 - if (StringUtils.equals(type, "0")) { - cQuery.and((wrapper) -> { - wrapper.eq(CustomerExportIn::getCheckStatus, AuditEnum.SUBMIT) - .or() - .eq(CustomerExportIn::getCheckStatus, AuditEnum.AUDIT_REJECT); - }); - } else { - cQuery.and((wrapper) -> { - wrapper.eq(CustomerExportIn::getCheckStatus, AuditEnum.AUDIT) - .or() - .eq(CustomerExportIn::getCheckStatus, AuditEnum.AUDIT_REJECT); - }); - } +// if (StringUtils.equals(type, "0")) { +// cQuery.and((wrapper) -> { +// wrapper.eq(CustomerExportIn::getCheckStatus, AuditEnum.SUBMIT) +// .or() +// .eq(CustomerExportIn::getCheckStatus, AuditEnum.AUDIT_REJECT); +// }); +// } else { +// cQuery.and((wrapper) -> { +// wrapper.eq(CustomerExportIn::getCheckStatus, AuditEnum.AUDIT) +// .or() +// .eq(CustomerExportIn::getCheckStatus, AuditEnum.AUDIT_REJECT); +// }); +// } List exportInList = customerExportInService.list(cQuery); @@ -2230,14 +2230,14 @@ public class ExportInHandler implements BaseHandler { } } - if (exportIn.getCheckStatus() == AuditEnum.AUDIT_PASS) { // 审核 - errorDataList.addAll(item.getValue().stream().map(p -> { - JSONObject o = JSONObject.from(p); - o.put("status", "审核通过状态的不可导入"); - return o; - }).collect(Collectors.toList())); - return; - } +// if (exportIn.getCheckStatus() == AuditEnum.AUDIT_PASS) { // 审核 +// errorDataList.addAll(item.getValue().stream().map(p -> { +// JSONObject o = JSONObject.from(p); +// o.put("status", "审核通过状态的不可导入"); +// return o; +// }).collect(Collectors.toList())); +// return; +// } if (exportIn.getEnterQuantity() != item.getValue().size()) { errorDataList.addAll(item.getValue().stream().map(p -> { @@ -3010,7 +3010,7 @@ public class ExportInHandler implements BaseHandler { } if (countryList.stream().filter(p -> StringUtils.equalsIgnoreCase(p.getCiyCnname(), item.getOriginPlace())).count() == 0) { JSONObject o = JSONObject.from(item); - o.put("status", "产地代码错误"); + o.put("status", "产地错误"); errorDataList.add(o); return; } @@ -3062,7 +3062,7 @@ public class ExportInHandler implements BaseHandler { } if (energyTypeList.stream().filter(p -> StringUtils.equalsIgnoreCase(p.getText(), item.getEnergyTypeName())).count() == 0) { JSONObject o = JSONObject.from(item); - o.put("status", "源类型不存在"); + o.put("status", "能源类型不存在"); errorDataList.add(o); return; } @@ -3465,4 +3465,13 @@ public class ExportInHandler implements BaseHandler { return ResultUtil.success(rst, String.valueOf(page.getTotal())); } + + private void formatData(List ins) { + if (CollectionUtils.isEmpty(ins)) { + return; + } + ins.stream().forEach(item -> { + + }); + } } diff --git a/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/ExportInspectHandler.java b/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/ExportInspectHandler.java index 2933e88..ee89420 100644 --- a/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/ExportInspectHandler.java +++ b/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/ExportInspectHandler.java @@ -14,20 +14,17 @@ import com.haitonggauto.rtosc.api.NuzarOpenApi; import com.haitonggauto.rtosc.api.NuzarYardApi; import com.haitonggauto.rtosc.api.dto.*; import com.haitonggauto.rtosc.common.context.UserContext; +import com.haitonggauto.rtosc.common.db.query.BaseQuery; import com.haitonggauto.rtosc.common.dto.DictDTO; import com.haitonggauto.rtosc.common.dto.Result; import com.haitonggauto.rtosc.common.enums.ErrorType; import com.haitonggauto.rtosc.common.handler.BaseHandler; -import com.haitonggauto.rtosc.common.utils.DateUtils; import com.haitonggauto.rtosc.common.utils.ResultUtil; import com.haitonggauto.rtosc.common.utils.ValidationGroup; import com.haitonggauto.rtosc.common.utils.WrapperKit; import com.haitonggauto.rtosc.dto.*; -import com.haitonggauto.rtosc.excel.ExportInCargoExportExcel; -import com.haitonggauto.rtosc.excel.ExportInExportExcel; -import com.haitonggauto.rtosc.excel.InspectExportExcel; +import com.haitonggauto.rtosc.excel.ExportInspectExportExcel; import com.haitonggauto.rtosc.query.CargoQuery; -import com.haitonggauto.rtosc.query.ExportInCheckQuery; import com.haitonggauto.rtosc.query.ExportInspectCheckQuery; import com.haitonggauto.rtosc.query.ExportInspectQuery; import com.haitonggauto.rtosc.repository.entity.*; @@ -262,8 +259,8 @@ public class ExportInspectHandler implements BaseHandler { List inspectStatusStatus = openApi.getInspectStatusStatus(ids); Map collect = inspectStatusStatus.stream().collect(Collectors.toMap(InspectStatusResp::getApplyId, InspectStatusResp::getInspectionStatusNm)); page.getRecords().forEach(item -> { - if (collect.containsKey(item.getId()+"")) { - item.setApiInspectStatus(collect.get(item.getId()+"")); + if (collect.containsKey(item.getId() + "")) { + item.setApiInspectStatus(collect.get(item.getId() + "")); } }); } @@ -287,8 +284,8 @@ public class ExportInspectHandler implements BaseHandler { List inspectStatusStatus = openApi.getInspectStatusStatus(ids); Map collect = inspectStatusStatus.stream().collect(Collectors.toMap(InspectStatusResp::getApplyId, InspectStatusResp::getInspectionStatusNm)); page.getRecords().forEach(item -> { - if (collect.containsKey(item.getId()+"")) { - item.setApiInspectStatus(collect.get(item.getId()+"")); + if (collect.containsKey(item.getId() + "")) { + item.setApiInspectStatus(collect.get(item.getId() + "")); } }); } @@ -319,13 +316,14 @@ public class ExportInspectHandler implements BaseHandler { // 数据拼装 list.stream().forEach(item -> { - List cs = collect.get(item.getId()); + List cs = collect.get(item.getId()); item.setCargos(cs); }); } return ResultUtil.success(list); } + /** * 新增 * @@ -397,8 +395,8 @@ public class ExportInspectHandler implements BaseHandler { @ApiOperation("撤销提交审核") @PostMapping("/submit-check/reverse") public Result submitCheckReverse(@RequestBody - @NotNull(message = "请传入要审核的海关查验ID") - @Size(min = 1, message = "ID列表不能为空") List ids) { + @NotNull(message = "请传入要审核的海关查验ID") + @Size(min = 1, message = "ID列表不能为空") List ids) { customerExportInspectService.lambdaUpdate().set(CustomerExportInspect::getCheckStatus, AuditEnum.SUBMIT).in(CustomerExportInspect::getId, ids).update(); return ResultUtil.success("success"); } @@ -432,8 +430,8 @@ public class ExportInspectHandler implements BaseHandler { @ApiOperation("编辑") @PostMapping("/edit") // 使用LambdaUpdateWrapper只在特定需求下做处理(推荐) 将字段修改为空值的处理方法 - public Result edit(@RequestParam(required = false, defaultValue = "false")Boolean flag, - @RequestBody @Validated(ValidationGroup.update.class) ExportInspectVo form) { + public Result edit(@RequestParam(required = false, defaultValue = "false") Boolean flag, + @RequestBody @Validated(ValidationGroup.update.class) ExportInspectVo form) { if (CollectionUtils.isNotEmpty(form.getCargos())) { List repeat = form.getCargos().stream().collect(Collectors.groupingBy(ExportInspectCargoVo::getVin, Collectors.counting())) .entrySet().stream().filter(entry -> entry.getValue() > 1).map(entry -> entry.getKey()).collect(Collectors.toList()); @@ -494,8 +492,8 @@ public class ExportInspectHandler implements BaseHandler { if (CollectionUtils.isNotEmpty(ids)) { List inspectStatusStatus = openApi.getInspectStatusStatus(ids); Map collect = inspectStatusStatus.stream().collect(Collectors.toMap(InspectStatusResp::getApplyId, InspectStatusResp::getInspectionStatus)); - if (collect.containsKey(exportInspect.getId()+"")) { - exportInspect.setApiInspectStatus(collect.get(exportInspect.getId()+"")); + if (collect.containsKey(exportInspect.getId() + "")) { + exportInspect.setApiInspectStatus(collect.get(exportInspect.getId() + "")); } } @@ -684,8 +682,8 @@ public class ExportInspectHandler implements BaseHandler { } /** - * * 导出excel + * * @param response */ @ApiOperation("导出excel") @@ -698,6 +696,7 @@ public class ExportInspectHandler implements BaseHandler { query.setTradType("E"); query.setPage(1); query.setRows(500); +// query.setSorts(Arrays.asList(new BaseQuery.SortField("shipName", "desc"), new BaseQuery.SortField("voyage", "desc"), new BaseQuery.SortField("billNo", "desc"))); Wrapper queryWrapper = new WrapperKit() { }.changeBaseQueryToWrapper(CustomerExportInspect.class, query); ExcelWriter excelWriter = null; @@ -714,7 +713,7 @@ public class ExportInspectHandler implements BaseHandler { excelWriter = EasyExcel.write(out).build(); - WriteSheet writeSheet = EasyExcel.writerSheet(0, "出口查验计划清单").head(InspectExportExcel.class).build(); + WriteSheet writeSheet = EasyExcel.writerSheet(0, "出口查验计划清单").head(ExportInspectExportExcel.class).build(); // 查询数据 Page page = customerExportInspectService.page(new Page<>(query.getPage(), query.getRows()), queryWrapper); @@ -752,19 +751,35 @@ public class ExportInspectHandler implements BaseHandler { customerService.wrapperEntity(headers); - // 头映射 - Map collect = headers.stream().collect(Collectors.toMap(item -> item.getId(), item -> item)); + // 处理明细数据 - List list = customerExportInspectCargoService.lambdaQuery().in(CustomerExportInspectCargo::getExportInspectId, headers.stream().map(item -> item.getId()).collect(Collectors.toList())).list(); + List list = customerExportInspectCargoService.lambdaQuery() + .in(CustomerExportInspectCargo::getExportInspectId, headers.stream().map(item -> item.getId()).collect(Collectors.toList())).list(); - List details = list.stream().map(item -> { - CustomerExportInspect head = collect.get(item.getExportInspectId()); - InspectExportExcel e = PoMapper.instance.inspectEntity2ExportExcel(head, item); - e.setSerialNo(index.getAndIncrement()); - e.setShipVoyageName(StringUtils.join(head.getShipName(), "/", head.getVoyage())); - return e; - }).collect(Collectors.toList()); + // 表头按照船名,船航,提单号进行分组,找出对应的id + LinkedHashMap> inMap = headers.stream() + .collect(Collectors.groupingBy(item -> StringUtils.joinWith("#$#", item.getShipId(), item.getVoyageId(), item.getBillNo()), LinkedHashMap::new, Collectors.toList())); + + + inMap.entrySet().forEach(item -> { + // 头映射 + Map collect = item.getValue().stream().collect(Collectors.toMap(p -> p.getId(), p -> p)); + + List ids = item.getValue().stream().map(p -> p.getId()).collect(Collectors.toList()); + + // 备件号排序 + List details = list.stream().filter(p -> ids.contains(p.getExportInspectId())) + .sorted(Comparator.comparing(CustomerExportInspectCargo::getCartType).reversed()) + .map(p -> { + CustomerExportInspect head = collect.get(p.getExportInspectId()); + ExportInspectExportExcel e = PoMapper.instance.inspectEntity2ExportExcel(head, p); + e.setSerialNo(index.getAndIncrement()); + e.setShipVoyageName(StringUtils.join(head.getShipName(), "/", head.getVoyage())); + return e; + }).collect(Collectors.toList()); + + excelWriter.write(details, writeSheet); + }); - excelWriter.write(details, writeSheet); } } 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 2f7b55a..cb2f22c 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 @@ -4,7 +4,6 @@ import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.fastjson2.JSONObject; -import com.alibaba.fastjson2.util.UUIDUtils; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; @@ -20,7 +19,6 @@ import com.haitonggauto.rtosc.common.dto.DictDTO; import com.haitonggauto.rtosc.common.dto.Result; import com.haitonggauto.rtosc.common.enums.ErrorType; import com.haitonggauto.rtosc.common.handler.BaseHandler; -import com.haitonggauto.rtosc.common.utils.DateUtils; import com.haitonggauto.rtosc.common.utils.ResultUtil; import com.haitonggauto.rtosc.common.utils.ValidationGroup; import com.haitonggauto.rtosc.common.utils.WrapperKit; @@ -28,7 +26,6 @@ import com.haitonggauto.rtosc.dto.*; import com.haitonggauto.rtosc.excel.*; import com.haitonggauto.rtosc.handler.excel.CustomCellWriteHandler; import com.haitonggauto.rtosc.query.CargoQuery; -import com.haitonggauto.rtosc.query.ExportInCheckQuery; import com.haitonggauto.rtosc.query.ExportLoadCheckQuery; import com.haitonggauto.rtosc.query.ExportLoadQuery; import com.haitonggauto.rtosc.repository.entity.*; @@ -717,6 +714,10 @@ public class ExportLoadHandler implements BaseHandler { List status = openApi.getVinStatus(req); collect = status.stream().collect(Collectors.toMap(WorkStatusDTO::getVinCode, WorkStatusDTO::getWorkStatus)); } + for (CustomerExportLoadCargo cargo : page.getRecords()) { + cargo.setDestPortId(exportLoad.getDestPortId()); + cargo.setDestPort(exportLoad.getDestPort()); + } if (MapUtils.isNotEmpty(collect)) { for (CustomerExportLoadCargo cargo : page.getRecords()) { cargo.setWorkStatus(collect.get(cargo.getVin())); @@ -1409,8 +1410,8 @@ public class ExportLoadHandler implements BaseHandler { //普通下拉数据 Map map = new HashMap<>(); - String[] isZgArray = {"是", "否"}; - map.put(3, isZgArray); + String[] isZgArray = {"正常", "国内中转", "外进转内出", "长江","沿海"}; + map.put(2, isZgArray); //检查类型-子类 Map> inspNameMap = new HashMap<>(); //检查类型-父类 diff --git a/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/ImportInspectHandler.java b/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/ImportInspectHandler.java index 3dd28df..65e30fa 100644 --- a/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/ImportInspectHandler.java +++ b/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/ImportInspectHandler.java @@ -22,8 +22,8 @@ import com.haitonggauto.rtosc.common.utils.ResultUtil; import com.haitonggauto.rtosc.common.utils.ValidationGroup; import com.haitonggauto.rtosc.common.utils.WrapperKit; import com.haitonggauto.rtosc.dto.*; -import com.haitonggauto.rtosc.excel.ExportInExportExcel; -import com.haitonggauto.rtosc.excel.InspectExportExcel; +import com.haitonggauto.rtosc.excel.ExportInspectExportExcel; +import com.haitonggauto.rtosc.excel.ImportInspectExportExcel; import com.haitonggauto.rtosc.handler.mapper.PoMapper; import com.haitonggauto.rtosc.query.CargoQuery; import com.haitonggauto.rtosc.query.ExportInspectCheckQuery; @@ -679,7 +679,7 @@ public class ImportInspectHandler implements BaseHandler { excelWriter = EasyExcel.write(out).build(); - WriteSheet writeSheet = EasyExcel.writerSheet(0, "出口查验计划清单").head(InspectExportExcel.class).build(); + WriteSheet writeSheet = EasyExcel.writerSheet(0, "出口查验计划清单").head(ImportInspectExportExcel.class).build(); // 查询数据 Page page = customerExportInspectService.page(new Page<>(query.getPage(), query.getRows()), queryWrapper); @@ -717,19 +717,34 @@ public class ImportInspectHandler implements BaseHandler { customerService.wrapperEntity(headers); - // 头映射 - Map collect = headers.stream().collect(Collectors.toMap(item -> item.getId(), item -> item)); + // 处理明细数据 - List list = customerExportInspectCargoService.lambdaQuery().in(CustomerExportInspectCargo::getExportInspectId, headers.stream().map(item -> item.getId()).collect(Collectors.toList())).list(); + List list = customerExportInspectCargoService.lambdaQuery() + .in(CustomerExportInspectCargo::getExportInspectId, headers.stream().map(item -> item.getId()).collect(Collectors.toList())).list(); - List details = list.stream().map(item -> { - CustomerExportInspect head = collect.get(item.getExportInspectId()); - InspectExportExcel e = PoMapper.instance.inspectEntity2ExportExcel(head, item); - e.setSerialNo(index.getAndIncrement()); - e.setShipVoyageName(StringUtils.join(head.getShipName(), "/", head.getVoyage())); - return e; - }).collect(Collectors.toList()); + // 表头按照船名,船航,提单号进行分组,找出对应的id + LinkedHashMap> inMap = headers.stream() + .collect(Collectors.groupingBy(item -> StringUtils.joinWith("#$#", item.getShipId(), item.getVoyageId(), item.getBillNo()), LinkedHashMap::new, Collectors.toList())); - excelWriter.write(details, writeSheet); + + inMap.entrySet().forEach(item -> { + // 头映射 + Map collect = item.getValue().stream().collect(Collectors.toMap(p -> p.getId(), p -> p)); + + List ids = item.getValue().stream().map(p -> p.getId()).collect(Collectors.toList()); + + // 备件号排序 + List details = list.stream().filter(p -> ids.contains(p.getExportInspectId())) + .sorted(Comparator.comparing(CustomerExportInspectCargo::getCartType).reversed()) + .map(p -> { + CustomerExportInspect head = collect.get(p.getExportInspectId()); + ExportInspectExportExcel e = PoMapper.instance.inspectEntity2ExportExcel(head, p); + e.setSerialNo(index.getAndIncrement()); + e.setShipVoyageName(StringUtils.join(head.getShipName(), "/", head.getVoyage())); + return e; + }).collect(Collectors.toList()); + + excelWriter.write(details, writeSheet); + }); } } diff --git a/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/excel/CustomCellWriteHandler.java b/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/excel/CustomCellWriteHandler.java index fd1f708..62c63e7 100644 --- a/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/excel/CustomCellWriteHandler.java +++ b/nuzar-customer-controller/src/main/java/com/haitonggauto/rtosc/handler/excel/CustomCellWriteHandler.java @@ -3,6 +3,8 @@ package com.haitonggauto.rtosc.handler.excel; import com.alibaba.excel.write.handler.SheetWriteHandler; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.MapUtils; import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellRangeAddressList; @@ -52,99 +54,103 @@ public class CustomCellWriteHandler implements SheetWriteHandler { // 获取工作簿对象,用于创建存放下拉数据的字典sheet数据页 Workbook workbook = writeWorkbookHolder.getWorkbook(); - // 普通数据,迭代索引,用于存放下拉数据的字典sheet数据页命名 - int index = 1; - for (Map.Entry entry : map.entrySet()) { + if (MapUtils.isNotEmpty(map)) { + // 普通数据,迭代索引,用于存放下拉数据的字典sheet数据页命名 + int index = 1; + for (Map.Entry entry : map.entrySet()) { - // 设置存放下拉数据的字典sheet,并把这些sheet隐藏掉,这样用户交互更友好 - String dictSheetName = "dict_hide_sheet" + index; - Sheet dictSheet = workbook.createSheet(dictSheetName); - // 隐藏字典sheet页 - workbook.setSheetHidden(index++, true); + // 设置存放下拉数据的字典sheet,并把这些sheet隐藏掉,这样用户交互更友好 + String dictSheetName = "dict_hide_sheet" + index; + Sheet dictSheet = workbook.createSheet(dictSheetName); + // 隐藏字典sheet页 + workbook.setSheetHidden(index++, true); - // 设置下拉列表覆盖的行数,从第一行开始到最后一行,这里注意,Excel行的 - // 索引是从0开始的,我这边第0行是标题行,第1行开始时数据化,可根据实 - // 际业务设置真正的数据开始行,如果要设置到最后一行,那么一定注意, - // 最后一行的行索引是1048575,千万别写成1048576,不然会导致下拉列表 - // 失效,出不来 - CellRangeAddressList infoList = new CellRangeAddressList(1, 1048575, entry.getKey(), entry.getKey()); - int rowLen = entry.getValue().length; - for (int i = 0; i < rowLen; i++) { - // 向字典sheet写数据,从第一行开始写,此处可根据自己业务需要,自定 - // 义从第几行还是写,写的时候注意一下行索引是从0开始的即可 - dictSheet.createRow(i).createCell(0).setCellValue(entry.getValue()[i]); + // 设置下拉列表覆盖的行数,从第一行开始到最后一行,这里注意,Excel行的 + // 索引是从0开始的,我这边第0行是标题行,第1行开始时数据化,可根据实 + // 际业务设置真正的数据开始行,如果要设置到最后一行,那么一定注意, + // 最后一行的行索引是1048575,千万别写成1048576,不然会导致下拉列表 + // 失效,出不来 + CellRangeAddressList infoList = new CellRangeAddressList(1, 1048575, entry.getKey(), entry.getKey()); + int rowLen = entry.getValue().length; + for (int i = 0; i < rowLen; i++) { + // 向字典sheet写数据,从第一行开始写,此处可根据自己业务需要,自定 + // 义从第几行还是写,写的时候注意一下行索引是从0开始的即可 + dictSheet.createRow(i).createCell(0).setCellValue(entry.getValue()[i]); + } + + // 设置关联数据公式,这个格式跟Excel设置有效性数据的表达式是一样的 + String refers = dictSheetName + "!$A$1:$A$" + entry.getValue().length; + Name name = workbook.createName(); + name.setNameName(dictSheetName); + // 将关联公式和sheet页做关联 + name.setRefersToFormula(refers); + + // 将上面设置好的下拉列表字典sheet页和目标sheet关联起来 + DataValidationConstraint constraint = helper.createFormulaListConstraint(dictSheetName); + setValidation(sheet, helper, constraint, infoList); } - - // 设置关联数据公式,这个格式跟Excel设置有效性数据的表达式是一样的 - String refers = dictSheetName + "!$A$1:$A$" + entry.getValue().length; - Name name = workbook.createName(); - name.setNameName(dictSheetName); - // 将关联公式和sheet页做关联 - name.setRefersToFormula(refers); - - // 将上面设置好的下拉列表字典sheet页和目标sheet关联起来 - DataValidationConstraint constraint = helper.createFormulaListConstraint(dictSheetName); - setValidation(sheet, helper, constraint, infoList); } - - //检查类型-父类 - Sheet hideSheet = workbook.createSheet("site"); - workbook.setSheetHidden(workbook.getSheetIndex(hideSheet), false); - // 将具体的数据写入到每一行中,行开头为父级区域,后面是子区域。 - int rowId = 0; - Row proviRow = hideSheet.createRow(rowId++); - proviRow.createCell(0).setCellValue("大类列表"); - for (int i = 0; i < proInspNameArray.length; i++) { - Cell proviCell = proviRow.createCell(i + 1); - proviCell.setCellValue(proInspNameArray[i]); - } - //检查类型-子类 - Iterator keyIterator = inspNameArray.keySet().iterator(); - while (keyIterator.hasNext()) { - String key = keyIterator.next(); - List son = inspNameArray.get(key); - - Row row = hideSheet.createRow(rowId++); - row.createCell(0).setCellValue(key); - for (int i = 0; i < son.size(); i++) { - Cell cell = row.createCell(i + 1); - cell.setCellValue(son.get(i)); + if (MapUtils.isNotEmpty(inspNameArray) && MapUtils.isNotEmpty(probPropsNameArray)) { + //检查类型-父类 + Sheet hideSheet = workbook.createSheet("site"); + workbook.setSheetHidden(workbook.getSheetIndex(hideSheet), false); + // 将具体的数据写入到每一行中,行开头为父级区域,后面是子区域。 + int rowId = 0; + Row proviRow = hideSheet.createRow(rowId++); + proviRow.createCell(0).setCellValue("大类列表"); + for (int i = 0; i < proInspNameArray.length; i++) { + Cell proviCell = proviRow.createCell(i + 1); + proviCell.setCellValue(proInspNameArray[i]); } - // 添加名称管理器 - String range = getRange(1, rowId, son.size()); - Name name = workbook.createName(); - name.setNameName(key); - String formula = "site!" + range; - name.setRefersToFormula(formula); - } + //检查类型-子类 + Iterator keyIterator = inspNameArray.keySet().iterator(); + while (keyIterator.hasNext()) { + String key = keyIterator.next(); + List son = inspNameArray.get(key); - //问题属性 - Iterator probPropsNameIterator = probPropsNameArray.keySet().iterator(); - while (probPropsNameIterator.hasNext()) { - String key = probPropsNameIterator.next(); - List son = probPropsNameArray.get(key); - - Row row = hideSheet.createRow(rowId++); - row.createCell(0).setCellValue(key); - for (int i = 0; i < son.size(); i++) { - Cell cell = row.createCell(i + 1); - cell.setCellValue(son.get(i)); + Row row = hideSheet.createRow(rowId++); + row.createCell(0).setCellValue(key); + for (int i = 0; i < son.size(); i++) { + Cell cell = row.createCell(i + 1); + cell.setCellValue(son.get(i)); + } + // 添加名称管理器 + String range = getRange(1, rowId, son.size()); + Name name = workbook.createName(); + name.setNameName(key); + String formula = "site!" + range; + name.setRefersToFormula(formula); + } + + //问题属性 + Iterator probPropsNameIterator = probPropsNameArray.keySet().iterator(); + while (probPropsNameIterator.hasNext()) { + String key = probPropsNameIterator.next(); + List son = probPropsNameArray.get(key); + + Row row = hideSheet.createRow(rowId++); + row.createCell(0).setCellValue(key); + for (int i = 0; i < son.size(); i++) { + Cell cell = row.createCell(i + 1); + cell.setCellValue(son.get(i)); + } + // 添加名称管理器 + String range = getRange(1, rowId, son.size()); + Name name = workbook.createName(); + name.setNameName(key); + String formula = "site!" + range; + name.setRefersToFormula(formula); } - // 添加名称管理器 - String range = getRange(1, rowId, son.size()); - Name name = workbook.createName(); - name.setNameName(key); - String formula = "site!" + range; - name.setRefersToFormula(formula); } ///开始设置(大类小类)下拉框 DataValidationHelper dvHelper = sheet.getDataValidationHelper(); // 大类规则 - DataValidationConstraint expConstraint = dvHelper.createExplicitListConstraint(proInspNameArray); - CellRangeAddressList expRangeAddressList = new CellRangeAddressList(1, 1048575, 3, 3); - setValidation(sheet, dvHelper, expConstraint, expRangeAddressList); +// DataValidationConstraint expConstraint = dvHelper.createExplicitListConstraint(proInspNameArray); +// CellRangeAddressList expRangeAddressList = new CellRangeAddressList(1, 1048575, 3, 3); +// setValidation(sheet, dvHelper, expConstraint, expRangeAddressList); + //检查类型-子类 // 小类规则(各单元格按个设置) 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 ee09b94..e5dd4f0 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 @@ -97,5 +97,5 @@ public interface PoMapper { @Mapping(source = "cargo.cartType", target = "cartType") @Mapping(source = "cargo.vin", target = "vin") @Mapping(source = "head.company", target = "company") - InspectExportExcel inspectEntity2ExportExcel(CustomerExportInspect head, CustomerExportInspectCargo cargo); + ExportInspectExportExcel inspectEntity2ExportExcel(CustomerExportInspect head, CustomerExportInspectCargo cargo); } 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 7612fdb6479693fccf2213f98f9698c261103d4e..acbc30c53ecb27594eabf5ea29212681d1577e48 100644 GIT binary patch delta 6719 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