中转业务更新

This commit is contained in:
dengjun 2024-01-18 10:11:23 +08:00
parent a6170c3fe0
commit e5d129219d
16 changed files with 1078 additions and 19 deletions

View File

@ -1,8 +1,8 @@
package com.haitonggauto.rtosc.dto; package com.haitonggauto.rtosc.dto;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.haitonggauto.rtosc.common.utils.ValidationGroup; import com.haitonggauto.rtosc.common.utils.ValidationGroup;
import com.haitonggauto.rtosc.common.validate.DependsOn;
import com.haitonggauto.rtosc.common.validate.MoreThan; import com.haitonggauto.rtosc.common.validate.MoreThan;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
@ -11,7 +11,6 @@ import lombok.Data;
import javax.validation.Valid; import javax.validation.Valid;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable; import java.io.Serializable;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
@ -25,6 +24,7 @@ import java.util.List;
@Data @Data
@ApiModel(value = "出口进场基本表", description = "") @ApiModel(value = "出口进场基本表", description = "")
@MoreThan(groups = {ValidationGroup.insert.class, ValidationGroup.update.class}, field1 = "quantity", field2 = "eachQuantity", message = "数量不得超过单票件数") @MoreThan(groups = {ValidationGroup.insert.class, ValidationGroup.update.class}, field1 = "quantity", field2 = "eachQuantity", message = "数量不得超过单票件数")
@DependsOn(groups = {ValidationGroup.insert.class, ValidationGroup.update.class}, field1 = "natureFlagName", fields = {"transferShipId", "transferShipName", "transferVoyageId", "transferVoyage"}, message = "货物性质为“正常”时中转船ID中转船名中转航次ID中转航次为空 否则必填")
public class ExportInVo implements Serializable { public class ExportInVo implements Serializable {
@ApiModelProperty(value = "是否直接提交审核") @ApiModelProperty(value = "是否直接提交审核")
@ -70,6 +70,27 @@ public class ExportInVo implements Serializable {
@ApiModelProperty(value = "航次", required = true) @ApiModelProperty(value = "航次", required = true)
private String voyage; private String voyage;
@NotBlank(groups = {ValidationGroup.insert.class, ValidationGroup.update.class}, message = "货物性质ID不能为空")
@ApiModelProperty(value = "货物性质ID", required = true)
private String natureFlag;
@NotBlank(groups = {ValidationGroup.insert.class, ValidationGroup.update.class}, message = "货物性质名称不能为空")
@ApiModelProperty(value = "货物性质名称", required = true)
private String natureFlagName;
@ApiModelProperty(value = "中转船ID")
private String transferShipId;
@ApiModelProperty(value = "中转船名")
private String transferShipName;
@ApiModelProperty(value = "中转航次ID")
private String transferVoyageId;
@ApiModelProperty(value = "中转航次名")
private String transferVoyage;
/** /**
* 港区ID * 港区ID
*/ */
@ -160,16 +181,14 @@ public class ExportInVo implements Serializable {
@ApiModelProperty(value = "运输方式", required = true) @ApiModelProperty(value = "运输方式", required = true)
private String transportWay; private String transportWay;
@NotNull(groups = {ValidationGroup.insert.class, ValidationGroup.update.class}, message = "进场开始时间不能为空") @ApiModelProperty(value = "进场开始时间")
@ApiModelProperty(value = "进场开始时间", required = true)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date beginEnterTime; private Date beginEnterTime;
/** /**
* 进场开始时间 * 进场开始时间
*/ */
@NotNull(groups = {ValidationGroup.insert.class, ValidationGroup.update.class}, message = "进场结束时间不能为空") @ApiModelProperty(value = "进场结束时间")
@ApiModelProperty(value = "进场结束时间", required = true)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date endEnterTime; private Date endEnterTime;

View File

@ -0,0 +1,32 @@
package com.haitonggauto.rtosc.excel;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
@Data
public class ExportInBillSpareExcel {
@ExcelProperty("*船名")
@NotBlank(message = "船名不能为空")
private String shipName;
@ExcelProperty("*航次")
@NotBlank(message = "航次不能为空")
private String voyage;
@ExcelProperty("*提单号")
@NotBlank(message = "提单号不能为空")
private String billNo;
@ExcelProperty("*品牌")
@NotBlank(message = "品牌不能为空")
private String brand;
@ExcelProperty("*备件号")
@NotBlank(message = "备件号不能为空")
@Size(min = 17, max = 17, message = "备件号长度为17位")
private String vin;
}

View File

@ -3,6 +3,9 @@ package com.haitonggauto.rtosc.excel;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat; import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.alibaba.excel.annotation.format.NumberFormat; import com.alibaba.excel.annotation.format.NumberFormat;
import com.baomidou.mybatisplus.annotation.TableField;
import com.haitonggauto.rtosc.common.utils.ValidationGroup;
import com.haitonggauto.rtosc.common.validate.DependsOn;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
@ -34,6 +37,7 @@ import java.util.Date;
* 19.源类型必须是是新能源不是新能源否则的导入不成功 * 19.源类型必须是是新能源不是新能源否则的导入不成功
*/ */
@Data @Data
@DependsOn(field1 = "natureFlagName", fields = {"transferShipName", "transferVoyage"}, message = "货物性质为“正常”时中转船ID中转船名中转航次ID中转航次为空 否则必填")
public class ExportInPlanExcel { public class ExportInPlanExcel {
/** /**
@ -57,6 +61,16 @@ public class ExportInPlanExcel {
@NotBlank(message = "航次不能为空") @NotBlank(message = "航次不能为空")
private String voyage; private String voyage;
@ExcelProperty("*货物性质")
@NotBlank(message = "货物性质不能为空")
private String natureFlagName;
@ExcelProperty("中转进口船名")
private String transferShipName;
@ExcelProperty("中转进口航次")
private String transferVoyage;
/** /**
* 货代 * 货代

View File

@ -0,0 +1,28 @@
package com.haitonggauto.rtosc.excel;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
/**
* 出口进场基本表
* @TableName customer_export_in
*/
@Data
@ApiModel
public class ExportInSpareExcel {
/**
* 船名
*/
@NotBlank(message = "备件号不能为空")
@Size(min = 17, max = 17, message = "备件号长度为17位")
@ApiModelProperty(value = "备件号")
@ExcelProperty("*备件号")
private String vin;
}

View File

@ -1,6 +1,7 @@
package com.haitonggauto.rtosc.excel; package com.haitonggauto.rtosc.excel;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import com.haitonggauto.rtosc.common.validate.DependsOn;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
@ -8,6 +9,7 @@ import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size; import javax.validation.constraints.Size;
@Data @Data
@DependsOn(field1 = "natureFlagName", fields = {"transferShipName", "transferVoyage"}, message = "货物性质为“正常”时中转船ID中转船名中转航次ID中转航次为空 否则必填")
public class ExportLoadInsideExcel { public class ExportLoadInsideExcel {
@ExcelProperty("*船名") @ExcelProperty("*船名")
@ -18,6 +20,16 @@ public class ExportLoadInsideExcel {
@NotBlank(message = "航次不能为空") @NotBlank(message = "航次不能为空")
private String voyage; private String voyage;
@ExcelProperty("*货物性质")
@NotBlank(message = "货物性质不能为空")
private String natureFlagName;
@ExcelProperty("中转进口船名")
private String transferShipName;
@ExcelProperty("中转进口航次")
private String transferVoyage;
@ExcelProperty("*港区") @ExcelProperty("*港区")
@NotBlank(message = "港区不能为空") @NotBlank(message = "港区不能为空")
private String portArea; private String portArea;
@ -30,7 +42,7 @@ public class ExportLoadInsideExcel {
@NotBlank(message = "品牌不能为空") @NotBlank(message = "品牌不能为空")
private String brand; private String brand;
@ExcelProperty("*目的港") @ExcelProperty("目的港")
private String destPort; private String destPort;
@ExcelProperty("*车架号") @ExcelProperty("*车架号")

View File

@ -0,0 +1,32 @@
package com.haitonggauto.rtosc.common.validate;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
/**
* 一个字段依赖于另一个字段
*/
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = DependsOnValidator.class)
public @interface DependsOn {
/**
* 违反校验时的错误信息
*/
String message() default "{DependsOn.message}";
/**
* 用于指定校验的条件
*/
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
// 比较字段一
String field1();
// 比较字段二
String[] fields();
}

View File

@ -0,0 +1,62 @@
package com.haitonggauto.rtosc.common.validate;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanWrapperImpl;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class DependsOnValidator implements ConstraintValidator<DependsOn, Object> {
// 字段一
private String field1;
// 字段二
private String[] fields;
@Override
public void initialize(final DependsOn constraintAnnotation) {
field1 = constraintAnnotation.field1();
fields = constraintAnnotation.fields();
}
@Override
public boolean isValid(final Object src, ConstraintValidatorContext context) {
BeanWrapperImpl wrapper = new BeanWrapperImpl(src);
if (StringUtils.isAnyEmpty(field1, field1)) {
return false;
}
Object value1 = wrapper.getPropertyValue(field1);
if (value1 == null) {
for (String field : fields) {
String v = (String) wrapper.getPropertyValue(field);
if (StringUtils.isNotEmpty(v)) {
return false;
}
}
return true;
}
if (value1 != null) {
if (StringUtils.equals("正常", (String)value1)) {
for (String field : fields) {
String v = (String) wrapper.getPropertyValue(field);
if (StringUtils.isNotEmpty(v)) {
return false;
}
}
} else {
for (String field : fields) {
String v = (String) wrapper.getPropertyValue(field);
if (StringUtils.isEmpty(v)) {
return false;
}
}
}
return true;
}
return false;
}
}

View File

@ -24,6 +24,10 @@ public interface NuzarPubApi {
@GetMapping(value = "/typeRef/domain/TRADE_TYPE") @GetMapping(value = "/typeRef/domain/TRADE_TYPE")
List<NuzarDictDTO> getTradType(); List<NuzarDictDTO> getTradType();
// 获取获物性质
@GetMapping(value = "/typeRef/domain/GOODS_NATURE")
List<NuzarDictDTO> getGoodsNatureList();
// 所有船舶 // 所有船舶
@GetMapping(value = "/shipManage/queryAllShipManage") @GetMapping(value = "/shipManage/queryAllShipManage")
List<ShipDTO> getAllShip(); List<ShipDTO> getAllShip();
@ -63,4 +67,9 @@ public interface NuzarPubApi {
// 根据客户名称查询客户信息 // 根据客户名称查询客户信息
@GetMapping(value = "/customerManage/query/name") @GetMapping(value = "/customerManage/query/name")
CompanyDTO getCompanyByName(@RequestParam("cueCnname") String cueCnname); CompanyDTO getCompanyByName(@RequestParam("cueCnname") String cueCnname);
// 船舶管理下拉框模糊查询
@GetMapping(value = "/shipManage/queryLikeShipManage")
List<ShipDTO> getShipList(@RequestParam("key") String key, @RequestParam("query") String query, @RequestParam("spmId") String spmId
, @RequestParam("valid") String valid, @RequestParam("vslCd") String vslCd, @RequestParam("vslCnname") String vslCnname, @RequestParam("vslEnnameList") List<String> vslEnnameList);
} }

View File

@ -12,8 +12,8 @@ import org.springframework.web.bind.annotation.RequestParam;
import java.util.List; import java.util.List;
//@FeignClient(name = "https://rtops4.haitongauto.com/tos/shp") @FeignClient(name = "https://rtops4.haitongauto.com/tos/shp")
@FeignClient(name = "shipment-service") //@FeignClient(name = "shipment-service")
public interface NuzarShpApi { public interface NuzarShpApi {
@GetMapping("/vesselVoyages/queryVvyName") @GetMapping("/vesselVoyages/queryVvyName")
@ -24,4 +24,9 @@ public interface NuzarShpApi {
@PostMapping("/vesselVoyages/queryVvyListByVvNameAndSpmName") @PostMapping("/vesselVoyages/queryVvyListByVvNameAndSpmName")
List<VoyageResp> queryVvyListByVvNameAndSpmName(@RequestBody List<VoyageReq> req); List<VoyageResp> queryVvyListByVvNameAndSpmName(@RequestBody List<VoyageReq> req);
// 获取航次
@GetMapping("/vesselVoyages/queryByKey")
List<VoyageResp> queryVoyageByKey(@RequestParam("ieType") String ieType, @RequestParam("key") String key, @RequestParam("pamId") String pamId, @RequestParam("spmId") String spmId
, @RequestParam("tradeType") String tradeType);
} }

View File

@ -3,6 +3,7 @@ package com.haitonggauto.rtosc.handler;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.haitonggauto.rtosc.api.NuzarOpenApi; import com.haitonggauto.rtosc.api.NuzarOpenApi;
import com.haitonggauto.rtosc.api.NuzarPubApi; import com.haitonggauto.rtosc.api.NuzarPubApi;
import com.haitonggauto.rtosc.api.NuzarShpApi;
import com.haitonggauto.rtosc.api.dto.*; import com.haitonggauto.rtosc.api.dto.*;
import com.haitonggauto.rtosc.common.context.UserContext; import com.haitonggauto.rtosc.common.context.UserContext;
import com.haitonggauto.rtosc.common.dto.DictDTO; import com.haitonggauto.rtosc.common.dto.DictDTO;
@ -41,15 +42,15 @@ import java.util.stream.Collectors;
@Validated @Validated
public class DictHandler implements BaseHandler { public class DictHandler implements BaseHandler {
@Resource
private LoginHandler loginHandler;
@Resource @Resource
private NuzarPubApi nuzarPubApi; private NuzarPubApi nuzarPubApi;
@Resource @Resource
private NuzarOpenApi nuzarOpenApi; private NuzarOpenApi nuzarOpenApi;
@Resource
private NuzarShpApi nuzarShpApi;
@Resource @Resource
private CustomerLinkmanService customerLinkmanService; private CustomerLinkmanService customerLinkmanService;
@ -446,4 +447,49 @@ public class DictHandler implements BaseHandler {
} }
} }
@ApiOperation("货物性质")
@GetMapping("/goodsNature")
public Result<List<NuzarDictDTO>> getGoodsNature() {
List<NuzarDictDTO> list = nuzarPubApi.getGoodsNatureList();
if (CollectionUtils.isEmpty(list)) {
return ResultUtil.success(Collections.emptyList());
} else {
}
return ResultUtil.success(list);
}
@ApiOperation("获取船名")
@GetMapping(value = "/shipManage/queryLikeShipManage")
public Result<List<ShipDTO>> getShipList(@RequestParam(value = "key", required = false) String key, @RequestParam(value = "query", required = false) String query, @RequestParam(value = "spmId", required = false) String spmId
, @RequestParam(value = "valid", required = false) String valid, @RequestParam(value = "vslCd", required = false) String vslCd, @RequestParam(value = "vslCnname", required = false) String vslCnname, @RequestParam(value = "vslEnnameList", required = false) List<String> vslEnnameList) {
List<ShipDTO> list = nuzarPubApi.getShipList(key, query, spmId, valid, vslCd, vslCnname, vslEnnameList);
if (CollectionUtils.isEmpty(list)) {
return ResultUtil.success(Collections.emptyList());
} else {
}
return ResultUtil.success(list);
}
@ApiOperation("获取航次")
@GetMapping("/vesselVoyages/queryByKey")
public Result<List<VoyageResp>> queryVoyageByKey(@RequestParam(value = "ieType", required = false) String ieType, @RequestParam(value = "key", required = false) String key, @RequestParam(value = "pamId", required = false) String pamId, @RequestParam(value = "spmId", required = false) String spmId
, @RequestParam(value = "tradeType", required = false) String tradeType) {
List<VoyageResp> list = nuzarShpApi.queryVoyageByKey(ieType, key, pamId, spmId, tradeType);
if (CollectionUtils.isEmpty(list)) {
return ResultUtil.success(Collections.emptyList());
} else {
}
return ResultUtil.success(list);
}
} }

View File

@ -683,7 +683,7 @@ public class ExportInHandler implements BaseHandler {
entity.setVinStatus(1); entity.setVinStatus(1);
return entity; return entity;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
if (CollectionUtils.isEmpty(spares) && StringUtils.equalsAnyIgnoreCase(exportIn.getCartType(), "备件", "BJ")) { if (CollectionUtils.isEmpty(spares) && StringUtils.equalsAnyIgnoreCase(exportIn.getCartType(), "备件", "BJ") && StringUtils.equals("正常", exportIn.getNatureFlagName())) {
// 出口进场计划备件条码生成的规则要变一下BJ+年月日时分+5随机数一共要17位 // 出口进场计划备件条码生成的规则要变一下BJ+年月日时分+5随机数一共要17位
String prefix = StringUtils.join("BJ", DateUtil.format(new Date(), "yyMMddHHmm")); String prefix = StringUtils.join("BJ", DateUtil.format(new Date(), "yyMMddHHmm"));
List<String> vins = new ArrayList<>(exportIn.getQuantity()); List<String> vins = new ArrayList<>(exportIn.getQuantity());
@ -931,6 +931,7 @@ public class ExportInHandler implements BaseHandler {
*/ */
@ApiOperation("编辑") @ApiOperation("编辑")
@PostMapping("/edit") @PostMapping("/edit")
@Transactional(rollbackFor = {Exception.class})
// 使用LambdaUpdateWrapper只在特定需求下做处理推荐 将字段修改为空值的处理方法 // 使用LambdaUpdateWrapper只在特定需求下做处理推荐 将字段修改为空值的处理方法
public Result<String> edit(@RequestParam(required = false, defaultValue = "false") Boolean flag, public Result<String> edit(@RequestParam(required = false, defaultValue = "false") Boolean flag,
@RequestBody @Validated(ValidationGroup.update.class) ExportInVo form) { @RequestBody @Validated(ValidationGroup.update.class) ExportInVo form) {
@ -954,6 +955,7 @@ public class ExportInHandler implements BaseHandler {
if (in.getCheckStatus() == AuditEnum.AUDIT_PASS) { if (in.getCheckStatus() == AuditEnum.AUDIT_PASS) {
return ResultUtil.failure(ErrorType.PARAMS_ERROR.id(), "审核通过之后不能进行编辑"); return ResultUtil.failure(ErrorType.PARAMS_ERROR.id(), "审核通过之后不能进行编辑");
} }
String batchNo = in.getBatchNo(); String batchNo = in.getBatchNo();
// 表单验证以及格式转换 // 表单验证以及格式转换
CustomerExportIn exportIn = PoMapper.instance.exportInVo2Entity(form); CustomerExportIn exportIn = PoMapper.instance.exportInVo2Entity(form);
@ -965,6 +967,9 @@ public class ExportInHandler implements BaseHandler {
exportIn.setCheckStatus(AuditEnum.AUDIT); exportIn.setCheckStatus(AuditEnum.AUDIT);
} }
// 判断货物性质是否发生变化
boolean f = StringUtils.equals(in.getNatureFlagName(), exportIn.getNatureFlagName());
List<CustomerExportInCargo> cargos = form.getCargos().stream().map(item -> { List<CustomerExportInCargo> cargos = form.getCargos().stream().map(item -> {
CustomerExportInCargo entity = PoMapper.instance.exportInCargoVo2Entity(item); CustomerExportInCargo entity = PoMapper.instance.exportInCargoVo2Entity(item);
entity.setBrand(exportIn.getBrand()); entity.setBrand(exportIn.getBrand());
@ -997,7 +1002,7 @@ public class ExportInHandler implements BaseHandler {
return entity; return entity;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(spares)) { if (CollectionUtils.isNotEmpty(spares) || (!f && StringUtils.equalsAnyIgnoreCase(exportIn.getCartType(), "备件", "BJ") && StringUtils.equalsAnyIgnoreCase(exportIn.getNatureFlagName(), "正常"))) {
// 验证数量 // 验证数量
if (exportIn.getQuantity() < spares.size()) { if (exportIn.getQuantity() < spares.size()) {
return ResultUtil.failure(ErrorType.PROGRAM_ERROR.id(), "备件列表不能大于备件总数"); return ResultUtil.failure(ErrorType.PROGRAM_ERROR.id(), "备件列表不能大于备件总数");
@ -1103,6 +1108,11 @@ public class ExportInHandler implements BaseHandler {
} }
} }
// 货物性质发生变化时需要清空表
if (!f && StringUtils.equalsAnyIgnoreCase(exportIn.getCartType(), "备件", "BJ")) {
customerExportInCargoService.lambdaUpdate().eq(CustomerExportInCargo::getExportInId, in.getId()).remove();
}
customerService.updateExportIn(false, exportIn, cargos, times, spares); customerService.updateExportIn(false, exportIn, cargos, times, spares);
return ResultUtil.success(String.valueOf(exportIn.getId())); return ResultUtil.success(String.valueOf(exportIn.getId()));
@ -1840,7 +1850,7 @@ public class ExportInHandler implements BaseHandler {
List<ExportVinExcel> existData = item.getValue().stream().filter(p -> existVins.contains(p.getVin())).collect(Collectors.toList()); List<ExportVinExcel> existData = item.getValue().stream().filter(p -> existVins.contains(p.getVin())).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(existData)) { if (CollectionUtils.isNotEmpty(existData)) {
errorDataList.addAll(item.getValue().stream().map(p -> { errorDataList.addAll(existData.stream().map(p -> {
JSONObject o = JSONObject.from(p); JSONObject o = JSONObject.from(p);
o.put("status", "数据已存在"); o.put("status", "数据已存在");
return o; return o;
@ -1871,6 +1881,192 @@ public class ExportInHandler implements BaseHandler {
return ResultUtil.success(errorDataList); return ResultUtil.success(errorDataList);
} }
@ApiOperation("备件号导入模板下载")
@GetMapping("/temp/down/spare")
public void tmpDownSpare(HttpServletResponse response) throws Exception {
ExcelWriter excelWriter = null;
OutputStream out = null;
try {
out = response.getOutputStream();
// 这里注意 有同学反应使用swagger 会导致各种问题请直接用浏览器或者用postman
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
String fileName = URLEncoder.encode("备件号导入模板", "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
excelWriter = EasyExcel.write(out).build();
WriteSheet writeSheet = EasyExcel.writerSheet(0, "备件号").head(ExportInSpareExcel.class).build();
// 查询数据
List<ExportInSpareExcel> rows = new ArrayList<>();
excelWriter.write(rows, writeSheet);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (excelWriter != null) {
excelWriter.finish();
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@ApiOperation("备件号导入")
@PostMapping("/import-spare")
public Result<List<JSONObject>> importSpare(@RequestParam(required = false) @NotNull(message = "出口进场ID不能为空") Long id, MultipartFile file) throws IOException {
CustomerExportIn exportIn = customerExportInService.getById(id);
List<Long> 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<ExportInSpareExcel> dataList = new ArrayList<>();
// 有错误的数据
List<JSONObject> errorDataList = new ArrayList<>();
// 验证成功的数据
List<JSONObject> successDataList = new ArrayList<>();
// 要存储的数据
List<CustomerExportInCargo> saveCargos = new ArrayList<>();
EasyExcel.read(file.getInputStream(), ExportInSpareExcel.class, new ReadExcelListener<ExportInSpareExcel>() {
@Override
protected void saveData(List<ExportInSpareExcel> list) { // 缓存数据
dataList.addAll(list);
}
}).sheet().doRead();
ValidatorFactory vf = Validation.buildDefaultValidatorFactory();
Validator validator = vf.getValidator();
List<ExportInSpareExcel> validData = new ArrayList<>();
// 数据验证
dataList.stream().forEach(item -> {
Set<ConstraintViolation<ExportInSpareExcel>> set = validator.validate(item);
if (CollectionUtils.isEmpty(set)) { // 验证通过的
validData.add(item);
} else { // 验证失败的
JSONObject o = JSONObject.from(item);
o.put("status", set.stream().map(p -> p.getMessage()).collect(Collectors.joining(",")));
errorDataList.add(o);
}
});
if (CollectionUtils.isEmpty(validData)) {
return ResultUtil.failure(ErrorType.PARAMS_ERROR.id(), "导入失败", errorDataList);
}
// 是否有重复的车架号
List<String> repeat = validData.stream().collect(Collectors.groupingBy(ExportInSpareExcel::getVin, Collectors.counting()))
.entrySet().stream().filter(entry -> entry.getValue() > 1).map(entry -> entry.getKey()).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(repeat)) {
errorDataList.addAll(validData.stream().filter(p -> repeat.contains(p.getVin())).map(p -> {
JSONObject o = JSONObject.from(p);
o.put("status", "车架号重复");
return o;
}).collect(Collectors.toList()));
return ResultUtil.failure(ErrorType.PARAMS_ERROR.id(), "导入失败", errorDataList);
}
if (exportIn.getQuantity() != validData.size()) {
errorDataList.addAll(validData.stream().map(p -> {
JSONObject o = JSONObject.from(p);
o.put("status", "数量不一致");
return o;
}).collect(Collectors.toList()));
return ResultUtil.failure(ErrorType.PARAMS_ERROR.id(), "导入失败", errorDataList);
}
List<CustomerExportInCargo> cargos = validData.stream().map(p -> {
CustomerExportInCargo cargo = new CustomerExportInCargo();
cargo.setExportInId(exportIn.getId());
cargo.setBrand(exportIn.getBrand());
cargo.setBrandId(exportIn.getBrandId());
cargo.setCargoType(0);
cargo.setVin(p.getVin());
cargo.setTermcd(exportIn.getPortAreaId());
cargo.setVinStatus(1);
return cargo;
}).collect(Collectors.toList());
List<String> vins = cargos.stream().map(p -> p.getVin()).collect(Collectors.toList());
// 验证哪些车架号已经存在了
List<CustomerExportInCargo> existCargos = customerExportInCargoService.list(new LambdaQueryWrapper<CustomerExportInCargo>().in(CustomerExportInCargo::getVin, vins).ne(CustomerExportInCargo::getExportInId, exportIn.getId()));
List<String> existVins = existCargos.stream().map(p -> p.getVin()).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(existCargos)) {
// 查询出对应的港区
List<CustomerExportIn> sList = customerExportInService.lambdaQuery().in(CustomerExportIn::getId, existCargos.stream().map(ss -> ss.getExportInId()).collect(Collectors.toList())).list();
Map<Long, String> portAreaMap = sList.stream().collect(Collectors.toMap(CustomerExportIn::getId, CustomerExportIn::getPortAreaId));
// 通过接口再次验证
List<CheckVinReq> req = existCargos.stream().map(ss -> {
CheckVinReq v = new CheckVinReq();
v.setIsRepetition(true);
v.setPamId(portAreaMap.get(ss.getExportInId()));
v.setVinCode(ss.getVin());
return v;
}).collect(Collectors.toList());
List<CheckVinReq> rst = shpApi.checkVinRepeat(req);
existVins.clear();
if (CollectionUtils.isNotEmpty(rst)) {
// 再次过滤出重复的
List<CheckVinReq> sCollect = rst.stream().filter(ss -> ss.getIsRepetition()).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(sCollect)) {
existVins.addAll(sCollect.stream().map(ss -> ss.getVinCode()).collect(Collectors.toList()));
}
}
}
List<ExportInSpareExcel> existData = validData.stream().filter(p -> existVins.contains(p.getVin())).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(existData)) {
errorDataList.addAll(existData.stream().map(p -> {
JSONObject o = JSONObject.from(p);
o.put("status", "数据已存在");
return o;
}).collect(Collectors.toList()));
}
successDataList.addAll(validData.stream().filter(p -> !existVins.contains(p.getVin()))
.map(p -> {
JSONObject o = JSONObject.from(p);
o.put("status", "数据验证成功");
return o;
}).collect(Collectors.toList()));
saveCargos.addAll(cargos.stream().filter(p -> !existVins.contains(p.getVin())).collect(Collectors.toList()));
if (CollectionUtils.isNotEmpty(errorDataList)) {
errorDataList.addAll(successDataList);
return ResultUtil.failure(ErrorType.PARAMS_ERROR.id(), "导入失败", errorDataList);
}
if (CollectionUtils.isNotEmpty(saveCargos)) {
// 删除原有的车架号
customerExportInCargoService.lambdaUpdate().eq(CustomerExportInCargo::getExportInId, exportIn.getId()).remove();
customerExportInCargoService.saveBatch(saveCargos);
}
return ResultUtil.success(errorDataList);
}
@ApiOperation("整船清单导入模板下载") @ApiOperation("整船清单导入模板下载")
@GetMapping("/temp/down/ship") @GetMapping("/temp/down/ship")
public void tmpDownShip(HttpServletResponse response) throws Exception { public void tmpDownShip(HttpServletResponse response) throws Exception {
@ -2095,7 +2291,268 @@ public class ExportInHandler implements BaseHandler {
List<ExportLoadExcel> existData = item.getValue().stream().filter(p -> existVins.contains(p.getVin())).collect(Collectors.toList()); List<ExportLoadExcel> existData = item.getValue().stream().filter(p -> existVins.contains(p.getVin())).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(existData)) { if (CollectionUtils.isNotEmpty(existData)) {
errorDataList.addAll(item.getValue().stream().filter(p -> existVins.contains(p.getVin())).map(p -> { errorDataList.addAll(existData.stream().map(p -> {
JSONObject o = JSONObject.from(p);
o.put("status", "数据已存在, 未导入");
return o;
}).collect(Collectors.toList()));
successDataList.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 {
successDataList.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()));
}
saveCargos.addAll(cargos.stream().filter(p -> !existVins.contains(p.getVin())).collect(Collectors.toList()));
});
if (CollectionUtils.isNotEmpty(errorDataList)) {
errorDataList.addAll(successDataList);
return ResultUtil.failure(ErrorType.PARAMS_ERROR.id(), "导入失败", errorDataList);
}
if (CollectionUtils.isNotEmpty(saveCargos)) {
// 删除原有的车架号
customerExportInCargoService.lambdaUpdate().in(CustomerExportInCargo::getExportInId, ids).remove();
customerExportInCargoService.saveBatch(saveCargos);
}
return ResultUtil.success(errorDataList);
}
@ApiOperation("整票备件号导入模板下载")
@GetMapping("/temp/spare/down/ship")
public void tmpDownShipSpare(HttpServletResponse response) throws Exception {
ExcelWriter excelWriter = null;
OutputStream out = null;
try {
out = response.getOutputStream();
// 这里注意 有同学反应使用swagger 会导致各种问题请直接用浏览器或者用postman
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
String fileName = URLEncoder.encode("整票备件号导入模板", "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
excelWriter = EasyExcel.write(out).build();
WriteSheet writeSheet = EasyExcel.writerSheet(0, "整票备件号").head(ExportInBillSpareExcel.class).build();
// 查询数据
List<ExportInBillSpareExcel> rows = new ArrayList<>();
excelWriter.write(rows, writeSheet);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (excelWriter != null) {
excelWriter.finish();
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@ApiOperation("整票备件号导入")
@PostMapping("/import-to-add/spare")
public Result<List<JSONObject>> uploadSpare(
@ApiParam(name = "操作方式, 0为前端1为审核端") @RequestParam(required = false, defaultValue = "0") String type,
MultipartFile file) throws IOException {
// 所有读取的数据
List<ExportInBillSpareExcel> dataList = new ArrayList<>();
// 有错误的数据
List<JSONObject> errorDataList = new ArrayList<>();
// 验证成功的数据
List<JSONObject> successDataList = new ArrayList<>();
// 需要清空的
List<Long> ids = new ArrayList<>();
// 要保存到数据库的数据
List<CustomerExportInCargo> saveCargos = new ArrayList<>();
EasyExcel.read(file.getInputStream(), ExportLoadExcel.class, new ReadExcelListener<ExportInBillSpareExcel>() {
@Override
protected void saveData(List<ExportInBillSpareExcel> list) { // 保存数据
dataList.addAll(list);
}
}).sheet().doRead();
ValidatorFactory vf = Validation.buildDefaultValidatorFactory();
Validator validator = vf.getValidator();
List<ExportInBillSpareExcel> validData = new ArrayList<>();
// 数据验证
dataList.stream().forEach(item -> {
Set<ConstraintViolation<ExportInBillSpareExcel>> set = validator.validate(item);
if (CollectionUtils.isEmpty(set)) { // 验证通过的
validData.add(item);
} else { // 验证失败的
JSONObject o = JSONObject.from(item);
o.put("status", set.stream().map(p -> p.getMessage()).collect(Collectors.joining(",")));
errorDataList.add(o);
}
});
// 所有数据验证都不通过
if (CollectionUtils.isEmpty(validData)) {
return ResultUtil.failure(ErrorType.PARAMS_ERROR.id(), "导入失败", errorDataList);
}
// 首先按对船名般次提单进行分组
Map<String, List<ExportInBillSpareExcel>> collect = validData.stream()
.collect(Collectors.groupingBy(item -> StringUtils.joinWith("#$#", item.getShipName(), item.getVoyage(), item.getBillNo(), item.getBrand()), Collectors.toList()));
collect.entrySet().forEach(item -> {
String[] keys = StringUtils.split(item.getKey(), "#$#");
String shipName = keys[0]; // 船名
String voyage = keys[1]; // 航次
String billNo = keys[2]; // 提单号
String brand = keys[3]; // 品牌
// 找到是否存在船名航次提单号的表头
LambdaQueryWrapper<CustomerExportIn> cQuery = new LambdaQueryWrapper<>();
cQuery.eq(CustomerExportIn::getShipName, shipName)
.eq(CustomerExportIn::getVoyage, voyage)
.eq(CustomerExportIn::getBillNum, billNo)
.eq(CustomerExportIn::getBrand, brand)
.eq(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);
});
}
List<CustomerExportIn> exportInList = customerExportInService.list(cQuery);
if (CollectionUtils.isEmpty(exportInList)) { // 船名航次等不存在
errorDataList.addAll(item.getValue().stream().map(p -> {
JSONObject o = JSONObject.from(p);
o.put("status", "船名、航次、提单号、品牌不存在");
return o;
}).collect(Collectors.toList()));
return;
}
// 找到和本次数量一致的
Optional<CustomerExportIn> first = exportInList.stream().filter(p -> p.getQuantity() == item.getValue().size()).findFirst();
CustomerExportIn exportIn = first.isPresent() ? first.get() : null;
if (exportIn == null) {
errorDataList.addAll(item.getValue().stream().map(p -> {
JSONObject o = JSONObject.from(p);
o.put("status", "数量不一致不允许导入");
return o;
}).collect(Collectors.toList()));
return;
}
ids.add(exportIn.getId());
// 已生成装船计划不能导入
List<Long> havePlans = openApi.haveShipPlan(exportIn.getVoyageId());
if (exportIn != null && CollectionUtils.isNotEmpty(havePlans)) {
Boolean c = havePlans.contains(exportIn.getId());
if (c) {
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 -> {
JSONObject o = JSONObject.from(p);
o.put("status", "车架号数量和实际货物数量不符合,无法导入");
return o;
}).collect(Collectors.toList()));
return;
}
List<CustomerExportInCargo> cargos = item.getValue().stream().map(p -> {
CustomerExportInCargo cargo = new CustomerExportInCargo();
cargo.setBrandId(exportIn.getBrandId());
cargo.setBrand(exportIn.getBrand());
cargo.setExportInId(exportIn.getId());
cargo.setCargoType(1);
cargo.setVin(p.getVin());
cargo.setTermcd(exportIn.getPortAreaId());
cargo.setVinStatus(1);
return cargo;
}).collect(Collectors.toList());
List<String> vins = cargos.stream().map(p -> p.getVin()).collect(Collectors.toList());
// 验证哪些车架号已经存在了
List<CustomerExportInCargo> existCargos = customerExportInCargoService.list(new LambdaQueryWrapper<CustomerExportInCargo>().in(CustomerExportInCargo::getVin, vins).ne(CustomerExportInCargo::getExportInId, exportIn.getId()));
List<String> existVins = existCargos.stream().map(p -> p.getVin()).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(existCargos)) {
// 查询出对应的港区
List<CustomerExportIn> sList = customerExportInService.lambdaQuery().in(CustomerExportIn::getId, existCargos.stream().map(ss -> ss.getExportInId()).collect(Collectors.toList())).list();
Map<Long, String> portAreaMap = sList.stream().collect(Collectors.toMap(CustomerExportIn::getId, CustomerExportIn::getPortAreaId));
// 通过接口再次验证
List<CheckVinReq> req = existCargos.stream().map(ss -> {
CheckVinReq v = new CheckVinReq();
v.setIsRepetition(true);
v.setPamId(portAreaMap.get(ss.getExportInId()));
v.setVinCode(ss.getVin());
return v;
}).collect(Collectors.toList());
List<CheckVinReq> rst = shpApi.checkVinRepeat(req);
existVins.clear(); // 先清空
if (CollectionUtils.isNotEmpty(rst)) {
// 再次过滤出重复的
List<CheckVinReq> sCollect = rst.stream().filter(ss -> ss.getIsRepetition()).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(sCollect)) {
existVins.addAll(sCollect.stream().map(ss -> ss.getVinCode()).collect(Collectors.toList()));
}
}
}
List<ExportInBillSpareExcel> existData = item.getValue().stream().filter(p -> existVins.contains(p.getVin())).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(existData)) {
errorDataList.addAll(existData.stream().map(p -> {
JSONObject o = JSONObject.from(p); JSONObject o = JSONObject.from(p);
o.put("status", "数据已存在, 未导入"); o.put("status", "数据已存在, 未导入");
return o; return o;
@ -2481,9 +2938,12 @@ public class ExportInHandler implements BaseHandler {
Map<String, DictDTO> portCountryList = new HashMap<>(); Map<String, DictDTO> portCountryList = new HashMap<>();
// 货代列表 // 货代列表
Map<String, String> companyMap = new HashMap<>(); Map<String, String> companyMap = new HashMap<>();
// 货物性质
List<NuzarDictDTO> goodsNature = dictHandler.getGoodsNature().getData();
// 车型明细缓存 // 车型明细缓存
Map<String, List<DictDTO>> carDetailTypeList = new HashMap<>(); Map<String, List<DictDTO>> carDetailTypeList = new HashMap<>();
// 航次缴存
Map<String, List<VoyageResp>> voyageMap = new HashMap<>();
EasyExcel.read(file.getInputStream(), ExportInPlanExcel.class, new ReadExcelListener<ExportInPlanExcel>() { EasyExcel.read(file.getInputStream(), ExportInPlanExcel.class, new ReadExcelListener<ExportInPlanExcel>() {
@Override @Override
@ -2606,6 +3066,30 @@ public class ExportInHandler implements BaseHandler {
errorDataList.add(o); errorDataList.add(o);
return; return;
} }
if (goodsNature.stream().filter(p -> StringUtils.equalsIgnoreCase(p.getPtrDesc(), item.getNatureFlagName())).count() == 0) {
JSONObject o = JSONObject.from(item);
o.put("status", "货物性质不存在");
errorDataList.add(o);
return;
}
if (!StringUtils.equals(item.getNatureFlagName(), "正常")) {
if (shipList.stream().filter(p -> StringUtils.equalsIgnoreCase(p.getText(), item.getTransferShipName())).count() == 0) {
JSONObject o = JSONObject.from(item);
o.put("status", "中转进口船名不存在");
errorDataList.add(o);
return;
}
if (!voyageMap.containsKey(item.getTransferShipName())) {
List<VoyageResp> data = dictHandler.queryVoyageByKey(null, null, null, shipList.stream().filter(p -> StringUtils.equalsIgnoreCase(p.getText(), item.getTransferShipName())).findFirst().get().getId(), null).getData();
voyageMap.put(item.getTransferShipName(), data);
}
if (voyageMap.get(item.getTransferShipName()).stream().filter(p -> StringUtils.equalsIgnoreCase(p.getVvyName(), item.getTransferVoyage())).count() == 0) {
JSONObject o = JSONObject.from(item);
o.put("status", "中转进口航次不存在");
errorDataList.add(o);
return;
}
}
Date bDate = DateUtils.parseDate(StringUtils.trim(item.getBeginEnterTime()), "yyyy/MM/dd"); Date bDate = DateUtils.parseDate(StringUtils.trim(item.getBeginEnterTime()), "yyyy/MM/dd");
if (bDate == null) { if (bDate == null) {
JSONObject o = JSONObject.from(item); JSONObject o = JSONObject.from(item);
@ -2683,6 +3167,11 @@ public class ExportInHandler implements BaseHandler {
in.setApplicantId(UserContext.getUser().getUserId()); in.setApplicantId(UserContext.getUser().getUserId());
in.setTermcd(in.getPortAreaId()); in.setTermcd(in.getPortAreaId());
in.setVolume(in.getLength().multiply(in.getWidth()).multiply(in.getHeight()).setScale(4, RoundingMode.HALF_UP)); // 计算体积 in.setVolume(in.getLength().multiply(in.getWidth()).multiply(in.getHeight()).setScale(4, RoundingMode.HALF_UP)); // 计算体积
in.setNatureFlag(goodsNature.stream().filter(p -> StringUtils.equalsIgnoreCase(p.getPtrDesc(), item.getNatureFlagName())).findFirst().get().getPtrCode());
if (!StringUtils.equals(item.getNatureFlagName(), "正常")) {
in.setTransferShipId(shipList.stream().filter(p -> StringUtils.equalsIgnoreCase(p.getText(), item.getTransferShipName())).findFirst().get().getId());
in.setTransferVoyageId(voyageMap.get(in.getTransferShipName()).stream().filter(p -> StringUtils.equalsIgnoreCase(p.getVvyName(), item.getTransferVoyage())).findFirst().get().getVvyId());
}
if (in.getEnterQuantity() == null) { if (in.getEnterQuantity() == null) {
in.setEnterQuantity(in.getQuantity()); in.setEnterQuantity(in.getQuantity());
} }
@ -2756,7 +3245,7 @@ public class ExportInHandler implements BaseHandler {
// 如果是备件自动生成条码 // 如果是备件自动生成条码
// 过滤出是备件的 // 过滤出是备件的
item.getValue().stream().filter(ss -> StringUtils.equals(ss.getCartType(), "备件")).forEach(ss -> { item.getValue().stream().filter(ss -> StringUtils.equals(ss.getCartType(), "备件") && StringUtils.equals(ss.getNatureFlagName(), "正常")).forEach(ss -> {
// 判断是否是国际中转航次ID // 判断是否是国际中转航次ID
String vvyId = ss.getVoyageId(); String vvyId = ss.getVoyageId();
TransitPartRequest request = new TransitPartRequest(); TransitPartRequest request = new TransitPartRequest();

View File

@ -26,6 +26,7 @@ import com.haitonggauto.rtosc.common.utils.ValidationGroup;
import com.haitonggauto.rtosc.common.utils.WrapperKit; import com.haitonggauto.rtosc.common.utils.WrapperKit;
import com.haitonggauto.rtosc.dto.*; import com.haitonggauto.rtosc.dto.*;
import com.haitonggauto.rtosc.excel.*; import com.haitonggauto.rtosc.excel.*;
import com.haitonggauto.rtosc.handler.excel.CustomCellWriteHandler;
import com.haitonggauto.rtosc.query.CargoQuery; import com.haitonggauto.rtosc.query.CargoQuery;
import com.haitonggauto.rtosc.query.ExportInCheckQuery; import com.haitonggauto.rtosc.query.ExportInCheckQuery;
import com.haitonggauto.rtosc.query.ExportLoadCheckQuery; import com.haitonggauto.rtosc.query.ExportLoadCheckQuery;
@ -1406,7 +1407,20 @@ public class ExportLoadHandler implements BaseHandler {
String fileName = URLEncoder.encode("内贸整船车辆导入模板", "UTF-8"); String fileName = URLEncoder.encode("内贸整船车辆导入模板", "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
excelWriter = EasyExcel.write(out).build(); //普通下拉数据
Map<Integer, String[]> map = new HashMap<>();
String[] isZgArray = {"", ""};
map.put(3, isZgArray);
//检查类型-子类
Map<String, List<String>> inspNameMap = new HashMap<>();
//检查类型-父类
String[] proInspNameMap = new String[0];
//问题属性
Map<String, List<String>> probPropsNameMap = new HashMap<>();
excelWriter = EasyExcel.write(out)
.registerWriteHandler(new CustomCellWriteHandler(map, proInspNameMap, inspNameMap, probPropsNameMap))
.build();
WriteSheet writeSheet = EasyExcel.writerSheet(0, "内贸整船车辆导入模板").head(ExportLoadInsideExcel.class).build(); WriteSheet writeSheet = EasyExcel.writerSheet(0, "内贸整船车辆导入模板").head(ExportLoadInsideExcel.class).build();
@ -1457,9 +1471,14 @@ public class ExportLoadHandler implements BaseHandler {
List<DictDTO> shipList = dictHandler.getAllShip(null).getData(); List<DictDTO> shipList = dictHandler.getAllShip(null).getData();
// 港区基础数据 // 港区基础数据
List<DictDTO> portAreaList = dictHandler.getPortAreaList(null).getData(); List<DictDTO> portAreaList = dictHandler.getPortAreaList(null).getData();
// 货物性质
List<NuzarDictDTO> goodsNature = dictHandler.getGoodsNature().getData();
// 缓存航次信息 // 缓存航次信息
Map<String, String> voyageMap = new HashMap<>(); Map<String, String> voyageMap = new HashMap<>();
// 缓存中转航次信息
Map<String, List<VoyageResp>> transferVoyageMap = new HashMap<>();
EasyExcel.read(file.getInputStream(), ExportLoadInsideExcel.class, new ReadExcelListener<ExportLoadInsideExcel>() { EasyExcel.read(file.getInputStream(), ExportLoadInsideExcel.class, new ReadExcelListener<ExportLoadInsideExcel>() {
@Override @Override
protected void saveData(List<ExportLoadInsideExcel> list) { // 保存数据 protected void saveData(List<ExportLoadInsideExcel> list) { // 保存数据
@ -1541,6 +1560,31 @@ public class ExportLoadHandler implements BaseHandler {
errorDataList.add(o); errorDataList.add(o);
return; return;
} }
if (goodsNature.stream().filter(p -> StringUtils.equalsIgnoreCase(p.getPtrDesc(), item.getNatureFlagName())).count() == 0) {
JSONObject o = JSONObject.from(item);
o.put("status", "货物性质不存在");
errorDataList.add(o);
return;
}
if (!StringUtils.equals(item.getNatureFlagName(), "正常")) {
if (shipList.stream().filter(p -> StringUtils.equalsIgnoreCase(p.getText(), item.getTransferShipName())).count() == 0) {
JSONObject o = JSONObject.from(item);
o.put("status", "中转进口船名不存在");
errorDataList.add(o);
return;
}
if (!transferVoyageMap.containsKey(item.getTransferShipName())) {
List<VoyageResp> data = dictHandler.queryVoyageByKey(null, null, null, shipList.stream().filter(p -> StringUtils.equalsIgnoreCase(p.getText(), item.getTransferShipName())).findFirst().get().getId(), null).getData();
transferVoyageMap.put(item.getTransferShipName(), data);
}
if (transferVoyageMap.get(item.getTransferShipName()).stream().filter(p -> StringUtils.equalsIgnoreCase(p.getVvyName(), item.getTransferVoyage())).count() == 0) {
JSONObject o = JSONObject.from(item);
o.put("status", "中转进口航次不存在");
errorDataList.add(o);
return;
}
}
if (CollectionUtils.containsAny(list, item.getSettleCompName())) { if (CollectionUtils.containsAny(list, item.getSettleCompName())) {
JSONObject o = JSONObject.from(item); JSONObject o = JSONObject.from(item);
o.put("status", "相同提单号需保持结费单位相同"); o.put("status", "相同提单号需保持结费单位相同");
@ -1684,6 +1728,11 @@ public class ExportLoadHandler implements BaseHandler {
exportLoad.setPortArea(item.getValue().get(0).getPortArea()); exportLoad.setPortArea(item.getValue().get(0).getPortArea());
exportLoad.setContact(item.getValue().get(0).getContact()); exportLoad.setContact(item.getValue().get(0).getContact());
exportLoad.setContactPhone(item.getValue().get(0).getContactPhone()); exportLoad.setContactPhone(item.getValue().get(0).getContactPhone());
exportLoad.setNatureFlag(goodsNature.stream().filter(p -> StringUtils.equalsIgnoreCase(p.getPtrDesc(), item.getValue().get(0).getNatureFlagName())).findFirst().get().getPtrCode());
if (!StringUtils.equals(item.getValue().get(0).getNatureFlagName(), "正常")) {
exportLoad.setTransferShipId(shipList.stream().filter(p -> StringUtils.equalsIgnoreCase(p.getText(), item.getValue().get(0).getTransferShipName())).findFirst().get().getId());
exportLoad.setTransferVoyageId(transferVoyageMap.get(exportLoad.getTransferShipName()).stream().filter(p -> StringUtils.equalsIgnoreCase(p.getVvyName(), item.getValue().get(0).getTransferVoyage())).findFirst().get().getVvyId());
}
if (StringUtils.isNotEmpty(item.getValue().get(0).getDestPort())) { // 内贸目的港可以为空 if (StringUtils.isNotEmpty(item.getValue().get(0).getDestPort())) { // 内贸目的港可以为空
exportLoad.setDestPort(item.getValue().get(0).getDestPort()); exportLoad.setDestPort(item.getValue().get(0).getDestPort());
exportLoad.setDestPortId(portList.stream().filter(s -> StringUtils.equals(s.getText(), item.getValue().get(0).getDestPort())).findFirst().get().getId()); exportLoad.setDestPortId(portList.stream().filter(s -> StringUtils.equals(s.getText(), item.getValue().get(0).getDestPort())).findFirst().get().getId());

View File

@ -0,0 +1,214 @@
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.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddressList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class CustomCellWriteHandler implements SheetWriteHandler {
/**
* 普通下拉数据
*/
private Map<Integer, String[]> map;
/**
* 检查类型-父类
*/
private String[] proInspNameArray;
/**
* 检查类型-子类
*/
private Map<String, List<String>> inspNameArray;
/**
* 问题属性
*/
private Map<String, List<String>> probPropsNameArray;
public CustomCellWriteHandler(Map<Integer, String[]> map, String[] proInspNameArray, Map<String, List<String>> inspNameArray, Map<String, List<String>> probPropsNameArray) {
this.map = map;
this.proInspNameArray = proInspNameArray;
this.inspNameArray = inspNameArray;
this.probPropsNameArray = probPropsNameArray;
}
@Override
public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
}
@Override
public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
// 获取第一个sheet页
Sheet sheet = writeSheetHolder.getCachedSheet();
// 获取sheet页的数据校验对象
DataValidationHelper helper = sheet.getDataValidationHelper();
// 获取工作簿对象用于创建存放下拉数据的字典sheet数据页
Workbook workbook = writeWorkbookHolder.getWorkbook();
// 普通数据迭代索引用于存放下拉数据的字典sheet数据页命名
int index = 1;
for (Map.Entry<Integer, String[]> entry : map.entrySet()) {
// 设置存放下拉数据的字典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设置有效性数据的表达式是一样的
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<String> keyIterator = inspNameArray.keySet().iterator();
while (keyIterator.hasNext()) {
String key = keyIterator.next();
List<String> 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));
}
// 添加名称管理器
String range = getRange(1, rowId, son.size());
Name name = workbook.createName();
name.setNameName(key);
String formula = "site!" + range;
name.setRefersToFormula(formula);
}
//问题属性
Iterator<String> probPropsNameIterator = probPropsNameArray.keySet().iterator();
while (probPropsNameIterator.hasNext()) {
String key = probPropsNameIterator.next();
List<String> 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);
}
///开始设置大类小类下拉框
DataValidationHelper dvHelper = sheet.getDataValidationHelper();
// 大类规则
DataValidationConstraint expConstraint = dvHelper.createExplicitListConstraint(proInspNameArray);
CellRangeAddressList expRangeAddressList = new CellRangeAddressList(1, 1048575, 3, 3);
setValidation(sheet, dvHelper, expConstraint, expRangeAddressList);
//检查类型-子类
// 小类规则(各单元格按个设置)
// "INDIRECT($A$" + 2 + ")" 表示规则数据会从名称管理器中获取key与单元格 A2 值相同的数据如果A2是浙江省那么此处就是浙江省下面的市
// 为了让每个单元格的公式能动态适应使用循环挨个给公式
// 循环几次就有几个单元格生效次数要和上面的大类影响行数一一对应要不然最后几个没对上的单元格实现不了级联
for (int i = 2; i < inspNameArray.size() + 10; i++) {
CellRangeAddressList rangeAddressList = new CellRangeAddressList(i-1 , i-1, 4, 4);
DataValidationConstraint formula = dvHelper.createFormulaListConstraint("INDIRECT($D$" + i + ")");
setValidation(sheet, dvHelper, formula, rangeAddressList);
}
//问题属性
for (int i = 2; i < probPropsNameArray.size() + 10; i++) {
CellRangeAddressList rangeAddressList = new CellRangeAddressList(i-1 , i-1, 5, 5);
DataValidationConstraint formula = dvHelper.createFormulaListConstraint("INDIRECT($E$" + i + ")");
setValidation(sheet, dvHelper, formula, rangeAddressList);
}
}
/**
* 设置验证规则
* @param sheet sheet对象
* @param helper 验证助手
* @param constraint createExplicitListConstraint
* @param addressList 验证位置对象
*/
private void setValidation(Sheet sheet, DataValidationHelper helper, DataValidationConstraint constraint, CellRangeAddressList addressList) {
DataValidation dataValidation = helper.createValidation(constraint, addressList);
dataValidation.createErrorBox("错误提示", "您输入的内容,不符合限制条件");
sheet.addValidationData(dataValidation);
}
/**
* @param offset 偏移量如果给0表示从A列开始1就是从B列
* @param rowId 第几行
* @param colCount 一共多少列
* @return 如果给入参 1,1,10. 表示从B1-K1最终返回 $B$1:$K$1
* @author denggonghai 2016年8月31日 下午5:17:49
*/
public String getRange(int offset, int rowId, int colCount) {
char start = (char) ('A' + offset);
if (colCount <= 25) {
char end = (char) (start + colCount - 1);
return "$" + start + "$" + rowId + ":$" + end + "$" + rowId;
} else {
char endPrefix = 'A';
char endSuffix = 'A';
if ((colCount - 25) / 26 == 0 || colCount == 51) {// 26-51之间包括边界仅两次字母表计算
if ((colCount - 25) % 26 == 0) {// 边界值
endSuffix = (char) ('A' + 25);
} else {
endSuffix = (char) ('A' + (colCount - 25) % 26 - 1);
}
} else {// 51以上
if ((colCount - 25) % 26 == 0) {
endSuffix = (char) ('A' + 25);
endPrefix = (char) (endPrefix + (colCount - 25) / 26 - 1);
} else {
endSuffix = (char) ('A' + (colCount - 25) % 26 - 1);
endPrefix = (char) (endPrefix + (colCount - 25) / 26);
}
}
return "$" + start + "$" + rowId + ":$" + endPrefix + endSuffix + "$" + rowId;
}
}
}

View File

@ -70,6 +70,30 @@ public class CustomerExportIn extends BaseEntity implements Serializable {
@EsLogMean(name = "航次", title = true) @EsLogMean(name = "航次", title = true)
private String voyage; private String voyage;
@TableField(value = "nature_flag")
@ApiModelProperty(value = "货物性质ID")
private String natureFlag;
@TableField(value = "nature_flag_name")
@ApiModelProperty(value = "货物性质名称")
private String natureFlagName;
@TableField(value = "transfer_ship_id")
@ApiModelProperty(value = "中转船ID")
private String transferShipId;
@TableField(value = "transfer_ship_name")
@ApiModelProperty(value = "中转船名")
private String transferShipName;
@TableField(value = "transfer_voyage_id")
@ApiModelProperty(value = "中转航次ID")
private String transferVoyageId;
@TableField(value = "transfer_voyage")
@ApiModelProperty(value = "中转航次名")
private String transferVoyage;
/** /**
* 港区ID * 港区ID
*/ */

View File

@ -76,6 +76,30 @@ public class CustomerExportLoad extends BaseEntity implements Serializable {
@EsLogMean(name = "航次", title = true) @EsLogMean(name = "航次", title = true)
private String voyage; private String voyage;
@TableField(value = "nature_flag")
@ApiModelProperty(value = "货物性质ID")
private String natureFlag;
@TableField(value = "nature_flag_name")
@ApiModelProperty(value = "货物性质名称")
private String natureFlagName;
@TableField(value = "transfer_ship_id")
@ApiModelProperty(value = "中转船ID")
private String transferShipId;
@TableField(value = "transfer_ship_name")
@ApiModelProperty(value = "中转船名")
private String transferShipName;
@TableField(value = "transfer_voyage_id")
@ApiModelProperty(value = "中转航次ID")
private String transferVoyageId;
@TableField(value = "transfer_voyage")
@ApiModelProperty(value = "中转航次名")
private String transferVoyage;
/** /**
* 港区ID * 港区ID
*/ */