工艺计划表 更新 模板大更新
This commit is contained in:
parent
d5a75728b9
commit
775aa67674
@ -3,6 +3,7 @@ package com.ruoyi.system.controller;
|
||||
import java.io.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.URLEncoder;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
@ -491,10 +492,10 @@ public class ProcessOrderProController extends BaseController {
|
||||
if (!found) {
|
||||
processDataList.add(item);
|
||||
}
|
||||
List<ProcessRouteExcelDTO> excelDTOList = iProcessOrderProService.getRouteAndBomDetail( processDataList,orderPro);
|
||||
|
||||
}
|
||||
|
||||
|
||||
List<ProcessRouteExcelDTO> excelDTOList = iProcessOrderProService.getRouteAndBomDetail(processDataList,orderPro);
|
||||
// 使用Excel模板文件
|
||||
String templatePath = "EXCEL模板/生产及工艺计划模版.xlsx";
|
||||
String outputPath = "D:/file/" + orderPro.getProductionOrderNo() + "生产及工艺计划表.xlsx";
|
||||
@ -551,6 +552,11 @@ public class ProcessOrderProController extends BaseController {
|
||||
List<Map<String, Object>> evoDataList = convertEVOProductsDataToMapList(evoProductsList);
|
||||
dynamicDataMappingList.addAll(DynamicDataMapping.createOneDataList("EVOProductsDataVO", evoDataList));
|
||||
}
|
||||
// 添加工艺路线
|
||||
if (!excelDTOList.isEmpty()) {
|
||||
List<Map<String, Object>> routeExcelList = convertEVORoutesDataToMapList(excelDTOList);
|
||||
dynamicDataMappingList.addAll(DynamicDataMapping.createOneDataList("ProcessRouteExcelDTO", routeExcelList));
|
||||
}
|
||||
|
||||
// 使用模板导出Excel
|
||||
ExcelTemplateProc.doExportExcelByTemplateProc(templatePath, outputPath, staticDataMap, dynamicDataMappingList);
|
||||
@ -584,6 +590,7 @@ public class ProcessOrderProController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 读取RawDataTable数据
|
||||
*/
|
||||
@ -984,6 +991,65 @@ public class ProcessOrderProController extends BaseController {
|
||||
}
|
||||
return mapList;
|
||||
}
|
||||
/**
|
||||
* 转换ProcessRouteExcelDTO为Map列表(用于模板)
|
||||
*/
|
||||
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
|
||||
private String formatDate(Date date) {
|
||||
return date == null ? "" : DATE_FORMAT.format(date);
|
||||
}
|
||||
private List<Map<String, Object>> convertEVORoutesDataToMapList(List<ProcessRouteExcelDTO> evoProductsList) {
|
||||
|
||||
List<Map<String, Object>> mapList = new ArrayList<>();
|
||||
int index = 1;
|
||||
for (ProcessRouteExcelDTO dto : evoProductsList) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("index", index);
|
||||
// 基础信息
|
||||
map.put("routeDescription", dto.getRouteDescription());
|
||||
map.put("materialCode", dto.getMaterialCode());
|
||||
map.put("materialName", dto.getMaterialName());
|
||||
map.put("material", dto.getMaterial());
|
||||
map.put("discWeight", dto.getDiscWeight());
|
||||
|
||||
|
||||
// BOM 部分
|
||||
map.put("rawMaterialCode", dto.getRawMaterialCode());
|
||||
map.put("rawMaterialName", dto.getRawMaterialName());
|
||||
map.put("bomMaterial", dto.getBomMaterial());
|
||||
map.put("bomDanZhong", dto.getBomDanZhong());
|
||||
map.put("discUsage", dto.getDiscUsage());
|
||||
map.put("bomUnit", dto.getBomUnit());
|
||||
|
||||
// 工艺部分
|
||||
map.put("processNo", dto.getProcessNo());
|
||||
map.put("workCenter", dto.getWorkCenter());
|
||||
map.put("processName", dto.getProcessName());
|
||||
map.put("processDescription", dto.getProcessDescription());
|
||||
map.put("processControl", dto.getProcessControl());
|
||||
map.put("activityDuration", dto.getActivityDuration());
|
||||
map.put("activityUnit", dto.getActivityUnit());
|
||||
|
||||
// 数量部分
|
||||
map.put("unitQuantity", dto.getUnitQuantity());
|
||||
map.put("batchQuantity", dto.getBatchQuantity());
|
||||
map.put("firstBatchQuantity", dto.getFirstBatchQuantity());
|
||||
|
||||
// 时间字段格式化
|
||||
map.put("planStartTime", formatDate(dto.getPlanStartTime()));
|
||||
map.put("planEndTime", formatDate(dto.getPlanEndTime()));
|
||||
map.put("xuStartTime", formatDate(dto.getXuStartTime()));
|
||||
map.put("xuEndTime", formatDate(dto.getXuEndTime()));
|
||||
|
||||
mapList.add(map);
|
||||
index++;
|
||||
}
|
||||
return mapList;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 转换工艺VO为Map列表(用于模板)
|
||||
|
||||
@ -59,7 +59,7 @@ public class ProcessRouteExcelDTO {
|
||||
/**
|
||||
* 材料BOM用量
|
||||
*/
|
||||
private Double discUsage;
|
||||
private String discUsage;
|
||||
/**
|
||||
* 材料BOM单位
|
||||
*/
|
||||
@ -103,13 +103,13 @@ public class ProcessRouteExcelDTO {
|
||||
/**
|
||||
* 单台数量
|
||||
*/
|
||||
private Long unitQuantity;
|
||||
private Double unitQuantity;
|
||||
|
||||
/**
|
||||
* 本批数量
|
||||
*/
|
||||
|
||||
private Long batchQuantity;
|
||||
private String batchQuantity;
|
||||
|
||||
/**
|
||||
* 首批数量
|
||||
|
||||
@ -1132,17 +1132,191 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService {
|
||||
* 将工艺部分 材料BOM部分 合并成ProcessRouteExcelDTO
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<ProcessRouteExcelDTO> getRouteAndBomDetail(List<ProductionOrderVo> processDataList,ProcessOrderPro orderPro) {
|
||||
String proRoot = orderPro.getProductionOrderNo();
|
||||
//工艺部分
|
||||
List<ProcessRoute> processRoutes = iProcessRouteService.selectByProjectNumber(proRoot);
|
||||
List<MaterialBom> materialBoms = materialBomService.selectByProCode(proRoot);
|
||||
for (ProductionOrderVo productionOrderVo : processDataList) {
|
||||
ProcessRouteExcelDTO processRouteExcelDTO = new ProcessRouteExcelDTO();
|
||||
//@Override
|
||||
public List<ProcessRouteExcelDTO> getRouteAndBomDetail1(List<ProductionOrderVo> processDataList,
|
||||
ProcessOrderPro orderPro) {
|
||||
String proRoot = orderPro.getProductionOrderNo();
|
||||
|
||||
// 查出所有工艺路线和BOM
|
||||
List<ProcessRoute> allRoutes = iProcessRouteService.selectByProjectNumber(proRoot);
|
||||
List<MaterialBom> allBoms = materialBomService.selectByProCode(proRoot);
|
||||
|
||||
List<ProcessRouteExcelDTO> resultList = new ArrayList<>();
|
||||
|
||||
for (ProductionOrderVo orderVo : processDataList) {
|
||||
String materialCode = orderVo.getDrawingNo(); // 这里我假设 drawingNo == materialCode
|
||||
|
||||
// 按 materialCode 过滤
|
||||
List<ProcessRoute> processRoutes = allRoutes.stream()
|
||||
.filter(r -> materialCode.equals(r.getMaterialCode()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<MaterialBom> materialBoms = allBoms.stream()
|
||||
.filter(b -> materialCode.equals(b.getParentMaterialCode()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 对齐到最长列表
|
||||
int maxSize = Math.max(processRoutes.size(), materialBoms.size());
|
||||
for (int i = 0; i < maxSize; i++) {
|
||||
ProcessRouteExcelDTO dto = new ProcessRouteExcelDTO();
|
||||
|
||||
// 订单基础信息
|
||||
dto.setRouteDescription(orderVo.getProductionOrderNo());
|
||||
dto.setMaterialCode(orderVo.getDrawingNo());
|
||||
dto.setMaterialName(orderVo.getDrawingName());
|
||||
dto.setMaterial(orderVo.getMaterial());
|
||||
dto.setDiscWeight(orderVo.getSingleWeight());
|
||||
dto.setUnitQuantity(orderVo.getQuantity());
|
||||
dto.setBatchQuantity(orderVo.getBatchQuantity());
|
||||
|
||||
|
||||
// 工艺部分
|
||||
if (i < processRoutes.size()) {
|
||||
ProcessRoute route = processRoutes.get(i);
|
||||
dto.setProcessNo(route.getProcessNo());
|
||||
dto.setProcessName(route.getProcessName());
|
||||
dto.setWorkCenter(route.getWorkCenter());
|
||||
dto.setProcessDescription(route.getProcessDescription());
|
||||
dto.setProcessControl(route.getProcessControl());
|
||||
dto.setActivityDuration(route.getActivityDuration());
|
||||
dto.setActivityUnit(route.getActivityUnit());
|
||||
dto.setXuEndTime(route.getXuEndTime());
|
||||
dto.setXuStartTime(route.getXuStartTime());
|
||||
}
|
||||
|
||||
// BOM 部分
|
||||
if (i < materialBoms.size()) {
|
||||
MaterialBom bom = materialBoms.get(i);
|
||||
dto.setRawMaterialCode(bom.getMaterialCode());
|
||||
dto.setRawMaterialName(bom.getMaterialName());
|
||||
dto.setBomMaterial(bom.getMaterialType());
|
||||
dto.setBomUnit(bom.getUnit());
|
||||
dto.setDiscUsage(bom.getQuantity());
|
||||
}
|
||||
|
||||
resultList.add(dto);
|
||||
}
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
/**
|
||||
* 将工艺部分 材料BOM部分 合并成ProcessRouteExcelDTO
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<ProcessRouteExcelDTO> getRouteAndBomDetail(List<ProductionOrderVo> processDataList,
|
||||
ProcessOrderPro orderPro) {
|
||||
String proRoot = orderPro.getProductionOrderNo();
|
||||
|
||||
// 查出所有工艺路线和BOM
|
||||
List<ProcessRoute> allRoutes = iProcessRouteService.selectByProjectNumber(proRoot);
|
||||
List<MaterialBom> allBoms = materialBomService.selectByProCode(proRoot);
|
||||
|
||||
List<ProcessRouteExcelDTO> resultList = new ArrayList<>();
|
||||
|
||||
// 规范化 key:trim + upper,避免空格/大小写导致匹配失败
|
||||
Function<String, String> normalize = s -> s == null ? "" : s.trim().toUpperCase();
|
||||
|
||||
// 按 materialCode 分组(工艺路线)
|
||||
Map<String, List<ProcessRoute>> routeMap = allRoutes.stream()
|
||||
.collect(Collectors.groupingBy(r -> normalize.apply(r.getMaterialCode())));
|
||||
|
||||
// 按 parentMaterialCode 分组(BOM 的 parent)
|
||||
Map<String, List<MaterialBom>> bomMap = allBoms.stream()
|
||||
.collect(Collectors.groupingBy(b -> normalize.apply(b.getParentMaterialCode())));
|
||||
|
||||
// 把订单数据做成 Map(key = drawingNo 规范化)
|
||||
Map<String, ProductionOrderVo> orderMap = processDataList.stream()
|
||||
.collect(Collectors.toMap(vo -> normalize.apply(vo.getDrawingNo()), vo -> vo, (a, b) -> a));
|
||||
|
||||
// 先把 routeMap 的 key 加入(保证 processRoutes 为基础),再补上 orderMap 中但不在 routeMap 的物料
|
||||
LinkedHashSet<String> materialKeys = new LinkedHashSet<>();
|
||||
materialKeys.addAll(routeMap.keySet()); // 以工艺路线为主序
|
||||
orderMap.keySet().stream()
|
||||
.filter(key -> !materialKeys.contains(key))
|
||||
.forEach(materialKeys::add); // 补充仅在订单里的物料
|
||||
|
||||
// 遍历每个物料编码(规范化 key)
|
||||
for (String key : materialKeys) {
|
||||
List<ProcessRoute> processRoutes = routeMap.getOrDefault(key, Collections.emptyList());
|
||||
List<MaterialBom> materialBoms = bomMap.getOrDefault(key, Collections.emptyList());
|
||||
ProductionOrderVo orderVo = orderMap.get(key); // 可能为 null
|
||||
|
||||
// 用于显示在 DTO 中的原始物料编码(未规范化的形式)
|
||||
String originalMaterialCode = null;
|
||||
String originalMaterialName = null;
|
||||
String originalMaterial = null;
|
||||
String originalDiscWeight = null;
|
||||
if (orderVo != null) {
|
||||
originalMaterialCode = orderVo.getDrawingNo();
|
||||
originalMaterialName = orderVo.getDrawingName();
|
||||
originalMaterial = orderVo.getMaterial();
|
||||
originalDiscWeight = String.valueOf(orderVo.getSingleWeight());
|
||||
} else if (!processRoutes.isEmpty()) {
|
||||
originalMaterialCode = processRoutes.get(0).getMaterialCode();
|
||||
} else if (!materialBoms.isEmpty()) {
|
||||
originalMaterialCode = materialBoms.get(0).getParentMaterialCode();
|
||||
} else {
|
||||
originalMaterialCode = key; // 退路:用规范化 key
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
// 以 processRoutes 为主,行数 = max(processRoutes.size(), materialBoms.size())
|
||||
int maxSize = Math.max(processRoutes.size(), materialBoms.size());
|
||||
// 如果两边都为空但有订单(order-only),也至少输出一行
|
||||
if (maxSize == 0 && orderVo != null) {
|
||||
maxSize = 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < maxSize; i++) {
|
||||
ProcessRouteExcelDTO dto = new ProcessRouteExcelDTO();
|
||||
|
||||
// 订单基础信息(有就填)
|
||||
if (orderVo != null) {
|
||||
dto.setRouteDescription(orderVo.getProductionOrderNo());
|
||||
dto.setMaterialCode(orderVo.getDrawingNo());
|
||||
dto.setMaterialName(orderVo.getDrawingName());
|
||||
dto.setMaterial(orderVo.getMaterial());
|
||||
dto.setDiscWeight(orderVo.getSingleWeight());
|
||||
dto.setUnitQuantity(orderVo.getQuantity());
|
||||
dto.setBatchQuantity(orderVo.getBatchQuantity());
|
||||
} else {
|
||||
// 若无订单,则至少把 materialCode 放入显示(用原始值)
|
||||
dto.setMaterialCode(originalMaterialCode);
|
||||
dto.setMaterialName(originalMaterialName);
|
||||
dto.setMaterial(originalMaterial);
|
||||
dto.setDiscUsage(originalDiscWeight);
|
||||
}
|
||||
|
||||
// 工艺部分(有就填)
|
||||
if (i < processRoutes.size()) {
|
||||
ProcessRoute route = processRoutes.get(i);
|
||||
dto.setProcessNo(route.getProcessNo());
|
||||
dto.setProcessName(route.getProcessName());
|
||||
dto.setWorkCenter(route.getWorkCenter());
|
||||
dto.setProcessDescription(route.getProcessDescription());
|
||||
dto.setProcessControl(route.getProcessControl());
|
||||
dto.setActivityDuration(route.getActivityDuration());
|
||||
dto.setActivityUnit(route.getActivityUnit());
|
||||
dto.setXuEndTime(route.getXuEndTime());
|
||||
dto.setXuStartTime(route.getXuStartTime());
|
||||
}
|
||||
|
||||
// BOM 部分(以 parentMaterialCode 为匹配依据)
|
||||
if (i < materialBoms.size()) {
|
||||
MaterialBom bom = materialBoms.get(i);
|
||||
dto.setRawMaterialCode(bom.getMaterialCode());
|
||||
dto.setRawMaterialName(bom.getMaterialName());
|
||||
dto.setBomMaterial(bom.getMaterialType());
|
||||
dto.setBomUnit(bom.getUnit());
|
||||
dto.setDiscUsage(bom.getQuantity());
|
||||
}
|
||||
|
||||
resultList.add(dto);
|
||||
}
|
||||
}
|
||||
|
||||
return resultList;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Binary file not shown.
Loading…
Reference in New Issue
Block a user