diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java index f91c2ae..e135653 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java @@ -1,5 +1,7 @@ package com.ruoyi.common.core.domain; +import com.alibaba.excel.annotation.ExcelIgnore; +import com.alibaba.excel.annotation.ExcelProperty; import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.TableField; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -27,30 +29,35 @@ public class BaseEntity implements Serializable { */ @JsonIgnore @TableField(exist = false) + @ExcelIgnore private String searchValue; /** * 创建者 */ @TableField(fill = FieldFill.INSERT) + @ExcelIgnore private String createBy; /** * 创建时间 */ @TableField(fill = FieldFill.INSERT) + @ExcelIgnore private Date createTime; /** * 更新者 */ @TableField(fill = FieldFill.INSERT_UPDATE) + @ExcelIgnore private String updateBy; /** * 更新时间 */ @TableField(fill = FieldFill.INSERT_UPDATE) + @ExcelIgnore private Date updateTime; /** @@ -58,6 +65,7 @@ public class BaseEntity implements Serializable { */ @JsonInclude(JsonInclude.Include.NON_EMPTY) @TableField(exist = false) + @ExcelIgnore private Map params = new HashMap<>(); } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/excel/DefaultExcelListener.java b/ruoyi-common/src/main/java/com/ruoyi/common/excel/DefaultExcelListener.java index 082fb12..1331bdc 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/excel/DefaultExcelListener.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/excel/DefaultExcelListener.java @@ -92,6 +92,11 @@ public class DefaultExcelListener extends AnalysisEventListener implements } excelResult.getList().add(data); } + @Override + public boolean hasNext(AnalysisContext context) { + return super.hasNext(context); + } + @Override public void doAfterAllAnalysed(AnalysisContext context) { diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/WxRobotUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/WxRobotUtil.java index 9f9a7b4..a9a0035 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/WxRobotUtil.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/WxRobotUtil.java @@ -63,11 +63,11 @@ public class WxRobotUtil { HashMap textMap = new HashMap<>(); textMap.put("content", msg); - // 添加@所有人的配置 - if (mentionAll) { - textMap.put("mentioned_list", Collections.singletonList("@all")); - } - + // 添加@所有人的配置 + if (mentionAll) { + textMap.put("mentioned_list", Collections.singletonList("@all")); + } + paramMap.put("msgtype", "text"); paramMap.put("text", textMap); diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/SmbUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/SmbUtil.java new file mode 100644 index 0000000..9f7b3eb --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/SmbUtil.java @@ -0,0 +1,143 @@ +package com.ruoyi.common.utils.file; + +import jcifs.CIFSContext; +import jcifs.Configuration; +import jcifs.config.PropertyConfiguration; +import jcifs.context.BaseContext; +import jcifs.smb.SmbFile; + +import java.io.*; +import java.nio.file.Files; +import java.util.Properties; + +public class SmbUtil { + // 配置常量 + private static final String TARGET_FOLDER = "CP-25-103-XCL"; // 需要进入的远程子目录 + private static final String FILE_EXTENSION = ".xlsx"; // 目标文件后缀 + private static final String LOCAL_DIR = "D:/file"; + public static void main(String[] args) { + String name = "CP-25-103-XCL"; + downloadExcelFiles(name); + } + + public static void downloadExcelFiles1(String targetFolder) { + try { + // 初始化SMB配置 + Properties ps = new Properties(); + ps.setProperty("jcifs.smb.client.username", "admin"); + ps.setProperty("jcifs.smb.client.password", "hbyt2025"); + ps.setProperty("jcifs.smb.client.dfs.disabled", "true"); + + Configuration config = new PropertyConfiguration(ps); + CIFSContext cifs = new BaseContext(config); + + // 创建本地保存目录 + File localDir = new File(LOCAL_DIR); + if (!localDir.exists() && !localDir.mkdirs()) { + throw new IOException("无法创建本地目录: " + localDir.getAbsolutePath()); + } + + // 定位到远程目标子目录 + SmbFile remoteDir = new SmbFile("smb://192.168.5.18/2025/" + targetFolder + "/", cifs); + + if (!remoteDir.exists() || !remoteDir.isDirectory()) { + System.err.println("远程目录不存在: " + remoteDir.getCanonicalPath()); + return; + } + + for (SmbFile remoteFile : remoteDir.listFiles()) { + // 过滤非目标文件 + if (remoteFile.isFile() && remoteFile.getName().toLowerCase().endsWith(FILE_EXTENSION)) { + // 提取原文件扩展名 + String originalName = remoteFile.getName(); + int dotIndex = originalName.lastIndexOf('.'); + String extension = (dotIndex != -1) ? originalName.substring(dotIndex) : ""; + + // 使用指定名称 + 原扩展名构造本地文件名 + String localFileName = targetFolder + extension; + File localFile = new File(localDir, localFileName); + + transferFile(remoteFile, localFile); + } + } + + } catch (Exception e) { + e.printStackTrace(); + } + } + public static void downloadExcelFiles(String targetFolder) { + try { + // 初始化SMB配置 + Properties ps = new Properties(); + ps.setProperty("jcifs.smb.client.username", "admin"); + ps.setProperty("jcifs.smb.client.password", "hbyt2025"); + ps.setProperty("jcifs.smb.client.dfs.disabled", "true"); + + Configuration config = new PropertyConfiguration(ps); + CIFSContext cifs = new BaseContext(config); + + // 创建本地保存目录 + File localDir = new File(LOCAL_DIR); + if (!localDir.exists() && !localDir.mkdirs()) { + throw new IOException("无法创建本地目录: " + localDir.getAbsolutePath()); + } + + // 定位到远程目标子目录 + SmbFile remoteDir = new SmbFile("smb://192.168.5.18/2025/" + targetFolder + "/", cifs); + + if (!remoteDir.exists() || !remoteDir.isDirectory()) { + System.err.println("远程目录不存在或不是一个目录: " + remoteDir.getCanonicalPath()); + return; + } + + // 指定要下载的文件名 + String targetFileName = targetFolder+"汇总表.xlsx"; + + // 构造远程文件路径 + SmbFile remoteFile = new SmbFile(remoteDir, targetFileName); + + if (!remoteFile.exists() || !remoteFile.isFile()) { + System.err.println("目标文件不存在: " + remoteFile.getCanonicalPath()); + return; + } + + // 本地保存路径:D:/file/项目生产数据表.xlsx + File localFile = new File(localDir, targetFileName); + + transferFile(remoteFile, localFile); + + } catch (Exception e) { + System.err.println("操作失败: " + e.getMessage()); + e.printStackTrace(); + } + } + + private static void transferFile(SmbFile remoteFile, File localFile) { + System.out.printf("正在下载 [%s] => [%s]%n", + remoteFile.getName(), + localFile.getAbsolutePath()); + + try (InputStream is = remoteFile.getInputStream(); + OutputStream os = Files.newOutputStream(localFile.toPath())) { + + // 使用8KB缓冲区提升传输效率 + byte[] buffer = new byte[8192]; + int bytesRead; + while ((bytesRead = is.read(buffer)) != -1) { + os.write(buffer, 0, bytesRead); + } + + System.out.println("√ 下载成功: " + remoteFile.getName()); + + } catch (IOException e) { + System.err.println("× 下载失败: " + remoteFile.getName()); + e.printStackTrace(); + + // 清理失败文件 + if (localFile.exists() && !localFile.delete()) { + System.err.println("! 无法清理残留文件: " + localFile.getName()); + } + } + } +} + diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java index 7ea323f..4555f53 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java @@ -5,12 +5,7 @@ import cn.hutool.core.io.resource.ClassPathResource; import cn.hutool.core.util.IdUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; -import com.alibaba.excel.enums.CellDataTypeEnum; -import com.alibaba.excel.metadata.GlobalConfiguration; -import com.alibaba.excel.metadata.data.CellData; -import com.alibaba.excel.metadata.property.ExcelContentProperty; -import com.alibaba.excel.read.builder.ExcelReaderBuilder; -import com.alibaba.excel.support.ExcelTypeEnum; + import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder; import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.fill.FillConfig; @@ -25,6 +20,8 @@ import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.file.FileUtils; import lombok.AccessLevel; import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.AllArgsConstructor; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; @@ -32,6 +29,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; import java.util.Collection; import java.util.List; import java.util.Map; @@ -139,39 +137,64 @@ public class ExcelUtil { } } -/** - * 导出excel - * - * @param list1 导出数据集合1 - * @param sheetName1 工作表的名称1 - * @param clazz1 实体类1 - * @param list2 导出数据集合2 - * @param sheetName2 工作表的名称2 - * @param clazz2 实体类2 - * @param response 响应体 - */ -public static void exportExcelWithMultipleSheets(List list1, String sheetName1, Class clazz1, - List list2, String sheetName2, Class clazz2, - HttpServletResponse response) { - try { - resetResponse(sheetName1, response); - ServletOutputStream os = response.getOutputStream(); - // 使用 EasyExcel 或 Apache POI 自定义导出 - ExcelWriter excelWriter = EasyExcel.write(os, clazz1).build(); - - // 写入第一个 sheet - WriteSheet writeSheet1 = EasyExcel.writerSheet(sheetName1).build(); - excelWriter.write(list1, writeSheet1); - - // 写入第二个 sheet - WriteSheet writeSheet2 = EasyExcel.writerSheet(sheetName2).build(); - excelWriter.write(list2, writeSheet2); - - excelWriter.finish(); - } catch (IOException e) { - throw new RuntimeException("导出Excel异常"); + /** + * 导出多个sheet的Excel + * + * @param list1 第一个sheet的数据集合 + * @param sheetName1 第一个sheet的名称 + * @param clazz1 第一个sheet的实体类 + * @param list2 第二个sheet的数据集合 + * @param sheetName2 第二个sheet的名称 + * @param clazz2 第二个sheet的实体类 + * @param response HTTP响应对象 + */ + public static void exportExcelWithMultipleSheets(List list1, String sheetName1, Class clazz1, + List list2, String sheetName2, Class clazz2, + HttpServletResponse response) { + ServletOutputStream os = null; + ExcelWriter excelWriter = null; + try { + // 设置响应头 + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + String fileName = URLEncoder.encode(sheetName1, "UTF-8").replaceAll("\\+", "%20"); + response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); + + os = response.getOutputStream(); + + // 创建ExcelWriter + excelWriter = EasyExcel.write(os) + .autoCloseStream(false) // 防止自动关闭流 + .build(); + + // 写入第一个sheet + WriteSheet writeSheet1 = EasyExcel.writerSheet(0, sheetName1) + .head(clazz1) + .build(); + excelWriter.write(list1, writeSheet1); + + // 写入第二个sheet + WriteSheet writeSheet2 = EasyExcel.writerSheet(1, sheetName2) + .head(clazz2) + .build(); + excelWriter.write(list2, writeSheet2); + + } catch (Exception e) { + throw new RuntimeException("导出Excel异常: " + e.getMessage(), e); + } finally { + // 确保资源正确关闭 + if (excelWriter != null) { + excelWriter.finish(); + } + if (os != null) { + try { + os.close(); + } catch (IOException e) { + // 忽略关闭时的异常 + } + } + } } -} /** * 导出excel @@ -404,4 +427,109 @@ public static void exportExcelWithMultipleSheets(List list1, String return IdUtil.fastSimpleUUID() + "_" + filename + ".xlsx"; } + /** + * 导出多个sheet的Excel(相同对象) + * + * @param list 导出数据集合的集合(每个元素代表一个sheet的数据) + * @param sheetNames sheet名称的集合(与list一一对应) + * @param clazz 实体类 + * @param response 响应体 + */ + public static void exportExcelWithSheets(List> list, List sheetNames, Class clazz, HttpServletResponse response) { + try { + if (CollUtil.isEmpty(list) || CollUtil.isEmpty(sheetNames) || list.size() != sheetNames.size()) { + throw new IllegalArgumentException("数据列表或sheet名称列表不能为空,且两者长度必须相等"); + } + + resetResponse(sheetNames.get(0), response); + ServletOutputStream os = response.getOutputStream(); + + // 创建ExcelWriter + ExcelWriter excelWriter = EasyExcel.write(os) + .autoCloseStream(false) + // 自动适配 + .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) + // 大数值自动转换 防止失真 + .registerConverter(new ExcelBigNumberConvert()) + .build(); + + try { + // 循环写入每个sheet + for (int i = 0; i < list.size(); i++) { + WriteSheet writeSheet = EasyExcel.writerSheet(i, sheetNames.get(i)) + .head(clazz) + .build(); + excelWriter.write(list.get(i), writeSheet); + } + } finally { + // 确保ExcelWriter被正确关闭 + if (excelWriter != null) { + excelWriter.finish(); + } + } + } catch (Exception e) { + throw new RuntimeException("导出Excel异常", e); + } + } + + /** + * 通用多sheet导出方法 + * + * @param sheetDataList sheet数据列表,每个元素包含:数据列表、sheet名称、数据类型 + * @param response HTTP响应对象 + */ + public static void exportExcelWithSheets(List> sheetDataList, HttpServletResponse response) { + ServletOutputStream os = null; + ExcelWriter excelWriter = null; + try { + // 设置响应头 + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + String fileName = URLEncoder.encode("导出数据", "UTF-8").replaceAll("\\+", "%20"); + response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); + + os = response.getOutputStream(); + + // 创建ExcelWriter + excelWriter = EasyExcel.write(os) + .autoCloseStream(false) // 防止自动关闭流 + .build(); + + // 循环写入每个sheet + for (int i = 0; i < sheetDataList.size(); i++) { + SheetData sheetData = sheetDataList.get(i); + WriteSheet writeSheet = EasyExcel.writerSheet(i, sheetData.getSheetName()) + .head(sheetData.getClazz()) + .build(); + excelWriter.write(sheetData.getData(), writeSheet); + } + + } catch (Exception e) { + throw new RuntimeException("导出Excel异常: " + e.getMessage(), e); + } finally { + // 确保资源正确关闭 + if (excelWriter != null) { + excelWriter.finish(); + } + if (os != null) { + try { + os.close(); + } catch (IOException e) { + // 忽略关闭时的异常 + } + } + } + } + + /** + * Sheet数据包装类 + */ + @Data + @AllArgsConstructor + public static class SheetData { + private List data; + private String sheetName; + private Class clazz; + } + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/BomDetailsController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/BomDetailsController.java index 5e9e2e9..8ead902 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/BomDetailsController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/BomDetailsController.java @@ -23,7 +23,8 @@ import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.system.domain.BomDetails; import com.ruoyi.system.domain.MaterialProperties; import com.ruoyi.system.domain.bo.BomDetailsBo; -import com.ruoyi.system.domain.dto.JDBom; +import com.ruoyi.system.domain.dto.JdValidateBomDTO; +import com.ruoyi.system.domain.dto.JdChildDTO; import com.ruoyi.system.domain.vo.BomDetailsVo; import com.ruoyi.system.runner.JdUtil; import com.ruoyi.system.service.IBomDetailsService; @@ -31,13 +32,13 @@ import com.ruoyi.system.service.IMaterialPropertiesService; import com.ruoyi.system.service.IMaterialTotalService; import com.ruoyi.system.service.IProcessRouteService; import lombok.RequiredArgsConstructor; +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.WorkbookFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -61,6 +62,7 @@ import static org.aspectj.bridge.MessageUtil.fail; @RequiredArgsConstructor @RestController @RequestMapping("/system/details") +@Slf4j public class BomDetailsController extends BaseController { private final IBomDetailsService iBomDetailsService; @@ -70,7 +72,8 @@ public class BomDetailsController extends BaseController { private final IProcessRouteService iProcessRouteService; private final IMaterialTotalService iMaterialTotalService; - private static final Logger log = LoggerFactory.getLogger(BomDetailsController.class); + + /** * 查询bom明细列表 @@ -197,7 +200,6 @@ public class BomDetailsController extends BaseController { /** * 导入BOM * daorubaon - * * @param file 导入文件 */ @@ -214,28 +216,21 @@ public class BomDetailsController extends BaseController { if (loadChengPinMaterialPreservation(bomFinishedProduct) == 1) { log.info("新增成品父级物流成功"); } - // loadChengPinMaterialPreservation() for (BomDetailsVo bomDetailsvo : bomDetailsVos) { BomDetails bomDetails = BeanUtil.toBean(bomDetailsvo, BomDetails.class); // 校验属性、材质、数量是否为空,并记录提示信息 if (bomDetails.getStats() == null || bomDetails.getMaterial() == null || bomDetails.getQuantity() == null) { - String warningMessage = String.format("记录 %s 缺少必要字段: 属性=%s, 材质=%s, 数量=%s", - bomDetails.getPartNumber(), bomDetails.getStats(), bomDetails.getMaterial(), - bomDetails.getQuantity()); + String warningMessage = String.format("记录 %s 缺少必要字段: 属性=%s, 材质=%s, 数量=%s", bomDetails.getPartNumber(), bomDetails.getStats(), bomDetails.getMaterial(), bomDetails.getQuantity()); missingFieldsWarnings.add(warningMessage); } // 验证物料是否存在 - if (bomDetails.getFNumber() != null && bomDetails.getFName() != null && bomDetails.getPartNumber() != null - && bomDetails.getName() != null) { + if (bomDetails.getFNumber() != null && bomDetails.getFName() != null && bomDetails.getPartNumber() != null && bomDetails.getName() != null) { int verification = isMaterialVerification(bomDetails.getPartNumber(), bomDetails.getName()); if (verification == 1) { bomDetails.setUnitWeight("是"); } else if (verification == 3) { - if (bomDetails.getStats() == null || bomDetails.getStats().equals("外购") - || bomDetails.getFName().startsWith("009") || bomDetails.getFName().startsWith("AA") - || bomDetails.getFName().startsWith("AB") || bomDetails.getFName().startsWith("AC") - || bomDetails.getFName().startsWith("015")) { + if (bomDetails.getStats() == null || bomDetails.getStats().equals("外购") || bomDetails.getFName().startsWith("009") || bomDetails.getFName().startsWith("AA") || bomDetails.getFName().startsWith("AB") || bomDetails.getFName().startsWith("AC") || bomDetails.getFName().startsWith("015")) { materialsToAdd.add(bomDetails); } else if (bomDetails.getStats().equals("自制")) { materialsToAdd.add(bomDetails); @@ -244,10 +239,7 @@ public class BomDetailsController extends BaseController { } bomDetails.setUnitWeight("编码名称不符"); } else { - if (bomDetails.getStats() == null || bomDetails.getStats().equals("外购") - || bomDetails.getFName().startsWith("009") || bomDetails.getFName().startsWith("AA") - || bomDetails.getFName().startsWith("AB") || bomDetails.getFName().startsWith("AC") - || bomDetails.getFName().startsWith("015")) { + if (bomDetails.getStats() == null || bomDetails.getStats().equals("外购") || bomDetails.getFName().startsWith("009") || bomDetails.getFName().startsWith("AA") || bomDetails.getFName().startsWith("AB") || bomDetails.getFName().startsWith("AC") || bomDetails.getFName().startsWith("015")) { materialsToAdd.add(bomDetails); } else if (bomDetails.getStats().equals("自制")) { materialsToAdd.add(bomDetails); @@ -288,6 +280,8 @@ public class BomDetailsController extends BaseController { log.info("开始新增不存在的物料==> 物料图号: " + material.getPartNumber() + " 物料名称: " + material.getName()); result = loadMaterialPreservation(material, state, a); } + + if (result == 1) { log.info("新增物料成功==> 物料图号: " + material.getPartNumber() + " 物料名称: " + material.getName()); material.setUnitWeight("新增成功"); @@ -407,8 +401,7 @@ public class BomDetailsController extends BaseController { // 获取工艺表中的非委外工时 Double fbWorkTime = iProcessRouteService.getFbWorkTime(material); - if (material.getPartNumber() != null && material.getName() != null - && material.getUnitWeight().equals("否")) { + if (material.getPartNumber() != null && material.getName() != null && material.getUnitWeight().equals("否")) { String state = determineState(material); log.info("开始新增不存在的物料 ==> 物料图号: {}, 物料名称: {}", material.getPartNumber(), material.getName()); @@ -434,7 +427,7 @@ public class BomDetailsController extends BaseController { } // 保存物料清单之前进行BOM校验 - if (!validateBOM(fnumber, bomDetails)) { + if (validateBOM(fnumber, bomDetails)) { log.error("BOM校验失败,物料编码: {}", fnumber); failedMaterials.add(fnumber); continue; // 跳过保存 @@ -448,53 +441,57 @@ public class BomDetailsController extends BaseController { // 返回处理结果 return R.ok("成功", bomDetailsList); + } - // BOM 校验方法 private boolean validateBOM(String fnumber, List bomDetails) { - List JDBomList = JdUtil.getSelectBomList(fnumber); + List JDBomList = JdUtil.getSelectBomList(fnumber); // 1. 判断BOM是否为空 if (JDBomList == null || JDBomList.isEmpty()) { log.error("BOM为空,物料编码: {}", fnumber); - return false; // BOM校验失败 + return false; // BOM为空,需要上传 } - // 2. 检查子项数量是否一致 - if (JDBomList.size() != bomDetails.size()) { - log.error("BOM子项数量不一致,物料编码: {},金蝶子项数量: {},传入子项数量: {}", - fnumber, JDBomList.size(), bomDetails.size()); - return false; // BOM校验失败 - } - - // 3. 比较每个子项的内容 - for (int i = 0; i < JDBomList.size(); i++) { - BomDetails jdBomDetail = JDBomList.get(i); - BomDetails inputBomDetail = bomDetails.get(i); - - // 比较物料编码和名称 - if (!jdBomDetail.getFNumber().equals(inputBomDetail.getFNumber()) || - !jdBomDetail.getName().equals(inputBomDetail.getName())) { - log.error("BOM子项内容不一致,物料编码: {},金蝶物料: {},传入物料: {}", - fnumber, jdBomDetail.getFNumber(), inputBomDetail.getFNumber()); - return false; // BOM校验失败 + for (JdValidateBomDTO jdBom : JDBomList) { + // 3. 检查子项数量是否一致 + if (jdBom.getChilds().size() != bomDetails.size()) { + continue; // 数量不一致,跳过这个BOM,继续检查下一个 } - // 比较分子和分母(假设有分子和分母字段) - if (!jdBomDetail.getDenominator().equals(inputBomDetail.getDenominator()) || - !jdBomDetail.getQuantity().equals(inputBomDetail.getQuantity())) { - log.error("BOM子项分子分母不一致,物料编码: {},金蝶分子: {}, 分母: {},传入分子: {}, 分母: {}", - fnumber, jdBomDetail.getDenominator(), jdBomDetail.getDenominator(), - inputBomDetail.getDenominator(), inputBomDetail.getDenominator()); - return false; // BOM校验失败 + // 4. 比较每个子项的内容 + boolean isMatch = true; + for (int i = 0; i < jdBom.getChilds().size(); i++) { + JdChildDTO jdChild = jdBom.getChilds().get(i); + BomDetails inputBomDetail = bomDetails.get(i); + + // 比较物料编码和名称 + if (!jdChild.getPartNumber().equals(inputBomDetail.getPartNumber()) || + !jdChild.getName().equals(inputBomDetail.getName())) { + isMatch = false; + break; + } + + // 比较分子和分母 + if (!jdChild.getDenominator().equals(inputBomDetail.getDenominator()) || !jdChild.getQuantity().equals(inputBomDetail.getQuantity())) { + isMatch = false; + break; + } + } + + if (isMatch) { + // 找到匹配的BOM,无需上传 + log.info("BOM完全相同,物料编码: {},无需上传", fnumber); + return true; } } - // 如果所有校验通过 - log.info("BOM校验通过,物料编码: {}", fnumber); - return true; // BOM校验成功 + // 所有BOM都不匹配,需要上传 + log.info("BOM不存在或不一致,物料编码: {},需要上传", fnumber); + return false; } + /* * 物料清单保存方法 */ @@ -741,7 +738,7 @@ public class BomDetailsController extends BaseController { fTreeEntityList.add(fTreeEntityItem); } String jsonData = json.toString(); - log.debug("打印json:" + jsonData); + log.info("打印json:" + jsonData); try { // 业务对象标识 String formId = "ENG_BOM"; @@ -1140,7 +1137,6 @@ public class BomDetailsController extends BaseController { /* * FB父级物料保存接口 - * 单位 是台 */ public int loadChengPinMaterialPreservation(HashMap bomDetail) { K3CloudApi client = new K3CloudApi(); @@ -1364,19 +1360,18 @@ public class BomDetailsController extends BaseController { public int loadMaterialPreservation(BomDetails bomDetails1, String states, Double fbWorkTime) { K3CloudApi client = new K3CloudApi(); - // 创建一个空的JsonObject JsonObject json = new JsonObject(); - // 添加IsAutoSubmitAndAudit字段 json.addProperty("IsAutoSubmitAndAudit", "true"); - // 创建Model对象,并加入JsonObject JsonObject model = new JsonObject(); json.add("Model", model); - // 添加Model字段 model.addProperty("FMATERIALID", 0); - if (!(bomDetails1.getDanzhong() == null)) { - model.addProperty("F_HBYT_DZ", bomDetails1.getDanzhong()); + //单重 + if (!(bomDetails1.getDanZhong() == null) && !(bomDetails1.getSingleWeghit() == null)) { + model.addProperty("F_HBYT_DZ", bomDetails1.getSingleWeghit()); + }else { + model.addProperty("F_HBYT_DZ", bomDetails1.getDanZhong()); } model.addProperty("FSpecification", bomDetails1.getRemarks()); model.addProperty("FNumber", bomDetails1.getPartNumber()); @@ -1392,21 +1387,18 @@ public class BomDetailsController extends BaseController { FSVRIAssistant.addProperty("FNumber", "17"); model.add("F_SVRI_Assistant", FSVRIAssistant); } - // 创建FMaterialGroup对象,并加入Model JsonObject fMaterialGroup = new JsonObject(); fMaterialGroup.addProperty("FNumber", "YT100.01"); model.add("FMaterialGroup", fMaterialGroup); model.addProperty("FIsHandleReserve", true); - // 创建SubHeadEntity对象,并加入Model JsonObject subHeadEntity = new JsonObject(); model.add("SubHeadEntity", subHeadEntity); subHeadEntity.addProperty("FErpClsID", states); subHeadEntity.addProperty("FFeatureItem", "1"); - // 创建FCategoryID对象,并加入SubHeadEntity JsonObject fCategoryID = new JsonObject(); if (states.equals("2") || states.equals("3")) { fCategoryID.addProperty("FNumber", "007"); @@ -1416,12 +1408,10 @@ public class BomDetailsController extends BaseController { subHeadEntity.add("FCategoryID", fCategoryID); - // 创建FTaxRateId对象,并加入SubHeadEntity JsonObject fTaxRateId = new JsonObject(); fTaxRateId.addProperty("FNUMBER", "SL02_SYS"); subHeadEntity.add("FTaxRateId", fTaxRateId); - // 创建FBaseUnitId对象,并加入SubHeadEntity JsonObject fBaseUnitId = new JsonObject(); subHeadEntity.add("FBaseUnitId", fBaseUnitId); if (bomDetails1.getPartNumber().startsWith("015") || bomDetails1.getName().contains("磨光棒")) { diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/EleMaterialsController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/EleMaterialsController.java index 06e1e16..6300758 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/EleMaterialsController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/EleMaterialsController.java @@ -6,6 +6,8 @@ import java.util.Arrays; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; +import java.util.concurrent.Future; +import java.util.concurrent.ExecutionException; import com.alibaba.fastjson.JSONObject; import com.kingdee.bos.webapi.entity.SuccessEntity; @@ -53,6 +55,7 @@ public class EleMaterialsController extends BaseController { private final IEleMaterialsService iEleMaterialsService; private static final Logger log = LoggerFactory.getLogger(EleMaterialsController.class); + /** * 查询电器物料管理列表 */ @@ -81,8 +84,7 @@ public class EleMaterialsController extends BaseController { */ @SaCheckPermission("system:materials:query") @GetMapping("/{id}") - public R getInfo(@NotNull(message = "主键不能为空") - @PathVariable Long id) { + public R getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) { return R.ok(iEleMaterialsService.queryById(id)); } @@ -116,12 +118,10 @@ public class EleMaterialsController extends BaseController { @SaCheckPermission("system:materials:remove") @Log(title = "电器物料管理", businessType = BusinessType.DELETE) @DeleteMapping("/{ids}") - public R remove(@NotEmpty(message = "主键不能为空") - @PathVariable Long[] ids) { + public R remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) { return toAjax(iEleMaterialsService.deleteWithValidByIds(Arrays.asList(ids), true)); } - /** * 将物料上传至金蝶 */ @@ -131,21 +131,23 @@ public class EleMaterialsController extends BaseController { @PostMapping("/addToK3") public R> addToK3() { - return iEleMaterialsService.addToJindie(); + return iEleMaterialsService.addToJindie(); } + @Log(title = "电器物料导入", businessType = BusinessType.IMPORT) @SaCheckPermission("system:materials:importData") @PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public ExcelVo importData(@RequestParam("file") MultipartFile file, HttpServletResponse response) throws Exception { String originalFilename = file.getOriginalFilename(); log.info("读取文件名: " + originalFilename); - + // 确保文件不为空 if (file.isEmpty()) { throw new RuntimeException("上传的文件为空"); } // 导入 Excel 数据 - ExcelResult eleMaterialsVoExcelResult = ExcelUtil.importExcelSheet1(file.getInputStream(), EleMaterialsVo.class, true); + ExcelResult eleMaterialsVoExcelResult = ExcelUtil.importExcelSheet1(file.getInputStream(), + EleMaterialsVo.class, true); // 检查导入结果 if (eleMaterialsVoExcelResult.getList() == null || eleMaterialsVoExcelResult.getList().isEmpty()) { throw new RuntimeException("导入的 Excel 文件没有有效数据"); @@ -161,7 +163,7 @@ public class EleMaterialsController extends BaseController { @PostMapping(value = "/exportData") public void importData1(@RequestBody ExcelVo excelVo, HttpServletResponse response) throws Exception { - //把 result 返回 + // 把 result 返回 try { // 保存数据并导出 Excel if (iEleMaterialsService.saveData(excelVo.getList(), response)) { @@ -189,16 +191,17 @@ public class EleMaterialsController extends BaseController { } - return R.ok("更新成功"); } + @Log(title = "禁用子项中包含的物料", businessType = BusinessType.IMPORT) @SaCheckPermission("system:materials:importDataTime") @PostMapping(value = "/importMA1", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public R importMA1(@RequestParam("file") MultipartFile file) throws Exception { String originalFilename = file.getOriginalFilename(); log.info("读取文件名: " + originalFilename); - ExcelResult result = ExcelUtil.importExcelSheet1(file.getInputStream(), EleMaterialsVo.class, true); + ExcelResult result = ExcelUtil.importExcelSheet1(file.getInputStream(), EleMaterialsVo.class, + true); List list = result.getList(); // 创建一个固定大小的线程池 ExecutorService executorService = Executors.newFixedThreadPool(10); // 可以根据需要调整线程数 @@ -238,12 +241,13 @@ public class EleMaterialsController extends BaseController { public R updaDateGongshi(@RequestParam("file") MultipartFile file) throws Exception { String originalFilename = file.getOriginalFilename(); log.info("读取文件名: " + originalFilename); - ExcelResult result = ExcelUtil.importExcelSheet1(file.getInputStream(), EleMaterialsVo.class, true); + ExcelResult result = ExcelUtil.importExcelSheet1(file.getInputStream(), EleMaterialsVo.class, + true); List list = result.getList(); - + // 创建固定大小的线程池 ExecutorService executor = Executors.newFixedThreadPool(10); // 可以根据需要调整线程数 - + for (EleMaterialsVo processRouteVo : list) { executor.submit(() -> { List entryID = JdUtil.getEntryID(processRouteVo.getMaterialCode()); @@ -255,20 +259,21 @@ public class EleMaterialsController extends BaseController { log.info("物料编码: " + processRouteVo.getMaterialValue()); log.info("工时: " + processRouteVo.getMaterialCode()); try { - JdUtil.atestSaveMaterial(FMATERIALID, fEntryId, processRouteVo.getMaterialCode(), Double.parseDouble(processRouteVo.getMaterialValue())); + JdUtil.atestSaveMaterial(FMATERIALID, fEntryId, processRouteVo.getMaterialCode(), + Double.parseDouble(processRouteVo.getMaterialValue())); } catch (Exception e) { throw new RuntimeException(e); } } }); } - + // 关闭线程池 executor.shutdown(); while (!executor.isTerminated()) { // 等待所有任务完成 } - + return R.ok("更新成功"); } @@ -285,20 +290,20 @@ public class EleMaterialsController extends BaseController { ExecutorService executor = Executors.newFixedThreadPool(10); // 可以根据需要调整线程数 for (JdVMIVo vmi : list) { - executor.submit(() -> { + executor.submit(() -> { List entryID = JdUtil.getFID(vmi.getMaterialCode()); for (JdHuoZhu jdEntryVmi : entryID) { int fmaterialid = jdEntryVmi.getFID(); int fEntryId1 = jdEntryVmi.getFTreeEntityFENTRYID(); - log.info("物料"+vmi.getMaterialCode()+"的FId: " + fmaterialid); - log.info("物料"+vmi.getMaterialCode()+"fEntryId: " + fEntryId1); + log.info("物料" + vmi.getMaterialCode() + "的FId: " + fmaterialid); + log.info("物料" + vmi.getMaterialCode() + "fEntryId: " + fEntryId1); try { - JdUtil.updateHuozhu(fmaterialid, fEntryId1,vmi.getMaterialCode()); + JdUtil.updateHuozhu(fmaterialid, fEntryId1, vmi.getMaterialCode()); } catch (Exception e) { throw new RuntimeException(e); } } - }); + }); } // 关闭线程池 executor.shutdown(); @@ -308,6 +313,7 @@ public class EleMaterialsController extends BaseController { return R.ok("更新成功"); } + @Log(title = "更新VMI仓位", businessType = BusinessType.IMPORT) @SaCheckPermission("system:route:updaDateCangwei") @PostMapping(value = "/updaDateCangwei", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @@ -318,10 +324,10 @@ public class EleMaterialsController extends BaseController { List list = result.getList(); // 创建固定大小的线程池 - ExecutorService executor = Executors.newFixedThreadPool(10); // 可以根据需要调整线程数 + ExecutorService executor = Executors.newFixedThreadPool(10); list.forEach(vmi -> executor.submit(() -> { - log.info("===============>开始查询物料编码: " + vmi.getMaterialCode()+"的entryID"); + log.info("===============>开始查询物料编码: " + vmi.getMaterialCode() + "的entryID"); List entryID = JdUtil.getEntryID2(vmi.getMaterialCode()); entryID.forEach(jdEntryVmi -> { int fmaterialid = jdEntryVmi.getFMATERIALID(); @@ -356,14 +362,15 @@ public class EleMaterialsController extends BaseController { public R updaDateKuCun(@RequestParam("file") MultipartFile file) throws Exception { String originalFilename = file.getOriginalFilename(); log.info("读取文件名: " + originalFilename); - ExcelResult result = ExcelUtil.importExcelSheet1(file.getInputStream(), JDSafeStockDTO.class, true); + ExcelResult result = ExcelUtil.importExcelSheet1(file.getInputStream(), JDSafeStockDTO.class, + true); List list = result.getList(); // 创建固定大小的线程池 ExecutorService executor = Executors.newFixedThreadPool(10); // 可以根据需要调整线程数 list.forEach(vmi -> executor.submit(() -> { - log.info("===============>开始查询物料编码: " + vmi.getMaterialCode()+"的entryID"); + log.info("===============>开始查询物料编码: " + vmi.getMaterialCode() + "的entryID"); List entryID = JdUtil.getSubHeadEntity1Id(vmi.getMaterialCode()); entryID.forEach(jdEntryVmi -> { int fmaterialid = jdEntryVmi.getFMATERIALID(); @@ -372,7 +379,93 @@ public class EleMaterialsController extends BaseController { int FSafeStock = vmi.getFSafeStock(); try { log.info("=====================>开始更新 " + vmi.getMaterialCode() + " 的安全库存"); - JdUtil.updateKunCun(fmaterialid, fEntryId1, fMaxStock, FSafeStock); + JdUtil.updateKunCun(fmaterialid, fEntryId1, fMaxStock, FSafeStock); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + })); + + // 关闭线程池并等待所有任务完成 + executor.shutdown(); + try { + if (!executor.awaitTermination(60, TimeUnit.MINUTES)) { + executor.shutdownNow(); // 超时后强制关闭 + } + } catch (InterruptedException e) { + executor.shutdownNow(); + Thread.currentThread().interrupt(); // 保留中断状态 + } + + return R.ok("更新成功"); + } + + @Log(title = "更新安全库存", businessType = BusinessType.IMPORT) + @SaCheckPermission("system:route:updateFOldNumber") + @PostMapping(value = "/updateFOldNumber", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + public R updateFOldNumber(@RequestParam("file") MultipartFile file) throws Exception { + String originalFilename = file.getOriginalFilename(); + log.info("读取文件名: {}", originalFilename); + ExcelResult result = ExcelUtil.importExcelSheet1(file.getInputStream(), JDMaterialOldNumber.class, true); + List list = result.getList(); + // 创建固定大小的线程池 + ExecutorService executor = Executors.newFixedThreadPool(10); // 可以根据需要调整线程数 + try { + List> futures = new ArrayList<>(); + + for (JDMaterialOldNumber vmi : list) { + futures.add(executor.submit(() -> { + JdUtil.updateOldFuNumber(vmi.getFMATERIALID(), vmi.getFNumber(), vmi.getFOldNumber()); + return null; // 返回值可以是 Void + })); + } + // 等待所有任务完成并处理异常 + for (Future future : futures) { + try { + future.get(); // 获取结果,如果有异常会抛出 + } catch (ExecutionException e) { + log.error("更新物料时发生异常: {}", e.getCause().getMessage()); + } + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); // 保留中断状态 + log.error("线程被中断: {}", e.getMessage()); + } finally { + executor.shutdown(); // 确保线程池关闭 + try { + if (!executor.awaitTermination(60, TimeUnit.SECONDS)) { + executor.shutdownNow(); // 超时后强制关闭 + } + } catch (InterruptedException e) { + executor.shutdownNow(); + Thread.currentThread().interrupt(); // 保留中断状态 + } + } + + return R.ok("更新成功"); + } + + + @Log(title = "更新物料单重", businessType = BusinessType.IMPORT) + @SaCheckPermission("system:route:updateDanzhong") + @PostMapping(value = "/updateDanzhong", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + public R updateDanzhong(@RequestParam("file") MultipartFile file) throws Exception { + String originalFilename = file.getOriginalFilename(); + log.info("读取文件名: " + originalFilename); + ExcelResult result = ExcelUtil.importExcelSheet1(file.getInputStream(), JdDanZhong.class, true); + List list = result.getList(); + + // 创建固定大小的线程池 + ExecutorService executor = Executors.newFixedThreadPool(10); + + list.forEach(vmi -> executor.submit(() -> { + List entryID = JdUtil.getEntryID2(vmi.getMaterialCode()); + entryID.forEach(jdEntryVmi -> { + int fmaterialid = jdEntryVmi.getFMATERIALID(); + + try { + log.info("=====================>开始更新 " + vmi.getMaterialCode() + " 的单重"); + JdUtil.updateDanzhong(fmaterialid,vmi.getDanzhong() ); } catch (Exception e) { throw new RuntimeException(e); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/ImMaterialController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/ImMaterialController.java index 5374759..dcdfd7d 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/ImMaterialController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/ImMaterialController.java @@ -188,20 +188,7 @@ public class ImMaterialController extends BaseController { e.printStackTrace(); } } - // 更新数据库中物料单重的示例方法 -/* private void updateMaterialWeight(String materialCode, Double weight) { - ImMaterial materialByCode = iImMaterialService.getMaterialByCode(materialCode); - if (materialByCode != null) { - materialByCode.setSingleWeight(BigDecimal.valueOf(weight)); - imMaterialMapper.updateById(materialByCode); - } else { - // 处理物料编码不存在的情况 - } - } catch (Exception e) { - // 处理数据库操作的异常 - e.printStackTrace(); - } - }*/ + /** * 导入数据 * diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/IndexController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/IndexController.java index 821bde4..172e48f 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/IndexController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/IndexController.java @@ -8,22 +8,31 @@ import com.ruoyi.common.core.domain.PageQuery; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.utils.JdUtils; +import com.ruoyi.system.domain.ImMaterial; import com.ruoyi.system.domain.bo.ImMaterialBo; import com.ruoyi.system.domain.bo.ImProductionPlanBo; +import com.ruoyi.system.domain.dto.JDInventoryDTO; +import com.ruoyi.system.domain.dto.JDProductionDTO; +import com.ruoyi.system.domain.dto.ProMoDTO; +import com.ruoyi.system.domain.dto.PurchaseOrderDTO; import com.ruoyi.system.domain.vo.ImMaterialVo; import com.ruoyi.system.domain.vo.InventoryInfoVO; +import com.ruoyi.system.runner.JdUtil; import com.ruoyi.system.service.IImMaterialService; import com.ruoyi.system.service.IImProductionPlanService; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Map; +import java.util.Optional; @RequiredArgsConstructor @RestController @RequestMapping("/index") +@Slf4j public class IndexController { private final IImMaterialService iImMaterialService; private final IImProductionPlanService imProductionPlanService; @@ -39,19 +48,47 @@ public class IndexController { @GetMapping("/inventory") public R handleData(String materialCode) { - Map marilMap = JdUtils.selectKuCun(materialCode); - if (marilMap.isEmpty() ) { - // 处理查询失败的情况 - return R.fail("库存信息未找到"); - } + double inventoryQty = Optional.ofNullable(JdUtil.getKuCun(materialCode)) + .map(list ->list.stream() + .mapToDouble(JDInventoryDTO::getFBaseQty) + .sum()) + .orElse(0.0); + log.info("查询子项物料的未领料量=============>"+System.currentTimeMillis()); + // 查询子项物料的未领料量 + + double fNoPickedQty = Optional.ofNullable(JdUtil.getWeiLingliao(materialCode)) + .map(list ->list.stream() + .mapToDouble(JDProductionDTO::getFNoPickedQty) + .sum()) + .orElse(0.0); + + System.out.println("获取生产订单未入库数量数量=============>"+System.currentTimeMillis()); + // 获取生产订单未入库数量数量 + double productionQty = Optional.ofNullable(JdUtil.getProMoList(materialCode)) + .map(list -> list.stream() + .mapToDouble(ProMoDTO::getFQty) + .sum()) + .orElse(0.0); + System.out.println("获取采购订单未入库数量=============>"+System.currentTimeMillis()); + // 获取采购订单未入库数量 + double purchaseQty = Optional.ofNullable(JdUtil.getPurchaseOrderList(materialCode)) + .map(list -> list.stream() + .mapToDouble(PurchaseOrderDTO::getFRemainStockINQty) + .sum()) + .orElse(0.0); + // 计算预计可用库存 + System.out.println("计算预计可用库存=============>"+System.currentTimeMillis()); + Double keyong = inventoryQty + productionQty + purchaseQty - fNoPickedQty; InventoryInfoVO inventoryInfoVO = new InventoryInfoVO(); - inventoryInfoVO.setMaterialCode(marilMap.get("materialCode")); - inventoryInfoVO.setQuantity(marilMap.get("inventory")); - inventoryInfoVO.setMaterialName(marilMap.get("materialName")); - inventoryInfoVO.setStockName(marilMap.get("stockName")); - inventoryInfoVO.setStockUnit(marilMap.get("stockUnit")); + inventoryInfoVO.setMaterialCode(materialCode); + inventoryInfoVO.setKucun(String.valueOf(inventoryQty)); + inventoryInfoVO.setQuantity(String.valueOf(fNoPickedQty)); + inventoryInfoVO.setMaterialName(String.valueOf(purchaseQty)); + inventoryInfoVO.setStockName(String.valueOf(productionQty)); + inventoryInfoVO.setStockUnit(String.valueOf(keyong)); return R.ok(inventoryInfoVO); } + @Log(title = "生产计划") @PostMapping("/JDList") public void synchronize_lists() { diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/KingdeeWorkCenterDataController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/KingdeeWorkCenterDataController.java index 8289332..279a3b3 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/KingdeeWorkCenterDataController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/KingdeeWorkCenterDataController.java @@ -1,14 +1,12 @@ package com.ruoyi.system.controller; import java.io.File; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Arrays; +import java.util.*; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.date.DateUtil; +import cn.hutool.json.JSONUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.converters.Converter; @@ -28,16 +26,23 @@ import com.ruoyi.common.utils.HttpRequestUtil; import com.ruoyi.common.utils.WxRobotUtil; import com.ruoyi.system.domain.SafetyStock; import com.ruoyi.system.domain.WlStockData; +import com.ruoyi.system.domain.dto.JDInventoryDTO; +import com.ruoyi.system.domain.dto.JDProductionDTO; +import com.ruoyi.system.domain.dto.ProMoDTO; +import com.ruoyi.system.domain.dto.PurchaseOrderDTO; import com.ruoyi.system.domain.vo.SafetyStockVo; import com.ruoyi.system.domain.vo.WlStockDataVo; import com.ruoyi.system.mapper.SafetyStockMapper; import com.ruoyi.system.mapper.WlStockDataMapper; +import com.ruoyi.system.runner.JdUtil; +import com.ruoyi.system.service.ISafetyStockService; import com.xxl.job.core.handler.annotation.XxlJob; import lombok.RequiredArgsConstructor; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import javax.validation.constraints.*; + import cn.dev33.satoken.annotation.SaCheckPermission; import cn.hutool.core.collection.CollUtil; @@ -77,7 +82,9 @@ public class KingdeeWorkCenterDataController extends BaseController { private final IKingdeeWorkCenterDataService iKingdeeWorkCenterDataService; private final HttpRequestUtil httpRequestUtil; private static final Logger log = LoggerFactory.getLogger(KingdeeWorkCenterDataController.class); - private final WlStockDataMapper baseMapper;; + private final WlStockDataMapper baseMapper; + private final ISafetyStockService iSafetyStockService; + /** * 查询金蝶工段数据列表 */ @@ -149,18 +156,18 @@ public class KingdeeWorkCenterDataController extends BaseController { @SaCheckPermission("system:workCenterData:remove") @Log(title = "金蝶工段数据提前2天", businessType = BusinessType.DELETE) @PostMapping("/getKingdeeWorkCenterData") - public R> getKingdeeWorkCenterData(@RequestParam(value="workCenter") String workCenter) { + public R> getKingdeeWorkCenterData(@RequestParam(value = "workCenter") String workCenter) { try { K3CloudApi client = new K3CloudApi(); JsonObject parameter = new JsonObject(); List kingdeeWorkCenterDataVos = new ArrayList<>(); parameter.addProperty("FWorkCenterName", workCenter); - Object[] parameters = new Object[] { parameter.toString() }; + Object[] parameters = new Object[]{parameter.toString()}; String execute = client.execute( "Ljint.Kingdee.YiTe.KanBan.WebApi.ProduceWebApi.ExecuteService,Ljint.Kingdee.YiTe.KanBan.WebApi", parameters); log.info("金蝶接口返回数据: {}", execute); - + // 解析响应 JSONObject response = JSONObject.parseObject(execute); if (!"true".equals(response.getString("IsSuccess"))) { @@ -170,7 +177,7 @@ public class KingdeeWorkCenterDataController extends BaseController { // 获取明天的日期字符串 (格式: yyyy-MM-dd) String tomorrow = DateUtil.format(DateUtil.tomorrow().toLocalDateTime().plusDays(1), "yyyy-MM-dd"); - + // 获取数据数组 JSONArray dataArray = response.getJSONArray("data"); if (dataArray == null || dataArray.isEmpty()) { @@ -181,7 +188,7 @@ public class KingdeeWorkCenterDataController extends BaseController { JSONArray queryList = dataArray.getJSONObject(i).getJSONArray("QueryList"); for (int j = 0; j < queryList.size(); j++) { JSONObject item = queryList.getJSONObject(j); - + // 获取计划结束时间并转换为日期格式进行比较 String planFinishTime = item.getString("FOperPlanFinishTime2"); if (StringUtils.hasText(planFinishTime)) { @@ -206,7 +213,7 @@ public class KingdeeWorkCenterDataController extends BaseController { data.setOperPlanFinishTime(planFinishTime); data.setDelayDays(item.getString("FDelayDays")); kingdeeWorkCenterDataVos.add(data); - + Boolean b = iKingdeeWorkCenterDataService.insertByBo(data); if (!b) { return R.fail("保存工段数据失败"); @@ -215,12 +222,12 @@ public class KingdeeWorkCenterDataController extends BaseController { } } } - + if (kingdeeWorkCenterDataVos.isEmpty()) { return R.ok("明天没有计划结束的工单"); } return R.ok(kingdeeWorkCenterDataVos); - + } catch (Exception e) { log.error("获取金蝶工段数据失败", e); return R.fail("获取金蝶工段数据失败:" + e.getMessage()); @@ -291,7 +298,7 @@ public class KingdeeWorkCenterDataController extends BaseController { K3CloudApi client = new K3CloudApi(); JsonObject parameter = new JsonObject(); parameter.addProperty("FWorkCenterName", "委外中心"); - Object[] parameters = new Object[] { parameter.toString() }; + Object[] parameters = new Object[]{parameter.toString()}; String execute = client.execute( "Ljint.Kingdee.YiTe.KanBan.WebApi.ProduceWebApi.ExecuteService,Ljint.Kingdee.YiTe.KanBan.WebApi", parameters); @@ -323,9 +330,9 @@ public class KingdeeWorkCenterDataController extends BaseController { // 添加每个工单的详细信息 markdownMsg.append(String.format("#### %d. %s (延期%s天)\n", - index++, - item.getString("FMaterialName"), - item.getString("FDelayDays"))) + index++, + item.getString("FMaterialName"), + item.getString("FDelayDays"))) .append(String.format("> 工单号:%s\n", item.getString("MoBillNo"))) .append(String.format("> 订单号:%s\n", @@ -373,8 +380,8 @@ public class KingdeeWorkCenterDataController extends BaseController { String currentTime = DateUtil.format(new Date(), "yyyy年MM月dd日 HH:mm:ss"); StringBuilder msg = new StringBuilder(); msg.append("🏭 生产数据更新提醒(提前两天)\n\n") - .append("更新时间:").append(currentTime).append("\n\n") - .append("🔧 工作中心数据统计:\n"); + .append("更新时间:").append(currentTime).append("\n\n") + .append("🔧 工作中心数据统计:\n"); // 获取并统计每个工段的数据 for (String workCenter : workCenters) { @@ -390,7 +397,7 @@ public class KingdeeWorkCenterDataController extends BaseController { // 生成Excel文件 String fileName = String.format("%s生产预警数据_%s.xlsx", workCenter, - DateUtil.format(new Date(), "yyyyMMddHHmmss")); + DateUtil.format(new Date(), "yyyyMMddHHmmss")); String filePath = FileUtils.getTempDirectoryPath() + File.separator + fileName; // 使用EasyExcel写入数据 @@ -429,13 +436,13 @@ public class KingdeeWorkCenterDataController extends BaseController { @SaCheckPermission("system:workCenterData:remove") @Log(title = "金蝶工段数据延期数据", businessType = BusinessType.DELETE) @PostMapping("/getKingdeeDelayData") - public R> getKingdeeDelayData(@RequestParam(value="workCenter") String workCenter) { + public R> getKingdeeDelayData(@RequestParam(value = "workCenter") String workCenter) { try { K3CloudApi client = new K3CloudApi(); JsonObject parameter = new JsonObject(); List kingdeeWorkCenterDataVos = new ArrayList<>(); parameter.addProperty("FWorkCenterName", workCenter); - Object[] parameters = new Object[] { parameter.toString() }; + Object[] parameters = new Object[]{parameter.toString()}; String execute = client.execute( "Ljint.Kingdee.YiTe.KanBan.WebApi.ProduceWebApi.ExecuteService,Ljint.Kingdee.YiTe.KanBan.WebApi", parameters); @@ -518,7 +525,7 @@ public class KingdeeWorkCenterDataController extends BaseController { @XxlJob("getMassageDelayDate") public R getMassageDelayDate() { try { - // String robotId = "4d2f037d-0cee-493a-a4ff-1758f67b8069"; + // String robotId = "4d2f037d-0cee-493a-a4ff-1758f67b8069"; String robotId = "483489b2-b219-468c-851f-f56a34a62d91"; List workCenters = Arrays.asList("机一工段", "机二工段", "机三工段", "装一工段", "装二工段", "委外中心", "电钳工段", "铆焊工段"); @@ -573,32 +580,37 @@ public class KingdeeWorkCenterDataController extends BaseController { return R.fail("发送工段数据失败:" + e.getMessage()); } } - @SaCheckPermission("system:workCenterData:getKuCun") - @Log(title = "金蝶工段数据延期数据", businessType = BusinessType.DELETE) - @PostMapping("/getKuCun") + + + @Log(title = "金蝶安全库存数据", businessType = BusinessType.OTHER) + @XxlJob("getKuCun") public R getKuCun() { + String robotId = "0d2390e0-3e74-49fc-bd02-900b86bf0f55"; + StringBuilder markdownMsg = new StringBuilder(); + // 获取今天的日期 + Date today = new Date(); + Date sixAM = DateUtil.parse(DateUtil.format(today, "yyyy-MM-dd") + " 06:00:00"); - String robotId = "0d2390e0-3e74-49fc-bd02-900b86bf0f55"; - StringBuilder markdownMsg = new StringBuilder(); + // 创建查询条件 + LambdaQueryWrapper safetyStockLambdaQueryWrapper = new LambdaQueryWrapper<>(); + // 获取时间在今天6点以后的数据 + safetyStockLambdaQueryWrapper.ge(WlStockData::getCreateTime, sixAM); - // 获取今天的日期 - Date today = new Date(); - Date sixAM = DateUtil.parse(DateUtil.format(today, "yyyy-MM-dd") + " 06:00:00"); + List safetyStocks = baseMapper.selectList(safetyStockLambdaQueryWrapper); + log.info("查询安全库存结果===========>:{}", safetyStocks); + // 处理物料分组 + safetyStocks = processMaterialGroups(safetyStocks); + //对数据进行排序 + safetyStocks.sort(Comparator.comparing(WlStockData::getMaterialCode)); - // 创建查询条件 - LambdaQueryWrapper safetyStockLambdaQueryWrapper = new LambdaQueryWrapper<>(); - // 获取时间在今天6点以后的数据 - safetyStockLambdaQueryWrapper.ge(WlStockData::getCreateTime, sixAM); - List safetyStocks = baseMapper.selectList(safetyStockLambdaQueryWrapper); - try { + try { if (CollUtil.isEmpty(safetyStocks)) { markdownMsg.append("## 🚀 安全库存提醒\n\n") .append("今日暂无安全库存预警数据。"); } else { markdownMsg.append("## 🚀 安全库存提醒\n\n") .append("以下是今日的安全库存预警数据:\n\n"); - // 只显示前三个安全库存数据 int count = Math.min(3, safetyStocks.size()); for (int i = 0; i < count; i++) { @@ -606,20 +618,19 @@ public class KingdeeWorkCenterDataController extends BaseController { markdownMsg.append("### 物料信息\n") .append("#### 物料编号: **").append(safetyStock.getMaterialCode()).append("**\n") .append("> **物料名称:** ").append(safetyStock.getMaterialName()).append("\n") - .append("> **可用库存:** ").append(String.format("%.2f", safetyStock.getAvailableStock())).append("\n") - .append("> **当前库存:** ").append(String.format("%.2f", safetyStock.getCurrentStock())).append("\n") + .append("> **预计可用量:** ").append(String.format("%.2f", safetyStock.getCurrentStock())).append("\n") + .append("> **即时库存:** ").append(String.format("%.2f", safetyStock.getSecAvbqty())).append("\n") .append("> **最大库存:** ").append(String.format("%.2f", safetyStock.getMaxsafetyStock())).append("\n") .append("> **创建时间:** ").append(DateUtil.formatDateTime(safetyStock.getCreateTime())).append("\n") .append("---\n"); // 添加分隔线 } - // 添加总数汇总 markdownMsg.append("### 总数汇总\n") .append("> 今日安全库存预警数据总数: **").append(safetyStocks.size()).append("**\n"); } // 生成Excel文件 - String fileName = String.format("%s安全预警数据_%s.xlsx","企标", DateUtil.format(new Date(), "yyyyMMddHHmmss")); + String fileName = String.format("%s安全预警数据_%s.xlsx", "企标", DateUtil.format(new Date(), "yyyyMMddHHmmss")); String filePath = FileUtils.getTempDirectoryPath() + File.separator + fileName; // 使用EasyExcel写入数据 @@ -633,20 +644,192 @@ public class KingdeeWorkCenterDataController extends BaseController { // 删除临时文件 FileUtils.deleteQuietly(excelFile); - markdownMsg.append("\n详细数据请查看发送的Excel文件!"); - String messageContent = markdownMsg.toString(); - int maxLength = 1000; - for (int i = 0; i < messageContent.length(); i += maxLength) { - String part = messageContent.substring(i, Math.min(i + maxLength, messageContent.length())); - wxRobotUtil.sendMarkdownMsgToWeChatGroup(part, robotId); - } - return R.ok(); + markdownMsg.append("\n详细数据请查看发送的Excel文件!"); + String messageContent = markdownMsg.toString(); + int maxLength = 1000; + for (int i = 0; i < messageContent.length(); i += maxLength) { + String part = messageContent.substring(i, Math.min(i + maxLength, messageContent.length())); + wxRobotUtil.sendMarkdownMsgToWeChatGroup(part, robotId); + } + return R.ok(); } catch (Exception e) { - markdownMsg.append("- ").append("安全库存").append(" (获取失败: ").append(e.getMessage()).append(")\n"); - return R.fail("发送安全库存数据失败:" + e.getMessage()); + markdownMsg.append("- ").append("安全库存").append(" (获取失败: ").append(e.getMessage()).append(")\n"); + return R.fail("发送安全库存数据失败:" + e.getMessage()); } - } + private List processMaterialGroups(List originalStocks) { + if (CollUtil.isEmpty(originalStocks)) { + return new ArrayList<>(); + } + // 创建新的结果列表 + List allStocks = new ArrayList<>(originalStocks); + + // 定义四种类型 + Map> typeGroups = new HashMap<>(); + typeGroups.put("行程检测白模具三", Arrays.asList("ELS-MJ.00.3-WH", "ELS-MJ.00.4-WH")); + typeGroups.put("行程检测灰模具三", Arrays.asList("ELS-MJ.00.3-GY", "ELS-MJ.00.4-GY")); + typeGroups.put("行程检测模具四", Arrays.asList("ELS-MJ.00.5", "ELS-MJ.00.6", "ELS-MJ.00.7", "ELS-MJ.00.8")); + typeGroups.put("行程检测模具五", Arrays.asList("ELS-MJ.00.9", "ELS-MJ.00.10", "ELS-MJ.00.11", "ELS-MJ.00.12", "ELS-MJ.00.13", "ELS-MJ.00.14")); + + // 遍历原始数据,检查每个物料所属的组 + Map> groupMaterials = new HashMap<>(); + for (WlStockData stock : originalStocks) { + String materialCode = stock.getMaterialCode(); + // 检查该物料属于哪个组 + for (Map.Entry> entry : typeGroups.entrySet()) { + String groupType = entry.getKey(); + List groupCodes = entry.getValue(); + + if (groupCodes.contains(materialCode)) { + // 将物料添加到对应组的Map中 + groupMaterials.computeIfAbsent(groupType, k -> new HashMap<>()) + .put(materialCode, stock); + break; + } + } + } + + // 处理每个有物料的组 + for (Map.Entry> entry : groupMaterials.entrySet()) { + String groupType = entry.getKey(); + Map existingMaterials = entry.getValue(); + List groupAllMaterials = typeGroups.get(groupType); + + if (!existingMaterials.isEmpty()) { + log.info("处理{}组, 已存在的物料: {}", groupType, existingMaterials.keySet()); + + // 获取该组的安全库存配置 + List safetyStocks = iSafetyStockService.selectByType(groupType); + if (CollUtil.isEmpty(safetyStocks)) { + log.warn("{}组无安全库存配置数据", groupType); + continue; + } + + // 找出该组中缺失的物料 + for (String materialCode : groupAllMaterials) { + if (!existingMaterials.containsKey(materialCode)) { + log.info("{}组缺少物料: {}, 准备补充", groupType, materialCode); + + // 查找对应的安全库存配置 + SafetyStock matchingSafetyStock = safetyStocks.stream() + .filter(s -> s.getMaterialCode().equals(materialCode)) + .findFirst() + .orElse(null); + + if (matchingSafetyStock == null) { + log.warn("物料 {} 未找到对应的安全库存配置", materialCode); + continue; + } + + // 获取同组中任意一个已存在的物料作为模板 + WlStockData template = existingMaterials.values().iterator().next(); + + // 创建新的物料记录 + WlStockData newStock = new WlStockData(); + BeanUtil.copyProperties(template, newStock); + + // 设置新物料的特定属性 + newStock.setId(null); + newStock.setCreateTime(new Date()); + newStock.setMaterialCode(materialCode); + newStock.setMaterialName(matchingSafetyStock.getMaterialName()); + newStock.setWlMaterial(groupType); + newStock.setDocumentType(matchingSafetyStock.getWlMaterial()); + + // 复制模板物料的数量相关属性 + newStock.setRequiredStock(template.getRequiredStock()); + newStock.setCurrentStock(template.getCurrentStock()); + newStock.setAvailableStock(template.getAvailableStock()); + newStock.setProductionQty(template.getProductionQty()); + newStock.setPurchaseQty(template.getPurchaseQty()); + newStock.setMinsafetyStock(template.getMinsafetyStock()); + newStock.setMaxsafetyStock(template.getMaxsafetyStock()); + newStock.setSecAvbqty(template.getSecAvbqty()); + + try { + int result = baseMapper.insert(newStock); + if (result > 0) { + log.info("成功补充物料到数据库: 物料编码={}, 组={}, 使用模板物料={}", + materialCode, groupType, template.getMaterialCode()); + allStocks.add(newStock); + } else { + log.error("补充物料到数据库失败: 物料编码={}, 组={}", materialCode, groupType); + } + } catch (Exception e) { + log.error("补充物料到数据库失败: 物料编码={}, 组={}, 错误信息={}", + materialCode, groupType, e.getMessage(), e); + } + } + } + } else { + log.info("{}组无任何物料存在,跳过处理", groupType); + } + } + + log.info("物料处理完成,最终物料总数: {}", allStocks.size()); + return allStocks; + } + @Log(title = "金蝶安全库存数据", businessType = BusinessType.OTHER) + @XxlJob("getKuCunTo40SB") + public R getKuCunTo40SB() { + String robotId = "0d2390e0-3e74-49fc-bd02-900b86bf0f55"; + + // 获取今天的日期 + Date today = new Date(); + Date sixAM = DateUtil.parse(DateUtil.format(today, "yyyy-MM-dd") + " 06:00:00"); + //指定此物料:40SB/L + String materialCode = "40SB/L"; + // 获取即时库存 + double inventoryQty = Optional.ofNullable(JdUtil.getKuCun(materialCode)) + .map(list ->list.stream() + .mapToDouble(JDInventoryDTO::getFBaseQty) + .sum()) + .orElse(0.0); + // 查询子项物料的未领料量 + double fNoPickedQty = Optional.ofNullable(JdUtil.getWeiLingliao(materialCode)) + .map(list ->list.stream() + .mapToDouble(JDProductionDTO::getFNoPickedQty) + .sum()) + .orElse(0.0); + + // 获取生产订单未入库数量 + double productionQty = Optional.ofNullable(JdUtil.getProMoList(materialCode)) + .map(list -> list.stream() + .mapToDouble(ProMoDTO::getFQty) + .sum()) + .orElse(0.0); + + // 获取采购订单未入库数量 + double purchaseQty = Optional.ofNullable(JdUtil.getPurchaseOrderList(materialCode)) + .map(list -> list.stream() + .mapToDouble(PurchaseOrderDTO::getFRemainStockINQty) + .sum()) + .orElse(0.0); + // 计算预计可用库存 + double availableStock = inventoryQty + productionQty + purchaseQty - fNoPickedQty; + //生产订单未入库数量 + //采购订单未入库数量 + //子项物料的未领料量 + //即时库存 + //监控数量 + // 构建Markdown消息 + StringBuilder markdownMsg = new StringBuilder(); + markdownMsg.append("# 实时库存告警通知\n\n") + .append("> **物料编码:** ").append(materialCode).append("\n") + .append("> **生产订单未入库:** ").append(String.format("%.2f", productionQty)).append("\n") + .append("> **采购订单未入库:** ").append(String.format("%.2f", purchaseQty)).append("\n") + .append("> **子项未领料数量:** ").append(String.format("%.2f", fNoPickedQty)).append("\n") + .append("> **当 前 库 存:** ").append(String.format("%.2f", inventoryQty)).append("\n") + .append("> **预计可用库存:** ").append(String.format("%.2f", availableStock)).append("\n\n") + .append("> **创建时间:** ").append(DateUtil.formatDateTime(new Date())).append("\n"); + + + + String part = markdownMsg.toString(); + wxRobotUtil.sendMarkdownMsgToWeChatGroup(part, robotId); + + return R.ok(); + } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/ProcessOrderProController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/ProcessOrderProController.java index 4cf7cca..6e6e5ae 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/ProcessOrderProController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/ProcessOrderProController.java @@ -4,10 +4,11 @@ import java.io.*; import java.util.List; import java.util.Arrays; +import com.alibaba.excel.EasyExcel; +import com.ruoyi.common.excel.DefaultExcelListener; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.file.SmbUtil; import com.ruoyi.system.domain.ProcessRoute; -import com.ruoyi.system.domain.ProductionOrder; -import com.ruoyi.system.domain.bo.ProcessRouteBo; -import com.ruoyi.system.domain.dto.CombinedDTO; import com.ruoyi.system.service.impl.ProductionOrderServiceImpl; import lombok.RequiredArgsConstructor; import javax.servlet.http.HttpServletResponse; @@ -117,5 +118,41 @@ public class ProcessOrderProController extends BaseController { return iProcessOrderProService.deleteWithValidByIds(Arrays.asList(ids), true); } + @SaCheckPermission("system:orderPro:getExcel") + @Log(title = "获取项目生产数据表", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping("/getExcel") + public R getExcel(@Validated(AddGroup.class) @RequestBody ProcessOrderProBo bo) { + // 获取项目生产数据表 获取项目令号 也是文件夹的名称 + SmbUtil.downloadExcelFiles(bo.getProductionOrderNo()); + // 在本地读取EXCEL 文件 + String ExcelName = "D:\\file\\" + bo.getProductionOrderNo() + ".xlsx"; + try { + File file = new File(ExcelName); + if (file.exists()) { + // 读取Excel的sheet6 从第三行开始 读取到第4列 无数据的跳过 + DefaultExcelListener listener = new DefaultExcelListener<>(true); + EasyExcel.read(ExcelName, ProcessRoute.class,listener).sheet(6).headRowNumber(3).doRead(); + List list = listener.getExcelResult().getList(); + for (ProcessRoute processRoute : list) { + System.out.println(processRoute.getMaterialCode()); + System.out.println(processRoute.getMaterialName()); + System.out.println(processRoute.getMaterial()); + System.out.println(processRoute.getDiscWeight()); + System.out.println("==================================================================="); + } + }else{ + throw new ServiceException("没有数据"); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + + //读取excel文件sheet + + + + return toAjax(iProcessOrderProService.insertByBo(bo)); + } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/ProcessRouteController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/ProcessRouteController.java index 761463a..bea331d 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/ProcessRouteController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/ProcessRouteController.java @@ -1,6 +1,10 @@ package com.ruoyi.system.controller; import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.json.JSONUtil; +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.support.ExcelTypeEnum; +import com.alibaba.excel.write.metadata.WriteSheet; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.RepeatSubmit; import com.ruoyi.common.core.controller.BaseController; @@ -10,28 +14,26 @@ import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.validate.AddGroup; import com.ruoyi.common.core.validate.EditGroup; import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.excel.DefaultExcelListener; import com.ruoyi.common.excel.ExcelResult; -import com.ruoyi.common.utils.HttpRequestUtil; -import com.ruoyi.common.utils.WxRobotUtil; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.file.SmbUtil; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.system.domain.*; import com.ruoyi.system.domain.bo.ProcessRouteBo; import com.ruoyi.system.domain.dto.*; -import com.ruoyi.system.domain.vo.PlannedProcessVo; +import com.ruoyi.system.domain.vo.*; import com.ruoyi.system.jdmain.rouplan.Model; -import com.ruoyi.system.domain.vo.ProcessRouteVo; -import com.ruoyi.system.domain.vo.ProductionOrderVo; import com.ruoyi.system.mapper.BomDetailsMapper; import com.ruoyi.system.mapper.ImMaterialMapper; import com.ruoyi.system.mapper.MaterialBomMapper; import com.ruoyi.system.mapper.ProcessRouteMapper; +import com.ruoyi.system.runner.JdUtil; import com.ruoyi.system.service.IProcessRouteService; import lombok.RequiredArgsConstructor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.io.ByteArrayResource; -import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -45,8 +47,11 @@ import javax.servlet.http.HttpServletResponse; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.io.*; -import java.nio.file.Files; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.net.URLEncoder; import java.util.*; +import java.util.stream.Collectors; /** * 工艺路线 @@ -217,20 +222,125 @@ public class ProcessRouteController extends BaseController { child.setXuEndTime(processRouteVo.getXuEndTime()); return child; } - /** * 导出工艺路线列表 */ @SaCheckPermission("system:route:export") @Log(title = "工艺路线", businessType = BusinessType.EXPORT) + @PostMapping("/export2") + public void export2(ProcessRouteBo bo, HttpServletResponse response) { + log.info("获取项目生产数据表:{}", bo); + List list = iProcessRouteService.queryList(bo); + List bomlist = JdUtil.getPRD_PPBOM(bo.getRouteDescription()); + + + + //过滤bomlist 只要009开头的标准件 + bomlist = bomlist.stream() + .filter(bom -> bom.getMaterialCode().startsWith("009")) + .collect(Collectors.toList()); + + if (list.isEmpty() && bomlist.isEmpty()) { + throw new ServiceException("没有数据"); + } + + try { + // 设置响应头 + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + String fileName = URLEncoder.encode("工艺路线", "UTF-8").replaceAll("\\+", "%20"); + response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); + + ServletOutputStream os = response.getOutputStream(); + + // 创建ExcelWriter + try (com.alibaba.excel.ExcelWriter excelWriter = EasyExcel.write(os) + .autoCloseStream(false) // 防止自动关闭流 + .build()) { + + // 写入工艺路线sheet + if (!list.isEmpty()) { + WriteSheet writeSheet1 = EasyExcel.writerSheet(0, "工艺路线") + .head(ProcessRoute.class) + .build(); + excelWriter.write(list, writeSheet1); + } + + // 写入标准件清单sheet + if (!bomlist.isEmpty()) { + WriteSheet writeSheet2 = EasyExcel.writerSheet(1, "标准件清单") + .head(MaterialUsageDTO2.class) + .build(); + excelWriter.write(bomlist, writeSheet2); + } + } + } catch (Exception e) { + throw new RuntimeException("导出Excel异常: " + e.getMessage(), e); + } + } + @SaCheckPermission("system:route:export") + @Log(title = "工艺路线", businessType = BusinessType.EXPORT) @PostMapping("/export") public void export(ProcessRouteBo bo, HttpServletResponse response) { - List list = iProcessRouteService.queryList(bo); - List list2 = iProcessRouteService.queryList2(bo); + log.info("获取项目生产数据表:{}", bo); + // 下载Excel模板 + SmbUtil.downloadExcelFiles(bo.getRouteDescription()); + // 构建Excel文件路径 + String ExcelName = "D:\\file\\" + bo.getRouteDescription() + "汇总表.xlsx"; + File file = new File(ExcelName); + if (!file.exists()) { + throw new ServiceException("文件不存在,请确认路径是否正确"); + } + //读取file的所有的物料编码 + try { - ExcelUtil.exportExceluseRoute(list, "工艺路线", ProcessRouteVo.class, response); + if (file.exists()) { + // 读取Excel的sheet6 从第三行开始 读取到第4列 无数据的跳过 + DefaultExcelListener listener = new DefaultExcelListener<>(true); + EasyExcel.read(ExcelName, ProcessRoute.class,listener) + .sheet(6) + .headRowNumber(3) + .doRead(); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + // 查询要写入的数据是否 + List list = iProcessRouteService.queryList(bo); + + try { + // 设置响应头 + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + String fileName = URLEncoder.encode("工艺路线", "UTF-8").replaceAll("\\+", "%20"); + response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); + + ServletOutputStream os = response.getOutputStream(); + + // 使用 EasyExcel 写入已有Excel的第七个sheet(index=6) + try (com.alibaba.excel.ExcelWriter excelWriter = EasyExcel.write(os) + .withTemplate(file) // 指定模板文件 + .autoCloseStream(true) + .build()) { + + // 写入到第七个 sheet(index=6),并命名为“工艺路线” + WriteSheet writeSheet = EasyExcel.writerSheet( "已有工艺路线") + .head(ProcessRoute.class) + .needHead(true) + .build(); + excelWriter.write(list, writeSheet); + } + + os.flush(); + } catch (Exception e) { + log.error("导出Excel异常", e); + throw new RuntimeException("导出Excel异常: " + e.getMessage(), e); + } } + + + /** * 获取工艺路线详细信息 * @@ -253,7 +363,7 @@ public class ProcessRouteController extends BaseController { return toAjax(iProcessRouteService.insertByBo(bo)); } - /** + /**导出 * 修改工艺路线 */ @SaCheckPermission("system:route:edit") @@ -448,8 +558,7 @@ public class ProcessRouteController extends BaseController { @RequestParam(value = "materialName") String materialName, @RequestParam(value = "productionOrderNo") String productionOrderNo) { - return ResponseEntity - .ok(iProcessRouteService.getProcessRouteList(materialCode, materialName, productionOrderNo)); + return ResponseEntity.ok(iProcessRouteService.getProcessRouteList(materialCode, materialName, productionOrderNo)); } @Log(title = "导入时间", businessType = BusinessType.IMPORT) @@ -465,6 +574,25 @@ public class ProcessRouteController extends BaseController { return R.ok("更新成功"); } + + @Log(title = "导入时间", businessType = BusinessType.IMPORT) + @SaCheckPermission("system:route:importDataTime") + @PostMapping(value = "/importDataTime123", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + public R importDataTime123(@RequestParam("file") MultipartFile file) throws Exception { + + DefaultExcelListener listener = new DefaultExcelListener<>(true); + EasyExcel.read(file.getInputStream(), PcRigidChainVO.class,listener) .excelType(ExcelTypeEnum.XLS).sheet(1).headRowNumber(4).doRead(); + + List list1 = listener.getExcelResult().getList(); + for (PcRigidChainVO pcRigidChainVO : list1) { + log.info("数据 ===============>: " + JSONUtil.toJsonStr(pcRigidChainVO)); + } + + return R.ok("更新成功"); + } + + + @Log(title = "获取金蝶工艺路线") @SaCheckPermission("system:route:getSelectProcessRoute") @PostMapping("/getSelectProcessRout1e") @@ -472,8 +600,7 @@ public class ProcessRouteController extends BaseController { return iProcessRouteService.getSelectProcessRoute(materilCode); } - private void processCombinedDTO(CombinedDTO combinedDTO, List bomDetailsList, - List routeList, List materialBoms, String productionOrderNo) { + private void processCombinedDTO(CombinedDTO combinedDTO, List bomDetailsList, List routeList, List materialBoms, String productionOrderNo) { // 处理工序列表 combinedDTO.getProcesses().forEach(process -> { ProcessRoute processRoute = createProcessRoute(process, combinedDTO, productionOrderNo); @@ -491,6 +618,106 @@ public class ProcessRouteController extends BaseController { }); } + private void processMaterAndRoute(JDMaterialAndRoute materialAndRoute, List bomDetailsList, List routeList, List materialBoms, String productionOrderNo) { + // 处理工序列表 + materialAndRoute.getPlannedProcessVos().forEach(processRouteDTO -> { + ProcessRoute processRoute = createProcessRoute1(processRouteDTO, materialAndRoute, productionOrderNo); + routeList.add(processRoute); + }); + // 处理物料清单 + materialAndRoute.getMaterialUseDTOS().forEach(materialUsageDTO -> { + BomDetails bomDetails = createBomDetails1(materialUsageDTO, materialAndRoute, productionOrderNo); + bomDetailsList.add(bomDetails); + }); + // 处理材料BOM + materialAndRoute.getMaterialUseDTOS().forEach(materialUsageDTO -> { + MaterialBom materialBom = creatBomMaterial1(materialUsageDTO, materialAndRoute, productionOrderNo); + materialBoms.add(materialBom); + }); + + } + + private MaterialBom creatBomMaterial1(MaterialUseDTO materialUsageDTO, JDMaterialAndRoute materialAndRoute, String productionOrderNo) { + MaterialBom materialBom = new MaterialBom(); + materialBom.setProjectNumber(productionOrderNo); + materialBom.setParentMaterialCode(materialAndRoute.getMaterialCode()); + materialBom.setParentMaterialName(materialAndRoute.getMaterialName()); + materialBom.setMaterialCode(materialUsageDTO.getMaterialCode()); + materialBom.setMaterialName(materialUsageDTO.getMaterialName()); + materialBom.setUnit(materialUsageDTO.getChildUnit()); + materialBom.setMaterialType(materialUsageDTO.getCaizhi()); + //保留四位小数 + materialBom.setQuantity( new BigDecimal(materialUsageDTO.getFenzi()).divide(new BigDecimal(materialUsageDTO.getFenmu()),2, RoundingMode.HALF_UP)); + + return materialBom; + } + + private BomDetails createBomDetails1(MaterialUseDTO materialUsageDTO, JDMaterialAndRoute materialAndRoute, String productionOrderNo) { + BomDetails bomDetails = new BomDetails(); + bomDetails.setTotalWeight(productionOrderNo); + bomDetails.setFNumber(materialAndRoute.getMaterialCode()); + bomDetails.setFName(materialAndRoute.getMaterialName()); + bomDetails.setPartNumber(materialUsageDTO.getMaterialCode()); + bomDetails.setUnitWeight("是"); + //子项分子 + bomDetails.setQuantity(Double.valueOf(materialUsageDTO.getFenzi())); + //子项分母 + bomDetails.setDenominator(Double.valueOf(materialUsageDTO.getFenmu())); + bomDetails.setName(materialUsageDTO.getMaterialName()); + /* if (materialUsageDTO.getItemType().equals("1")){ + bomDetails.setStats("外购"); + }else{ + bomDetails.setStats("自制"); + }*/ + + bomDetails.setMaterial(materialUsageDTO.getCaizhi()); + return bomDetails; + } + + private ProcessRoute createProcessRoute1(ProcessRouteDTO processRouteDTO, JDMaterialAndRoute materialAndRoute, String productionOrderNo) { + + ProcessRoute processRoute = new ProcessRoute(); + // 设置路线描述为生产订单号 + processRoute.setRouteDescription(productionOrderNo); + // 设置工序号 + processRoute.setProcessNo(processRouteDTO.getProcessNo()); + // 设置工序名称 + processRoute.setProcessName(processRouteDTO.getProcessName()); + processRoute.setDiscWeight(Double.valueOf(materialAndRoute.getDanzhong())); + processRoute.setMaterial(materialAndRoute.getCaizhi()); + + // 设置物料代码 + processRoute.setMaterialCode(materialAndRoute.getMaterialCode()); + processRoute.setMaterialName(materialAndRoute.getMaterialName()); + + processRoute.setWorkCenter(processRouteDTO.getWorkCenter()); + // 基本时长 + processRoute.setActivityDuration(processRouteDTO.getActivityDuration()); + processRoute.setProcessDescription(processRouteDTO.getProcessDescription()); + processRoute.setProcessControl(processRouteDTO.getProcessControl()); + processRoute.setXuStartTime(null); + processRoute.setXuEndTime(null); + processRoute.setActivityUnit("分"); + // 本批数量对应 + processRoute.setBatchQuantity(materialAndRoute.getBenpi()); + processRoute.setFirstBatchQuantity(Double.valueOf(materialAndRoute.getDantai())); + List materialUsageDTOList = materialAndRoute.getMaterialUseDTOS(); + for (MaterialUseDTO materialUsageDTO : materialUsageDTOList) { + processRoute.setUnitQuantity(Double.valueOf(materialUsageDTO.getFenzi())); + processRoute.setRawMaterialCode(materialUsageDTO.getMaterialCode()); + processRoute.setRawMaterialName(materialUsageDTO.getMaterialName()); + processRoute.setBomUnit(materialUsageDTO.getChildUnit()); + if (materialUsageDTO.getChildUnit().equals("根")) { + processRoute.setDiscUsage(Double.valueOf(materialUsageDTO.getFenmu())); + } else { + processRoute.setDiscUsage((double) (materialUsageDTO.getFenzi() / materialUsageDTO.getFenmu())); + } + + processRoute.setMaterial(materialUsageDTO.getCaizhi()); + + } + return processRoute; + } @Log(title = "生成金蝶标准工艺") @SaCheckPermission("system:route:getKindeeExcel") @@ -519,8 +746,7 @@ public class ProcessRouteController extends BaseController { } } - private ProcessRoute createProcessRoute(PlannedProcessVo process, CombinedDTO combinedDTO, - String productionOrderNo) { + private ProcessRoute createProcessRoute(PlannedProcessVo process, CombinedDTO combinedDTO, String productionOrderNo) { ProcessRoute processRoute = new ProcessRoute(); // 设置路线描述为生产订单号 processRoute.setRouteDescription(productionOrderNo); @@ -572,8 +798,7 @@ public class ProcessRouteController extends BaseController { return processRoute; } - private BomDetails createBomDetails(MaterialUsageDTO materialUsageDTO, CombinedDTO combinedDTO, - String productionOrderNo) { + private BomDetails createBomDetails(MaterialUsageDTO materialUsageDTO, CombinedDTO combinedDTO, String productionOrderNo) { BomDetails bomDetails = new BomDetails(); bomDetails.setTotalWeight(productionOrderNo); bomDetails.setFNumber(combinedDTO.getMaterialCode()); @@ -605,8 +830,58 @@ public class ProcessRouteController extends BaseController { materialBom.setMaterialName(materialUsageDTO.getMaterialName()); materialBom.setUnit(materialUsageDTO.getUnit()); materialBom.setMaterialType(materialUsageDTO.getItemType()); - materialBom.setQuantity(String.valueOf(materialUsageDTO.getRequiredQty())); + materialBom.setQuantity(BigDecimal.valueOf(materialUsageDTO.getFNumerator())); return materialBom; } + + + /** + * 导出工艺路线列表 + */ + @SaCheckPermission("system:route:getAllRouteAndUse") + @Log(title = "获取全部工艺路线和物料清单", businessType = BusinessType.OTHER) + @PostMapping("/getAllRouteAndUse") + public void getAllRouteAndUse(@RequestParam("rooteProdet") String rooteProdet) { + log.info("获取项目生产数据表:{}", rooteProdet); + // 下载Excel模板 + SmbUtil.downloadExcelFiles(rooteProdet); + + // 构建Excel文件路径 + String ExcelName = "D:\\file\\" + rooteProdet + "汇总表.xlsx"; + File file = new File(ExcelName); + + if (!file.exists()) { + throw new ServiceException("文件不存在,请确认路径是否正确"); + } + List processRoutes = new ArrayList<>(); + //读取file的所有的物料编码 + try { + + if (file.exists()) { + // 读取Excel的sheet6 从第三行开始 读取到第4列 无数据的跳过 + DefaultExcelListener listener = new DefaultExcelListener<>(true); + EasyExcel.read(ExcelName, ProcessRouteVo.class, listener) + .sheet(6) + .headRowNumber(3) + .doRead(); + List list = listener.getExcelResult().getList(); + List list1 = iProcessRouteService.getProcessRouteGD(list); + + List bomDetailsList = new ArrayList<>(); + List routeList = new ArrayList<>(); + List materialBoms = new ArrayList<>(); + + for (JDMaterialAndRoute materialAndRoute : list1) { + processMaterAndRoute(materialAndRoute, bomDetailsList, routeList, materialBoms, rooteProdet); + } + + bomDetailsMapper.insertBatch(bomDetailsList); + baseMapper.insertBatch(routeList); + materialBomMapper.insertBatch(materialBoms); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/WlStockDataController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/WlStockDataController.java index 9e4f8ad..a810977 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/WlStockDataController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/WlStockDataController.java @@ -67,7 +67,6 @@ public class WlStockDataController extends BaseController { /** * 获取安全库存单据详细信息 - * * @param id 主键 */ @SaCheckPermission("system:stockData:query") @@ -125,10 +124,21 @@ public class WlStockDataController extends BaseController { return R.ok(result); } + @Log(title = "安全库存") + @XxlJob("generateDoc2") + public R> generateDoc1() { + List result = iWlStockDataService.generateDoc(); + if (result.isEmpty()) { + return R.fail("没有生成任何数据"); + } + return R.ok(result); + } + + @GetMapping("/logs") -public List getLogs(@RequestParam(value = "lastIndex", defaultValue = "0") int lastIndex) { - List logs = iWlStockDataService.getLogs(lastIndex); - int nextIndex = lastIndex + logs.size(); - return logs; -} + public List getLogs(@RequestParam(value = "lastIndex", defaultValue = "0") int lastIndex) { + List logs = iWlStockDataService.getLogs(lastIndex); + int nextIndex = lastIndex + logs.size(); + return logs; + } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/BomDetails.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/BomDetails.java index 107e84b..d5cfe4e 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/BomDetails.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/BomDetails.java @@ -96,5 +96,9 @@ public class BomDetails extends BaseEntity { /** * 单重 */ - private Double danzhong; + private Double danZhong; + /** + * 子项单重 + */ + private Double singleWeghit; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/MaterialBom.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/MaterialBom.java index f8f3d43..9daa6e5 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/MaterialBom.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/MaterialBom.java @@ -1,5 +1,6 @@ package com.ruoyi.system.domain; +import com.alibaba.excel.annotation.ExcelProperty; import com.baomidou.mybatisplus.annotation.*; import com.ruoyi.common.core.domain.BaseEntity; import lombok.Data; @@ -28,37 +29,46 @@ public class MaterialBom extends BaseEntity { /** * 项目令号 */ + @ExcelProperty("项目令号") private String projectNumber; /** * 物料编码 */ + @ExcelProperty("物料编码") private String materialCode; /** * 物料名称 */ + @ExcelProperty("物料名称") private String materialName; /** * 用量 */ - private String quantity; + @ExcelProperty("用量") + private BigDecimal quantity; /** * 单位 */ + @ExcelProperty("单位") private String unit; /** * 材质 */ + @ExcelProperty("材质") private String materialType; /** * 父级物料编码 */ + @ExcelProperty("父级物料编码") private String parentMaterialCode; /** * 父级物料名称 */ + @ExcelProperty("父级物料名称") private String parentMaterialName; /** * 库存 */ private Double stock; + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/ProcessRoute.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/ProcessRoute.java index 9b6d126..d3f00f8 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/ProcessRoute.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/ProcessRoute.java @@ -1,8 +1,12 @@ package com.ruoyi.system.domain; +import com.alibaba.excel.annotation.ExcelIgnore; +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.write.style.ColumnWidth; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; import com.ruoyi.common.core.domain.BaseEntity; import lombok.Data; import lombok.EqualsAndHashCode; @@ -23,104 +27,159 @@ public class ProcessRoute extends BaseEntity { private static final long serialVersionUID=1L; @TableId(value = "id", type = IdType.AUTO) + @ExcelIgnore private Long id; /** * 工艺路线描述 */ + @ColumnWidth(15) + @ExcelProperty(value={"生产令号","生产令号"},index=0) private String routeDescription; /** * 物料编码 */ + @ColumnWidth(20) + @ExcelProperty(value ={"物料编码","物料编码"},index=1 ) private String materialCode; /** * 物料名称 */ + @ColumnWidth(25) + @ExcelProperty(value ={"名称","名称"},index=2) private String materialName; /** * 材料BOM单位 */ + @ColumnWidth(10) + @ExcelProperty(value={ "材料BOM","单位"},index=10) private String bomUnit; + /** + * 材料BOM单位 + */ + @ExcelProperty(value={ "材料BOM","材料单重KG"},index=8) + private Double bomDanZhong; /** * 工序号 */ + @ColumnWidth(10) + @ExcelProperty(value ={ "工序号","工序号"},index = 11) private Long processNo; /** * 工作中心(加工车间) */ + @ColumnWidth(20) + @ExcelProperty(value ={ "工作中心(加工车间)","工作中心(加工车间)"},index = 12) private String workCenter; /** * 工序名称 */ + @ColumnWidth(20) + @ExcelProperty(value ={ "工序名称","工序名称"},index = 13) private String processName; /** * 材料BOM物料编码 */ + @ColumnWidth(20) + @ExcelProperty(value={ "材料BOM","物料编码"}, index=5) private String rawMaterialCode; /** * 材料BOM物料名称 */ + @ColumnWidth(25) + @ExcelProperty(value={ "材料BOM","物料名称"},index = 6) private String rawMaterialName; /** * 单重KG */ + @ColumnWidth(10) + @ExcelProperty(value={"单重KG","单重KG"},index=4) private Double discWeight; /** * 材料BOM用量 */ + @ColumnWidth(10) + @ExcelProperty(value = { "材料BOM","用量"},index = 9) private Double discUsage; /** * 工序说明(序描述) */ + @ColumnWidth(30) + @ExcelProperty(value ={ "工序说明(序描述)","工序说明(序描述)"},index = 14) private String processDescription; /** * 工序控制 */ + @ColumnWidth(20) + @ExcelProperty(value ={ "工序控制","工序控制"},index = 15) private String processControl; /** * 活动时长 */ + @ColumnWidth(10) + + @ExcelProperty(value={ "活动时长","活动时长"},index = 16) private Double activityDuration; /** * 活动单位 */ + @ColumnWidth(10) + + @ExcelProperty(value={ "活动单位","活动单位"},index =17) private String activityUnit; /** * bom材质 */ + @ColumnWidth(15) + @ExcelProperty(value={ "材料BOM","材质"},index = 7) private String bomMaterial; /** * 材质 */ + @ColumnWidth(15) + @ExcelProperty(value={ "材质","材质"},index=3) private String material; /** * 单台数量 */ + @ColumnWidth(10) + @ExcelProperty(value = {"制件数量","单台数量"},index = 18) private Double unitQuantity; /** * 本批数量 */ + @ColumnWidth(10) + @ExcelProperty(value = {"制件数量","本批数量"},index = 19) private Long batchQuantity; /** * 首批数量 */ + @ExcelIgnore private Double firstBatchQuantity; /** * 计划开始时间 */ + @ExcelIgnore private Date planStartTime; /** * 计划结束时间 */ + @ExcelIgnore private Date planEndTime; /** * 序开始时间 */ + @ColumnWidth(15) + @ExcelProperty(value = {"计划完成时间","起始日期"},index = 20) + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") private Date xuStartTime; /** * 序结束时间 */ + @ColumnWidth(15) + @ExcelProperty(value = {"计划完成时间","完成日期"},index = 22) + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") private Date xuEndTime; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SafetyStock.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SafetyStock.java index c0abd46..e67aedc 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SafetyStock.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SafetyStock.java @@ -34,6 +34,10 @@ public class SafetyStock extends BaseEntity { * 物料名称 */ private String materialName; + /** + * 材质 + */ + private String wlMaterial; /** * 最低安全库存 */ @@ -46,4 +50,12 @@ public class SafetyStock extends BaseEntity { * 当前库存 */ private Double currentStock; + /** + *分类 + */ + private String type; + /** + * 单台数量 + */ + private Long singleNum; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/WlStockData.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/WlStockData.java index e62fef6..0a88595 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/WlStockData.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/WlStockData.java @@ -37,11 +37,11 @@ public class WlStockData extends BaseEntity { */ private String materialName; /** - * 所需库存 + * 预计可用量 */ private Double requiredStock; /** - * 当前库存 + * 即时库存 */ private Double currentStock; /** @@ -53,7 +53,7 @@ public class WlStockData extends BaseEntity { */ private String documentType; /** - * 可用库存 + * 用料清单未领料数量 */ private BigDecimal availableStock; /** @@ -61,15 +61,15 @@ public class WlStockData extends BaseEntity { */ private BigDecimal secAvbqty; /** - * 生产订单数量 + * 生产订单未入库数量 */ private BigDecimal productionQty; /** - * 采购订单数量 + * 采购订单未入库数量 */ private BigDecimal purchaseQty; /** - * 预留量 + * 预留量X */ private BigDecimal secQty; /** @@ -84,4 +84,13 @@ public class WlStockData extends BaseEntity { * 金蝶单据编码 */ private String doucCode; + /** + * 材质 + */ + private String wlMaterial; + /** + * 安全库存状态(符合1,不符合0) + */ + private int safeStatus; + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SafetyStockBo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SafetyStockBo.java index 5bc37c4..04f8fc7 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SafetyStockBo.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SafetyStockBo.java @@ -38,6 +38,12 @@ public class SafetyStockBo extends BaseEntity { */ @NotBlank(message = "物料名称不能为空", groups = { AddGroup.class, EditGroup.class }) private String materialName; + /** + * 材质 + */ + @NotBlank(message = "材质不能为空", groups = { AddGroup.class, EditGroup.class }) + private String wlMaterial; + /** * 最低安全库存 @@ -54,5 +60,11 @@ public class SafetyStockBo extends BaseEntity { * 当前库存 */ private Double currentStock; + /** + *类型 + */ + @NotBlank(message = "类型不能为空", groups = { AddGroup.class, EditGroup.class }) + private String type; + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/WlStockDataBo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/WlStockDataBo.java index 74ff98e..77f3923 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/WlStockDataBo.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/WlStockDataBo.java @@ -62,6 +62,11 @@ public class WlStockDataBo extends BaseEntity { * 单据类型 (1: 最高库存单, 0: 最低库存单) */ private String documentType; + /** + * 材质 + */ + @NotBlank(message = "材质不能为空", groups = { AddGroup.class, EditGroup.class }) + private String wlMaterial; /** * 可用库存 @@ -109,4 +114,9 @@ public class WlStockDataBo extends BaseEntity { */ @NotBlank(message = "金蝶单据编码不能为空", groups = { AddGroup.class, EditGroup.class }) private String doucCode; + /** + * 安全库存状态(符合1,不符合0) + */ + private int safeStatus; + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JDInventoryDTO.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JDInventoryDTO.java new file mode 100644 index 0000000..687d052 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JDInventoryDTO.java @@ -0,0 +1,16 @@ +package com.ruoyi.system.domain.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +@Schema(name = "即时库存返回值") +public class JDInventoryDTO { + @JsonProperty("FMaterialId.FNumber") + private String FMaterialIdFNumber; + @JsonProperty("FMaterialName") + private String FMaterialName; + @JsonProperty("FBaseQty") + private Double FBaseQty; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JDMaterialAndRoute.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JDMaterialAndRoute.java new file mode 100644 index 0000000..0f8b65c --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JDMaterialAndRoute.java @@ -0,0 +1,25 @@ +package com.ruoyi.system.domain.dto; + +import com.ruoyi.system.domain.vo.PlannedProcessVo; +import lombok.Data; +import okhttp3.Route; + +import java.util.List; +/* + * @Description:用在获取物料清单和工艺路线(固定) + * @author: tzy + * 用在获取物料清单和工艺路线(固定) + * @date: 2025/5/16 15:03 + */ +@Data +public class JDMaterialAndRoute { + private String materialCode; // 物料编码 + private String materialName; + private String caizhi; + private String danzhong; + private Long benpi; + private Long dantai; + + private List materialUseDTOS; + private List plannedProcessVos; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JDMaterialOldNumber.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JDMaterialOldNumber.java new file mode 100644 index 0000000..a81acc5 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JDMaterialOldNumber.java @@ -0,0 +1,25 @@ +package com.ruoyi.system.domain.dto; + +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; + +@Data +public class JDMaterialOldNumber { + /** + * 编码 + */ + @ExcelProperty(value = "FMATERIALID") + private String FMATERIALID; + + + /** + * 安全库存 + */ + @ExcelProperty(value = "FNumber") + private String FNumber; + /** + * 最高库存 + */ + @ExcelProperty(value = "FOldNumber") + private String FOldNumber; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JDProductionDTO.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JDProductionDTO.java new file mode 100644 index 0000000..228c1ce --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JDProductionDTO.java @@ -0,0 +1,16 @@ +package com.ruoyi.system.domain.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +@Schema(name = "生产用料清单返回值获取") +public class JDProductionDTO { + @JsonProperty("FMaterialID2.FNumber") + private String FMaterialIdFNumber; + @JsonProperty("FMaterialName1") + private String FMaterialName; + @JsonProperty("FNoPickedQty") + private Double FNoPickedQty; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JdChildDTO.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JdChildDTO.java new file mode 100644 index 0000000..752d591 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JdChildDTO.java @@ -0,0 +1,50 @@ +package com.ruoyi.system.domain.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +@Data +public class JdChildDTO { + /** + * 部件图号 + */ + @JsonProperty("F_HBYT_BJBM") + private String partdiagramCode; + /** + * 部件名称 + */ + @JsonProperty("F_HBYT_BJMC") + private String partdiagramName; + + /** + * 子项物料单位 + */ + @JsonProperty("FUNITID.FName") + private String wareHouse; + + /** + *子项物料编码 + */ + @JsonProperty("FMATERIALIDCHILD.FNumber") + private String partNumber; + /** + *子项物料名称 + */ + @JsonProperty("FCHILDITEMNAME") + private String name; + /** + *属性 + */ + @JsonProperty("FCHILDITEMPROPERTY") + private String stats; + /** + * 子项分子 + */ + @JsonProperty("FNUMERATOR") + private Double quantity; + /** + * 子项分母 + */ + @JsonProperty("FDENOMINATOR") + private Double denominator; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JdDanZhong.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JdDanZhong.java new file mode 100644 index 0000000..c8f6ce4 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JdDanZhong.java @@ -0,0 +1,25 @@ +package com.ruoyi.system.domain.dto; + +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; + +@Data +public class JdDanZhong { + /** + * 编码 + */ + @ExcelProperty(value = "物料编码") + private String materialCode; + /** + * 名称 + */ + @ExcelProperty(value = "物料名称") + private String materialName; + + /** + * 仓库编码 + */ + @ExcelProperty(value = "单重") + private String Danzhong; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JdValidateBomDTO.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JdValidateBomDTO.java new file mode 100644 index 0000000..77cd884 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JdValidateBomDTO.java @@ -0,0 +1,27 @@ +package com.ruoyi.system.domain.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class JdValidateBomDTO { + /** + * FID + */ + @JsonProperty("FID") + private String FID; + /** + * 父级物料编码 + */ + @JsonProperty("FMATERIALID.FNumber") + private String fNumber; + /** + * 父级物料名称 + */ + @JsonProperty("FITEMNAME") + private String fName; + + private List childs; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/MaterialUsageDTO2.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/MaterialUsageDTO2.java new file mode 100644 index 0000000..ff8d0bb --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/MaterialUsageDTO2.java @@ -0,0 +1,64 @@ +package com.ruoyi.system.domain.dto; + +import com.alibaba.excel.annotation.ExcelProperty; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.Date; + +/** + * @author tzy + * @version 1.0 + * @date 2021/4/26 14:01 + * 生产用料清单用作导出用料 + */ +@Data +public class MaterialUsageDTO2 { + + @JsonProperty("F_HBYT_SCLH") + @ExcelProperty("生产令号") + private String planCode; + + @JsonProperty("FMaterialID2.FNumber") + @ExcelProperty("子项物料编码") + private String materialCode; + // 子物料编码 + @JsonProperty("FMaterialName1") + @ExcelProperty("子物料名称") + private String materialName;// 子物料名称 + // 物料名称 + @JsonProperty("FNumerator") + @ExcelProperty("单台数量") + private double FNumerator; + + @JsonProperty("FMustQty") + @ExcelProperty("本批数量") + private double FMustQty; + + @JsonProperty("FUnitID2.FName") + @ExcelProperty("单位") + private String unit; + // 单位 + @JsonProperty("F_HBYT_DZ") + @ExcelProperty("单重") + private String danzhong; // 单重 + // 应发数量 + @JsonProperty("FPickedQty") + @ExcelProperty("已领数量") + private double FPickedQty; + // 已领数量 + @JsonProperty("F_HBYT_CZ") + @ExcelProperty("材质") + private String materialCZ; // 材质 + + @JsonProperty("FDenominator") // 分子 + private double FDenominator; + // 分母 + @JsonProperty("FMaterialName") + @ExcelProperty("父级物料名称") + private String FMaterialName1; + // 父级物料名称 + @JsonProperty("FMaterialID.FNumber") + @ExcelProperty("父级物料编码") + private String FNumber; // 父级物料编码 +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/MaterialUseDTO.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/MaterialUseDTO.java new file mode 100644 index 0000000..eb05f94 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/MaterialUseDTO.java @@ -0,0 +1,39 @@ +package com.ruoyi.system.domain.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +/* + * @Description:物料清单 + * 物料清单映射对象 + * @author 田志阳 + * @date 2025/5/25 + */ +@Data +public class MaterialUseDTO +{ + //BOM版本 + @JsonProperty("FNumber") + private String fnumber; + + //子项物料编码 + @JsonProperty("FMATERIALIDCHILD.FNumber") + private String materialCode; + //子项物料名称 + @JsonProperty("FCHILDITEMNAME") + private String materialName; + //分子 + @JsonProperty("FNUMERATOR") + private Integer fenzi; + //分母 + @JsonProperty("FDENOMINATOR") + private Integer fenmu; + //单重 + @JsonProperty("F_HBYT_DZ") + private Double danzhong; + //材质 + @JsonProperty("F_HBYT_CZ") + private String caizhi; + //子项物料单位 + @JsonProperty("FCHILDUNITID.FName") + private String childUnit; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/ProMoDTO.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/ProMoDTO.java index 481533f..5273272 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/ProMoDTO.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/ProMoDTO.java @@ -9,6 +9,6 @@ public class ProMoDTO { private String FMaterialIdFNumber; @JsonProperty("FMaterialName") private String FMaterialName; - @JsonProperty("FQty") + @JsonProperty("FNoStockInQty") private Double FQty; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/ProcessRouteDTO.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/ProcessRouteDTO.java index d007daa..2e06962 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/ProcessRouteDTO.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/ProcessRouteDTO.java @@ -1,40 +1,48 @@ package com.ruoyi.system.domain.dto; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; @Data public class ProcessRouteDTO { - + /** + * 工序名称描述 + */ + @JsonProperty("FNumber") + private String processNameDescription; /** * 工序号 */ + @JsonProperty("FOperNumber") private Long processNo; /** * 工作中心(加工车间) */ + @JsonProperty("FWorkCenterId.FName") private String workCenter; /** * 工序名称 */ + @JsonProperty("FProcessId.FName") private String processName; /** * 工序说明(序描述) */ + @JsonProperty("FOperDescription") private String processDescription; /** * 工序控制 */ + @JsonProperty("FOptCtrlCodeId.FName") private String processControl; /** * 活动时长 */ + @JsonProperty("FActivity1Qty") private Double activityDuration; /** * 活动单位 */ + @JsonProperty("FActivity1UnitID.FName") private String activityUnit; - /** - * 工序名称描述 - */ - private String processNameDescription; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/PurchaseOrderDTO.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/PurchaseOrderDTO.java index 329c76c..41abf4b 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/PurchaseOrderDTO.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/PurchaseOrderDTO.java @@ -9,6 +9,6 @@ public class PurchaseOrderDTO { private String FMaterialIdFNumber; @JsonProperty("FMaterialName") private String FMaterialName; - @JsonProperty("FQty") - private Double FQty; + @JsonProperty("FRemainStockINQty") + private Double FRemainStockINQty; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/SingleWe.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/SingleWe.java new file mode 100644 index 0000000..708c07a --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/SingleWe.java @@ -0,0 +1,19 @@ +package com.ruoyi.system.domain.dto; + +import lombok.Data; + +/** + * material_bom + * 单重映射对象 + * @author tzy + * @date 2024-11-08 + */ +@Data +public class SingleWe { + private Long sid; + private String materialCode; + private String RmaterialCode; + private String RmaterialName; + private String materialName; + private Double danZhon; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/BomDetailsVo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/BomDetailsVo.java index 911836d..3cc9bb7 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/BomDetailsVo.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/BomDetailsVo.java @@ -92,13 +92,15 @@ public class BomDetailsVo { /** - * + *仓库 */ @ExcelProperty(value = "备注/仓库") private String remarks; /** * 单重 */ - private Double danzhong; + private Double danZhong; + + private Double singleWeghit; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/InventoryInfoVO.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/InventoryInfoVO.java index 0bb5646..bfc6f14 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/InventoryInfoVO.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/InventoryInfoVO.java @@ -6,6 +6,7 @@ import lombok.Data; public class InventoryInfoVO { private String materialCode; // 图号 private String materialName; // 名称 + private String kucun; // 名称 private String stockName; // 仓库 private String stockUnit; // 单位 private String quantity; // 数量 diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/PcRigidChainVO.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/PcRigidChainVO.java new file mode 100644 index 0000000..a4d8dc2 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/PcRigidChainVO.java @@ -0,0 +1,455 @@ +package com.ruoyi.system.domain.vo; + +import com.alibaba.excel.annotation.ExcelProperty; + +import com.ruoyi.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + + +/** + * 销齿链型号对象 pc_rigid_chain + * + * @author zhukangchao + * @date 2020-10-22 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class PcRigidChainVO extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 类型 */ + @ExcelProperty("类型") + private String type; + + /** 型号全称 */ + @ExcelProperty( "型号") + private String typeName; + + /** 产品id */ + @ExcelProperty( "产品id") + private Long productId; + + /** 产品名称 */ + @ExcelProperty( "产品名称") + private String productName; + + /** 物料编码 */ + @ExcelProperty( "物料编码") + private String materialCode; + + + /** 轴向 */ + @ExcelProperty( "轴向") + private String axialDirection; + + /** 箱体 */ + @ExcelProperty( "箱体") + private String box; + + /** 行程(mm) */ + @ExcelProperty( "{V1}") + private Long journey; + + /** 标记号 */ + @ExcelProperty( "标记号") + private String lableNumber; + + /** L1(mm) */ + @ExcelProperty( "L1") + private Long lOne; + + /** L2(mm) */ + @ExcelProperty( "L2") + private Long lTwo; + + /** L3(mm) */ + @ExcelProperty( "L3") + private Long lThree; + + /** 总重量 */ + @ExcelProperty( "总重量") + private Long sumWeight; + + /** 链条自重 */ + @ExcelProperty( "链条自重") + private Long chainWeight; + + /** 动载荷(KN) */ + @ExcelProperty( "动载荷") + private Long dynamicLoad; + + /** 静载荷(KN) */ + @ExcelProperty( "静载荷") + private Long deadLoad; + + /** 每转上升高度(mm) */ + @ExcelProperty( "每转上升高度") + private Long riseInHeightPerRevolution; + + /** 速度(mm/s) */ + @ExcelProperty( "速度") + private Double speed; + + /** 系统效率(%) */ + @ExcelProperty( "系统效率") + private Long efficiency; + + /** 链条节距(mm) */ + @ExcelProperty( "链条节距") + private Long chainPitch; + + /** 节圆半径(mm) */ + @ExcelProperty( "节圆半径") + private Long pitchRadius; + + /** 最低高度(mm) */ + @ExcelProperty( "最低高度") + private Long minimumAltitude; + + /** 一米链条自重(Kg/m) */ + @ExcelProperty( "一米链条自重") + private Double singleMeterChainWeight; + + /** 驱动箱重量(Kg) */ + @ExcelProperty( "驱动箱重量") + private Long drivingBoxWeight; + + /** 链箱重量(Kg/m) */ + @ExcelProperty( "链箱重量") + private Double chainBoxWeight; + + /** 单价 */ + @ExcelProperty( "单价") + private Double univalence; + + /** 图片 */ + @ExcelProperty( "图片") + private String picture; + + /** 部件id集合 */ + @ExcelProperty( "部件id集合") + private String partId; + + /** 备用字段1 */ + @ExcelProperty( "备用字段1") + private String sparedOne; + + /** 备用字段2 */ + @ExcelProperty( "备用字段2") + private String sparedTwo; + + /** 备用字段3 */ + @ExcelProperty( "备用字段3") + private Long sparedThree; + + /** 备用字段4 */ + @ExcelProperty( "备用字段4") + private Long sparedFour; + + /** 删除标记(0:未删除,1:已删除) */ + private Long delFlag; + + /** 行程 */ + @ExcelProperty( "{V1}") + private Long vOne; + + /** 设备总长 */ + @ExcelProperty( "{V2}") + private Long vTwo; + + /** 地脚位置1 */ + @ExcelProperty( "{V3}") + private Long vThree; + + /** 地脚位置2 */ + @ExcelProperty("{V4}") + private Long vFour; + + /** 箱体装配长度 */ + @ExcelProperty("{V5}") + private Long vFive; + + /** 箱体地脚位置1 */ + @ExcelProperty( "{V6}") + private Long vSix; + + /** 箱体地脚位置2 */ + @ExcelProperty( "{V7}") + private Long vSeven; + + /** 铝箱长度1 */ + @ExcelProperty( "{V8}") + private Long vEight; + + /** 铝箱长度2 */ + @ExcelProperty( "{V9}") + private Long vNine; + + /** 导向条长度1 */ + @ExcelProperty( "{V10}") + private Long vTen; + + /** 导向条长度1数量 */ + @ExcelProperty( "{V11}") + private Long vEleven; + + /** 导向条长度2 */ + @ExcelProperty( "{V12}") + private Long vTwelve; + + /** 导向条长度2数量 */ + @ExcelProperty( "{V13}") + //@Excel(name = "导向条2数量") + private Long vThirteen; + + /** 导向条长度3 */ + @ExcelProperty( "{V14}") + private Long vFourteen; + + /** 导向条长度3数量 */ + @ExcelProperty( "{V15}") + //@Excel(name = "导向条3数量") + private Long vFifteen; + + /** 孔位总长1 */ + @ExcelProperty( "{V16}") + private Long vSixteen; + + /** 间隔数量1 */ + @ExcelProperty( "{V17}") + private Long vSeveteen; + + /** 孔位总长2 */ + @ExcelProperty( "{V18}") + private Long vEighteen; + + /** 间隔数量2 */ + @ExcelProperty( "{V19}") + private Long vNineteen; + + /** 铆钉数量 */ + @ExcelProperty( "{V20}") + private Long vTwenty; + + /** 待定义 */ + @ExcelProperty( "{V21}") + private Long vTwentyOne; + + /** 待定义 */ + @ExcelProperty( "{V22}") + private Long vTwentyTwo; + + /** 待定义 */ + @ExcelProperty( "{V23}") + private Long vTwentyThree; + + /** 待定义 */ + @ExcelProperty( "{V24}") + private Long vTwentyFour; + + /** 待定义 */ + // @ExcelProperty( "{V25}") + private Long vTwentyFive; + + /** 待定义 */ + @ExcelProperty( "{V26}") + private Long vTwentySix; + + /** 待定义 */ + @ExcelProperty( "{V27}") + private Long vTwentySeven; + + /** 待定义 */ + @ExcelProperty( "{V28}") + private Long vTwentyEight; + + /** 待定义 */ + @ExcelProperty( "{V29}") + private Long vTwentyNine; + + /** 待定义 */ + @ExcelProperty( "{V30}") + private Long vThirty; + + /** 待定义 */ + @ExcelProperty( "{V31}") + private Long vThirtyOne; + + /** 待定义 */ + @ExcelProperty( "{V32}") + private Long vThirtyTwo; + + /** 待定义 */ + @ExcelProperty( "{V33}") + private Long vThirtyThree; + + /** 待定义 */ + @ExcelProperty( "{V34}") + private Long vThirtyFour; + + /** 待定义 */ + @ExcelProperty( "{V35}") + private Long vThirtyFive; + + /** 待定义 */ + @ExcelProperty( "{V36}") + private Long vThirtySix; + + /** 待定义 */ + @ExcelProperty( "{V37}") + private Long vThirtySeven; + + /** 待定义 */ + @ExcelProperty( "{V38}") + private Long vThirtyEight; + + /** 待定义 */ + @ExcelProperty( "{V39}") + private Long vThirtyNine; + + /** 待定义 */ + @ExcelProperty( "{V40}") + private Long vForty; + + /** X1 */ + @ExcelProperty( "{V41}") + private Long vFortyOne; + + /** X2 */ + @ExcelProperty( "{V42}") + private Long vFortyTwo; + + /** X3 */ + @ExcelProperty( "{V43}") + private Long vFortyThree; + + /** X4 */ + @ExcelProperty( "{V44}") + private Long vFortyFour; + + /** X5 */ + @ExcelProperty( "{V45}") + private Long vFortyFive; + + /** X6 */ + @ExcelProperty( "{V46}") + private Long vFortySix; + + /** X7 */ + @ExcelProperty( "{V48}") + private Long vFortySeven; + + /** X8 */ + @ExcelProperty( "V48") + private Long vFortyEight; + + /** X9 */ + @ExcelProperty( "{V49}") + private Long vFortyNine; + + /** X10 */ + @ExcelProperty( "{V50}") + private Long vFifty; + + /** X11 */ + @ExcelProperty( "{V51}") + private Long vFiftyOne; + + /** X12 */ + @ExcelProperty( "{V52}") + private Long vFiftyTwo; + + /** X13 */ + @ExcelProperty( "{V53}") + private Long vFiftyThree; + + /** 重量 */ + @ExcelProperty( "{G1}") + private Double gOne; + + /** 重量 */ + @ExcelProperty( "{G2}") + private Double gTwo; + + /** 重量 */ + @ExcelProperty( "{G3}") + private Double gThree; + + /** 重量 */ + @ExcelProperty( "{G4}") + private Double gFour; + + /** 重量 */ + @ExcelProperty( "{G5}") + private Double gFive; + + /** 重量 */ + @ExcelProperty( "{G6}") + private Double gSix; + + /** 重量 */ + @ExcelProperty( "{G7}") + private Double gSeven; + + /** 重量 */ + @ExcelProperty( "{G8}") + private Double gEight; + + /** 重量 */ + @ExcelProperty( "{G9}") + private Double gNine; + + /** 重量 */ + @ExcelProperty( "{G10}") + private Double gTen; + + /** 重量 */ + @ExcelProperty( "{G11}") + private Double gEleven; + + /** 重量 */ + @ExcelProperty( "{G12}") + private Double gTwelve; + + /** 重量 */ + @ExcelProperty( "{G13}") + private Double gThirteen; + + /** 重量 */ + @ExcelProperty( "{G14}") + private Double gFourteen; + + /** 重量 */ + @ExcelProperty( "{G15}") + private Double gFifteen; + + /** 重量 */ + @ExcelProperty( "{G16}") + private Double gSixteen; + + /** 重量 */ + @ExcelProperty( "{G17}") + private Double gSeveteen; + + /** 重量 */ + @ExcelProperty( "{G18}") + private Double gEighteen; + + /** 重量 */ + @ExcelProperty( "{G19}") + private Double gNineteen; + + /** 重量 */ + @ExcelProperty( "{G20}") + private Double gTwenty; + + private Double vipLevel; + private String spline; + private Long number; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/PlannedProcessVo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/PlannedProcessVo.java index c65b729..2c83faf 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/PlannedProcessVo.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/PlannedProcessVo.java @@ -14,7 +14,7 @@ import lombok.Data; /** * 计划工序视图对象 planned_process * - * @author ruoyi + * @author tzy * @date 2024-10-24 */ @Data diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/ProcessRouteStandVo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/ProcessRouteStandVo.java new file mode 100644 index 0000000..0dfb241 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/ProcessRouteStandVo.java @@ -0,0 +1,179 @@ +package com.ruoyi.system.domain.vo; + +import com.alibaba.excel.annotation.ExcelIgnore; +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.write.style.ColumnWidth; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 工艺路线对象 process_route + * + * @author ruoyi + * @date 2024-10-09 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("process_route") +public class ProcessRouteStandVo extends BaseEntity { + + private static final long serialVersionUID=1L; + @TableId(value = "id", type = IdType.AUTO) + @ExcelIgnore + private Long id; + + /** + * 工艺路线描述 + */ + @ColumnWidth(15) + // @ExcelProperty(value={"生产令号","生产令号"},index=0) + private String routeDescription; + /** + * 物料编码 + */ + @ColumnWidth(20) + @ExcelProperty(value ={"物料编码","物料编码"},index=0 ) + private String materialCode; + /** + * 物料名称 + */ + @ColumnWidth(25) + @ExcelProperty(value ={"名称","名称"},index=1) + private String materialName; + /** + * 材料BOM单位 + */ + @ColumnWidth(10) + @ExcelProperty(value={ "材料BOM","单位"},index=10) + private String bomUnit; + + /** + * 工序号 + */ + @ColumnWidth(10) + @ExcelProperty(value ={ "工序号","工序号"},index = 11) + private Long processNo; + /** + * 工作中心(加工车间) + */ + @ColumnWidth(20) + @ExcelProperty(value ={ "工作中心(加工车间)","工作中心(加工车间)"},index = 12) + private String workCenter; + /** + * 工序名称 + */ + @ColumnWidth(20) + @ExcelProperty(value ={ "工序名称","工序名称"},index = 13) + private String processName; + /** + * 材料BOM物料编码 + */ + @ColumnWidth(20) + @ExcelProperty(value={ "材料BOM","物料编码"}, index=4) + private String rawMaterialCode; + /** + * 材料BOM物料名称 + */ + @ColumnWidth(25) + @ExcelProperty(value={ "材料BOM","物料名称"},index = 5) + private String rawMaterialName; + /** + * 单重KG + */ + @ColumnWidth(10) + @ExcelProperty(value={"单重KG","单重KG"},index=3) + private Double discWeight; + /** + * 材料BOM用量 + */ + @ColumnWidth(10) + @ExcelProperty(value = { "材料BOM","用量"},index = 9) + private Double discUsage; + /** + * 工序说明(序描述) + */ + @ColumnWidth(30) + @ExcelProperty(value ={ "工序说明(序描述)","工序说明(序描述)"},index = 14) + private String processDescription; + /** + * 工序控制 + */ + @ColumnWidth(20) + @ExcelProperty(value ={ "工序控制","工序控制"},index = 15) + private String processControl; + /** + * 活动时长 + */ + @ColumnWidth(10) + @ExcelProperty(value ={ "活动时长","活动时长"},index = 16) + private Double activityDuration; + /** + * 活动单位 + */ + @ColumnWidth(10) + @ExcelProperty(value ={ "活动单位","活动单位"},index = 17) + private String activityUnit; + + /** + * bom材质 + */ + @ColumnWidth(15) + @ExcelProperty(value={ "材料BOM","材质"},index = 7) + private String bomMaterial; + /** + * 材质 + */ + @ColumnWidth(15) + @ExcelProperty(value={ "材质","材质"},index=2) + private String material; + /** + * 单台数量 + */ + @ColumnWidth(10) + @ExcelProperty(value = {"制件数量","单台数量"},index = 18) + private Double unitQuantity; + /** + * 本批数量 + */ + @ColumnWidth(10) + @ExcelProperty(value = {"制件数量","本批数量"},index = 19) + private Long batchQuantity; + /** + * 首批数量 + */ + @ExcelIgnore + private Double firstBatchQuantity; + + /** + * 计划开始时间 + */ + @ExcelIgnore + private Date planStartTime; + /** + * 计划结束时间 + */ + @ExcelIgnore + private Date planEndTime; + /** + * 序开始时间 + */ + @ColumnWidth(15) + @ExcelProperty(value = {"计划完成时间","起始日期"},index = 20) + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") + private Date xuStartTime; + /** + * 序结束时间 + */ + @ColumnWidth(15) + @ExcelProperty(value = {"计划完成时间","完成日期"},index = 22) + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") + private Date xuEndTime; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/ProcessRouteVo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/ProcessRouteVo.java index 61f1ae6..8d90ba7 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/ProcessRouteVo.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/ProcessRouteVo.java @@ -3,6 +3,9 @@ package com.ruoyi.system.domain.vo; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.format.NumberFormat; +import com.alibaba.excel.annotation.write.style.ColumnWidth; +import com.alibaba.excel.annotation.write.style.ContentRowHeight; +import com.alibaba.excel.annotation.write.style.HeadRowHeight; import com.fasterxml.jackson.annotation.JsonFormat; import com.ruoyi.common.convert.ExcelDictConvert; import lombok.Data; @@ -21,6 +24,9 @@ import java.util.List; */ @Data @ExcelIgnoreUnannotated +@ContentRowHeight(15) +@HeadRowHeight(20) +@ColumnWidth(15) public class ProcessRouteVo { private static final long serialVersionUID = 1L; @@ -38,29 +44,34 @@ public class ProcessRouteVo { /** * 工艺路线描述 */ + @ExcelProperty(value={"生产令号","生产令号"},index=0) private String routeDescription; /** * 物料编码 */ + @ExcelProperty(value ={"物料编码","物料编码"},index=1 ) private String materialCode; /** * 物料名称 */ + @ExcelProperty(value ={"名称","名称"},index=2) private String materialName; /** * 材质 */ + @ExcelProperty(value={ "材质","材质"},index=3) private String material; /** * 单重KG */ + @ColumnWidth(5) @ExcelProperty(value={"单重KG","单重KG"},index=4) private Double discWeight; /** @@ -79,72 +90,83 @@ public class ProcessRouteVo { /** * bom材质 */ + @ColumnWidth(7) @ExcelProperty(value={ "材料BOM","材质"},index = 7) private String bomMaterial; + /** + * 材料BOM单位 + */ + @ExcelProperty(value={ "材料BOM","材料单重KG"},index=8) + private Double bomDanZhong; + /** * 材料BOM用量 */ - @ExcelProperty(value = { "材料BOM","用量"},index = 8) + @ColumnWidth(10) + @ExcelProperty(value = { "材料BOM","用量"},index = 9) private Double discUsage; /** * 材料BOM单位 */ - @ExcelProperty(value={ "材料BOM","单位"},index=9) + @ColumnWidth(6) + @ExcelProperty(value={ "材料BOM","单位"},index=10) private String bomUnit; - /** * 工序号 */ - @ExcelProperty(value ={ "工序号","工序号"},index = 10) + @ColumnWidth(10) + @ExcelProperty(value ={ "工序号","工序号"},index = 11) private Long processNo; /** * 工作中心(加工车间) */ - @ExcelProperty(value ={ "工作中心(加工车间)","工作中心(加工车间)"},index = 11) + @ExcelProperty(value ={ "工作中心(加工车间)","工作中心(加工车间)"},index = 12) private String workCenter; /** * 工序名称 */ - @ExcelProperty(value ={ "工序名称","工序名称"},index = 12) + @ExcelProperty(value ={ "工序名称","工序名称"},index = 13) private String processName; /** * 工序说明(序描述) */ - @ExcelProperty(value ={ "工序说明(序描述)","工序说明(序描述)"},index = 13) + @ColumnWidth(25) + @ExcelProperty(value ={ "工序说明(序描述)","工序说明(序描述)"},index = 14) private String processDescription; /** * 工序控制 */ - @ExcelProperty(value ={ "工序控制","工序控制"},index = 14) + @ExcelProperty(value ={ "工序控制","工序控制"},index = 15) private String processControl; /** * 活动时长 */ - @ExcelProperty(value ={ "活动时长","活动时长"},index = 15) + @ExcelProperty(value ={ "活动时长","活动时长"},index = 16) private Double activityDuration; /** * 活动单位 */ - @ExcelProperty(value ={ "活动单位","活动单位"},index = 16) + @ExcelProperty(value ={ "活动单位","活动单位"},index = 17) private String activityUnit; /** * 单台数量 */ - @ExcelProperty(value = {"制件数量","单台数量"},index = 17) + @ExcelProperty(value = {"制件数量","单台数量"},index = 18) private Long unitQuantity; /** * 本批数量 */ - @ExcelProperty(value = {"制件数量","本批数量"},index = 18) + + @ExcelProperty(value = {"制件数量","本批数量"},index = 19) private Long batchQuantity; /** @@ -167,14 +189,16 @@ public class ProcessRouteVo { /** * 序开始时间 */ - @ExcelProperty(value = {"计划完成时间","起始日期"},index = 19) + @ColumnWidth(18) + @ExcelProperty(value = {"计划完成时间","起始日期"},index = 20) @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") private Date xuStartTime; /** * 序结束时间 */ - @ExcelProperty(value = {"计划完成时间","完成日期"},index = 21) + @ColumnWidth(18) + @ExcelProperty(value = {"计划完成时间","完成日期"},index = 22) @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") private Date xuEndTime; diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SafetyStockVo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SafetyStockVo.java index c29e003..ca74c2a 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SafetyStockVo.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SafetyStockVo.java @@ -2,8 +2,12 @@ package com.ruoyi.system.domain.vo; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelProperty; +import com.ruoyi.common.core.validate.AddGroup; +import com.ruoyi.common.core.validate.EditGroup; import lombok.Data; +import javax.validation.constraints.NotBlank; + /** * 安全库存视图对象 wl_safety_stock @@ -54,5 +58,19 @@ public class SafetyStockVo { */ @ExcelProperty(value = "金蝶单据编码") private String doucCode; - + /** + * 单台数量 + */ + @ExcelProperty(value = "单台数量") + private Long singleNum; + /** + *分类 + */ + @ExcelProperty(value = "分类") + private String type; + /** + * 材质 + */ + @ExcelProperty(value = "材质") + private String wlMaterial; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/WlStockDataVo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/WlStockDataVo.java index 42a347e..3273933 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/WlStockDataVo.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/WlStockDataVo.java @@ -37,53 +37,45 @@ public class WlStockDataVo { @ExcelProperty(value = "物料名称") private String materialName; + @ExcelProperty(value = "材质") + private String documentType; /** * 所需库存 */ - @ExcelProperty(value = "所需库存") private Double requiredStock; - /** * 当前库存 */ - @ExcelProperty(value = "当前库存") + @ExcelProperty(value = "预计可用量") private Double currentStock; - - /** - * 触发时间 - */ - @ExcelProperty(value = "触发时间") - private Date triggerTime; - - /** * 可用库存 */ - @ExcelProperty(value = "可用库存") + @ExcelProperty(value = "用料清单未领料数量") private BigDecimal availableStock; /** * 库存量 */ - @ExcelProperty(value = "库存量") + @ExcelProperty(value = "即时库存") private BigDecimal secAvbqty; /** * 生产订单数量 */ - @ExcelProperty(value = "生产订单数量") + @ExcelProperty(value = "生产订单未入库数量") private BigDecimal productionQty; /** * 采购订单数量 */ - @ExcelProperty(value = "采购订单数量") + @ExcelProperty(value = "采购订单未入库数量") private BigDecimal purchaseQty; /** * 预留量 */ - @ExcelProperty(value = "预留量") + /* @ExcelProperty(value = "预留量")*/ private BigDecimal secQty; /** @@ -99,9 +91,19 @@ public class WlStockDataVo { private BigDecimal minsafetyStock; /** - * 单据类型 (1: 最高库存单, 0: 最低库存单) + * 安全库存状态(符合1,不符合0) */ - @ExcelProperty(value = "金蝶相关数据") - private String documentType; + @ExcelProperty(value = "是否符合要求") + private int safeStatus; + /** + * 分组 + */ + @ExcelProperty(value = "分组") + private String wlMaterial; + /** + * 触发时间 + */ + @ExcelProperty(value = "触发时间") + private Date triggerTime; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/runner/JdUtil.java b/ruoyi-system/src/main/java/com/ruoyi/system/runner/JdUtil.java index 3147494..b4ab923 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/runner/JdUtil.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/runner/JdUtil.java @@ -540,7 +540,7 @@ public class JdUtil { } /** * 查询生产订单单据体 - * + *查询 * @param materialCode * @return */ @@ -551,7 +551,7 @@ public class JdUtil { JsonObject json = new JsonObject(); json.addProperty("FormId", "PRD_MO"); json.addProperty("FieldKeys", - "FMaterialId.FNumber,FMaterialName,FQty"); + "FMaterialId.FNumber,FMaterialName,FNoStockInQty"); // 创建过滤条件 JsonArray filterString = new JsonArray(); JsonObject filterObject = new JsonObject(); @@ -584,8 +584,16 @@ public class JdUtil { filterObject3.addProperty("Value", 7); filterObject3.addProperty("Left", ""); filterObject3.addProperty("Right", ""); - filterObject3.addProperty("Logic", 0);// 从 PlanOrderVo 获取生产令号 + filterObject3.addProperty("Logic", 0); filterString.add(filterObject3); + JsonObject filterObject4 = new JsonObject(); + filterObject4.addProperty("FieldName", "FNoStockInQty"); + filterObject4.addProperty("Compare", "21"); // 改为等号运算符 + filterObject4.addProperty("Value", 0); + filterObject4.addProperty("Left", ""); + filterObject4.addProperty("Right", ""); + filterObject4.addProperty("Logic", 0); + filterString.add(filterObject4); json.add("FilterString", filterString); json.addProperty("OrderString", ""); @@ -616,6 +624,7 @@ public class JdUtil { /** * 查询采购订单 单据体 + * 将预留量更改为 剩余未入库数量20250325 * @param materialCode * @return */ @@ -628,7 +637,7 @@ public class JdUtil { JsonObject json = new JsonObject(); json.addProperty("FormId", "PUR_PurchaseOrder"); json.addProperty("FieldKeys", - "FMaterialId.FNumber,FMaterialName,FQty"); + "FMaterialId.FNumber,FMaterialName,FRemainStockINQty"); // 创建过滤条件 JsonArray filterString = new JsonArray(); JsonObject filterObject = new JsonObject(); @@ -641,12 +650,20 @@ public class JdUtil { filterString.add(filterObject); JsonObject filterObject1 = new JsonObject(); filterObject1.addProperty("FieldName", "FMRPCloseStatus"); - filterObject1.addProperty("Compare", "="); // 改为等号运算符 + filterObject1.addProperty("Compare", "105"); // 改为等号运算符 filterObject1.addProperty("Value", "A"); filterObject1.addProperty("Left", ""); filterObject1.addProperty("Right", ""); filterObject1.addProperty("Logic", 0);// 从 PlanOrderVo 获取生产令号 filterString.add(filterObject1); + /* JsonObject filterObject2 = new JsonObject(); + filterObject2.addProperty("FieldName", "FCloseStatus"); + filterObject2.addProperty("Compare", "106"); // 改为等号运算符 + filterObject2.addProperty("Value", "A"); + filterObject2.addProperty("Left", ""); + filterObject2.addProperty("Right", ""); + filterObject2.addProperty("Logic", 0);// 从 PlanOrderVo 获取生产令号 + filterString.add(filterObject2);*/ json.add("FilterString", filterString); json.addProperty("OrderString", ""); json.addProperty("TopRowCount", 0); @@ -674,19 +691,147 @@ public class JdUtil { return plannedProcessList; // 返回结果 } + /** + * 查询生产用料清单单据体 + * 查询子项物料的未领料量 + * @param materialCode + * @return + */ + public static List getWeiLingliao(String materialCode) { + K3CloudApi client = new K3CloudApi(); + + // 请求参数,要求为json字符串 + JsonObject json = new JsonObject(); + json.addProperty("FormId", "PRD_PPBOM"); + json.addProperty("FieldKeys", + "FMaterialID2.FNumber,FMaterialName1,FNoPickedQty"); + // 创建过滤条件 + JsonArray filterString = new JsonArray(); + JsonObject filterObject = new JsonObject(); + filterObject.addProperty("FieldName", "FMaterialID2.FNumber"); + filterObject.addProperty("Compare", "67"); + filterObject.addProperty("Value", materialCode); + filterObject.addProperty("Left", ""); + filterObject.addProperty("Right", ""); + filterObject.addProperty("Logic", 0); + filterString.add(filterObject); + JsonObject filterObject1 = new JsonObject(); + filterObject1.addProperty("FieldName", "FMoEntryStatus"); + filterObject1.addProperty("Compare", "5"); + filterObject1.addProperty("Value", "7"); + filterObject1.addProperty("Left", ""); + filterObject1.addProperty("Right", ""); + filterObject1.addProperty("Logic", 0); + filterString.add(filterObject1); + JsonObject filterObject2 = new JsonObject(); + filterObject2.addProperty("FieldName", "FMoEntryStatus");// 改为等号运算符 + filterObject2.addProperty("Compare", "5"); + filterObject2.addProperty("Value", "5"); + filterObject2.addProperty("Left", ""); + filterObject2.addProperty("Right", ""); + filterObject2.addProperty("Logic", 0); + filterString.add(filterObject2); + JsonObject filterObject3 = new JsonObject(); + filterObject3.addProperty("FieldName", "FMoEntryStatus"); + filterObject3.addProperty("Compare", "5"); + filterObject3.addProperty("Value", "6"); + filterObject3.addProperty("Left", ""); + filterObject3.addProperty("Right", ""); + filterObject3.addProperty("Logic", 0); + filterString.add(filterObject3); + JsonObject filterObject4 = new JsonObject(); + filterObject4.addProperty("FieldName", "FDocumentStatus"); + filterObject4.addProperty("Compare", "105"); + filterObject4.addProperty("Value", "C");//单据状态:已审核 + filterObject4.addProperty("Left", ""); + filterObject4.addProperty("Right", ""); + filterObject4.addProperty("Logic", 0); + filterString.add(filterObject4); + json.add("FilterString", filterString); + json.addProperty("OrderString", ""); + json.addProperty("TopRowCount", 0); + json.addProperty("StartRow", 0); + json.addProperty("Limit", 2000); + json.addProperty("SubSystemId", ""); + + String jsonData = json.toString(); + List plannedProcessList = null; + try { + // 调用接口 + String resultJson = String.valueOf(client.billQuery(jsonData)); + JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class); + + // 使用 ObjectMapper 将 JsonArray 转换为 List + ObjectMapper objectMapper = new ObjectMapper(); + plannedProcessList = objectMapper.readValue(jsonArray.toString(), + new TypeReference>() { + + }); + + } catch (Exception e) { + e.printStackTrace(); // 输出异常日志 + } + + return plannedProcessList; // 返回结果 + } + public static List getKuCun(String materialCode) { + + K3CloudApi client = new K3CloudApi(); + + // 请求参数,要求为json字符串 + JsonObject json = new JsonObject(); + json.addProperty("FormId", "STK_Inventory"); + json.addProperty("FieldKeys", + "FMaterialId.FNumber,FMaterialName,FBaseQty"); + // 创建过滤条件 + JsonArray filterString = new JsonArray(); + JsonObject filterObject = new JsonObject(); + filterObject.addProperty("FieldName", "FMaterialId.FNumber"); + filterObject.addProperty("Compare", "="); + filterObject.addProperty("Value", materialCode); + filterObject.addProperty("Left", ""); + filterObject.addProperty("Right", ""); + filterObject.addProperty("Logic", 0); + filterString.add(filterObject); + + json.add("FilterString", filterString); + json.addProperty("OrderString", ""); + json.addProperty("TopRowCount", 0); + json.addProperty("StartRow", 0); + json.addProperty("Limit", 2000); + json.addProperty("SubSystemId", ""); + + String jsonData = json.toString(); + List plannedProcessList = null; + try { + // 调用接口 + String resultJson = String.valueOf(client.billQuery(jsonData)); + JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class); + + // 使用 ObjectMapper 将 JsonArray 转换为 List + ObjectMapper objectMapper = new ObjectMapper(); + plannedProcessList = objectMapper.readValue(jsonArray.toString(), + new TypeReference>() { + + }); + + } catch (Exception e) { + e.printStackTrace(); // 输出异常日志 + } + + return plannedProcessList; // 返回结果 + } public static Double getKeyong(String materialCode) { List analyzeRpt =getInvReserveAnalyzeRpt(materialCode); - if (analyzeRpt == null || analyzeRpt.isEmpty()) { + if (analyzeRpt.isEmpty()) { System.err.println("No inventory data found for materialCode: " + materialCode); return 0.0; // 返回 0.0 而不是 null } double fSecAVBQty = 0.0; double fSecQty = 0.0; - if (!analyzeRpt.isEmpty()) { - fSecAVBQty = analyzeRpt.get(0).getFSecAVBQty(); - } + fSecAVBQty = analyzeRpt.get(0).getFSecAVBQty(); for (InvReserveAnalyzeRptDTO analyzeRptDTO : analyzeRpt) { if (analyzeRptDTO.getFSecQty() != null) { fSecQty += analyzeRptDTO.getFSecQty(); @@ -703,12 +848,12 @@ public class JdUtil { List purchaseOrderList = getPurchaseOrderList(materialCode); if (purchaseOrderList != null) { for (PurchaseOrderDTO purchaseOrderDTO : purchaseOrderList) { - purchaseQty += purchaseOrderDTO.getFQty(); + purchaseQty += purchaseOrderDTO.getFRemainStockINQty(); } } return fSecAVBQty + productionQty + purchaseQty - fSecQty; } - + // 金蝶物料查询 public static int isMaterialVerification(String DrawingNumber, String name) { if (DrawingNumber == null || DrawingNumber.isEmpty() || name == null || name.isEmpty()) { return 0; @@ -732,7 +877,6 @@ public class JdUtil { return 1; // 编码未找到,返回1表示正常 } } - /*本接口用于实现物料清单 的禁用功能*/ public static void jtestForbidMaterial(String FNumber) throws Exception { K3CloudApi api = new K3CloudApi(); @@ -747,7 +891,6 @@ public class JdUtil { fail("物料提交接口: " + gson.toJson(repoRet.getResult())); } } - //用料清单查询接口腹肌无聊 public static List getFuji(String materialCode) { List jinYongDTOS = new ArrayList<>(); @@ -906,8 +1049,8 @@ public class JdUtil { // 添加Model字段 model.addProperty("FMATERIALID", 0); - if(!(bomDetail.getDanzhong() ==null)){ - model.addProperty("F_HBYT_DZ", bomDetail.getDanzhong()); + if(!(bomDetail.getDanZhong() ==null)){ + model.addProperty("F_HBYT_DZ", bomDetail.getDanZhong()); } model.addProperty("FNumber", bomDetail.getFNumber()); model.addProperty("FName", bomDetail.getFName()); @@ -1086,13 +1229,13 @@ public class JdUtil { if (jsonArray != null && jsonArray.size() > 0) { ObjectMapper objectMapper = new ObjectMapper(); - List JinYongDTOList = objectMapper.readValue(jsonArray.toString(), + List entryVmis = objectMapper.readValue(jsonArray.toString(), new TypeReference>() {}); - if (JinYongDTOList != null && !JinYongDTOList.isEmpty()) { - jinYongDTOS.addAll(JinYongDTOList); + if (entryVmis != null && !entryVmis.isEmpty()) { + jinYongDTOS.addAll(entryVmis); } } else { - log.warn("未找到与bom版本号 " + materialCode + " 相关的记录"); + log.warn("未找到与 " + materialCode + " 相关的记录"); } } catch (Exception e) { log.error("调用接口时发生异常: " + e.getMessage(), e); @@ -1100,8 +1243,7 @@ public class JdUtil { return jinYongDTOS; } - - + //更新VMI public static String updateVMI(int FMATERIALID, int fEntryId1, int fEntryId2, String cangkunum, String cangWeiNum) throws Exception { K3CloudApi api = new K3CloudApi(false); JsonObject json = new JsonObject(); @@ -1113,7 +1255,8 @@ public class JdUtil { needUpDateFields.add("SubHeadEntity3"); needUpDateFields.add("FStockPlaceId"); needUpDateFields.add("FStockId"); - needUpDateFields.add("FIsVmiBusiness"); + + //needUpDateFields.add("FIsVmiBusiness"); json.add("NeedUpDateFields", needUpDateFields); // 添加 IsDeleteEntry 属性 @@ -1134,9 +1277,11 @@ public class JdUtil { // 创建 FStockPlaceId 对象 JsonObject fStockPlaceId = new JsonObject(); - JsonObject fStockPlaceIdFF100002 = new JsonObject(); - fStockPlaceIdFF100002.addProperty("FNumber", cangWeiNum); - fStockPlaceId.add("FSTOCKPLACEID__FF100002", fStockPlaceIdFF100002); + JsonObject fStockPlaceIdFF100003 = new JsonObject(); + fStockPlaceIdFF100003.addProperty("FNumber", cangWeiNum); + // + // fStockPlaceId.add("FSTOCKPLACEID__FF100002", fStockPlaceIdFF100002); + fStockPlaceId.add("FSTOCKPLACEID__FF100003", fStockPlaceIdFF100003); subHeadEntity1.add("FStockPlaceId", fStockPlaceId); model.add("SubHeadEntity1", subHeadEntity1); @@ -1150,7 +1295,7 @@ public class JdUtil { json.add("Model", model); String data = json.toString(); String result = api.save("BD_Material", data); - + Gson gson = new Gson(); RepoRet sRet = gson.fromJson(result, RepoRet.class); if (sRet.isSuccessfully()) { @@ -1163,6 +1308,36 @@ public class JdUtil { return errorMessage; } } + public static void updateDanzhong(int FMATERIALID, String danzhong) throws Exception { + K3CloudApi api = new K3CloudApi(false); + JsonObject json = new JsonObject(); + + // 创建 NeedUpDateFields 数组 + JsonArray needUpDateFields = new JsonArray(); + needUpDateFields.add("FMATERIALID"); + needUpDateFields.add("F_HBYT_DZ"); + + //needUpDateFields.add("FIsVmiBusiness"); + json.add("NeedUpDateFields", needUpDateFields); + // 添加 IsDeleteEntry 属性 + json.addProperty("IsDeleteEntry", "false"); + + JsonObject model = new JsonObject(); + model.addProperty("FMATERIALID", FMATERIALID); // 创建 Model 对象 + model.addProperty("F_HBYT_DZ", danzhong); + json.add("Model", model); + String data = json.toString(); + String result = api.save("BD_Material", data); + Gson gson = new Gson(); + RepoRet sRet = gson.fromJson(result, RepoRet.class); + if (sRet.isSuccessfully()) { + String successMessage = String.format("物料 %s 保存成功", sRet.getResult().getResponseStatus()); + System.out.println(successMessage); + } else { + String errorMessage = String.format("物料 %s 保存失败: %s", FMATERIALID, gson.toJson(sRet.getResult())); + System.out.println(errorMessage); + } + } //查询物料清单 的 行iD public static List getFID(String materialCode) { List jinYongDTOS = new ArrayList<>(); @@ -1306,7 +1481,6 @@ public class JdUtil { return null; // 如果没有找到,返回 null } - //保存更新生产订单的开工时间 public static String updateOrder(JdHuoZhu jdHuoZhu, Model numDTO, Date xuStartTime, Date xuEndTime) throws Exception { String planStartDate = dateFormat.format(xuStartTime); @@ -1433,8 +1607,8 @@ public class JdUtil { subHeadEntity1.addProperty("FIsEnableMaxStock", true); subHeadEntity1.addProperty("FIsEnableSafeStock", true); - subHeadEntity1.addProperty(" FMaxStock", FMaxStock); - subHeadEntity1.addProperty(" FSafeStock", FSafeStock); + subHeadEntity1.addProperty("FMaxStock", FMaxStock); + subHeadEntity1.addProperty("FSafeStock", FSafeStock); @@ -1456,14 +1630,14 @@ public class JdUtil { } } //获取用料清单 根据父级物料编码,作为bom校验使用 - public static List getSelectBomList(String FMaterialCode) { + public static List getSelectBomList(String FMaterialCode) { K3CloudApi client = new K3CloudApi(); // 请求参数,要求为json字符串 JsonObject json = new JsonObject(); - json.addProperty("FormId", "PRD_PPBOM"); + json.addProperty("FormId", "ENG_BOM"); json.addProperty("FieldKeys", - "FNumber,FMATERIALID.FNumber,FITEMNAME,FUNITID.FName,F_HBYT_CZ,FCHILDITEMNAME,FCHILDITEMPROPERTY,FCHILDUNITID.FName,FNUMERATOR,FDENOMINATOR,F_HBYT_BJBM,F_HBYT_BJMC"); + "FID,FMATERIALID.FNumber,FITEMNAME,FUNITID.FName,FCHILDITEMNAME,FCHILDITEMPROPERTY,FMATERIALIDCHILD.FNumber,FNUMERATOR,FDENOMINATOR,F_HBYT_BJBM,F_HBYT_BJMC"); JsonArray filterString = new JsonArray(); JsonObject filterObject = new JsonObject(); filterObject.addProperty("FieldName", "FMATERIALID.FNumber"); @@ -1473,6 +1647,14 @@ public class JdUtil { filterObject.addProperty("Right", ""); filterObject.addProperty("Logic", 0); filterString.add(filterObject); + JsonObject filterObjec1 = new JsonObject(); + filterObjec1.addProperty("FieldName", "FForbidStatus"); + filterObjec1.addProperty("Compare", "105"); + filterObjec1.addProperty("Value", "A"); + filterObjec1.addProperty("Left", ""); + filterObjec1.addProperty("Right", ""); + filterObjec1.addProperty("Logic", 0); + filterString.add(filterObjec1); json.add("FilterString", filterString); json.addProperty("OrderString", ""); json.addProperty("TopRowCount", 0); @@ -1485,14 +1667,289 @@ public class JdUtil { try { // 调用API接口 resultJson = String.valueOf(client.billQuery(jsonData)); - JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class); - // 将JsonArray转为PlanOrder列表 - ObjectMapper objectMapper = new ObjectMapper(); - return objectMapper.readValue(jsonArray.toString(), new TypeReference>() { - }); + // 将JsonArray转为JdValidateBomDTO列表 + return JdUtil.transformToJdValidateBomDTO(resultJson); } catch (Exception e) { e.printStackTrace(); return null; } } + public static String updateOldFuNumber(String FMATERIALID, String FNumber, String FOldNumber) throws Exception { + K3CloudApi api = new K3CloudApi(false); + JsonObject json = new JsonObject(); + + // 创建 NeedUpDateFields 数组 + JsonArray needUpDateFields = new JsonArray(); + needUpDateFields.add("FMATERIALID"); + needUpDateFields.add("FNumber"); + needUpDateFields.add("FOldNumber"); + json.add("NeedUpDateFields", needUpDateFields); + + // 添加 IsDeleteEntry 属性 + json.addProperty("IsDeleteEntry", "false"); + + // 创建 Model 对象 + JsonObject model = new JsonObject(); + model.addProperty("FMATERIALID", FMATERIALID); + model.addProperty("FNumber", FNumber); + model.addProperty("FOldNumber", FOldNumber); + json.add("Model", model); + String data = json.toString(); + String result = api.save("BD_Material", data); + + Gson gson = new Gson(); + RepoRet sRet = gson.fromJson(result, RepoRet.class); + if (sRet.isSuccessfully()) { + String successMessage = String.format("物料 %s 保存成功", sRet.getResult().getResponseStatus()); + return successMessage; + } else { + String errorMessage = String.format("物料 %s 保存失败: %s", FMATERIALID, gson.toJson(sRet.getResult())); + return errorMessage; + } + } + + public static List transformToJdValidateBomDTO(String jsonData) { + try { + ObjectMapper objectMapper = new ObjectMapper(); + JsonArray jsonArray = new Gson().fromJson(jsonData, JsonArray.class); + + Map bomMap = new HashMap<>(); + + for (JsonElement element : jsonArray) { + JsonObject obj = element.getAsJsonObject(); + + String key = obj.get("FID").getAsString() + "_" + + obj.get("FMATERIALID.FNumber").getAsString() + "_" + + obj.get("FITEMNAME").getAsString(); + JdValidateBomDTO parentDTO = bomMap.computeIfAbsent(key, k -> { + JdValidateBomDTO dto = new JdValidateBomDTO(); + dto.setFID(obj.get("FID").getAsString()); + dto.setFNumber(obj.get("FMATERIALID.FNumber").getAsString()); + dto.setFName(obj.get("FITEMNAME").getAsString()); + dto.setChilds(new ArrayList<>()); + return dto; + }); + + JdChildDTO childDTO = new JdChildDTO(); + childDTO.setPartdiagramCode(obj.get("F_HBYT_BJBM").getAsString()); + childDTO.setPartdiagramName(obj.get("F_HBYT_BJMC").getAsString()); + childDTO.setWareHouse(obj.get("FUNITID.FName").getAsString()); + childDTO.setPartNumber(obj.get("FMATERIALIDCHILD.FNumber").getAsString()); + childDTO.setName(obj.get("FCHILDITEMNAME").getAsString()); + childDTO.setStats(obj.get("FCHILDITEMPROPERTY").getAsString()); + childDTO.setQuantity(obj.get("FNUMERATOR").getAsDouble()); + childDTO.setDenominator(obj.get("FDENOMINATOR").getAsDouble()); + + parentDTO.getChilds().add(childDTO); + } + + return new ArrayList<>(bomMap.values()); + + } catch (Exception e) { + e.printStackTrace(); + return new ArrayList<>(); + } + } + /** + * 获取生产用料清单 + * @param F_HBYT_SCLH + * @return + */ + public static List getPRD_PPBOM(String F_HBYT_SCLH) { + + K3CloudApi client = new K3CloudApi(); + + // 请求参数,要求为json字符串 + JsonObject json = new JsonObject(); + json.addProperty("FormId", "PRD_PPBOM"); + json.addProperty("FieldKeys", + "F_HBYT_SCLH,FMaterialID.FNumber,FMaterialName,FUnitID2.FName,FMaterialID2.FNumber,FMaterialName1,FNumerator,FDenominator,FMustQty,FPickedQty,F_HBYT_CZ,F_HBYT_DZ"); + // 创建过滤条件 + JsonArray filterString = new JsonArray(); + JsonObject filterObject = new JsonObject(); + filterObject.addProperty("FieldName", "F_HBYT_SCLH"); + filterObject.addProperty("Compare", "67"); + filterObject.addProperty("Value", F_HBYT_SCLH); + filterObject.addProperty("Left", ""); + filterObject.addProperty("Right", ""); + filterObject.addProperty("Logic", 0); + filterString.add(filterObject); + json.add("FilterString", filterString); + json.addProperty("OrderString", ""); + json.addProperty("TopRowCount", 0); + json.addProperty("StartRow", 0); + json.addProperty("Limit", 2000); + json.addProperty("SubSystemId", ""); + + String jsonData = json.toString(); + List materialUsageDTO2List = null; + try { + // 调用接口 + String resultJson = String.valueOf(client.billQuery(jsonData)); + JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class); + + // 使用 ObjectMapper 将 JsonArray 转换为 List + ObjectMapper objectMapper = new ObjectMapper(); + materialUsageDTO2List = objectMapper.readValue(jsonArray.toString(), + new TypeReference>() { + }); + + } catch (Exception e) { + e.printStackTrace(); // 输出异常日志 + } + + return materialUsageDTO2List; // 返回结果 + } + //用料清单查询接口腹肌无聊 + public static List getEngBom(String materialCode) { + List jinYongDTOS = new ArrayList<>(); + K3CloudApi client = new K3CloudApi(); + JsonObject json = new JsonObject(); + json.addProperty("FormId", "ENG_BOM"); + json.addProperty("FieldKeys", "FNumber"); + + JsonArray filterString = new JsonArray(); + JsonObject filterObject = new JsonObject(); + filterObject.addProperty("FieldName", "FMATERIALIDCHILD.FNumber"); + filterObject.addProperty("Compare", "="); + filterObject.addProperty("Value", materialCode); + filterObject.addProperty("Left", ""); + filterObject.addProperty("Right", ""); + filterObject.addProperty("Logic", 0); + filterString.add(filterObject); + + json.add("FilterString", filterString); + json.addProperty("OrderString", ""); + json.addProperty("TopRowCount", 0); + json.addProperty("StartRow", 0); + json.addProperty("Limit", 2000); + json.addProperty("SubSystemId", ""); + + String jsonData = json.toString(); + try { + String resultJson = String.valueOf(client.billQuery(jsonData)); + JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class); + + if (jsonArray != null && jsonArray.size() > 0) { + ObjectMapper objectMapper = new ObjectMapper(); + List JinYongDTOList = objectMapper.readValue(jsonArray.toString(), + new TypeReference>() {}); + if (JinYongDTOList != null && !JinYongDTOList.isEmpty()) { + jinYongDTOS.addAll(JinYongDTOList); + } + } else { + log.warn("未找到与bom版本号 " + materialCode + " 相关的记录"); + } + } catch (Exception e) { + log.error("调用接口时发生异常: " + e.getMessage(), e); + } + + return jinYongDTOS; + } + + + /** + * 获取固定工艺路线 + * @param FMaterialCode + * @return + */ + public static List getRouteGuDing(String FMaterialCode) { + K3CloudApi client = new K3CloudApi(); + // 请求参数,要求为json字符串 + JsonObject json = new JsonObject(); + json.addProperty("FormId", "ENG_Route"); + + json.addProperty("FieldKeys", + "FNumber,FOperNumber,FWorkCenterId.FName,FProcessId.FName,FOperDescription,FOptCtrlCodeId.FName,FActivity1Qty,FActivity1UnitID.FName"); + JsonArray filterString = new JsonArray(); + JsonObject filterObject = new JsonObject(); + filterObject.addProperty("FieldName", "FMATERIALID.FNumber"); + filterObject.addProperty("Compare", "67"); + filterObject.addProperty("Value", FMaterialCode); + filterObject.addProperty("Left", ""); + filterObject.addProperty("Right", ""); + filterObject.addProperty("Logic", 0); + filterString.add(filterObject); + JsonObject filterObject1 = new JsonObject(); + filterObject1.addProperty("FieldName", "FForbidStatus"); + filterObject1.addProperty("Compare", "105"); + filterObject1.addProperty("Value", "A"); + filterObject1.addProperty("Left", ""); + filterObject1.addProperty("Right", ""); + filterObject1.addProperty("Logic", 0); + filterString.add(filterObject1); + json.add("FilterString", filterString); + json.addProperty("OrderString", ""); + json.addProperty("TopRowCount", 0); + json.addProperty("StartRow", 0); + json.addProperty("Limit", 2000); + json.addProperty("SubSystemId", ""); + + String jsonData = json.toString(); + try { + String resultJson = String.valueOf(client.billQuery(jsonData)); + JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class); + + if (jsonArray != null && jsonArray.size() > 0) { + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.readValue(jsonArray.toString(), new TypeReference>() {}); + } else { + return Collections.emptyList(); + } + } catch (Exception e) { + log.error("调用接口时发生异常: " + e.getMessage(), e); + } + return Collections.emptyList(); + } + /** + * 获取物料清单 + * @param FMaterialCode + * @return + */ + public static List getMaterialUseX(String FMaterialCode) { + K3CloudApi client = new K3CloudApi(); + // 请求参数,要求为json字符串 + JsonObject json = new JsonObject(); + json.addProperty("FormId", "ENG_BOM"); + json.addProperty("FieldKeys", "FNumber,FMATERIALIDCHILD.FNumber,FCHILDITEMNAME,FCHILDUNITID.FName,FNUMERATOR,FDENOMINATOR,F_HBYT_DZ,F_HBYT_CZ"); + JsonArray filterString = new JsonArray(); + JsonObject filterObject = new JsonObject(); + filterObject.addProperty("FieldName", "FMATERIALID.FNumber"); + filterObject.addProperty("Compare", "67"); + filterObject.addProperty("Value", FMaterialCode); + filterObject.addProperty("Left", ""); + filterObject.addProperty("Right", ""); + filterObject.addProperty("Logic", 0); + filterString.add(filterObject); + JsonObject filterObject1 = new JsonObject(); + filterObject1.addProperty("FieldName", "FForbidStatus"); + filterObject1.addProperty("Compare", "105"); + filterObject1.addProperty("Value", "A"); + filterObject1.addProperty("Left", ""); + filterObject1.addProperty("Right", ""); + filterObject1.addProperty("Logic", 0); + filterString.add(filterObject1); + json.add("FilterString", filterString); + json.addProperty("OrderString", ""); + json.addProperty("TopRowCount", 0); + json.addProperty("StartRow", 0); + json.addProperty("Limit", 2000); + json.addProperty("SubSystemId", ""); + + String jsonData = json.toString(); + try { + String resultJson = String.valueOf(client.billQuery(jsonData)); + JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class); + if (jsonArray != null && jsonArray.size() > 0) { + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.readValue(jsonArray.toString(), new TypeReference>() {}); + } else { + return Collections.emptyList(); + } + } catch (Exception e) { + log.error("调用接口时发生异常: " + e.getMessage(), e); + } + return Collections.emptyList(); + } + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/IProcessRouteService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/IProcessRouteService.java index 8249a6c..ea73808 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/IProcessRouteService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/IProcessRouteService.java @@ -39,7 +39,7 @@ public interface IProcessRouteService { /** * 查询工艺路线列表 */ - List queryList(ProcessRouteBo bo); + List queryList(ProcessRouteBo bo); /** * 新增工艺路线 @@ -119,6 +119,7 @@ public interface IProcessRouteService { boolean isAnTuDingGou(String materialCode); List getSelectProcessRoute(String materilCode); + List getSelectStandProcessRoute(String materilCode); //根据项目令号删除 材料bom 总装bom 工艺路线 R selectByProjectCode(String productionOrderNo); @@ -134,4 +135,8 @@ public interface IProcessRouteService { List updateProcesTime(String rooteProdet) throws Exception; List queryList2(ProcessRouteBo bo); + + List getProcessMaterialListAll(String routeDescription); + + List getProcessRouteGD(List list); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISafetyStockService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISafetyStockService.java index 4e857b4..8deac15 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISafetyStockService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISafetyStockService.java @@ -2,6 +2,7 @@ package com.ruoyi.system.service; import com.ruoyi.common.core.domain.PageQuery; import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.system.domain.SafetyStock; import com.ruoyi.system.domain.bo.SafetyStockBo; import com.ruoyi.system.domain.vo.SafetyStockVo; @@ -45,4 +46,6 @@ public interface ISafetyStockService { * 校验并批量删除安全库存信息 */ Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + List selectByType(String type1); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/BomDetailsServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/BomDetailsServiceImpl.java index 84c0a53..e97fa75 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/BomDetailsServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/BomDetailsServiceImpl.java @@ -12,11 +12,14 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ruoyi.system.controller.BomDetailsController; +import com.ruoyi.system.domain.MaterialBom; import com.ruoyi.system.domain.MaterialProperties; +import com.ruoyi.system.mapper.MaterialBomMapper; import com.ruoyi.system.service.IMaterialPropertiesService; import lombok.RequiredArgsConstructor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.ruoyi.system.domain.bo.BomDetailsBo; import com.ruoyi.system.domain.vo.BomDetailsVo; @@ -27,6 +30,7 @@ import com.ruoyi.system.service.IBomDetailsService; import java.util.List; import java.util.Map; import java.util.Collection; +import java.util.stream.Collectors; import static org.aspectj.bridge.MessageUtil.fail; @@ -43,7 +47,8 @@ public class BomDetailsServiceImpl implements IBomDetailsService { private final BomDetailsMapper baseMapper; private final IMaterialPropertiesService iMaterialPropertiesService; private static final Logger log = LoggerFactory.getLogger(BomDetailsController.class); - + @Autowired + MaterialBomMapper materialBomMapper; /** * 查询bom明细 */ @@ -186,14 +191,41 @@ public class BomDetailsServiceImpl implements IBomDetailsService { * @param totalWeight * @return */ - @Override public List selectByFNumberAndTotalWeight(String fnumber, String totalWeight) { + // 查询 BomDetails LambdaQueryWrapper bomDetailsLambdaQueryWrapper = new LambdaQueryWrapper<>(); - bomDetailsLambdaQueryWrapper.eq(BomDetails::getTotalWeight,totalWeight) - .eq(BomDetails::getFNumber,fnumber); - return baseMapper.selectList(bomDetailsLambdaQueryWrapper); + bomDetailsLambdaQueryWrapper.eq(BomDetails::getTotalWeight, totalWeight) + .eq(BomDetails::getFNumber, fnumber); + List bomDetails = baseMapper.selectList(bomDetailsLambdaQueryWrapper); + + // 查询 MaterialBom + LambdaQueryWrapper materialBomLambdaQueryWrapper = new LambdaQueryWrapper<>(); + materialBomLambdaQueryWrapper.eq(MaterialBom::getParentMaterialCode, fnumber) + .eq(MaterialBom::getProjectNumber, totalWeight); + List materialBoms = materialBomMapper.selectList(materialBomLambdaQueryWrapper); + + // 使用Map缓存MaterialBom,避免双重循环带来的性能问题 + if (!materialBoms.isEmpty() && !bomDetails.isEmpty()) { + Map materialBomMap = materialBoms.stream() + .collect(Collectors.toMap( + mb -> mb.getMaterialCode() + "-" + mb.getMaterialName(), + mb -> mb, + (existing, replacement) -> existing + )); + + for (BomDetails bomDetail : bomDetails) { + String key = bomDetail.getPartNumber() + "-" + bomDetail.getName(); + MaterialBom matchedMaterialBom = materialBomMap.get(key); + if (matchedMaterialBom != null) { + bomDetail.setQuantity(Double.valueOf(String.valueOf(matchedMaterialBom.getQuantity()))); + } + } + } + + return bomDetails; } + public int loadMaterialPreservation(BomDetails bomDetails1) { K3CloudApi client = new K3CloudApi(); // 创建一个空的JsonObject diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/EleMaterialsServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/EleMaterialsServiceImpl.java index c651c8d..bc9aec8 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/EleMaterialsServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/EleMaterialsServiceImpl.java @@ -17,6 +17,7 @@ import com.ruoyi.system.runner.JdUtil; import com.ruoyi.system.service.IMaterialPropertiesService; import com.ruoyi.system.service.ISysDictDataService; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.aspectj.bridge.MessageUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,6 +43,7 @@ import java.util.*; */ @RequiredArgsConstructor @Service + public class EleMaterialsServiceImpl implements IEleMaterialsService { private final EleMaterialsMapper baseMapper; @@ -334,7 +336,7 @@ public class EleMaterialsServiceImpl implements IEleMaterialsService { // 创建一个空的JsonObject JsonObject json = new JsonObject(); // 添加IsAutoSubmitAndAudit字段 - json.addProperty("IsAutoSubmitAndAudit", "true"); + json.addProperty("IsAutoSubmitAndAudit", "false"); // 创建Model对象,并加入JsonObject JsonObject model = new JsonObject(); diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ImMaterialServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ImMaterialServiceImpl.java index f3c9d89..98ef949 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ImMaterialServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ImMaterialServiceImpl.java @@ -20,6 +20,10 @@ import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.controller.ImMaterialController; import com.ruoyi.system.domain.ImMaterial; import com.ruoyi.system.domain.bo.ImMaterialBo; +import com.ruoyi.system.domain.dto.JDInventoryDTO; +import com.ruoyi.system.domain.dto.JDProductionDTO; +import com.ruoyi.system.domain.dto.ProMoDTO; +import com.ruoyi.system.domain.dto.PurchaseOrderDTO; import com.ruoyi.system.domain.vo.ImMaterialVo; import com.ruoyi.system.mapper.ImMaterialMapper; import com.ruoyi.system.runner.JdUtil; @@ -71,7 +75,7 @@ public class ImMaterialServiceImpl implements IImMaterialService { // 添加额外的过滤条件,排除售后库 JsonObject excludeStockFilter = new JsonObject(); excludeStockFilter.addProperty("FieldName", "FStockId.FNumber"); // 设置字段名称为仓库编号 - excludeStockFilter.addProperty("Compare", "83"); // 设置比较方式为“不等于” (假设 83 代表不等于) + excludeStockFilter.addProperty("Compare", "83"); // 设置比较方式为"不等于" (假设 83 代表不等于) excludeStockFilter.addProperty("Value", "CK012"); // 设置需要排除的仓库编号 excludeStockFilter.addProperty("Left", ""); // 保留字段,不使用 excludeStockFilter.addProperty("Right", ""); // 保留字段,不使用 @@ -81,7 +85,7 @@ public class ImMaterialServiceImpl implements IImMaterialService { ImMaterialVo record = records.get(i); JsonObject filterObject = new JsonObject(); // 每次循环创建新的过滤条件对象 filterObject.addProperty("FieldName", "FMaterialId.FNumber"); // 设置字段名称为物料编码 - filterObject.addProperty("Compare", "67"); // 设置比较方式为“等于” (假设 67 代表等于) + filterObject.addProperty("Compare", "67"); // 设置比较方式为"等于" (假设 67 代表等于) filterObject.addProperty("Value", record.getMaterialCode()); // 设置比较的值为物料编码 // 为第一个和最后一个元素设置括号 if (i == 0) { @@ -171,6 +175,7 @@ public class ImMaterialServiceImpl implements IImMaterialService { public TableDataInfo queryPageList(ImMaterialBo bo, PageQuery pageQuery) { try { + System.out.println("查询开始"+System.currentTimeMillis()); LambdaQueryWrapper lqw = buildQueryWrapper(bo); // 执行查询 @@ -179,8 +184,11 @@ public class ImMaterialServiceImpl implements IImMaterialService { if (CollectionUtils.isEmpty(result.getRecords())) { return TableDataInfo.build(result); // 如果结果为空,直接返回 } + System.out.println("查询结束"+System.currentTimeMillis()); // 调用库存查询方法,优化为批量查询而非逐个查询 Map jsonMap = queryAllKuCun(result.getRecords()); + System.out.println("组装结束"+System.currentTimeMillis()); + // 更新库存信息 updateRecordsWithKuCunInfo(jsonMap, result.getRecords()); // 更新数量,更新实体类 @@ -268,9 +276,7 @@ public class ImMaterialServiceImpl implements IImMaterialService { for (JsonElement jsonElement : jsonArray) { JsonObject jsonObject = jsonElement.getAsJsonObject(); String materialCode = jsonObject.get("FMaterialId.FNumber").getAsString(); - BigDecimal lockQty = Optional.ofNullable(jsonObject.get("FLockQty")) - .map(JsonElement::getAsBigDecimal) - .orElse(BigDecimal.ZERO); + BigDecimal lockQty = Optional.ofNullable(jsonObject.get("FLockQty")).map(JsonElement::getAsBigDecimal).orElse(BigDecimal.ZERO); lockStockMap.merge(materialCode, lockQty, BigDecimal::add); } } @@ -286,8 +292,6 @@ public class ImMaterialServiceImpl implements IImMaterialService { * @return */ private void updateRecordsWithKuCunInfo(Map jsonMap, List records) { - // 先查询锁库信息 - Map lockStockMap = queryLockStock(records); for (ImMaterialVo record : records) { String materialCode = record.getMaterialCode(); JsonObject jsonObject = jsonMap.get(materialCode); @@ -299,31 +303,26 @@ public class ImMaterialServiceImpl implements IImMaterialService { String unit = jsonObject.get("FStockUnitId.FName").getAsString(); if (unit != null && !unit.isEmpty()) { record.setClassificationName(unit); - }else { + } else { record.setClassificationName("件"); } - JsonElement qualityElement = jsonObject.get("F_UCHN_BaseProperty"); - if (qualityElement != null && !qualityElement.isJsonNull()) { - record.setMaterialQuality(qualityElement.getAsString()); + JsonElement qualityElement = jsonObject.get("F_UCHN_BaseProperty"); + if (qualityElement != null && !qualityElement.isJsonNull()) { + record.setMaterialQuality(qualityElement.getAsString()); + } else { + record.setMaterialQuality(""); + } } else { record.setMaterialQuality(""); } - } else { - record.setMaterialQuality(""); - } - // 计算可用库存 - BigDecimal totalLockQty = lockStockMap.getOrDefault(materialCode, BigDecimal.ZERO); - BigDecimal unit = Optional.ofNullable(record.getUnit()) - .map(NumberUtils::createBigDecimal) - .orElse(BigDecimal.ZERO); + // 使用keYong方法计算可用库存 + ImMaterial material = BeanUtil.toBean(record, ImMaterial.class); + /* double availableStock = keYong(material); + record.setSingleWeight(BigDecimal.valueOf(availableStock));*/ - // 计算 subtract,如果 totalLockQty 是 0 或者为空,subtract 就是 unit - BigDecimal subtract = unit.subtract(totalLockQty); - record.setSingleWeight(subtract); // 可用数量 - - // 仅当记录确实需要更新时执行更新操作 + // 更新记录 ImMaterial bean = BeanUtil.toBean(record, ImMaterial.class); baseMapper.updateById(bean); } @@ -336,6 +335,46 @@ public class ImMaterialServiceImpl implements IImMaterialService { public ImMaterialVo queryById(Long id) { return baseMapper.selectVoById(id); } + /** + * 计算可用库存 + */ + + public double keYong(ImMaterial material) { + // 获取库存 + System.out.println("查询可用库存开始=============>"+System.currentTimeMillis()); + double inventoryQty = Optional.ofNullable(JdUtil.getKuCun(material.getMaterialCode())) + .map(list ->list.stream() + .mapToDouble(JDInventoryDTO::getFBaseQty) + .sum()) + .orElse(0.0); + System.out.println("查询子项物料的未领料量=============>"+System.currentTimeMillis()); + // 查询子项物料的未领料量 + + double fNoPickedQty = Optional.ofNullable(JdUtil.getWeiLingliao(material.getMaterialCode())) + .map(list ->list.stream() + .mapToDouble(JDProductionDTO::getFNoPickedQty) + .sum()) + .orElse(0.0); + + System.out.println("获取生产订单未入库数量数量=============>"+System.currentTimeMillis()); + // 获取生产订单未入库数量数量 + double productionQty = Optional.ofNullable(JdUtil.getProMoList(material.getMaterialCode())) + .map(list -> list.stream() + .mapToDouble(ProMoDTO::getFQty) + .sum()) + .orElse(0.0); + System.out.println("获取采购订单未入库数量=============>"+System.currentTimeMillis()); + // 获取采购订单未入库数量 + double purchaseQty = Optional.ofNullable(JdUtil.getPurchaseOrderList(material.getMaterialCode())) + .map(list -> list.stream() + .mapToDouble(PurchaseOrderDTO::getFRemainStockINQty) + .sum()) + .orElse(0.0); + // 计算预计可用库存 + System.out.println("计算预计可用库存=============>"+System.currentTimeMillis()); + return inventoryQty + productionQty + purchaseQty - fNoPickedQty; + + } /** diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ProcessOrderProServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ProcessOrderProServiceImpl.java index 531be48..3ccd276 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ProcessOrderProServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ProcessOrderProServiceImpl.java @@ -7,6 +7,7 @@ import com.ruoyi.common.core.domain.PageQuery; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.ruoyi.common.utils.file.SmbUtil; import com.ruoyi.system.domain.EleMaterials; import com.ruoyi.system.domain.ProcessRoute; import com.ruoyi.system.mapper.ProcessRouteMapper; @@ -87,6 +88,10 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService { */ @Override public Boolean insertByBo(ProcessOrderProBo bo) { + // 下载excel文件 + log.info("下载excel文件.."+bo.getProductionOrderNo()); + SmbUtil.downloadExcelFiles(bo.getProductionOrderNo()); + ProcessOrderPro add = BeanUtil.toBean(bo, ProcessOrderPro.class); validEntityBeforeSave(add); @@ -160,7 +165,6 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper eq = wrapper.eq(ProcessRoute::getProcessDescription, bo.getProductionOrderNo()); List processRoutes = processRouteMapper.selectList(wrapper); - System.out.println(processRoutes); return processRouteMapper.selectList(wrapper); } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ProcessRouteServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ProcessRouteServiceImpl.java index c184a64..8d0b54e 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ProcessRouteServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ProcessRouteServiceImpl.java @@ -2,6 +2,7 @@ package com.ruoyi.system.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; @@ -44,13 +45,16 @@ import org.aspectj.bridge.MessageUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.annotation.LastModifiedDate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.math.BigDecimal; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.concurrent.*; +import java.util.function.Function; import java.util.stream.Collectors; import static com.ruoyi.system.controller.BomDetailsController.*; @@ -82,6 +86,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { @Autowired ProcessInfoMapper processInfoMapper; + private final ProductionRouteTwoMapper productionRouteTwoMapper; private final IBomDetailsService bomDetailsService; @@ -125,9 +130,9 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { } @Override - public List queryList(ProcessRouteBo bo) { + public List queryList(ProcessRouteBo bo) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); - List sortedList = new ArrayList<>(); + List sortedList = new ArrayList<>(); // 获取工艺表中材质为总装部件的物料编码和名称 LambdaQueryWrapper lqwRoute = buildQueryWrapper(bo); @@ -138,16 +143,11 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { if (!processRoutes.isEmpty()) { // 装配工艺路线 for (ProcessRoute processRoute : processRoutes) { - List routes1 = getProcessRoutesByOrder(processRoute.getRouteDescription(), - processRoute.getMaterialCode()); - for (ProcessRoute route : routes1) { - ProcessRouteVo processRouteVo1 = BeanUtil.copyProperties(route, ProcessRouteVo.class); - sortedList.add(processRouteVo1); - } + List routes1 = getProcessRoutesByOrder(processRoute.getRouteDescription(), processRoute.getMaterialCode()); + sortedList.addAll(routes1); // 查询 BOM 详情 - List bomDetails1 = bomDetailsService.selectByFNumberAndTotalWeight( - processRoute.getMaterialCode(), processRoute.getRouteDescription()); + List bomDetails1 = bomDetailsService.selectByFNumberAndTotalWeight(processRoute.getMaterialCode(), processRoute.getRouteDescription()); List filteredBomDetails = filterBomDetails(bomDetails1); log.info("过滤后的 BOM 详情数量: {}", filteredBomDetails.size()); @@ -158,8 +158,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { // 将组焊件写入工艺 if ("组焊件".equals(bomDetail.getMaterial())) { - List bomDetails = bomDetailsService - .selectByFNumberAndTotalWeight(bomDetail.getPartNumber(), bomDetail.getTotalWeight()); + List bomDetails = bomDetailsService.selectByFNumberAndTotalWeight(bomDetail.getPartNumber(), bomDetail.getTotalWeight()); for (BomDetails detail : bomDetails) { addProcessRoutesFromBomDetail(detail, sortedList); } @@ -174,9 +173,9 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { Set addedKeys = new HashSet<>(); // 记录已添加的 BOM 详情键 - for (ProcessRoute processRoute : normalProcessRoutes) { + for (ProcessRoute processRoute : normalProcessRoutes) { // 创建一个新的 ProcessRouteVo 对象,并复制 ProcessRoute 的基本信息 - ProcessRouteVo processRouteVo = BeanUtil.copyProperties(processRoute, ProcessRouteVo.class); + ProcessRoute processRouteVo = BeanUtil.copyProperties(processRoute, ProcessRoute.class); processRouteVo.setRawMaterialName(null); processRouteVo.setRawMaterialCode(null); processRouteVo.setBomMaterial(null); @@ -194,7 +193,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { String key = generateKey1(bomDetail,processRoute); // 生成唯一键 if (!addedKeys.contains(key)) { // 创建一个新的 ProcessRouteVo 对象来存储 BOM 详情的信息 - ProcessRouteVo bomDetailsVo = new ProcessRouteVo(); + ProcessRoute bomDetailsVo = new ProcessRoute(); bomDetailsVo.setRouteDescription(bomDetail.getTotalWeight()); bomDetailsVo.setMaterialCode(bomDetail.getFNumber()); bomDetailsVo.setMaterialName(bomDetail.getFName()); @@ -204,9 +203,10 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { bomDetailsVo.setRawMaterialName(bomDetail.getName()); bomDetailsVo.setBomUnit(bomDetail.getWareHouse()); + // 找到对应的 ProcessRouteVo 位置并插入 for (int i = 0; i < sortedList.size(); i++) { - ProcessRouteVo existingVo = sortedList.get(i); + ProcessRoute existingVo = sortedList.get(i); if (existingVo.getMaterialCode().equals(bomDetailsVo.getMaterialCode()) && existingVo.getMaterialName().equals(bomDetailsVo.getMaterialName())) { sortedList.add(i, bomDetailsVo); // 插入到匹配的 ProcessRouteVo 之前 @@ -233,6 +233,50 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { return Collections.emptyList(); } + + /** + * @param routeDescription + * @return + */ + @Override + public List getProcessMaterialListAll(String routeDescription) { + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq("project_number", routeDescription); + + return materialBomMapper.selectList(wrapper); + } + + /** + * @param list + * @return + */ + @Override + public List getProcessRouteGD(List list) { + List materialAndRouteList = new ArrayList<>(); + for (ProcessRouteVo processRoute : list) { + //获取固定工艺路线和物料清单 + List routeList = JdUtil.getRouteGuDing(processRoute.getRouteDescription()); + List materialUseX = JdUtil.getMaterialUseX(processRoute.getRouteDescription()); + if (materialUseX == null || routeList == null) { + continue; + } + //表格错乱错行了 + + JDMaterialAndRoute jdMaterialAndRoute = new JDMaterialAndRoute(); + jdMaterialAndRoute.setMaterialCode(processRoute.getRouteDescription()); + jdMaterialAndRoute.setMaterialName(processRoute.getMaterialCode()); + jdMaterialAndRoute.setCaizhi(processRoute.getMaterialName()); + jdMaterialAndRoute.setDanzhong(processRoute.getMaterial()); + jdMaterialAndRoute.setMaterialUseDTOS(materialUseX); + jdMaterialAndRoute.setPlannedProcessVos(routeList); + jdMaterialAndRoute.setBenpi(processRoute.getUnitQuantity()); + jdMaterialAndRoute.setDantai(Long.valueOf(processRoute.getActivityUnit())); + materialAndRouteList.add(jdMaterialAndRoute); + } + + return materialAndRouteList; + } + private String generateKey1(BomDetails bomDetail,ProcessRoute processRoute) { return String.format("%s:%s:%s", processRoute.getMaterialCode(), processRoute.getMaterialName(), bomDetail.getName(),bomDetail.getPartNumber()); } @@ -246,12 +290,9 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { .collect(Collectors.toList()); } - private void addProcessRoutesFromBomDetail(BomDetails bomDetail, List sortedList) { + private void addProcessRoutesFromBomDetail(BomDetails bomDetail, List sortedList) { List routes = getProcessRoutesByOrder(bomDetail.getTotalWeight(), bomDetail.getPartNumber()); - for (ProcessRoute route : routes) { - ProcessRouteVo processRouteVo1 = BeanUtil.copyProperties(route, ProcessRouteVo.class); - sortedList.add(processRouteVo1); - } + sortedList.addAll(routes); } private LambdaQueryWrapper buildQueryWrapper(ProcessRouteBo bo) { @@ -501,13 +542,17 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { return true; } - public boolean saveData(List routeVoList, List productionOrderVos) { + public boolean saveData(List routeVoList, List productionOrderVos) { List processRoutes = BeanUtil.copyToList(routeVoList, ProcessRoute.class); + processMaterialBom(processRoutes); + List bomDetailsVos = processBomDetails(routeVoList, productionOrderVos); + saveBomDetails(bomDetailsVos); List routeArrayList = new ArrayList<>(); + Map inventoryCache = new HashMap<>(); // 批量查询所有需要的库存信息 @@ -635,6 +680,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { } } + private void processMaterialBom(List processRoutes) { for (ProcessRoute processRoute : processRoutes) { if (processRoute.getRawMaterialCode() != null && processRoute.getRawMaterialName() != null) { @@ -644,8 +690,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { String unit = processRoute.getBomUnit(); String materialType = processRoute.getBomMaterial(); Double quantity = processRoute.getDiscUsage() != null ? processRoute.getDiscUsage() : 0; - if (projectNumber == null || parentMaterialCode == null || parentMaterialName == null || unit == null - || materialType == null) { + if (projectNumber == null || parentMaterialCode == null || parentMaterialName == null || unit == null || materialType == null) { // 处理空值情况,例如记录日志或抛出异常 log.error("必填字段为空: {}", processRoute); continue; @@ -659,7 +704,8 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { materialBom.setMaterialName(processRoute.getRawMaterialName()); materialBom.setUnit(unit); materialBom.setMaterialType(materialType); - materialBom.setQuantity(String.valueOf(quantity)); + //保留4位小数 + materialBom.setQuantity(new BigDecimal(quantity)); // 这里插入 materialBom 数据 materialBomMapper.insert(materialBom); } @@ -671,9 +717,9 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { * * @routeVoList 工艺路线 */ - private List processBomDetails(List routeVoList, - List productionOrderVos) { + private List processBomDetails(List routeVoList, List productionOrderVos) { List bomDetailsVos = new ArrayList<>(); + //总装BOM if (productionOrderVos != null && !productionOrderVos.isEmpty()) { List productionOrderList = productionOrderVos.stream().map(productionOrderVo -> { ProductionOrder productionOrder = new ProductionOrder(); @@ -685,7 +731,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { boolean b = productionOrderMapper.insertBatch(productionOrderList); log.info("插入到装备BOM清单中: {}", b); - // 获取主产品图号 + // 处理总装BOM 将bom存表 bomdetail for (ProductionOrderVo productionOrderVo : productionOrderVos) { BomDetailsVo bomDetails = new BomDetailsVo(); bomDetails.setTotalWeight(productionOrderVo.getProductionOrderNo()); @@ -704,7 +750,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { } else { bomDetails.setRemarks(productionOrderVo.getRemark()); } - bomDetails.setDanzhong(productionOrderVo.getSingleWeight()); + bomDetails.setDanZhong(productionOrderVo.getSingleWeight()); // 判断外购或自制 String drawingNo = productionOrderVo.getDrawingNo(); String remark = productionOrderVo.getRemark(); @@ -720,6 +766,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { bomDetailsVos.add(bomDetails); } } + //将带工艺的bom 存表 bomdetail if (routeVoList != null && !routeVoList.isEmpty()) { for (ProcessRouteVo processRouteVo : routeVoList) { if (processRouteVo.getRawMaterialCode() != null && processRouteVo.getRawMaterialName() != null) { @@ -728,7 +775,6 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { } } } - return bomDetailsVos; // 如果需要返回结果 } @@ -745,7 +791,13 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { bomDetails.setFName(processRoute.getMaterialName()); bomDetails.setPartNumber(processRoute.getRawMaterialCode()); bomDetails.setName(processRoute.getRawMaterialName()); - bomDetails.setDanzhong(processRoute.getDiscWeight()); + + // 添加单重验证和日志 + Double discWeight = processRoute.getDiscWeight(); + + bomDetails.setDanZhong(discWeight); + bomDetails.setSingleWeghit(processRoute.getBomDanZhong()); + bomDetails.setMaterial(processRoute.getMaterial()); // 处理单位换算 if ("mm".equals(processRoute.getBomUnit())) { bomDetails.setQuantity(processRoute.getDiscUsage() / 1000.0); // 转换为米 @@ -769,45 +821,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { return bomDetails; } - private void createAssemblyBomDetails(String zFlinghao, String zFnumber, String zFname, - List productionOrderVos) { - List bomDetailsVos = new ArrayList<>(); - for (ProductionOrderVo productionOrderVo : productionOrderVos) { - if (productionOrderVo != null) { - BomDetailsVo bomDetails = new BomDetailsVo(); - bomDetails.setTotalWeight(zFlinghao); - bomDetails.setFNumber(zFnumber); - bomDetails.setFName(zFname); - bomDetails.setPartdiagramCode(productionOrderVo.getParentDrawingNo()); - bomDetails.setPartdiagramName(productionOrderVo.getParentPart()); - bomDetails.setPartNumber(productionOrderVo.getDrawingNo()); - bomDetails.setName(productionOrderVo.getDrawingName()); - bomDetails.setQuantity(productionOrderVo.getQuantity()); - bomDetails.setMaterial(productionOrderVo.getMaterial()); - bomDetails.setRemarks(productionOrderVo.getRemark()); - bomDetails.setDanzhong(productionOrderVo.getSingleWeight()); - // 判断外购或自制 - String drawingNo = productionOrderVo.getDrawingNo(); - String remark = productionOrderVo.getRemark(); - if (drawingNo != null) { - if ((isOutsourced(drawingNo) - || (remark != null && (remark.contains("外购件") || remark.contains("伊特"))) - || drawingNo.startsWith(" ")) || drawingNo.startsWith("009")) { - bomDetails.setStats("外购"); - } else { - bomDetails.setStats("自制"); - } - } - // iBomDetailsService.insertByVo(bomDetails); - bomDetailsVos.add(bomDetails); - } - - } - log.info("总装bom物料添加"); - - saveBomDetails(bomDetailsVos); - } public int loadMaterialPreservation(BomDetails bomDetails1, String states) { K3CloudApi client = new K3CloudApi(); @@ -1025,32 +1039,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { iBomDetailsService.insertByVo(BeanUtil.toBean(bomDetails, BomDetailsVo.class)); } - /* - * // 新增不存在的物料 - * for (BomDetails material : materialsToAdd) { - * if (material != null && material.getPartNumber() != null && - * material.getName() != null) { - * String state = determineState(material); - * log.info("开始新增不存在的物料 ==> 物料图号: " + material.getPartNumber() + " 物料名称: " + - * material.getName()); - * - * int result = loadMaterialPreservation(material, state); - * if (result == 1) { - * log.info("新增物料成功 ==> 物料图号: " + material.getPartNumber() + " 物料名称: " + - * material.getName()); - * material.setUnitWeight("新增成功"); - * } else { - * log.error("新增物料失败 ==> 物料图号: " + material.getPartNumber() + " 物料名称: " + - * material.getName()); - * } - * - * // 更新物料状态 - * iBomDetailsService.updateByBo(BeanUtil.toBean(material, BomDetailsBo.class)); - * } else { - * log.error("物料信息不完整,无法新增物料"); - * } - * } - */ + } @Override @@ -1117,6 +1106,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(ProcessRoute::getRouteDescription, rooteProdet).ne(ProcessRoute::getMaterialName, "") .ne(ProcessRoute::getProcessName, "按图订制") + .ne(ProcessRoute::getProcessName, "按图定制") .isNotNull(ProcessRoute::getMaterialName).ne(ProcessRoute::getMaterialCode, "") .isNotNull(ProcessRoute::getMaterialCode).ne(ProcessRoute::getProcessNo, "") .isNotNull(ProcessRoute::getProcessNo).ne(ProcessRoute::getProcessName, "") @@ -1165,8 +1155,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { * 查询这个项目下的所有工艺路线,材料bom ,原材料bom集合 */ public List getRawBomList(String rooteProdet) { - return baseMapper - .selectList(new LambdaQueryWrapper().eq(ProcessRoute::getRouteDescription, rooteProdet)); + return baseMapper.selectList(new LambdaQueryWrapper().eq(ProcessRoute::getRouteDescription, rooteProdet)); } @Override @@ -1252,8 +1241,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { return resultDTO; } - private boolean compareProcessRoutes(List processRouteDT, - Map> groupedByFNumber) { + private boolean compareProcessRoutes(List processRouteDT, Map> groupedByFNumber) { // 对当前物料的工艺路线进行排序 processRouteDT.sort(Comparator.comparing(ProcessRouteDTO::getProcessNo)); for (List jdRoutes : groupedByFNumber.values()) { @@ -1336,12 +1324,10 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { // 调用接口 String resultJson = String.valueOf(client.billQuery(jsonData)); JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class); - // 使用 ObjectMapper 将 JsonArray 转换为 List ObjectMapper objectMapper = new ObjectMapper(); List plannedProcessList = objectMapper.readValue(jsonArray.toString(), new TypeReference>() { - }); // 检查 plannedProcessList 是否为 null,避免空指针异常 @@ -1714,8 +1700,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { * 查询材料bom */ @Override - public List getProcessMaterialList(String materialCode, String materialName, - String productionOrderNo) { + public List getProcessMaterialList(String materialCode, String materialName, String productionOrderNo) { if (materialCode == null) { logger.error("做工艺的物料不存在"); throw new IllegalArgumentException("做工艺的物料不能为空"); @@ -2113,10 +2098,64 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { return null; } } + public List getSelectStandProcessRoute(String materialCode) { + K3CloudApi client = new K3CloudApi(); + // 请求参数,要求为json字符串 + JsonObject json = new JsonObject(); + json.addProperty("FormId", "ENG_Route"); + + json.addProperty("FieldKeys", + "FNumber,FMATERIALID.FNumber,FMATERIALNAME,FOperNumber,FProcessProperty,FWorkCenterId.FName,FOperDescription,FOptCtrlCodeId.FName,FActivity1Qty"); + JsonArray filterString = new JsonArray(); + JsonObject filterObject = new JsonObject(); + filterObject.addProperty("FieldName", "FMATERIALID.FNumber"); + filterObject.addProperty("Compare", "67"); + filterObject.addProperty("Value", materialCode); + filterObject.addProperty("Left", ""); + filterObject.addProperty("Right", ""); + filterObject.addProperty("Logic", 0); + filterString.add(filterObject); + JsonObject filterObject1 = new JsonObject(); + filterObject1.addProperty("FieldName", "FRouteGroupId.FName"); + filterObject1.addProperty("Compare", "17"); + filterObject1.addProperty("Value", "固定工艺"); + filterObject1.addProperty("Left", ""); + filterObject1.addProperty("Right", ""); + filterObject1.addProperty("Logic", 0); + filterString.add(filterObject1); + JsonObject filterObject2 = new JsonObject(); + filterObject2.addProperty("FieldName", "FForbidStatus"); + filterObject2.addProperty("Compare", "105"); + filterObject2.addProperty("Value", "A"); + filterObject2.addProperty("Left", ""); + filterObject2.addProperty("Right", ""); + filterObject2.addProperty("Logic", 0); + filterString.add(filterObject2); + json.add("FilterString", filterString); + json.addProperty("OrderString", ""); + json.addProperty("TopRowCount", 0); + json.addProperty("StartRow", 0); + json.addProperty("Limit", 2000); + json.addProperty("SubSystemId", ""); + + String jsonData = json.toString(); + String resultJson; + try { + // 调用API接口 + resultJson = String.valueOf(client.billQuery(jsonData)); + JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class); + // 将JsonArray转为PlanOrder列表 + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.readValue(jsonArray.toString(), new TypeReference>() { + }); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } /** * 根据项目令号删除 材料bom 总装bom 工艺路线 - * * @param productionOrderNo * @return */ diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SafetyStockServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SafetyStockServiceImpl.java index a5fde4b..aab5496 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SafetyStockServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SafetyStockServiceImpl.java @@ -23,10 +23,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; /** * 安全库存Service业务层处理 @@ -89,6 +86,9 @@ public class SafetyStockServiceImpl implements ISafetyStockService { lqw.like(StringUtils.isNotBlank(bo.getMaterialName()), SafetyStock::getMaterialName, bo.getMaterialName()); lqw.eq(bo.getMinSafetyStock() != null, SafetyStock::getMinSafetyStock, bo.getMinSafetyStock()); lqw.eq(bo.getMaxSafetyStock() != null, SafetyStock::getMaxSafetyStock, bo.getMaxSafetyStock()); + lqw.eq(bo.getWlMaterial() != null, SafetyStock::getWlMaterial, bo.getWlMaterial()); + lqw.eq(StringUtils.isNotBlank(bo.getType()), SafetyStock::getType, bo.getType()); + lqw.eq(StringUtils.isNotBlank(bo.getWlMaterial()), SafetyStock::getWlMaterial, bo.getWlMaterial()); return lqw; } @@ -133,6 +133,21 @@ public class SafetyStockServiceImpl implements ISafetyStockService { } return baseMapper.deleteBatchIds(ids) > 0; } + + /** + * @param type1 + * @return + */ + @Override + public List selectByType(String type1) { + if (type1 != null) { + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(SafetyStock::getType, type1); + return baseMapper.selectList(lqw); + } + return Collections.emptyList(); + } + /** * 物料批量查询 */ diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WlStockDataServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WlStockDataServiceImpl.java index fc7b089..b3c742c 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WlStockDataServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WlStockDataServiceImpl.java @@ -17,13 +17,12 @@ import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.domain.SafetyStock; import com.ruoyi.system.domain.WlStockData; import com.ruoyi.system.domain.bo.WlStockDataBo; -import com.ruoyi.system.domain.dto.InvReserveAnalyzeRptDTO; -import com.ruoyi.system.domain.dto.ProMoDTO; -import com.ruoyi.system.domain.dto.PurchaseOrderDTO; +import com.ruoyi.system.domain.dto.*; import com.ruoyi.system.domain.vo.WlStockDataVo; import com.ruoyi.system.mapper.SafetyStockMapper; import com.ruoyi.system.mapper.WlStockDataMapper; import com.ruoyi.system.runner.JdUtil; +import com.ruoyi.system.service.ISafetyStockService; import com.ruoyi.system.service.IWlStockDataService; import com.xxl.job.core.handler.annotation.XxlJob; import lombok.RequiredArgsConstructor; @@ -51,6 +50,7 @@ public class WlStockDataServiceImpl implements IWlStockDataService { private static final Logger logger = LoggerFactory.getLogger(WlStockDataServiceImpl.class); private final WlStockDataMapper baseMapper; private final SafetyStockMapper safetyStockMapper; + private final ISafetyStockService iSafetyStockService; private static final int MAX_RETRIES = 3; private static final long RETRY_DELAY = 2000L; // 2秒 @@ -94,11 +94,13 @@ public class WlStockDataServiceImpl implements IWlStockDataService { lqw.eq(StringUtils.isNotBlank(bo.getDocumentType()), WlStockData::getDocumentType, bo.getDocumentType()); lqw.eq(bo.getAvailableStock() != null, WlStockData::getAvailableStock, bo.getAvailableStock()); lqw.eq(bo.getSecAvbqty() != null, WlStockData::getSecAvbqty, bo.getSecAvbqty()); + lqw.eq( WlStockData::getSafeStatus, bo.getSafeStatus()); lqw.eq(bo.getProductionQty() != null, WlStockData::getProductionQty, bo.getProductionQty()); lqw.eq(bo.getPurchaseQty() != null, WlStockData::getPurchaseQty, bo.getPurchaseQty()); lqw.eq(bo.getSecQty() != null, WlStockData::getSecQty, bo.getSecQty()); lqw.eq(bo.getMaxsafetyStock() != null, WlStockData::getMaxsafetyStock, bo.getMaxsafetyStock()); lqw.eq(bo.getMinsafetyStock() != null, WlStockData::getMinsafetyStock, bo.getMinsafetyStock()); + lqw.eq(StringUtils.isNotBlank(bo.getWlMaterial()), WlStockData::getWlMaterial, bo.getWlMaterial()); return lqw; } @@ -230,8 +232,8 @@ public class WlStockDataServiceImpl implements IWlStockDataService { } } } - @XxlJob("generateDoc2") - public List generateDoc2() { + + public List generateDoc12() { List safetyStocks = safetyStockMapper.selectList(); if (CollectionUtils.isEmpty(safetyStocks)) { logger.warn("没有找到安全库存数据"); @@ -324,293 +326,115 @@ public class WlStockDataServiceImpl implements IWlStockDataService { } String materialCode = safetyStock.getMaterialCode(); - boolean isMainMaterial5 = "ELS-MJ.00.5".equals(materialCode); - boolean isMainMaterial9 = "ELS-MJ.00.9".equals(materialCode); - boolean isMainMaterial3WH = "ELS-MJ.00.3-WH".equals(materialCode); - boolean isMainMaterial3GY = "ELS-MJ.00.3-GY".equals(materialCode); - boolean isAssociatedMaterial5 = "ELS-MJ.00.6".equals(materialCode) || - "ELS-MJ.00.7".equals(materialCode) || - "ELS-MJ.00.8".equals(materialCode); - - boolean isAssociatedMaterial9 = "ELS-MJ.00.10".equals(materialCode) || - "ELS-MJ.00.12".equals(materialCode) || - "ELS-MJ.00.13".equals(materialCode) || - "ELS-MJ.00.14".equals(materialCode); - - boolean isAssociatedMaterial3WH = "ELS-MJ.00.4-WH".equals(materialCode); - boolean isAssociatedMaterial3GY = "ELS-MJ.00.4-GY".equals(materialCode); try { // 获取库存 - List analyzeRpt = JdUtil.getInvReserveAnalyzeRpt(materialCode); - double fSecAVBQty = 0.0; - double fSecQty = 0.0; + double inventoryQty = Optional.ofNullable(JdUtil.getKuCun(materialCode)) + .map(list ->list.stream() + .mapToDouble(JDInventoryDTO::getFBaseQty) + .sum()) + .orElse(0.0); + // 查询子项物料的未领料量 + double fNoPickedQty = Optional.ofNullable(JdUtil.getWeiLingliao(materialCode)) + .map(list ->list.stream() + .mapToDouble(JDProductionDTO::getFNoPickedQty) + .sum()) + .orElse(0.0); - if (!CollectionUtils.isEmpty(analyzeRpt)) { - fSecAVBQty = analyzeRpt.get(0).getFSecAVBQty(); - fSecQty = analyzeRpt.stream() - .mapToDouble(dto -> dto.getFSecQty() != null ? dto.getFSecQty() : 0.0) - .sum(); - } - - // 获取生产订单数量 + // 获取生产订单未入库数量数量 double productionQty = Optional.ofNullable(JdUtil.getProMoList(materialCode)) .map(list -> list.stream() .mapToDouble(ProMoDTO::getFQty) .sum()) .orElse(0.0); - // 获取采购订单数量 + // 获取采购订单未入库数量 double purchaseQty = Optional.ofNullable(JdUtil.getPurchaseOrderList(materialCode)) .map(list -> list.stream() - .mapToDouble(PurchaseOrderDTO::getFQty) + .mapToDouble(PurchaseOrderDTO::getFRemainStockINQty) .sum()) .orElse(0.0); - - // 计算可用库存 - double availableStock = fSecAVBQty + productionQty + purchaseQty - fSecQty; + // 计算预计可用库存 + double availableStock = inventoryQty + productionQty + purchaseQty - fNoPickedQty; double minSafetyStock = safetyStock.getMinSafetyStock(); double maxSafetyStock = safetyStock.getMaxSafetyStock(); - - logger.debug("物料编码:{}, 生产订单数量: {}, 采购订单数量: {}, 可用库存: {}", materialCode, productionQty, purchaseQty, availableStock); + logger.debug("物料编码:{},即时库存: {},用料清单未领料数量: {} 生产订单未入库数量: {}, 采购订单未入库数量: {}, 预计可用库存: {}", materialCode,inventoryQty, fNoPickedQty,productionQty, purchaseQty, availableStock); logMessages("物料编码:" + materialCode + ", 生产订单数量: " + productionQty + ", 采购订单数量: " + purchaseQty + ", 可用库存: " + availableStock); - - // 检查主物料是否满足条件 - if ((isMainMaterial5 && (fSecAVBQty <= 0 || fSecQty <= 0)) || - (isMainMaterial9 && (fSecAVBQty <= 0 || fSecQty <= 0)) || - (isMainMaterial3WH && (fSecAVBQty <= 0 || fSecQty <= 0)) || - (isMainMaterial3GY && (fSecAVBQty <= 0 || fSecQty <= 0))) { - logger.warn("物料 {} 不满足条件", materialCode); - return null; // 主物料不满足条件 - } - - // 如果主物料不满足条件,关联物料也不满足条件 - if ((isAssociatedMaterial5 || isAssociatedMaterial9 || isAssociatedMaterial3WH || isAssociatedMaterial3GY)) { - return null; // 关联物料不满足条件 - } - // 如果可用库存低于最小安全库存,创建库存数据记录 - if (availableStock < minSafetyStock) { - return createWlStockData(safetyStock, availableStock, fSecAVBQty, productionQty, purchaseQty, fSecQty, minSafetyStock, maxSafetyStock); - } + + //预计可用库存 + return createWlStockData(safetyStock, availableStock,inventoryQty, fNoPickedQty, productionQty, purchaseQty, minSafetyStock, maxSafetyStock); } catch (Exception e) { logger.error("处理物料编码时出错: {}", materialCode, e); logMessages("处理物料编码时出错: " + materialCode); throw e; // 抛出异常以触发重试机制 + } - return null; + } - private WlStockData createWlStockData(SafetyStock safetyStock, double availableStock, double fSecAVBQty, double productionQty, double purchaseQty, double fSecQty, double minSafetyStock, double maxSafetyStock) { - //创建安全库存单据 - WlStockData wlStockData = new WlStockData(); - wlStockData.setMaterialCode(safetyStock.getMaterialCode()); - wlStockData.setMaterialName(safetyStock.getMaterialName()); - wlStockData.setRequiredStock(maxSafetyStock); - wlStockData.setCurrentStock(availableStock); - wlStockData.setTriggerTime(new Date()); - wlStockData.setAvailableStock(BigDecimal.valueOf(availableStock)); - wlStockData.setProductionQty(BigDecimal.valueOf(productionQty)); - wlStockData.setPurchaseQty(BigDecimal.valueOf(purchaseQty)); - wlStockData.setSecQty(BigDecimal.valueOf(fSecQty)); - wlStockData.setMinsafetyStock(BigDecimal.valueOf(minSafetyStock)); - wlStockData.setMaxsafetyStock(BigDecimal.valueOf(maxSafetyStock)); - wlStockData.setSecAvbqty(BigDecimal.valueOf(fSecAVBQty)); + private WlStockData createWlStockData(SafetyStock safetyStock, double availableStock, double inventoryQty, double fNoPickedQty, double productionQty, double purchaseQty, double minSafetyStock, double maxSafetyStock) { + if (availableStock < minSafetyStock) { + //创建安全库存单据 + WlStockData wlStockData = new WlStockData(); + wlStockData.setMaterialCode(safetyStock.getMaterialCode()); + wlStockData.setWlMaterial(safetyStock.getType()); + //将相同类型的物料也要生成WlStockData ,如果有就不生成了 + + wlStockData.setMaterialName(safetyStock.getMaterialName()); + wlStockData.setDocumentType(safetyStock.getWlMaterial()); + wlStockData.setRequiredStock(maxSafetyStock); + //预计可用量 + wlStockData.setCurrentStock(availableStock); + wlStockData.setTriggerTime(new Date()); + //用料清单未领料数量 + wlStockData.setAvailableStock(BigDecimal.valueOf(fNoPickedQty)); + //生产订单未入库数量 + wlStockData.setProductionQty(BigDecimal.valueOf(productionQty)); + //采购订单未入库数量 + wlStockData.setPurchaseQty(BigDecimal.valueOf(purchaseQty)); + + // wlStockData.setSecQty(BigDecimal.valueOf(purchaseQty)); + wlStockData.setMinsafetyStock(BigDecimal.valueOf(minSafetyStock)); + wlStockData.setMaxsafetyStock(BigDecimal.valueOf(maxSafetyStock)); + //即时库存 + wlStockData.setSecAvbqty(BigDecimal.valueOf(inventoryQty)); + + wlStockData.setSafeStatus(1); + return wlStockData; + }else { + //创建安全库存单据 + WlStockData wlStockData = new WlStockData(); + wlStockData.setMaterialCode(safetyStock.getMaterialCode()); + wlStockData.setWlMaterial(safetyStock.getType()); + //将相同类型的物料也要生成WlStockData ,如果有就不生成了 + + wlStockData.setMaterialName(safetyStock.getMaterialName()); + wlStockData.setDocumentType(safetyStock.getWlMaterial()); + wlStockData.setRequiredStock(maxSafetyStock); + //预计可用量 + wlStockData.setCurrentStock(availableStock); + wlStockData.setTriggerTime(new Date()); + //用料清单未领料数量 + wlStockData.setAvailableStock(BigDecimal.valueOf(fNoPickedQty)); + //生产订单未入库数量 + wlStockData.setProductionQty(BigDecimal.valueOf(productionQty)); + //采购订单未入库数量 + wlStockData.setPurchaseQty(BigDecimal.valueOf(purchaseQty)); + + // wlStockData.setSecQty(BigDecimal.valueOf(purchaseQty)); + wlStockData.setMinsafetyStock(BigDecimal.valueOf(minSafetyStock)); + wlStockData.setMaxsafetyStock(BigDecimal.valueOf(maxSafetyStock)); + //即时库存 + wlStockData.setSecAvbqty(BigDecimal.valueOf(inventoryQty)); + + wlStockData.setSafeStatus(0); + return wlStockData; + } - /* wlStockData.setDocumentType(String.format("物料编码:%s||可用库存:%.2f||库存量:%.2f||生产订单:%.2f||" + - "采购订单:%.2f||预留量:%.2f||最大库存:%.2f||最低库存:%.2f", - safetyStock.getMaterialCode(), availableStock, fSecAVBQty, productionQty, - purchaseQty, fSecQty, maxSafetyStock, minSafetyStock)); -*/ - return wlStockData; } - public List getInvReserveAnalyzeRpt(String materialCode) { - List rptDTOS = new ArrayList<>(); - K3CloudApi client = new K3CloudApi(); - JsonObject jsonData = new JsonObject(); - jsonData.addProperty("FieldKeys", "FMATERIALNUMBER,FMaterialName,FDemandTypeName,FSecQty,FSecAVBQty"); - jsonData.addProperty("SchemeId", ""); - jsonData.addProperty("StartRow", 0); - jsonData.addProperty("Limit", 2000); - jsonData.addProperty("IsVerifyBaseDataField", "true"); - - JsonArray filterArray = new JsonArray(); - JsonObject filterObject = new JsonObject(); - filterObject.addProperty("Left", ""); - filterObject.addProperty("FieldName", "FMATERIALNUMBER"); - filterObject.addProperty("Compare", "67"); - filterObject.addProperty("Value", materialCode); - filterObject.addProperty("Right", ""); - filterObject.addProperty("Logic", 0); - filterArray.add(filterObject); - jsonData.add("FilterString", filterArray); - - JsonObject model = new JsonObject(); - model.addProperty("FStockOrgId", "1"); - - JsonObject beginMaterialId = new JsonObject(); - beginMaterialId.addProperty("FNUMBER", materialCode); - model.add("FBeginMaterialId", beginMaterialId); - - model.addProperty("FDemandType", "PLN_FORECAST,PLN_PLANORDER,PRD_PPBOM,SAL_SaleOrder"); - model.addProperty("FNeedTransOnly", false); - - jsonData.add("Model", model); - - String jsonString = jsonData.toString(); - String formId = "PLN_InvReserveAnalyzeRpt"; - String resultJson = null; - try { - resultJson = client.getSysReportData(formId, jsonString); - } catch (Exception e) { - System.err.println("Error fetching data for materialCode: " + materialCode); - logMessages("Error fetching data for materialCode: " + materialCode); - e.printStackTrace(); - return new ArrayList<>(); - } - - if (resultJson == null) { - System.err.println("No data returned for materialCode: " + materialCode); - logMessages("No data returned for materialCode: " + materialCode); - return new ArrayList<>(); - } - - JsonObject resultObject = new Gson().fromJson(resultJson, JsonObject.class); - JsonArray rows = resultObject.getAsJsonObject("Result").getAsJsonArray("Rows"); - if (rows == null) { - System.err.println("No data returned for materialCode: " + materialCode); - logMessages("No data returned for materialCode: " + materialCode); - return new ArrayList<>(); - } - System.out.println("库存预留单===========>" + rows); - logMessages("库存预留单===========>" + rows); - - for (JsonElement rowElement : rows) { - JsonArray row = rowElement.getAsJsonArray(); - InvReserveAnalyzeRptDTO analyzeRptDTO = new InvReserveAnalyzeRptDTO(); - analyzeRptDTO.setFMATERIALNUMBER(getStringFromJsonArray(row, 0)); - analyzeRptDTO.setFMaterialName(getStringFromJsonArray(row, 1)); - analyzeRptDTO.setFDemandTypeName(getStringFromJsonArray(row, 2)); - analyzeRptDTO.setFSecQty(getDoubleFromJsonArray(row, 3)); - analyzeRptDTO.setFSecAVBQty(getDoubleFromJsonArray(row, 4)); - - rptDTOS.add(analyzeRptDTO); - } - - return rptDTOS; - } - - private static String getStringFromJsonArray(JsonArray array, int index) { - return array.size() > index && !array.get(index).isJsonNull() ? array.get(index).getAsString() : ""; - } - - private static double getDoubleFromJsonArray(JsonArray array, int index) { - if (array.size() > index && !array.get(index).isJsonNull()) { - String value = array.get(index).getAsString(); - if (!value.isEmpty()) { - try { - return Double.parseDouble(value); - } catch (NumberFormatException e) { - System.err.println("NumberFormatException for value: " + value); - } - } - } - return 0.0; - } - - /** - * 物料批量查询 - */ - public static JsonArray selectKuCun1(List safetyStocks) { - K3CloudApi client = new K3CloudApi(); - // 请求参数,要求为json字符串 - JsonObject json = new JsonObject(); - json.addProperty("FormId", "STK_Inventory"); - json.addProperty("FieldKeys", "FMaterialId.FNumber,FMaterialName,FStockName,FStockUnitId.FName,FBaseQty"); - JsonArray filterString = new JsonArray(); - // 添加额外的过滤条件,排除售后库 - JsonObject excludeStockFilter = new JsonObject(); - excludeStockFilter.addProperty("FieldName", "FStockId.FNumber"); // 设置字段名称为仓库编号 - excludeStockFilter.addProperty("Compare", "!="); // 设置比较方式为"不等于" - excludeStockFilter.addProperty("Value", "CK012"); // 设置需要排除的仓库编号 - excludeStockFilter.addProperty("Left", ""); // 保留字段,不使用 - excludeStockFilter.addProperty("Right", ""); // 保留字段,不使用 - excludeStockFilter.addProperty("Logic", 0); // 设置逻辑关系为 OR (假设 0 代表 OR) - filterString.add(excludeStockFilter); // 将排除条件添加到过滤条件数组中 - - JsonObject excludeStockFilter1 = new JsonObject(); - excludeStockFilter1.addProperty("FieldName", "FStockId.FNumber"); // 设置字段名称为仓库编号 - excludeStockFilter1.addProperty("Compare", "!="); // 设置比较方式为"不等于" - excludeStockFilter1.addProperty("Value", "CK018"); // 设置需要排除的仓库编号 - excludeStockFilter1.addProperty("Left", ""); // 保留字段,不使用 - excludeStockFilter1.addProperty("Right", ""); // 保留字段,不使用 - excludeStockFilter1.addProperty("Logic", 0); // 设置逻辑关系为 OR (假设 0 代表 OR) - filterString.add(excludeStockFilter1); - - for (int i = 0; i < safetyStocks.size(); i++) { - SafetyStock safetyStock = safetyStocks.get(i); - JsonObject filterObject = new JsonObject(); - filterObject.addProperty("FieldName", "FMaterialId.FNumber"); - filterObject.addProperty("Compare", "="); - filterObject.addProperty("Value", safetyStock.getMaterialCode()); - // 为第一个和最后一个元素设置括号 - if (i == 0) { - filterObject.addProperty("Left", "("); // 第一个物料左括号 - } else { - filterObject.addProperty("Left", ""); // 其他物料不设置左括号 - } - - if (i == safetyStocks.size() - 1) { - filterObject.addProperty("Right", ")"); // 最后一个物料右括号 - } else { - filterObject.addProperty("Right", ""); // 其他物料不设置右括号 - } - filterObject.addProperty("Logic", 1); - filterString.add(filterObject); - } - - json.add("FilterString", filterString); - json.addProperty("OrderString", ""); - json.addProperty("TopRowCount", 0); - json.addProperty("StartRow", 0); - json.addProperty("Limit", 2000); - json.addProperty("SubSystemId", ""); - - String jsonData = json.toString(); - JsonArray jsonArray; - try { - // 调用接口 - String resultJson = String.valueOf(client.billQuery(jsonData)); - jsonArray = new Gson().fromJson(resultJson, JsonArray.class); - logger.info("查询库存信息:{}", jsonArray); - } catch (Exception e) { - return null; - } - // 聚合库存数据 - Map materialStockMap = new HashMap<>(); - for (int i = 0; i < jsonArray.size(); i++) { - JsonObject stockData = jsonArray.get(i).getAsJsonObject(); - String materialCode = stockData.has("FMaterialId.FNumber") - ? stockData.get("FMaterialId.FNumber").getAsString() - : ""; - double baseQty = stockData.has("FBaseQty") ? stockData.get("FBaseQty").getAsDouble() : 0; - - // 聚合相同物料的库存数量 - materialStockMap.put(materialCode, materialStockMap.getOrDefault(materialCode, 0.0) + baseQty); - } - - // 构建返回的 JsonArray - JsonArray resultJsonArray = new JsonArray(); - for (Map.Entry entry : materialStockMap.entrySet()) { - JsonObject aggregatedData = new JsonObject(); - aggregatedData.addProperty("FMaterialId.FNumber", entry.getKey()); - aggregatedData.addProperty("FBaseQty", entry.getValue()); // 物料总库存 - resultJsonArray.add(aggregatedData); - } - return resultJsonArray; - } } diff --git a/ruoyi-system/src/main/resources/mapper/system/BomDetailsMapper.xml b/ruoyi-system/src/main/resources/mapper/system/BomDetailsMapper.xml index e5e2541..2cf6d83 100644 --- a/ruoyi-system/src/main/resources/mapper/system/BomDetailsMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/BomDetailsMapper.xml @@ -24,7 +24,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - + + diff --git a/ruoyi-system/src/main/resources/mapper/system/WlStockDataMapper.xml b/ruoyi-system/src/main/resources/mapper/system/WlStockDataMapper.xml index fb5de6d..da40094 100644 --- a/ruoyi-system/src/main/resources/mapper/system/WlStockDataMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/WlStockDataMapper.xml @@ -24,6 +24,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + +