工艺计划表 更新 模板大更新

This commit is contained in:
tzy 2025-09-16 23:38:28 +08:00
parent d5a75728b9
commit 775aa67674
4 changed files with 254 additions and 14 deletions

View File

@ -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列表用于模板

View File

@ -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;
/**
* 首批数量

View File

@ -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<>();
// 规范化 keytrim + 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())));
// 把订单数据做成 Mapkey = 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;
}
}