mirror of
http://192.168.1.205:9980/cf_devdept2/cf_imes_server.git
synced 2026-08-12 12:52:07 +08:00
文件导入改善
This commit is contained in:
@@ -89,6 +89,9 @@
|
||||
|
||||
<!-- 拼音 -->
|
||||
<pingyinfj.version>2.5.1</pingyinfj.version>
|
||||
<xlsx-streamer.version>2.1.0</xlsx-streamer.version>
|
||||
<stax-api.version>1.0-2</stax-api.version>
|
||||
<excel-poi.version>4.1.2</excel-poi.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
@@ -511,6 +514,17 @@
|
||||
<version>${easyexcel.verion}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi</artifactId>
|
||||
<version>${excel-poi.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
<version>${excel-poi.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
@@ -647,6 +661,26 @@
|
||||
<version>${pingyinfj.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.monitorjbl/xlsx-streamer -->
|
||||
<dependency>
|
||||
<groupId>com.monitorjbl</groupId>
|
||||
<artifactId>xlsx-streamer</artifactId>
|
||||
<version>${xlsx-streamer.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/javax.xml.stream/stax-api -->
|
||||
<dependency>
|
||||
<groupId>javax.xml.stream</groupId>
|
||||
<artifactId>stax-api</artifactId>
|
||||
<version>${stax-api.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
<!-- SMS SDK begin -->
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
|
||||
@@ -152,6 +152,31 @@
|
||||
<artifactId>podam</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.monitorjbl/xlsx-streamer -->
|
||||
<dependency>
|
||||
<groupId>com.monitorjbl</groupId>
|
||||
<artifactId>xlsx-streamer</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.xml.stream</groupId>
|
||||
<artifactId>stax-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- JSON -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
|
||||
+37
-38
@@ -24,10 +24,9 @@ import com.cf.imes.module.executor.service.order.OrderService;
|
||||
import com.cf.imes.module.executor.util.ExcelWriterUtil;
|
||||
import com.cf.imes.module.executor.util.fileConversion.admin.api.webcad.ApiDataAchieve;
|
||||
import com.cf.imes.module.executor.util.fileConversion.admin.api.webcad.ApiTypeRealize;
|
||||
import com.cf.imes.module.executor.util.fileConversion.admin.files.excel.ExcelReadUtil;
|
||||
import com.cf.imes.module.executor.util.fileConversion.admin.files.excel.ExcelTypeRealize;
|
||||
import com.cf.imes.module.executor.util.fileConversion.admin.files.excel.OrderPlateImportExcelVO;
|
||||
import com.cf.imes.module.executor.util.fileConversion.admin.files.excel.*;
|
||||
import com.cf.imes.module.executor.util.fileConversion.admin.files.xml.VO.OrderXmlVO;
|
||||
import com.cf.imes.module.executor.util.fileConversion.admin.files.xml.VO.XmlCheckVO;
|
||||
import com.cf.imes.module.executor.util.fileConversion.admin.files.xml.XMLUtil;
|
||||
import com.cf.imes.module.executor.util.fileConversion.admin.files.xml.XmlBuilder;
|
||||
import com.cf.imes.module.executor.util.fileConversion.admin.files.xml.XmlTypeRealize;
|
||||
@@ -72,7 +71,10 @@ public class OrderController {
|
||||
private OrderMapper orderMapper;
|
||||
|
||||
@Resource
|
||||
private ExcelReadUtil excelReadUtil;
|
||||
private LargeFilesUtils largeFilesUtils;
|
||||
|
||||
@Resource
|
||||
private ExcelCheckListUtil excelCheckListUtil;
|
||||
|
||||
@Resource
|
||||
private ApiDataAchieve apiDataAchieve;
|
||||
@@ -256,10 +258,10 @@ public class OrderController {
|
||||
Map<String, Object> listMap = null;
|
||||
|
||||
OrderDO orderDO = null;
|
||||
Map<String, Object> mapOrder = null;
|
||||
Map<String, String> mapOrder = null;
|
||||
|
||||
Boolean flag = true;
|
||||
String customOrderNoKey = "自定义单号";
|
||||
|
||||
boolean isLocked = redisLockUtil.lock(lockKey);
|
||||
if (!isLocked) {
|
||||
log.error(errKey, errValue);
|
||||
@@ -267,45 +269,39 @@ public class OrderController {
|
||||
} else {
|
||||
try {
|
||||
if (type == 0) { //excel
|
||||
excelReadUtil.setErr(0);
|
||||
Map<String, Object> map = excelReadUtil.read(file);
|
||||
list = (List<OrderPlateImportExcelVO>) map.get("plate");
|
||||
mapOrder = (Map<String, Object>) map.get("orderPri");
|
||||
|
||||
List<OrderPlateImportExcelVO>[] listBoth = largeFilesUtils.importExcelLargeFile(file);// 表头+列表
|
||||
list = listBoth[1];// 列表
|
||||
mapOrder = largeFilesUtils.changeToOrderMap(listBoth[0]); // 表头
|
||||
|
||||
if (index == 0) { // 全部
|
||||
if (mapOrder != null) {
|
||||
Map<String, Object> mapChange = excelReadUtil.changeOrderDO(mapOrder);
|
||||
mapOrder = (Map<String, Object>) mapChange.get("file");
|
||||
orderDO = (OrderDO) mapChange.get("order");
|
||||
orderDO.setId((Long) snowFlakeGenerator.nextId(null));
|
||||
AtomicBoolean error = (AtomicBoolean) mapChange.get("error");
|
||||
flag = error.get();
|
||||
}
|
||||
} else {
|
||||
ExcelCheckVO excelCheckVO = excelCheckListUtil.checkExcelList(mapOrder); // 表头验证
|
||||
orderDO = excelCheckVO.getOrderDO();
|
||||
orderDO.setId((Long) snowFlakeGenerator.nextId(null));
|
||||
flag = excelCheckVO.getFlag();
|
||||
} else { // 补板
|
||||
orderDO = orderService.getOrder(orderId);
|
||||
if (orderDO == null) {
|
||||
mapOrder = new HashMap<>();
|
||||
mapOrder.put("自定义单号", "生产单号不存在");
|
||||
mapOrder.put(ProduceExcelConstants.ORDER_CUSTOM_ORDER_NO, "---< 生产单号不存在 >---");
|
||||
flag = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (mapOrder == null) {
|
||||
mapOrder = new HashMap<>();
|
||||
mapOrder.put(customOrderNoKey, "生产单内容解析为空");
|
||||
String customOrderNo = mapOrder.get(ProduceExcelConstants.ORDER_CUSTOM_ORDER_NO);
|
||||
if (index == 0 && customOrderNo != null && !orderService.customOrderNoIsExists(customOrderNo)) {
|
||||
mapOrder.put(ProduceExcelConstants.ORDER_CUSTOM_ORDER_NO, customOrderNo + "重复");
|
||||
flag = false;
|
||||
}else if (orderDO == null) {
|
||||
mapOrder.put(customOrderNoKey, "生产单内为空");
|
||||
flag = false;
|
||||
} else if (index == 0 && orderDO.getCustomOrderNo() != null && !orderService.customOrderNoIsExists(orderDO.getCustomOrderNo())) {
|
||||
mapOrder.put(customOrderNoKey, mapOrder.get(customOrderNoKey) + customOrderNoKey + "重复");
|
||||
flag = false;
|
||||
} else if ( excelReadUtil.isErr() > 0 ){
|
||||
flag = false;
|
||||
} else if ( excelReadUtil.isErr() == 0 && flag ){
|
||||
if (list.size() == 0) {
|
||||
}
|
||||
|
||||
if (flag){
|
||||
// list 校验
|
||||
ExcelCheckVO excelCheckVO = excelCheckListUtil.checkExcelLargeFile(listBoth[1]);
|
||||
list = excelCheckVO.getList();
|
||||
flag = excelCheckVO.getFlag() & flag;
|
||||
if (excelCheckVO.getFlag() && excelCheckVO.getList().size() == 0) {
|
||||
orderDO.setStatus(OrderStatusEnum.EMPTY.getStatus());
|
||||
} else {
|
||||
} else if (excelCheckVO.getFlag()){
|
||||
orderDO.setStatus(OrderStatusEnum.NEW_ORDER.getStatus());
|
||||
listMap = excelTypeRealize.changeDate(list, orderDO.getId());
|
||||
}
|
||||
@@ -321,10 +317,10 @@ public class OrderController {
|
||||
|
||||
if (index == 0){
|
||||
if (orderXmlVO != null) {
|
||||
mapOrder = xmlUtil.changeDate(orderXmlVO, getUserOrganId()); // 生产单数据格式验证
|
||||
orderDO = (OrderDO) mapOrder.get("order");
|
||||
XmlCheckVO xmlCheckVO = xmlUtil.changeDate(orderXmlVO, getUserOrganId()); // 生产单数据格式验证
|
||||
orderDO = xmlCheckVO.getOrderDO();
|
||||
orderDO.setId((Long) snowFlakeGenerator.nextId(null));
|
||||
flag = (Boolean) mapOrder.get("error");
|
||||
flag = xmlCheckVO.getFlag();
|
||||
}
|
||||
} else {
|
||||
orderDO = orderService.getOrder(orderId);
|
||||
@@ -377,13 +373,16 @@ public class OrderController {
|
||||
String xmlStr = XmlBuilder.objectToXmlStr(orderXmlVO);
|
||||
XMLUtil.writeErr(response, xmlStr, " order_add_xml_err.xml");
|
||||
}
|
||||
} finally {
|
||||
|
||||
// 进行判断,为空,写入时出现了错误,数据库数据回滚,此时删除 ES 里的数据
|
||||
OrderDO order = orderMapper.selectById(orderDO.getId());
|
||||
if (order == null) {
|
||||
orderInputProcessor.deleteByOrderId(orderDO.getId(), ORDER_PLATE_MODEL);
|
||||
orderInputProcessor.deleteByOrderId(orderDO.getId(), ORDER_PLATE_MODEL_COMPRESS);
|
||||
}
|
||||
|
||||
} finally {
|
||||
|
||||
redisLockUtil.unlock(lockKey);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-4
@@ -520,9 +520,7 @@ public class OrderServiceImpl implements OrderService {
|
||||
if (plateDetail != null && !plateDetail.isEmpty()){
|
||||
List<OrderModelDO> orderModelDOs = BeanUtils.toBean(plateDetail, OrderModelDO.class);
|
||||
orderInputProcessor.batchSaveModel(orderModelDOs);
|
||||
// if (!orderModelDOs.isEmpty()) {
|
||||
// orderModelDOs.forEach(orderModelDO -> orderModelDO.setOrderId(orderDO.getId()));
|
||||
// System.out.println("----" + orderModelDOs);
|
||||
|
||||
// 将生产单板材的造型信息进行压缩并保存
|
||||
OrderModelCompressDO orderModelCompressDO = new OrderModelCompressDO();
|
||||
orderModelCompressDO.setOrderId(orderDO.getId());
|
||||
@@ -763,7 +761,7 @@ public class OrderServiceImpl implements OrderService {
|
||||
List<PartsDO> partsDOS = new ArrayList<>();
|
||||
|
||||
for (OrderPartsDO partsDO : partsLists) {
|
||||
if (partsDO.getGoodsId() != null) { // 有goodsId
|
||||
if (partsDO.getGoodsId() != null && !partsDO.getGoodsId().isEmpty()) { // 有goodsId
|
||||
PartsDO part = partsMapper.selectByGoodID(partsDO.getGoodsId(), OrganContextHolder.getOrganId());
|
||||
if (part == null) { // 不存在记录,存入数据库
|
||||
partsDOS.add(BeanUtils.toBean(partsDO, PartsDO.class).setOrganId(OrganContextHolder.getOrganId()));
|
||||
|
||||
+2
-15
@@ -27,7 +27,7 @@ public class ExcelWriterUtil {
|
||||
|
||||
// 写excel
|
||||
public static void write(HttpServletResponse response,
|
||||
Map<String, Object> orderMap,
|
||||
Map<String, String> orderMap,
|
||||
List<OrderPlateImportExcelVO> list,
|
||||
String filePathErr) {
|
||||
ServletOutputStream outputStream = null;
|
||||
@@ -44,20 +44,7 @@ public class ExcelWriterUtil {
|
||||
//开启自动换行,自动换行表示每次写入一条list数据是都会重新生成一行空行,此选项默认是关闭的,需要提前设置为true
|
||||
FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
|
||||
|
||||
//准备单组和数据
|
||||
Map<String, String> map = new HashMap<>();
|
||||
map.put("customOrderNo", (String) orderMap.get("自定义单号"));
|
||||
map.put("customer", (String) orderMap.get("客户"));
|
||||
map.put("address", (String) orderMap.get("客户地址"));
|
||||
map.put("phoneNumber", (String) orderMap.get("客户电话"));
|
||||
map.put("remark", (String) orderMap.get("备注"));
|
||||
map.put("splitter", (String) orderMap.get("拆单员"));
|
||||
map.put("salesman", (String) orderMap.get("业务员"));
|
||||
map.put("dealerPhoneNumber", (String) orderMap.get("经销商电话"));
|
||||
map.put("dealer", (String) orderMap.get("经销商"));
|
||||
map.put("deliveryDate", (String) orderMap.get("出货日期"));
|
||||
|
||||
excelWriter.fill(map, writeSheet);
|
||||
excelWriter.fill(orderMap, writeSheet);
|
||||
|
||||
//列表
|
||||
excelWriter.fill(list, fillConfig, writeSheet);
|
||||
|
||||
+24
@@ -1,5 +1,6 @@
|
||||
package com.cf.imes.module.executor.util.fileConversion.admin;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
@@ -110,4 +111,27 @@ public class ToolUtil {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 判断对象是否全为空或是null,进行去除
|
||||
/**
|
||||
* 检查给定的对象的所有字段是否为空或 null。
|
||||
* @param obj 要检查的对象。
|
||||
* @return 如果所有字段都是空或 null,则返回 true;否则返回 false。
|
||||
*/
|
||||
public static boolean isAllFieldsEmptyOrNull(Object obj) {
|
||||
if (obj == null) return true;
|
||||
|
||||
Class<?> clazz = obj.getClass();
|
||||
for (Field field : clazz.getDeclaredFields()) {
|
||||
field.setAccessible(true);
|
||||
try {
|
||||
Object value = field.get(obj);
|
||||
if (value != null && !(value instanceof String && ((String)value).trim().isEmpty())) {
|
||||
return false;
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+393
@@ -0,0 +1,393 @@
|
||||
package com.cf.imes.module.executor.util.fileConversion.admin.files.excel;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.cf.imes.framework.organ.core.context.OrganContextHolder;
|
||||
import com.cf.imes.module.executor.dal.dataobject.order.OrderDO;
|
||||
import com.cf.imes.module.executor.enums.*;
|
||||
import com.cf.imes.module.executor.util.fileConversion.admin.ToolUtil;
|
||||
import com.cf.imes.module.system.api.dict.DictDataApi;
|
||||
import com.cf.imes.module.system.api.dict.dto.DictDataRespDTO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.lang.reflect.Field;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* Excel文件数据校验器
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ExcelCheckListUtil {
|
||||
|
||||
@Resource
|
||||
private DictDataApi dictDataApi;
|
||||
|
||||
private static final String ERR = "error";
|
||||
private static final String DEALER_PHONE = "dealerPhoneNumber";
|
||||
private static final String NUMBER_TYPE_ERR = "数量类型错误";
|
||||
private static final String NOT_EMPTY= "不可为空";
|
||||
private static final String NUMBER_ERR = "数量错误";
|
||||
private static final String ACCORD_ENUM = "请按照提示词语选择填入";
|
||||
private static final String POSITIVE_ERR = "数据需为正数";
|
||||
private static final String NUMBER_LENGTH_ERR = "数据长度过长";
|
||||
|
||||
// 校验文件订单数据, 当有错时返回Map<String,String>,当数据完全正确时,返回OrderDO
|
||||
public ExcelCheckVO checkExcelList(Map<String, String> orderMap) {
|
||||
|
||||
AtomicBoolean error = new AtomicBoolean(true);
|
||||
|
||||
// 非空判断
|
||||
setIfInvalid(ProduceExcelConstants.ORDER_CUSTOMER, "---< 客户不能为空 >---", orderMap, 255, error);
|
||||
setIfInvalid(ProduceExcelConstants.ORDER_SALESMAN, "---< 经销商不能为空 >---", orderMap, 255, error);
|
||||
setIfInvalid(ProduceExcelConstants.ORDER_ADDRESS, "---< 客户地址不能为空 >---", orderMap, 255, error);
|
||||
setIfInvalid(ProduceExcelConstants.ORDER_ADDRESS, "---< 客户地址不能为空 >---", orderMap, 255, error);
|
||||
|
||||
if (orderMap.get(ProduceExcelConstants.ORDER_PHONE_NUMBER) == null) {
|
||||
orderMap.put(ProduceExcelConstants.ORDER_PHONE_NUMBER, "---< 客户电话不能为空 >---");
|
||||
error.set(false);
|
||||
} else {
|
||||
setPhone(ProduceExcelConstants.ORDER_PHONE_NUMBER, "---< 客户电话格式错误 >---", orderMap, error);
|
||||
}
|
||||
if (orderMap.get(ProduceExcelConstants.ORDER_DEALER_PHONE_NUMBER) != null) {
|
||||
setPhone(ProduceExcelConstants.ORDER_DEALER_PHONE_NUMBER, "---< 经销商电话格式错误 >---", orderMap, error);
|
||||
}
|
||||
LocalDate deliverDate = null;
|
||||
if (orderMap.get(ProduceExcelConstants.ORDER_DELIVERY_DATE) == null) {
|
||||
orderMap.put(ProduceExcelConstants.ORDER_DELIVERY_DATE, "---< 出货日期不能为空 >---");
|
||||
error.set(false);
|
||||
} else {
|
||||
String s = orderMap.get(ProduceExcelConstants.ORDER_DELIVERY_DATE);
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||
Map<String, Object> mapDate = ToolUtil.changeDate(s, formatter);
|
||||
if (mapDate.get(ERR) instanceof Integer && (Integer) mapDate.get(ERR) == -1) {
|
||||
orderMap.put(ProduceExcelConstants.ORDER_DELIVERY_DATE, s + "---< 出货日期格式错误 >---");
|
||||
error.set(false);
|
||||
} else {
|
||||
deliverDate = (LocalDate) mapDate.get("date");
|
||||
if (deliverDate.isBefore(LocalDate.now())) {
|
||||
deliverDate = LocalDate.now().plus(30, ChronoUnit.DAYS);
|
||||
}
|
||||
}
|
||||
}
|
||||
OrderDO orderDO = new OrderDO();
|
||||
if (error.get()) {
|
||||
orderDO = OrderDO.builder()
|
||||
.organId(OrganContextHolder.getOrganId())
|
||||
.dataType(DataTypeEnum.FILE_IMPORT.getStatus())
|
||||
.orderDate(LocalDateTime.now())
|
||||
.customer(ProduceExcelConstants.ORDER_CUSTOMER)
|
||||
.customOrderNo(orderMap.get(ProduceExcelConstants.ORDER_CUSTOM_ORDER_NO))
|
||||
.dealer(orderMap.get(ProduceExcelConstants.ORDER_DEALER))
|
||||
.dealerPhoneNumber(orderMap.get(ProduceExcelConstants.ORDER_DEALER_PHONE_NUMBER))
|
||||
.address(orderMap.get(ProduceExcelConstants.ORDER_CUSTOMER))
|
||||
.phoneNumber(orderMap.get(ProduceExcelConstants.ORDER_PHONE_NUMBER))
|
||||
.salesman(orderMap.get(ProduceExcelConstants.ORDER_SALESMAN))
|
||||
.splitter(orderMap.get(ProduceExcelConstants.ORDER_SPLITTER))
|
||||
.deliveryDate(deliverDate.atStartOfDay())
|
||||
.orderType(OrderTypeEnum.MAIN_ORDER.getStatus())
|
||||
.remark(orderMap.get(ProduceExcelConstants.ORDER_REMARK))
|
||||
.build();
|
||||
}
|
||||
|
||||
return new ExcelCheckVO().setFlag(error.get()).setOrderDO(orderDO).setMapOder(orderMap);
|
||||
}
|
||||
|
||||
// order生产单校验电话号码
|
||||
private void setPhone(String key, String errValue, Map<String, String> orderMap, AtomicBoolean error) {
|
||||
if (!ToolUtil.validatePhoneNumber(orderMap.get(key))) {
|
||||
orderMap.put(key, orderMap.get(key) + errValue);
|
||||
error.set(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void setIfInvalid(String key, String errValue, Map<String, String> orderMap, int length, AtomicBoolean error) {
|
||||
orderMap.compute(key, (k, v) -> {
|
||||
if (v == null) {
|
||||
error.set(false);
|
||||
return errValue;
|
||||
} else {
|
||||
int size = (v).length();
|
||||
if (size > length) {
|
||||
error.set(false);
|
||||
return NUMBER_LENGTH_ERR;
|
||||
}
|
||||
}
|
||||
return v;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 校验文件生产数据
|
||||
public ExcelCheckVO checkExcelLargeFile(List<OrderPlateImportExcelVO> list) {
|
||||
List<OrderPlateImportExcelVO> resultList = new ArrayList<>();
|
||||
// 100条一分,确定分片多少
|
||||
int batchSize = 100;
|
||||
int batchCount = (list.size() + batchSize - 1) / batchSize;
|
||||
|
||||
List<CompletableFuture<List<OrderPlateImportExcelVO>>> futures = new ArrayList<>();
|
||||
AtomicBoolean flag = new AtomicBoolean(true);
|
||||
|
||||
// 遍历分片
|
||||
for (int i = 0; i < batchCount; i++) {
|
||||
int start = i * batchSize;
|
||||
int end = Math.min(start + batchSize, list.size());
|
||||
List<OrderPlateImportExcelVO> subList = list.subList(start, end);
|
||||
|
||||
|
||||
CompletableFuture<List<OrderPlateImportExcelVO>> future = CompletableFuture.supplyAsync(() -> checkData(subList, flag));
|
||||
futures.add(future);
|
||||
}
|
||||
|
||||
// 等待所有异步操作完成,并收集结果
|
||||
CompletableFuture.allOf(futures.toArray(new CompletableFuture[batchCount])).join();
|
||||
|
||||
for (CompletableFuture<List<OrderPlateImportExcelVO>> future : futures) {
|
||||
try {
|
||||
List<OrderPlateImportExcelVO> result = future.get(); // 获取每个任务的结果
|
||||
|
||||
resultList.addAll(result);
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
return new ExcelCheckVO().setFlag(flag.get()).setList(resultList);
|
||||
}
|
||||
|
||||
// List数据校验
|
||||
private List<OrderPlateImportExcelVO> checkData(List<OrderPlateImportExcelVO> list, AtomicBoolean flag) {
|
||||
|
||||
for (OrderPlateImportExcelVO vo : list) {
|
||||
List<String> errList = new ArrayList<>();
|
||||
// 全部需要值的字段
|
||||
// 检查非空 类型、数量
|
||||
isEmpty(vo.getGoodType(), errList, "类型",32, flag);
|
||||
isEmpty(vo.getGoodsNumber(), errList, "数量", 10000000 ,flag);
|
||||
|
||||
// 检查商品物料编码或是商品名称、规格、材质、颜色不可全为空
|
||||
if (StringUtils.isEmpty(vo.getGoodsName()) || StringUtils.isEmpty(vo.getSpec())
|
||||
|| StringUtils.isEmpty(vo.getMaterial()) || StringUtils.isEmpty(vo.getColor()) || StringUtils.isEmpty(vo.getUnit())) {
|
||||
errList.add("商品商品名称、规格、材质、颜色、单位不可为空");
|
||||
flag.set(false);
|
||||
}
|
||||
|
||||
|
||||
if (StringUtils.equals(vo.getGoodType(), "配件")) {
|
||||
// 复合部件必填
|
||||
isNotEmptyAndBack(vo.getIsComposite(), QuarrelEnum.class, errList, "是否复合部件", 1, flag); // 判断传入的值,是否符合字典中的枚举类
|
||||
// 配件类型必填
|
||||
isNotEmptyAndBack(vo.getCategory(), CategoryEnum.class, errList, "配件类型", 32, flag);
|
||||
// 配件长宽厚,存在判断是否可以转义
|
||||
isEmptyAndPositiveNumberSize(vo.getGoodsWidth(), Double.class, 5, 3, errList, "配件宽", flag);
|
||||
isEmptyAndPositiveNumberSize(vo.getGoodsHeight(), Double.class, 5, 3, errList, "配件高", flag);
|
||||
isEmptyAndPositiveNumberSize(vo.getGoodsThickness(), Double.class, 5, 3, errList, "配件厚", flag);
|
||||
// 配件类型为封边条的时候,需要填写配件宽厚
|
||||
if (StringUtils.equals(vo.getCategory(), CategoryEnum.EDGING.getValue())) { // 封边条必须有宽高
|
||||
isNotEmptyAndBack(vo.getGoodsWidth(), errList, "封边条宽", flag);
|
||||
isNotEmptyAndBack(vo.getGoodsThickness(), errList, "封边条厚", flag);
|
||||
}
|
||||
// 配件数量判断
|
||||
isEmptyAndPositiveNumber(vo.getGoodsNumber(), Double.class, errList, "配件数量", flag);
|
||||
}
|
||||
// 若商品类型为板材,需检查房间、柜体、板名称、成品长、成品宽、拆单长、拆单宽、厚、左封边、右封边、上封边、下封边、排版面、纹路、开门方向不能为空
|
||||
if (StringUtils.equals(vo.getGoodType(), "板材")) {
|
||||
checkPlate(vo, errList, flag);
|
||||
}
|
||||
|
||||
|
||||
// if (!flag.get()) {
|
||||
// isErr.getAndIncrement();
|
||||
// }
|
||||
JSONArray jsonArray = JSON.parseArray(JSON.toJSONString(errList));// 错误列表
|
||||
vo.setResult(String.valueOf(jsonArray));
|
||||
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
// 非空判断,错误填入
|
||||
private void isEmpty(String value, List<String> errList, String errValue, int length, AtomicBoolean flag) {
|
||||
if (StringUtils.isEmpty(value)) {
|
||||
errList.add(errValue + NOT_EMPTY);
|
||||
flag.set(false);
|
||||
} else {
|
||||
// 字符串长度检查
|
||||
int size = value.length();
|
||||
if (size > length) {
|
||||
errList.add(errValue + NUMBER_LENGTH_ERR);
|
||||
flag.set(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 错误判断通用方法
|
||||
// 判断非零,错误返回;不为空时,判断是否符合枚举类
|
||||
private void isNotEmptyAndBack(String value, Class<? extends Enum<?>> enumClass, List<String> errList, String errValue, int length , AtomicBoolean flag) {
|
||||
if (StringUtils.isEmpty(value)) {
|
||||
errList.add(errValue + NOT_EMPTY);
|
||||
flag.set(false);
|
||||
} else {
|
||||
isEmptyAndSize(value, length, errList, errValue, flag);
|
||||
try {
|
||||
// 获取枚举类的所有值
|
||||
Enum<?>[] enums = enumClass.getEnumConstants();
|
||||
boolean isValid = false;
|
||||
for (Enum<?> enumValue : enums) {
|
||||
Field valueField = enumValue.getClass().getDeclaredField("value");
|
||||
valueField.setAccessible(true);
|
||||
String enumValueStr = (String) valueField.get(enumValue);
|
||||
if (enumValueStr.equals(value)) {
|
||||
isValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isValid) {
|
||||
errList.add(errValue + ACCORD_ENUM);
|
||||
flag.set(false);
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
errList.add(errValue + ACCORD_ENUM);
|
||||
flag.set(false);
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 非零判断,有值判断---判断数值类型,数值长度
|
||||
private void isEmptyAndPositiveNumberSize(String value, Class<?> targetType, Integer length, Integer decimalLength, List<String> errList, String errValue, AtomicBoolean flag) {
|
||||
if (StringUtils.isNotEmpty(value)) {
|
||||
if (Boolean.TRUE.equals(ToolUtil.convertToType(value, targetType))) {
|
||||
if (Boolean.TRUE.equals(ToolUtil.checkNumber(value))) {
|
||||
if (!ToolUtil.checkPrecision(value, length, decimalLength)) {
|
||||
errList.add(errValue + NUMBER_LENGTH_ERR);
|
||||
flag.set(false);
|
||||
}
|
||||
} else {
|
||||
errList.add(errValue + POSITIVE_ERR);
|
||||
flag.set(false);
|
||||
}
|
||||
} else {
|
||||
errList.add(errValue + NUMBER_TYPE_ERR);
|
||||
flag.set(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 判断非零,错误返回
|
||||
private void isNotEmptyAndBack(String value, List<String> errList, String errValue, AtomicBoolean flag) {
|
||||
if (StringUtils.isEmpty(value)) {
|
||||
errList.add(errValue + NOT_EMPTY);
|
||||
flag.set(false);
|
||||
}
|
||||
}
|
||||
|
||||
// 判断非空,有值判断字符串的长度
|
||||
private void isEmptyAndSize(String value, Integer length, List<String> errList, String errValue, AtomicBoolean flag) {
|
||||
if (StringUtils.isNotEmpty(value)) {
|
||||
int size = value.length();
|
||||
if (size > length) {
|
||||
errList.add(errValue + NUMBER_LENGTH_ERR);
|
||||
flag.set(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 判断非空,大于零判断
|
||||
public void isEmptyAndPositiveNumber(String value, Class<?> targetType, List<String> errList, String errValue, AtomicBoolean flag) {
|
||||
if (StringUtils.isNotEmpty(value)) {
|
||||
if (Boolean.FALSE.equals(ToolUtil.convertToType(value, targetType))) {
|
||||
errList.add(errValue + NUMBER_TYPE_ERR);
|
||||
flag.set(false);
|
||||
}else {
|
||||
if (Boolean.FALSE.equals(checkNumber(value))) {
|
||||
errList.add(errValue + "数量不能为0");
|
||||
flag.set(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 板材的数据以及长度的检验
|
||||
public void checkPlate(OrderPlateImportExcelVO vo, List<String> errList , AtomicBoolean flag) {
|
||||
// 数量类型判断
|
||||
isEmptyAndPositiveNumber(vo.getGoodsNumber(), Integer.class, errList, "板材数量", flag);
|
||||
// 板材纹理
|
||||
isNotEmptyAndBack(vo.getWave(), IsHavaeEnum.class, errList, "板材纹理", 4, flag);
|
||||
// 大板的长宽厚存在以及是否符合数个
|
||||
isNotEmptyAndBack(vo.getGoodsWidth(), errList, "板材长度", flag);
|
||||
isEmptyAndPositiveNumberSize(vo.getGoodsWidth(), Double.class, 5, 3, errList, "板材长度", flag);
|
||||
isNotEmptyAndBack(vo.getGoodsHeight(), errList, "板材宽度", flag);
|
||||
isEmptyAndPositiveNumberSize(vo.getGoodsHeight(), Double.class, 5, 3, errList, "板材宽度", flag);
|
||||
isNotEmptyAndBack(vo.getGoodsThickness(), errList, "板材厚度", flag);
|
||||
isEmptyAndPositiveNumberSize(vo.getGoodsThickness(), Double.class, 5, 3, errList, "板材厚度", flag);
|
||||
// 房间、柜体、板名称 不可以为空
|
||||
isEmpty(vo.getRoomsName(), errList, "房间名称", 64, flag);
|
||||
isEmpty(vo.getCabinetsName(), errList, "柜体名称", 64, flag);
|
||||
isEmpty(vo.getName(), errList, "板材名称", 64, flag);
|
||||
//成品长、成品宽、拆单长、拆单宽、厚、左封边、右封边、上封边、下封边 不能为空
|
||||
isNotEmptyAndBack(vo.getHeight(), errList, "成品长度", flag);
|
||||
isEmptyAndPositiveNumberSize(vo.getHeight(), Double.class, 5, 3, errList, "成品长度", flag);
|
||||
isNotEmptyAndBack(vo.getWidth(), errList, "成品宽度", flag);
|
||||
isEmptyAndPositiveNumberSize(vo.getWidth(), Double.class, 5, 3, errList, "成品宽度", flag);
|
||||
isNotEmptyAndBack(vo.getSplitHeight(), errList, "拆单长度", flag);
|
||||
isEmptyAndPositiveNumberSize(vo.getSplitHeight(), Double.class, 5, 3, errList, "拆单长度", flag);
|
||||
isNotEmptyAndBack(vo.getSplitWidth(), errList, "拆单宽度", flag);
|
||||
isEmptyAndPositiveNumberSize(vo.getSplitWidth(), Double.class, 5, 3, errList, "拆单宽度", flag);
|
||||
isNotEmptyAndBack(vo.getThickness(), errList, "厚度", flag);
|
||||
isEmptyAndPositiveNumberSize(vo.getThickness(), Double.class, 5, 3, errList, "厚度", flag);
|
||||
isNotEmptyAndBack(vo.getSealLeft(), errList, "左封边", flag);
|
||||
isEmptyAndPositiveNumberSize(vo.getSealLeft(), Double.class, 5, 3, errList, "左封边", flag);
|
||||
isNotEmptyAndBack(vo.getSealRight(), errList, "右封边", flag);
|
||||
isEmptyAndPositiveNumberSize(vo.getSealRight(), Double.class, 5, 3, errList, "右封边", flag);
|
||||
isNotEmptyAndBack(vo.getSealUp(), errList, "上封边", flag);
|
||||
isEmptyAndPositiveNumberSize(vo.getSealUp(), Double.class, 5, 3, errList, "上封边", flag);
|
||||
isNotEmptyAndBack(vo.getSealDown(), errList, "下封边", flag);
|
||||
isEmptyAndPositiveNumberSize(vo.getSealDown(), Double.class, 5, 3, errList, "下封边", flag);
|
||||
// 排版面、纹路、开门方向
|
||||
isNotEmptyAndDict(vo.getTypographicFace(), DictTypeConstants.TYPOGRAPHY_TYPE, errList, "排版面", flag);
|
||||
isNotEmptyAndDict(vo.getTexture(), DictTypeConstants.GRAIN_TYPE, errList, "纹路", flag);
|
||||
isNotEmptyAndDict(vo.getOpenDoorType(), DictTypeConstants.DOOR_OPENING_DIRECTIONS, errList, "开门方向", flag);
|
||||
|
||||
}
|
||||
|
||||
// 判断非空,字典值判断
|
||||
public void isNotEmptyAndDict(String value, String dictType, List<String> errList, String errValue, AtomicBoolean flag) {
|
||||
if (StringUtils.isEmpty(value)) {
|
||||
errList.add(errValue + NOT_EMPTY);
|
||||
flag.set(false);
|
||||
} else {
|
||||
DictDataRespDTO dictDataRespDTO = dictDataApi.parseDictData(dictType, value).getData();
|
||||
if (dictDataRespDTO == null) {
|
||||
errList.add(errValue + ACCORD_ENUM);
|
||||
flag.set(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 数量大小判断
|
||||
public Boolean checkNumber(String numberStr) {
|
||||
if (numberStr == null) {
|
||||
return false;
|
||||
}
|
||||
if (Double.parseDouble(numberStr) <= 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package com.cf.imes.module.executor.util.fileConversion.admin.files.excel;
|
||||
|
||||
import com.cf.imes.module.executor.dal.dataobject.order.OrderDO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Excel 校验数据类型
|
||||
*/
|
||||
@Schema(description = "Excel 校验数据类型")
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@ToString(callSuper = true)
|
||||
public class ExcelCheckVO {
|
||||
|
||||
@Schema(description = "校验结果")
|
||||
private Boolean flag;
|
||||
|
||||
@Schema(description = "校验结果数据")
|
||||
private List<OrderPlateImportExcelVO> list;
|
||||
|
||||
@Schema(description = "订单信息")
|
||||
private OrderDO orderDO;
|
||||
|
||||
@Schema(description = "订单信息")
|
||||
private Map<String, String> mapOder;
|
||||
}
|
||||
-45
@@ -1,45 +0,0 @@
|
||||
package com.cf.imes.module.executor.util.fileConversion.admin.files.excel;
|
||||
|
||||
import com.alibaba.excel.context.AnalysisContext;
|
||||
import com.alibaba.excel.event.AnalysisEventListener;
|
||||
import com.alibaba.excel.exception.ExcelDataConvertException;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Slf4j
|
||||
public final class ExcelListener extends AnalysisEventListener<Map<Integer, String>> {
|
||||
/**
|
||||
* 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收
|
||||
*/
|
||||
// private static final int BATCH_COUNT = 100;
|
||||
// private List<Map<Integer, String>> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
|
||||
private List<Map<Integer, String>> cachedDataList = new ArrayList<Map<Integer, String>>();
|
||||
private boolean stopParsing = false; // 添加一个标志位用于控制是否停止解析数据
|
||||
|
||||
@Override
|
||||
public void invoke(Map<Integer, String> data, AnalysisContext context) {
|
||||
log.info("解析到一条数据: {}", JSON.toJSONString(data));
|
||||
|
||||
if (data.get(0) != null && data.get(0).equals("***")) {
|
||||
log.info("遇到指定数据 ***, 停止写入!");
|
||||
stopParsing = true;
|
||||
}
|
||||
|
||||
if (!stopParsing) {
|
||||
data.entrySet().removeIf(entry -> Objects.isNull(entry.getValue()));
|
||||
cachedDataList.add(data);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAfterAllAnalysed(AnalysisContext context) {
|
||||
log.info("所有数据解析完成!");
|
||||
}
|
||||
|
||||
public List<Map<Integer, String>> getDataLists() {
|
||||
return cachedDataList;
|
||||
}
|
||||
}
|
||||
-564
@@ -1,564 +0,0 @@
|
||||
package com.cf.imes.module.executor.util.fileConversion.admin.files.excel;
|
||||
|
||||
import com.alibaba.excel.EasyExcelFactory;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.cf.imes.framework.organ.core.context.OrganContextHolder;
|
||||
import com.cf.imes.module.executor.dal.dataobject.order.OrderDO;
|
||||
import com.cf.imes.module.executor.enums.*;
|
||||
import com.cf.imes.module.executor.util.fileConversion.admin.ToolUtil;
|
||||
import com.cf.imes.module.system.api.dict.DictDataApi;
|
||||
import com.cf.imes.module.system.api.dict.dto.DictDataRespDTO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ExcelReadUtil { // 文件读取
|
||||
private AtomicInteger isErr = new AtomicInteger(0);
|
||||
|
||||
@Resource
|
||||
private DictDataApi dictDataApi;
|
||||
|
||||
private static final String ERR = "error";
|
||||
private static final String DEALER_PHONE = "dealerPhoneNumber";
|
||||
private static final String NUMBER_TYPE_ERR = "数量类型错误";
|
||||
private static final String NOT_EMPTY= "不可为空";
|
||||
private static final String NUMBER_ERR = "数量错误";
|
||||
private static final String ACCORD_ENUM = "请按照提示词语选择填入";
|
||||
private static final String POSITIVE_ERR = "数据需为正数";
|
||||
private static final String NUMBER_LENGTH_ERR = "数据长度过长";
|
||||
// 读excel
|
||||
public Map<String, Object> read(MultipartFile file) throws IOException {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
ExcelListener excelListener = new ExcelListener();
|
||||
|
||||
// 读文件
|
||||
EasyExcelFactory.read(file.getInputStream(), excelListener).headRowNumber(-1).sheet().doRead();
|
||||
|
||||
Map<String, Object> orderMap = new HashMap<>();// order
|
||||
List<Map<Integer, String>> dataLists = excelListener.getDataLists();// 读取的内容
|
||||
List<OrderPlateImportExcelVO> list = new ArrayList<>();// plate
|
||||
|
||||
AtomicBoolean index = new AtomicBoolean(true);
|
||||
AtomicInteger i = new AtomicInteger();
|
||||
dataLists.forEach(
|
||||
item -> {
|
||||
if (item.get(0) != null){
|
||||
if (item.get(0).equals("###")) {
|
||||
index.set(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (index.get()) {
|
||||
orderMap.put(item.get(0), item.get(1));
|
||||
orderMap.put(item.get(19), item.get(20));
|
||||
i.getAndIncrement();
|
||||
} else {
|
||||
if (i.getAndIncrement() > 6){
|
||||
list.add(changeValue(item));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
);
|
||||
index.set(true);
|
||||
map.put("orderPri", orderMap);
|
||||
map.put("plate", list);
|
||||
return map;
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
private void setIfInvalid(String key, String errValue, Map<String, Object> orderMap,int length, AtomicBoolean error) {
|
||||
orderMap.compute(key, (k, v) -> {
|
||||
if (v == null) {
|
||||
error.set(false);
|
||||
return errValue;
|
||||
} else {
|
||||
int size = ((String) v).length();
|
||||
if (size > length) {
|
||||
error.set(false);
|
||||
return NUMBER_LENGTH_ERR;
|
||||
}
|
||||
}
|
||||
return v;
|
||||
});
|
||||
}
|
||||
|
||||
private void setPhone(String key, String errValue, Map<String, Object> orderMap, AtomicBoolean error) {
|
||||
if (!ToolUtil.validatePhoneNumber((String) orderMap.get(key))) {
|
||||
orderMap.put(key, orderMap.get(key) + errValue);
|
||||
error.set(false);
|
||||
}
|
||||
}
|
||||
// order 数据转换
|
||||
public Map<String, Object> changeOrderDO(Map<String, Object> orderMap) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
|
||||
if (MapUtils.isEmpty(orderMap)) {
|
||||
map.put(ERR, false);
|
||||
return map;
|
||||
}
|
||||
|
||||
AtomicBoolean error = new AtomicBoolean(true);
|
||||
|
||||
setIfInvalid("客户", "---< 客户不能为空 >---", orderMap, 255, error);
|
||||
setIfInvalid("经销商", "---< 经销商不能为空 >---", orderMap, 255, error);
|
||||
setIfInvalid("客户地址", "---< 客户地址不能为空 >---", orderMap, 255, error);
|
||||
setIfInvalid("客户地址", "---< 客户地址不能为空 >---", orderMap, 255, error);
|
||||
|
||||
if (orderMap.get("客户电话") == null) {
|
||||
orderMap.put("客户电话", "---< 客户电话不能为空 >---");
|
||||
error.set(false);
|
||||
} else {
|
||||
setPhone("客户电话", "---< 客户电话格式错误 >---", orderMap, error);
|
||||
}
|
||||
if (orderMap.get(DEALER_PHONE) != null) {
|
||||
setPhone(DEALER_PHONE, "---< 经销商电话格式错误 >---", orderMap, error);
|
||||
}
|
||||
LocalDate deliverDate = null;
|
||||
if (orderMap.get("出货日期") == null) {
|
||||
orderMap.put("出货日期", "---< 出货日期不能为空 >---");
|
||||
error.set(false);
|
||||
} else {
|
||||
String s = (String) orderMap.get("出货日期");
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||
Map<String, Object> mapDate = ToolUtil.changeDate(s, formatter);
|
||||
if (mapDate.get(ERR) instanceof Integer && (Integer) mapDate.get(ERR) == -1) {
|
||||
orderMap.put("出货日期", s + "---< 出货日期格式错误 >---");
|
||||
error.set(false);
|
||||
} else {
|
||||
deliverDate = (LocalDate) mapDate.get("date");
|
||||
if (deliverDate.isBefore(LocalDate.now())) {
|
||||
deliverDate = LocalDate.now().plus(30, ChronoUnit.DAYS);
|
||||
}
|
||||
}
|
||||
}
|
||||
OrderDO orderDO = new OrderDO();
|
||||
if (error.get()) {
|
||||
orderDO = OrderDO.builder()
|
||||
.organId(OrganContextHolder.getOrganId())
|
||||
.dataType(DataTypeEnum.FILE_IMPORT.getStatus())
|
||||
.orderDate(LocalDateTime.now())
|
||||
.customer((String) orderMap.get("客户"))
|
||||
.customOrderNo((String) orderMap.get("自定义单号"))
|
||||
.dealer((String) orderMap.get("经销商"))
|
||||
.dealerPhoneNumber((String) orderMap.get(DEALER_PHONE))
|
||||
.address((String) orderMap.get("客户地址"))
|
||||
.phoneNumber((String) orderMap.get("客户电话"))
|
||||
.salesman((String) orderMap.get("业务员"))
|
||||
.splitter((String) orderMap.get("拆单员"))
|
||||
.deliveryDate(deliverDate.atStartOfDay())
|
||||
.orderType(OrderTypeEnum.MAIN_ORDER.getStatus())
|
||||
.remark((String) orderMap.get("备注"))
|
||||
.build();
|
||||
}
|
||||
map.put("order", orderDO);
|
||||
map.put("file", orderMap);
|
||||
map.put(ERR, error);
|
||||
return map;
|
||||
}
|
||||
|
||||
// 赋值单元格数据
|
||||
private OrderPlateImportExcelVO changeValue(Map<Integer, String> dataMap) {
|
||||
OrderPlateImportExcelVO vo = new OrderPlateImportExcelVO();
|
||||
|
||||
for (Map.Entry<Integer, String> entry : dataMap.entrySet()) {
|
||||
Integer key = entry.getKey();
|
||||
String value = entry.getValue();
|
||||
|
||||
switch (key) {
|
||||
case 0:
|
||||
vo.setOrdinal(value);
|
||||
break;
|
||||
case 1:// 类型
|
||||
vo.setGoodType(value);
|
||||
break;
|
||||
case 2:// 物料编码
|
||||
vo.setGoodsId(value);
|
||||
break;
|
||||
case 3:// 商品名称
|
||||
vo.setGoodsName(value);
|
||||
break;
|
||||
case 4:// 材质
|
||||
vo.setMaterial(value);
|
||||
break;
|
||||
case 5:// 纹理
|
||||
vo.setWave(value);
|
||||
break;
|
||||
case 6:// 颜色
|
||||
vo.setColor(value);
|
||||
break;
|
||||
case 7:// 复合部件
|
||||
vo.setIsComposite(value);
|
||||
break;
|
||||
case 8:// 配件类型
|
||||
vo.setCategory(value);
|
||||
break;
|
||||
case 9:// 子类
|
||||
vo.setType(value);
|
||||
break;
|
||||
case 10:// 厂家
|
||||
vo.setFactory(value);
|
||||
break;
|
||||
case 11:// 品牌
|
||||
vo.setBrand(value);
|
||||
break;
|
||||
case 12:// 型号
|
||||
vo.setModel(value);
|
||||
break;
|
||||
case 13:// 板材/配件长
|
||||
vo.setGoodsHeight(value);
|
||||
break;
|
||||
case 14:// 板材/配件宽
|
||||
vo.setGoodsWidth(value);
|
||||
break;
|
||||
case 15:// 板材/配件厚
|
||||
vo.setGoodsThickness(value);
|
||||
break;
|
||||
case 16:// 规格
|
||||
vo.setSpec(value);
|
||||
break;
|
||||
case 17:// 单位
|
||||
vo.setUnit(value);
|
||||
break;
|
||||
case 18:// 数量
|
||||
vo.setGoodsNumber(value);
|
||||
break;
|
||||
case 19:// 房间
|
||||
vo.setRoomsName(value);
|
||||
break;
|
||||
case 20:// 柜体
|
||||
vo.setCabinetsName(value);
|
||||
break;
|
||||
case 21:// 加工组类型
|
||||
vo.setSynthesisTypeName(value);
|
||||
break;
|
||||
case 22:// 加工组名称
|
||||
vo.setCombinationName(value);
|
||||
break;
|
||||
case 23://板名称
|
||||
vo.setName(value);
|
||||
break;
|
||||
case 24:// 自定义板编号
|
||||
vo.setPlateNo(value);
|
||||
break;
|
||||
case 25:// 成品长
|
||||
vo.setHeight(value);
|
||||
break;
|
||||
case 26:// 成品宽
|
||||
vo.setWidth(value);
|
||||
break;
|
||||
case 27:// 拆单长
|
||||
vo.setSplitHeight(value);
|
||||
break;
|
||||
case 28:// 拆单宽
|
||||
vo.setSplitWidth(value);
|
||||
break;
|
||||
case 29:// 厚
|
||||
vo.setThickness(value);
|
||||
break;
|
||||
case 30:// 左封边
|
||||
vo.setSealLeft(value);
|
||||
break;
|
||||
case 31:// 右封边
|
||||
vo.setSealRight(value);
|
||||
break;
|
||||
case 32:// 上封边
|
||||
vo.setSealUp(value);
|
||||
break;
|
||||
case 33:// 下封边
|
||||
vo.setSealDown(value);
|
||||
break;
|
||||
case 34:// 排版面
|
||||
vo.setTypographicFace(value);
|
||||
break;
|
||||
case 35:// 纹路
|
||||
vo.setTexture(value);
|
||||
break;
|
||||
case 36:// 开门方向
|
||||
vo.setOpenDoorType(value);
|
||||
break;
|
||||
case 37://备注1
|
||||
vo.setRemark1(value);
|
||||
break;
|
||||
case 38://备注2
|
||||
vo.setRemark2(value);
|
||||
break;
|
||||
case 39://备注3
|
||||
vo.setRemark3(value);
|
||||
break;
|
||||
case 40://备注4
|
||||
vo.setRemark4(value);
|
||||
break;
|
||||
case 41://备注5
|
||||
vo.setRemark5(value);
|
||||
break;
|
||||
case 42://备注6
|
||||
vo.setRemark6(value);
|
||||
break;
|
||||
case 43://备注7
|
||||
vo.setRemark7(value);
|
||||
break;
|
||||
case 44://备注8
|
||||
vo.setRemark8(value);
|
||||
break;
|
||||
case 45://备注9
|
||||
vo.setRemark9(value);
|
||||
break;
|
||||
case 46://备注10
|
||||
vo.setRemark10(value);
|
||||
break;
|
||||
default:
|
||||
// 处理默认情况,可以选择忽略或者做其他处理
|
||||
break;
|
||||
}
|
||||
}
|
||||
checkVO(vo);
|
||||
return vo;
|
||||
}
|
||||
|
||||
// 错误判断通用方法
|
||||
// 判断非零,错误返回;不为空时,判断是否符合枚举类
|
||||
private void isNotEmptyAndBack(String value, Class<? extends Enum<?>> enumClass, List<String> errList, String errValue, int length , AtomicBoolean flag) {
|
||||
if (StringUtils.isEmpty(value)) {
|
||||
errList.add(errValue + NOT_EMPTY);
|
||||
flag.set(false);
|
||||
} else {
|
||||
isEmptyAndSize(value, length, errList, errValue, flag);
|
||||
try {
|
||||
// 获取枚举类的所有值
|
||||
Enum<?>[] enums = enumClass.getEnumConstants();
|
||||
boolean isValid = false;
|
||||
for (Enum<?> enumValue : enums) {
|
||||
Field valueField = enumValue.getClass().getDeclaredField("value");
|
||||
valueField.setAccessible(true);
|
||||
String enumValueStr = (String) valueField.get(enumValue);
|
||||
if (enumValueStr.equals(value)) {
|
||||
isValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isValid) {
|
||||
errList.add(errValue + ACCORD_ENUM);
|
||||
flag.set(false);
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
errList.add(errValue + ACCORD_ENUM);
|
||||
flag.set(false);
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 非零判断,有值判断---判断数值类型,数值长度
|
||||
private void isEmptyAndPositiveNumberSize(String value, Class<?> targetType, Integer length, Integer decimalLength, List<String> errList, String errValue, AtomicBoolean flag) {
|
||||
if (StringUtils.isNotEmpty(value)) {
|
||||
if (Boolean.TRUE.equals(ToolUtil.convertToType(value, targetType))) {
|
||||
if (Boolean.TRUE.equals(ToolUtil.checkNumber(value))) {
|
||||
if (!ToolUtil.checkPrecision(value, length, decimalLength)) {
|
||||
errList.add(errValue + NUMBER_LENGTH_ERR);
|
||||
flag.set(false);
|
||||
}
|
||||
} else {
|
||||
errList.add(errValue + POSITIVE_ERR);
|
||||
flag.set(false);
|
||||
}
|
||||
} else {
|
||||
errList.add(errValue + NUMBER_TYPE_ERR);
|
||||
flag.set(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 判断非零,错误返回
|
||||
private void isNotEmptyAndBack(String value, List<String> errList, String errValue, AtomicBoolean flag) {
|
||||
if (StringUtils.isEmpty(value)) {
|
||||
errList.add(errValue + NOT_EMPTY);
|
||||
flag.set(false);
|
||||
}
|
||||
}
|
||||
|
||||
// 判断非空,有值判断字符串的长度
|
||||
private void isEmptyAndSize(String value, Integer length, List<String> errList, String errValue, AtomicBoolean flag) {
|
||||
if (StringUtils.isNotEmpty(value)) {
|
||||
int size = value.length();
|
||||
if (size > length) {
|
||||
errList.add(errValue + NUMBER_LENGTH_ERR);
|
||||
flag.set(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 非空判断,错误填入
|
||||
private void isEmpty(String value, List<String> errList, String errValue, int length, AtomicBoolean flag) {
|
||||
if (StringUtils.isEmpty(value)) {
|
||||
errList.add(errValue + NOT_EMPTY);
|
||||
flag.set(false);
|
||||
} else {
|
||||
// 字符串长度检查
|
||||
int size = value.length();
|
||||
if (size > length) {
|
||||
errList.add(errValue + NUMBER_LENGTH_ERR);
|
||||
flag.set(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 判断非空,大于零判断
|
||||
public void isEmptyAndPositiveNumber(String value, Class<?> targetType, List<String> errList, String errValue, AtomicBoolean flag) {
|
||||
if (StringUtils.isNotEmpty(value)) {
|
||||
if (Boolean.FALSE.equals(ToolUtil.convertToType(value, targetType))) {
|
||||
errList.add(errValue + NUMBER_TYPE_ERR);
|
||||
flag.set(false);
|
||||
}else {
|
||||
if (Boolean.FALSE.equals(checkNumber(value))) {
|
||||
errList.add(errValue + "数量不能为0");
|
||||
flag.set(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 判断非空,字典值判断
|
||||
public void isNotEmptyAndDict(String value, String dictType, List<String> errList, String errValue, AtomicBoolean flag) {
|
||||
if (StringUtils.isEmpty(value)) {
|
||||
errList.add(errValue + NOT_EMPTY);
|
||||
flag.set(false);
|
||||
} else {
|
||||
DictDataRespDTO dictDataRespDTO = dictDataApi.parseDictData(dictType, value).getData();
|
||||
if (dictDataRespDTO == null) {
|
||||
errList.add(errValue + ACCORD_ENUM);
|
||||
flag.set(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 板材的数据以及长度的检验
|
||||
public void checkPlate(OrderPlateImportExcelVO vo, List<String> errList , AtomicBoolean flag) {
|
||||
// 数量类型判断
|
||||
isEmptyAndPositiveNumber(vo.getGoodsNumber(), Integer.class, errList, "板材数量", flag);
|
||||
// 板材纹理
|
||||
isNotEmptyAndBack(vo.getWave(), IsHavaeEnum.class, errList, "板材纹理", 4, flag);
|
||||
// 大板的长宽厚存在以及是否符合数个
|
||||
isNotEmptyAndBack(vo.getGoodsWidth(), errList, "板材长度", flag);
|
||||
isEmptyAndPositiveNumberSize(vo.getGoodsWidth(), Double.class, 5, 3, errList, "板材长度", flag);
|
||||
isNotEmptyAndBack(vo.getGoodsHeight(), errList, "板材宽度", flag);
|
||||
isEmptyAndPositiveNumberSize(vo.getGoodsHeight(), Double.class, 5, 3, errList, "板材宽度", flag);
|
||||
isNotEmptyAndBack(vo.getGoodsThickness(), errList, "板材厚度", flag);
|
||||
isEmptyAndPositiveNumberSize(vo.getGoodsThickness(), Double.class, 5, 3, errList, "板材厚度", flag);
|
||||
// 房间、柜体、板名称 不可以为空
|
||||
isEmpty(vo.getRoomsName(), errList, "房间名称", 64, flag);
|
||||
isEmpty(vo.getCabinetsName(), errList, "柜体名称", 64, flag);
|
||||
isEmpty(vo.getName(), errList, "板材名称", 64, flag);
|
||||
//成品长、成品宽、拆单长、拆单宽、厚、左封边、右封边、上封边、下封边 不能为空
|
||||
isNotEmptyAndBack(vo.getHeight(), errList, "成品长度", flag);
|
||||
isEmptyAndPositiveNumberSize(vo.getHeight(), Double.class, 5, 3, errList, "成品长度", flag);
|
||||
isNotEmptyAndBack(vo.getWidth(), errList, "成品宽度", flag);
|
||||
isEmptyAndPositiveNumberSize(vo.getWidth(), Double.class, 5, 3, errList, "成品宽度", flag);
|
||||
isNotEmptyAndBack(vo.getSplitHeight(), errList, "拆单长度", flag);
|
||||
isEmptyAndPositiveNumberSize(vo.getSplitHeight(), Double.class, 5, 3, errList, "拆单长度", flag);
|
||||
isNotEmptyAndBack(vo.getSplitWidth(), errList, "拆单宽度", flag);
|
||||
isEmptyAndPositiveNumberSize(vo.getSplitWidth(), Double.class, 5, 3, errList, "拆单宽度", flag);
|
||||
isNotEmptyAndBack(vo.getThickness(), errList, "厚度", flag);
|
||||
isEmptyAndPositiveNumberSize(vo.getThickness(), Double.class, 5, 3, errList, "厚度", flag);
|
||||
isNotEmptyAndBack(vo.getSealLeft(), errList, "左封边", flag);
|
||||
isEmptyAndPositiveNumberSize(vo.getSealLeft(), Double.class, 5, 3, errList, "左封边", flag);
|
||||
isNotEmptyAndBack(vo.getSealRight(), errList, "右封边", flag);
|
||||
isEmptyAndPositiveNumberSize(vo.getSealRight(), Double.class, 5, 3, errList, "右封边", flag);
|
||||
isNotEmptyAndBack(vo.getSealUp(), errList, "上封边", flag);
|
||||
isEmptyAndPositiveNumberSize(vo.getSealUp(), Double.class, 5, 3, errList, "上封边", flag);
|
||||
isNotEmptyAndBack(vo.getSealDown(), errList, "下封边", flag);
|
||||
isEmptyAndPositiveNumberSize(vo.getSealDown(), Double.class, 5, 3, errList, "下封边", flag);
|
||||
// 排版面、纹路、开门方向
|
||||
isNotEmptyAndDict(vo.getTypographicFace(), DictTypeConstants.TYPOGRAPHY_TYPE, errList, "排版面", flag);
|
||||
isNotEmptyAndDict(vo.getTexture(), DictTypeConstants.GRAIN_TYPE, errList, "纹路", flag);
|
||||
isNotEmptyAndDict(vo.getOpenDoorType(), DictTypeConstants.DOOR_OPENING_DIRECTIONS, errList, "开门方向", flag);
|
||||
|
||||
}
|
||||
// OrderPlateImportExcelVO 数据验证
|
||||
private Boolean checkVO(OrderPlateImportExcelVO vo) {
|
||||
List<String> errList = new ArrayList<>();
|
||||
AtomicBoolean flag = new AtomicBoolean(true);
|
||||
|
||||
// 全部需要值的字段
|
||||
// 检查非空 类型、数量
|
||||
isEmpty(vo.getGoodType(), errList, "类型",32, flag);
|
||||
isEmpty(vo.getGoodsNumber(), errList, "数量", 10000000 ,flag);
|
||||
|
||||
// 检查商品物料编码或是商品名称、规格、材质、颜色不可全为空
|
||||
if (StringUtils.isEmpty(vo.getGoodsName()) || StringUtils.isEmpty(vo.getSpec())
|
||||
|| StringUtils.isEmpty(vo.getMaterial()) || StringUtils.isEmpty(vo.getColor()) || StringUtils.isEmpty(vo.getUnit())) {
|
||||
errList.add("商品商品名称、规格、材质、颜色、单位不可为空");
|
||||
flag.set(false);
|
||||
}
|
||||
|
||||
|
||||
if (StringUtils.equals(vo.getGoodType(), "配件")) {
|
||||
// 复合部件必填
|
||||
isNotEmptyAndBack(vo.getIsComposite(), QuarrelEnum.class, errList, "是否复合部件", 1, flag); // 判断传入的值,是否符合字典中的枚举类
|
||||
// 配件类型必填
|
||||
isNotEmptyAndBack(vo.getCategory(), CategoryEnum.class, errList, "配件类型", 32, flag);
|
||||
// 配件长宽厚,存在判断是否可以转义
|
||||
isEmptyAndPositiveNumberSize(vo.getGoodsWidth(), Double.class, 5, 3, errList, "配件宽", flag);
|
||||
isEmptyAndPositiveNumberSize(vo.getGoodsHeight(), Double.class, 5, 3, errList, "配件高", flag);
|
||||
isEmptyAndPositiveNumberSize(vo.getGoodsThickness(), Double.class, 5, 3, errList, "配件厚", flag);
|
||||
// 配件类型为封边条的时候,需要填写配件宽厚
|
||||
if (StringUtils.equals(vo.getCategory(), CategoryEnum.EDGING.getValue())) { // 封边条必须有宽高
|
||||
isNotEmptyAndBack(vo.getGoodsWidth(), errList, "封边条宽", flag);
|
||||
isNotEmptyAndBack(vo.getGoodsThickness(), errList, "封边条厚", flag);
|
||||
}
|
||||
// 配件数量判断
|
||||
isEmptyAndPositiveNumber(vo.getGoodsNumber(), Double.class, errList, "配件数量", flag);
|
||||
}
|
||||
// 若商品类型为板材,需检查房间、柜体、板名称、成品长、成品宽、拆单长、拆单宽、厚、左封边、右封边、上封边、下封边、排版面、纹路、开门方向不能为空
|
||||
if (StringUtils.equals(vo.getGoodType(), "板材")) {
|
||||
checkPlate(vo, errList, flag);
|
||||
}
|
||||
|
||||
|
||||
if (!flag.get()) {
|
||||
isErr.getAndIncrement();
|
||||
}
|
||||
JSONArray jsonArray = JSON.parseArray(JSON.toJSONString(errList));// 错误列表
|
||||
vo.setResult(String.valueOf(jsonArray));
|
||||
return flag.get();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public int isErr() {
|
||||
return isErr.get();
|
||||
}
|
||||
|
||||
public void setErr(int isErr) {
|
||||
this.isErr.set(isErr);
|
||||
}
|
||||
|
||||
// 数量大小判断
|
||||
public Boolean checkNumber(String numberStr) {
|
||||
if (numberStr == null) {
|
||||
return false;
|
||||
}
|
||||
if (Double.parseDouble(numberStr) <= 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -138,11 +138,11 @@ public class ExcelTypeRealize {
|
||||
// 配件信息合集,添加生产单id,添加生产单配件设计端商品编码,配件信息写入order_parts
|
||||
Map<String, List<OrderPlateImportExcelVO>> partsIdMap = checkMap.get(PARTS).stream().collect(
|
||||
Collectors.groupingBy(
|
||||
excelVO -> excelVO.getGoodsId() != null ? excelVO.getGoodsId() : " ",
|
||||
excelVO -> excelVO.getGoodsId() != null ? excelVO.getGoodsId() : "",
|
||||
Collectors.toList()
|
||||
));
|
||||
partsIdMap.forEach((key, value) -> {
|
||||
if (key.equals(" ")) { // 没有商品编号的 value.get(0).getGoodsId() == null
|
||||
if (key.equals("")) { // 没有商品编号的 value.get(0).getGoodsId() == null
|
||||
// 将相同条件的元素归为一个集合
|
||||
Map<List<Object>, List<OrderPlateImportExcelVO>> partsMap = value.stream()
|
||||
.collect(Collectors.groupingBy(
|
||||
|
||||
+317
@@ -0,0 +1,317 @@
|
||||
package com.cf.imes.module.executor.util.fileConversion.admin.files.excel;
|
||||
|
||||
import com.cf.imes.module.executor.util.fileConversion.admin.ToolUtil;
|
||||
import com.monitorjbl.xlsx.StreamingReader;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
* 大文件 excel 导入
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class LargeFilesUtils {
|
||||
|
||||
public List<OrderPlateImportExcelVO>[] importExcelLargeFile(MultipartFile file) {
|
||||
try (InputStream inputStream = file.getInputStream();
|
||||
Workbook workbook = StreamingReader.builder()
|
||||
.rowCacheSize(1000)
|
||||
.bufferSize(10240)
|
||||
.open(inputStream)) {
|
||||
|
||||
Sheet sheet = workbook.getSheetAt(0);
|
||||
return processRows(sheet);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Error processing Excel file", e);
|
||||
throw new RuntimeException("Failed to process Excel file", e);
|
||||
}
|
||||
}
|
||||
|
||||
private List<OrderPlateImportExcelVO>[] processRows(Sheet sheet) { // 一个是order,一个是plateLiat
|
||||
List<OrderPlateImportExcelVO> preDelimiterList = new ArrayList<>();
|
||||
List<OrderPlateImportExcelVO> postDelimiterList = new ArrayList<>();
|
||||
AtomicBoolean fastRowBoolean = new AtomicBoolean(false);
|
||||
AtomicBoolean delimiterFound = new AtomicBoolean(false);
|
||||
AtomicBoolean stopReading = new AtomicBoolean(false);
|
||||
|
||||
for (Row row : sheet) {
|
||||
if (stopReading.get() || shouldSkipRow(row, delimiterFound,fastRowBoolean, stopReading)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
OrderPlateImportExcelVO vo = createOrderPlateFromRow(row);
|
||||
if (delimiterFound.get()) {
|
||||
postDelimiterList.add(vo);
|
||||
} else {
|
||||
preDelimiterList.add(vo);
|
||||
}
|
||||
|
||||
handleSpecialDelimiters(row, () -> delimiterFound.set(true), () -> stopReading.set(true));
|
||||
}
|
||||
|
||||
logResults(preDelimiterList.size(), postDelimiterList.size());
|
||||
|
||||
return new List[] { preDelimiterList, postDelimiterList.stream()
|
||||
.filter(item -> !ToolUtil.isAllFieldsEmptyOrNull(item))
|
||||
.collect(Collectors.toList()) };
|
||||
}
|
||||
|
||||
private boolean shouldSkipRow(Row row, AtomicBoolean delimiterFound, AtomicBoolean fastRowBoolean, AtomicBoolean stopReading) {
|
||||
if (stopReading.get()) return true;
|
||||
|
||||
String firstCellValue = getFirstCellValue(row);
|
||||
if ("###".equals(firstCellValue) && !delimiterFound.get()) {
|
||||
delimiterFound.set(true);
|
||||
fastRowBoolean.set(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (fastRowBoolean.get()) {
|
||||
fastRowBoolean.set(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
if ("***".equals(firstCellValue)) {
|
||||
stopReading.set(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private String getFirstCellValue(Row row) {
|
||||
Cell cell = row.getCell(0);
|
||||
return cell != null ? cell.getStringCellValue() : "";
|
||||
}
|
||||
|
||||
private OrderPlateImportExcelVO createOrderPlateFromRow(Row row) {
|
||||
OrderPlateImportExcelVO vo = new OrderPlateImportExcelVO();
|
||||
int columnIndex = 0;
|
||||
|
||||
for (Cell cell : row) {
|
||||
setOrderPlateProperty(vo, cell, columnIndex++);
|
||||
}
|
||||
|
||||
return vo;
|
||||
}
|
||||
|
||||
private void setOrderPlateProperty(OrderPlateImportExcelVO vo, Cell cell, int index) {
|
||||
String value = cell.getStringCellValue();
|
||||
|
||||
switch (index) {
|
||||
case 0:
|
||||
vo.setOrdinal(value);
|
||||
break;
|
||||
case 1:// 类型
|
||||
vo.setGoodType(value);
|
||||
break;
|
||||
case 2:// 物料编码
|
||||
vo.setGoodsId(value);
|
||||
break;
|
||||
case 3:// 商品名称
|
||||
vo.setGoodsName(value);
|
||||
break;
|
||||
case 4:// 材质
|
||||
vo.setMaterial(value);
|
||||
break;
|
||||
case 5:// 纹理
|
||||
vo.setWave(value);
|
||||
break;
|
||||
case 6:// 颜色
|
||||
vo.setColor(value);
|
||||
break;
|
||||
case 7:// 复合部件
|
||||
vo.setIsComposite(value);
|
||||
break;
|
||||
case 8:// 配件类型
|
||||
vo.setCategory(value);
|
||||
break;
|
||||
case 9:// 子类
|
||||
vo.setType(value);
|
||||
break;
|
||||
case 10:// 厂家
|
||||
vo.setFactory(value);
|
||||
break;
|
||||
case 11:// 品牌
|
||||
vo.setBrand(value);
|
||||
break;
|
||||
case 12:// 型号
|
||||
vo.setModel(value);
|
||||
break;
|
||||
case 13:// 板材/配件长
|
||||
vo.setGoodsHeight(value);
|
||||
break;
|
||||
case 14:// 板材/配件宽
|
||||
vo.setGoodsWidth(value);
|
||||
break;
|
||||
case 15:// 板材/配件厚
|
||||
vo.setGoodsThickness(value);
|
||||
break;
|
||||
case 16:// 规格
|
||||
vo.setSpec(value);
|
||||
break;
|
||||
case 17:// 单位
|
||||
vo.setUnit(value);
|
||||
break;
|
||||
case 18:// 数量
|
||||
vo.setGoodsNumber(value);
|
||||
break;
|
||||
case 19:// 房间
|
||||
vo.setRoomsName(value);
|
||||
break;
|
||||
case 20:// 柜体
|
||||
vo.setCabinetsName(value);
|
||||
break;
|
||||
case 21:// 加工组类型
|
||||
vo.setSynthesisTypeName(value);
|
||||
break;
|
||||
case 22:// 加工组名称
|
||||
vo.setCombinationName(value);
|
||||
break;
|
||||
case 23://板名称
|
||||
vo.setName(value);
|
||||
break;
|
||||
case 24:// 自定义板编号
|
||||
vo.setPlateNo(value);
|
||||
break;
|
||||
case 25:// 成品长
|
||||
vo.setHeight(value);
|
||||
break;
|
||||
case 26:// 成品宽
|
||||
vo.setWidth(value);
|
||||
break;
|
||||
case 27:// 拆单长
|
||||
vo.setSplitHeight(value);
|
||||
break;
|
||||
case 28:// 拆单宽
|
||||
vo.setSplitWidth(value);
|
||||
break;
|
||||
case 29:// 厚
|
||||
vo.setThickness(value);
|
||||
break;
|
||||
case 30:// 左封边
|
||||
vo.setSealLeft(value);
|
||||
break;
|
||||
case 31:// 右封边
|
||||
vo.setSealRight(value);
|
||||
break;
|
||||
case 32:// 上封边
|
||||
vo.setSealUp(value);
|
||||
break;
|
||||
case 33:// 下封边
|
||||
vo.setSealDown(value);
|
||||
break;
|
||||
case 34:// 排版面
|
||||
vo.setTypographicFace(value);
|
||||
break;
|
||||
case 35:// 纹路
|
||||
vo.setTexture(value);
|
||||
break;
|
||||
case 36:// 开门方向
|
||||
vo.setOpenDoorType(value);
|
||||
break;
|
||||
case 37://备注1
|
||||
vo.setRemark1(value);
|
||||
break;
|
||||
case 38://备注2
|
||||
vo.setRemark2(value);
|
||||
break;
|
||||
case 39://备注3
|
||||
vo.setRemark3(value);
|
||||
break;
|
||||
case 40://备注4
|
||||
vo.setRemark4(value);
|
||||
break;
|
||||
case 41://备注5
|
||||
vo.setRemark5(value);
|
||||
break;
|
||||
case 42://备注6
|
||||
vo.setRemark6(value);
|
||||
break;
|
||||
case 43://备注7
|
||||
vo.setRemark7(value);
|
||||
break;
|
||||
case 44://备注8
|
||||
vo.setRemark8(value);
|
||||
break;
|
||||
case 45://备注9
|
||||
vo.setRemark9(value);
|
||||
break;
|
||||
case 46://备注10
|
||||
vo.setRemark10(value);
|
||||
break;
|
||||
default:
|
||||
// 处理默认情况,可以选择忽略或者做其他处理
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSpecialDelimiters(Row row, Runnable onDelimiter, Runnable onStop) {
|
||||
String firstCellValue = getFirstCellValue(row);
|
||||
if ("###".equals(firstCellValue)) onDelimiter.run();
|
||||
if ("***".equals(firstCellValue)) onStop.run();
|
||||
}
|
||||
|
||||
private void logResults(int preSize, int postSize) {
|
||||
log.info("preDelimiterList size: {}, postDelimiterList size: {}", preSize, postSize);
|
||||
}
|
||||
|
||||
// vo转换
|
||||
public Map<String, String> changeToOrderMap(List<OrderPlateImportExcelVO> list) {
|
||||
Map<String, String> orderMap = new HashMap<>();
|
||||
|
||||
// 初始化默认值
|
||||
orderMap.put(ProduceExcelConstants.ORDER_CUSTOM_ORDER_NO, "");
|
||||
orderMap.put(ProduceExcelConstants.ORDER_CUSTOMER, "");
|
||||
orderMap.put(ProduceExcelConstants.ORDER_ADDRESS, "");
|
||||
orderMap.put(ProduceExcelConstants.ORDER_PHONE_NUMBER, "");
|
||||
orderMap.put(ProduceExcelConstants.ORDER_REMARK, "");
|
||||
orderMap.put(ProduceExcelConstants.ORDER_SPLITTER, "");
|
||||
orderMap.put(ProduceExcelConstants.ORDER_SALESMAN, "");
|
||||
orderMap.put(ProduceExcelConstants.ORDER_DEALER_PHONE_NUMBER, "");
|
||||
orderMap.put(ProduceExcelConstants.ORDER_DEALER, "");
|
||||
orderMap.put(ProduceExcelConstants.ORDER_DELIVERY_DATE, "");
|
||||
|
||||
// 定义一个映射规则数组,用于指示每个索引应更新哪些键
|
||||
String[][] keyMapping = {
|
||||
{ProduceExcelConstants.ORDER_CUSTOM_ORDER_NO, ProduceExcelConstants.ORDER_CUSTOMER},
|
||||
{ProduceExcelConstants.ORDER_DEALER, ProduceExcelConstants.ORDER_ADDRESS},
|
||||
{ProduceExcelConstants.ORDER_DEALER_PHONE_NUMBER, ProduceExcelConstants.ORDER_PHONE_NUMBER},
|
||||
{ProduceExcelConstants.ORDER_SALESMAN, ProduceExcelConstants.ORDER_DELIVERY_DATE},
|
||||
{ProduceExcelConstants.ORDER_SPLITTER, ProduceExcelConstants.ORDER_REMARK}
|
||||
};
|
||||
|
||||
for (int i = 0; i < Math.min(keyMapping.length, list.size()); i++) {
|
||||
OrderPlateImportExcelVO vo = list.get(i);
|
||||
String[] keys = keyMapping[i];
|
||||
|
||||
// 假设getGoodType()和getCabinetsName()只是示例方法,实际应用中应该根据实际情况选择合适的方法
|
||||
if (vo.getGoodType() != null && !vo.getGoodType().isEmpty()) {
|
||||
orderMap.put(keys[0], vo.getGoodType());
|
||||
}
|
||||
if (vo.getCabinetsName() != null && !vo.getCabinetsName().isEmpty()) {
|
||||
orderMap.put(keys[1], vo.getCabinetsName());
|
||||
}
|
||||
}
|
||||
|
||||
return orderMap;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.cf.imes.module.executor.util.fileConversion.admin.files.excel;
|
||||
|
||||
/**
|
||||
* Excel 常用字符
|
||||
*/
|
||||
public class ProduceExcelConstants {
|
||||
|
||||
// ========== order 模块 ==========
|
||||
public static final String ORDER_CUSTOM_ORDER_NO = "customOrderNo";
|
||||
public static final String ORDER_CUSTOMER = "customer";
|
||||
public static final String ORDER_ADDRESS = "address";
|
||||
public static final String ORDER_PHONE_NUMBER = "phoneNumber";
|
||||
public static final String ORDER_REMARK = "remark";
|
||||
public static final String ORDER_SPLITTER = "splitter";
|
||||
public static final String ORDER_SALESMAN = "salesman";
|
||||
public static final String ORDER_DEALER_PHONE_NUMBER = "dealerPhoneNumber";
|
||||
public static final String ORDER_DEALER = "dealer";
|
||||
public static final String ORDER_DELIVERY_DATE = "deliveryDate";
|
||||
|
||||
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package com.cf.imes.module.executor.util.fileConversion.admin.files.xml.VO;
|
||||
|
||||
import com.cf.imes.module.executor.dal.dataobject.order.OrderDO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
|
||||
|
||||
/**
|
||||
* Excel 校验数据类型
|
||||
*/
|
||||
@Schema(description = "Excel 校验数据类型")
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@ToString(callSuper = true)
|
||||
public class XmlCheckVO {
|
||||
|
||||
@Schema(description = "校验结果")
|
||||
private Boolean flag;
|
||||
|
||||
@Schema(description = "校验结果数据")
|
||||
private OrderXmlVO orderXmlVO;
|
||||
|
||||
@Schema(description = "订单信息")
|
||||
private OrderDO orderDO;
|
||||
|
||||
}
|
||||
+2
-6
@@ -121,8 +121,7 @@ public class XMLUtil {
|
||||
}
|
||||
|
||||
// 生产单数据格式验证
|
||||
public Map<String, Object> changeDate(OrderXmlVO orderXmlVO, Long organId) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
public XmlCheckVO changeDate(OrderXmlVO orderXmlVO, Long organId) {
|
||||
boolean error = validatePhoneNumbers(orderXmlVO);
|
||||
|
||||
LocalDate orderDate = null;
|
||||
@@ -176,10 +175,7 @@ public class XMLUtil {
|
||||
}
|
||||
|
||||
// 生产单信息验证
|
||||
map.put("order", orderDO);
|
||||
map.put("file", orderXmlVO);
|
||||
map.put("error", error);
|
||||
return map;
|
||||
return new XmlCheckVO(error, orderXmlVO, orderDO);
|
||||
}
|
||||
|
||||
// 数据格式转换
|
||||
|
||||
Reference in New Issue
Block a user