From 43a4b7a756b181efb129943418e7e9ecccd3bdd2 Mon Sep 17 00:00:00 2001 From: tzy Date: Mon, 28 Jul 2025 08:42:58 +0800 Subject: [PATCH] =?UTF-8?q?feat(common):=20=E6=96=B0=E5=A2=9E=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E6=93=8D=E4=BD=9C=E4=B8=8EPDF=E5=A4=84=E7=90=86?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=20=20=20-=20=E6=96=B0=E5=A2=9E=E5=9B=BE?= =?UTF-8?q?=E7=BA=B8=E8=B7=AF=E5=BE=84=E5=B8=B8=E9=87=8F=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=20=20=20-=20=E6=96=B0=E5=A2=9EDeleteFile=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=B7=A5=E5=85=B7=E7=B1=BB=20=20=20-=20?= =?UTF-8?q?=E6=96=B0=E5=A2=9EPDFDocHelper=E7=94=A8=E4=BA=8EPDF=E6=B0=B4?= =?UTF-8?q?=E5=8D=B0=E3=80=81=E5=90=88=E5=B9=B6=E7=AD=89=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=20=20=20-=20=E6=96=B0=E5=A2=9EFTPDownload=E6=94=AF=E6=8C=81FTP?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E6=89=B9=E9=87=8F=E4=B8=8B=E8=BD=BD=20=20=20?= =?UTF-8?q?-=20=E6=96=B0=E5=A2=9EFtpUtil=E6=8F=90=E4=BE=9B=E5=AE=8C?= =?UTF-8?q?=E6=95=B4=E7=9A=84FTP=E5=AE=A2=E6=88=B7=E7=AB=AF=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=EF=BC=8C=E6=94=AF=E6=8C=81=E6=96=87=E4=BB=B6=E4=B8=8A?= =?UTF-8?q?=E4=BC=A0=E4=B8=8B=E8=BD=BD=E5=8F=8A=E7=9B=AE=E5=BD=95=E7=AE=A1?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- ruoyi-common/pom.xml | 18 +- .../com/ruoyi/common/constant/Constants.java | 16 + .../com/ruoyi/common/utils/FTPDownload.java | 104 ++ .../java/com/ruoyi/common/utils/FtpUtil.java | 722 ++++++++++ .../com/ruoyi/common/utils/HttpUtils.java | 254 ++++ .../com/ruoyi/common/utils/WxRobotUtil.java | 52 +- .../ruoyi/common/utils/file/DeleteFile.java | 146 ++ .../ruoyi/common/utils/file/PDFDocHelper.java | 329 +++++ .../com/ruoyi/common/utils/file/SmbUtil.java | 4 +- .../controller/BomDetailsController.java | 5 +- .../controller/EleMaterialsController.java | 2 +- .../controller/PcRigidChainController.java | 106 ++ .../controller/ProcessOrderProController.java | 159 +- .../controller/ProcessRouteController.java | 22 +- .../controller/SysConfigIniController.java | 106 ++ .../com/ruoyi/system/domain/FigureSave.java | 27 +- .../com/ruoyi/system/domain/MaterialBom.java | 2 +- .../com/ruoyi/system/domain/PcRigidChain.java | 442 ++++++ .../ruoyi/system/domain/ProcessOrderPro.java | 27 + .../com/ruoyi/system/domain/SysConfigIni.java | 73 + .../ruoyi/system/domain/bo/FigureSaveBo.java | 61 +- .../system/domain/bo/PcRigidChainBo.java | 665 +++++++++ .../system/domain/bo/ProcessOrderProBo.java | 52 +- .../system/domain/bo/ProcessRouteBo.java | 2 +- .../system/domain/bo/SysConfigIniBo.java | 89 ++ .../system/domain/dto/JDSafeStockDTO.java | 9 +- .../domain/dto/excuteDrawing/DataInfo.java | 154 ++ .../domain/dto/excuteDrawing/ProductInfo.java | 14 + .../dto/excuteDrawing/PwProductionBill.java | 19 + .../domain/dto/excuteDrawing/Subparts.java | 11 + .../ruoyi/system/domain/vo/BomDetailsVo.java | 7 +- .../ruoyi/system/domain/vo/FigureSaveVo.java | 54 +- ...cRigidChainVO.java => PcRigidChainVo.java} | 2 +- .../system/domain/vo/ProcessOrderProVo.java | 38 + .../system/domain/vo/ProcessRouteVo.java | 2 +- .../system/domain/vo/SysConfigIniVo.java | 89 ++ .../com/ruoyi/system/listener/FileToZip.java | 52 + .../com/ruoyi/system/listener/SmbUtils.java | 232 +++ .../system/mapper/PcRigidChainMapper.java | 15 + .../system/mapper/SysConfigIniMapper.java | 15 + .../java/com/ruoyi/system/runner/JdUtil.java | 8 +- .../com/ruoyi/system/runner/PDFGenerator.java | 95 +- .../system/service/IFigureSaveService.java | 8 + .../system/service/IPcRigidChainService.java | 60 + .../service/IProcessOrderProService.java | 16 +- .../system/service/IProcessRouteService.java | 6 +- .../service/IProductionOrderService.java | 4 + .../system/service/ISysConfigIniService.java | 49 + .../service/impl/FigureSaveServiceImpl.java | 15 + .../service/impl/ImMaterialServiceImpl.java | 2 +- .../service/impl/PcRigidChainServiceImpl.java | 139 ++ .../impl/ProcessOrderProServiceImpl.java | 1273 +++++++++++++---- .../service/impl/ProcessRouteServiceImpl.java | 50 +- .../impl/ProductionOrderServiceImpl.java | 156 +- .../service/impl/SysConfigIniServiceImpl.java | 111 ++ .../mapper/system/FigureSaveMapper.xml | 8 +- .../mapper/system/PcRigidChainMapper.xml | 120 ++ .../mapper/system/ProcessOrderProMapper.xml | 6 + .../mapper/system/SysConfigIniMapper.xml | 24 + 60 files changed, 5886 insertions(+), 464 deletions(-) create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/FTPDownload.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/FtpUtil.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/HttpUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/file/DeleteFile.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/file/PDFDocHelper.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/controller/PcRigidChainController.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/controller/SysConfigIniController.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/domain/PcRigidChain.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/domain/SysConfigIni.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/PcRigidChainBo.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysConfigIniBo.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/excuteDrawing/DataInfo.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/excuteDrawing/ProductInfo.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/excuteDrawing/PwProductionBill.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/excuteDrawing/Subparts.java rename ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/{PcRigidChainVO.java => PcRigidChainVo.java} (99%) create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysConfigIniVo.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/listener/FileToZip.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/listener/SmbUtils.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/mapper/PcRigidChainMapper.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysConfigIniMapper.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/IPcRigidChainService.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysConfigIniService.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/PcRigidChainServiceImpl.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigIniServiceImpl.java create mode 100644 ruoyi-system/src/main/resources/mapper/system/PcRigidChainMapper.xml create mode 100644 ruoyi-system/src/main/resources/mapper/system/SysConfigIniMapper.xml diff --git a/pom.xml b/pom.xml index eb9fc84..796092e 100644 --- a/pom.xml +++ b/pom.xml @@ -43,6 +43,7 @@ 1.33 1.12.400 + 2.0.23 3.1.687 @@ -343,7 +344,6 @@ - diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml index 013fb23..837132c 100644 --- a/ruoyi-common/pom.xml +++ b/ruoyi-common/pom.xml @@ -167,7 +167,12 @@ org.bouncycastle bcprov-jdk15to18 - + + + com.itextpdf + itextpdf + 5.5.13 + org.lionsoul @@ -240,7 +245,16 @@ commons-io 2.15.0 - + + org.apache.pdfbox + pdfbox + + + + commons-net + commons-net + 3.6 + diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java index 68e81cc..9fcdde1 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java @@ -72,5 +72,21 @@ public interface Constants { */ String TOKEN = "token"; + + /** 图纸存放路径 */ + public static final String BASIC_URL = "E:/电子档案/1.标准图纸存放文件夹"; + public static final String BASIC_URL_BZ = "/1.1标准图纸"; + public static final String BASIC_URL_FB = "/1.3非标图纸/"; + public static final String XCL_URL = "/1.1.1 XCL-销齿链标准图纸/"; + public static final String ELS_URL = "/1.1.2 ELS-行程检测装置标准图纸/"; + public static final String EDS_URL = "/1.1.3 EDS-行程检测装置(带显示灯)标准图纸/"; + public static final String WB_URL = "/1.1.4 WB-舞台设备标准图纸/"; + public static final String QD_URL = "/1.1.5 QD-销齿链驱动单元标准图纸/"; + public static final String ZHD_URL = "/1.1.6 ZHD-中置换电标准图纸/"; + public static final String ETK_URL = "/1.1.7 ETK-K系列减速器标准图纸/"; + public static final String ETT_URL = "/1.1.8 ETT-T系列换向器标准图纸/"; + public static final String ETP_URL = "/1.1.9 ETP-P系列减速器标准图纸/"; + public static final String ETH_URL = "/1.1.10 ETH-H系列减速器标准图纸/"; + } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/FTPDownload.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/FTPDownload.java new file mode 100644 index 0000000..9020311 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/FTPDownload.java @@ -0,0 +1,104 @@ +package com.ruoyi.common.utils; + +import org.apache.commons.net.ftp.FTPClient; +import org.apache.commons.net.ftp.FTPFile; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +public class FTPDownload { + + private FTPClient ftpClient; + + public FTPDownload() { + ftpClient = new FTPClient(); + } + + /** + * 连接到FTP服务器 + */ + public void connect(String ftpHost, String ftpUserName, String ftpPassword, int ftpPort) { + try { + ftpClient.connect(ftpHost, ftpPort); + ftpClient.login(ftpUserName, ftpPassword); + ftpClient.enterLocalPassiveMode(); // 设置被动模式 + System.out.println("FTP连接成功!"); + } catch (IOException e) { + System.out.println("FTP连接失败!"); + e.printStackTrace(); + } + } + + /** + * 列出远程目录中的文件 + * @param remoteDir 远程目录路径 + * @return FTPFile列表 + * @throws IOException + */ + public FTPFile[] listFiles(String remoteDir) throws IOException { + return ftpClient.listFiles(remoteDir); + } + + /** + * 下载文件 + * @param remoteFile 远程文件路径 + * @param localFile 本地保存路径 + * @throws IOException + */ + public void downloadFile(String remoteFile, String localFile) throws IOException { + try (OutputStream os = new FileOutputStream(localFile)) { + ftpClient.retrieveFile(remoteFile, os); + System.out.println("文件下载成功: " + remoteFile); + } catch (IOException e) { + System.out.println("文件下载失败: " + remoteFile); + e.printStackTrace(); + } + } + + /** + * 下载整个目录中的所有文件 + * @param remoteDir 远程目录路径 + * @param localDir 本地保存目录 + */ + public void downloadFilesInDirectory(String remoteDir, String localDir) { + try { + FTPFile[] files = listFiles(remoteDir); + for (FTPFile file : files) { + String remoteFilePath = remoteDir + "/" + file.getName(); + String localFilePath = localDir + "/" + file.getName(); + + if (file.isFile()) { + downloadFile(remoteFilePath, localFilePath); + } else if (file.isDirectory()) { + // 递归下载文件夹 + File localFolder = new File(localFilePath); + if (!localFolder.exists()) { + localFolder.mkdirs(); // 创建本地文件夹 + } + downloadFilesInDirectory(remoteFilePath, localFilePath); // 递归下载子文件夹 + } + } + } catch (IOException e) { + System.out.println("列出文件失败: " + remoteDir); + e.printStackTrace(); + } + } + + public static void main(String[] args) { + FTPDownload ftpDownload = new FTPDownload(); + String ftpHost = "192.168.5.18"; // FTP服务器IP + String ftpUserName = "admin"; // FTP用户名 + String ftpPassword = "hbyt2025"; // FTP密码 + int ftpPort = 21; // FTP端口,默认21 + + String remoteDir = "/FB-25-039-FS-01/FS25040.03.0-PDF"; // 远程目录 + String localDir = "F:/FB-25-039-FS-01"; // 本地保存目录 + + // 连接到FTP服务器 + ftpDownload.connect(ftpHost, ftpUserName, ftpPassword, ftpPort); + + // 下载文件 + ftpDownload.downloadFilesInDirectory(remoteDir, localDir); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/FtpUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/FtpUtil.java new file mode 100644 index 0000000..f6ccede --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/FtpUtil.java @@ -0,0 +1,722 @@ +package com.ruoyi.common.utils; + +import com.ruoyi.common.core.domain.R; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.net.ftp.*; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.X509TrustManager; +import java.io.*; +import java.net.SocketException; +import java.nio.charset.StandardCharsets; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +@Slf4j +public class FtpUtil { + private FTPClient ftpClient; + /** + * 本地字符编码 + */ + private static String LOCAL_CHARSET = "UTF-8"; + + // FTP协议里面,规定文件名编码为iso-8859-1 + private static final String SERVER_CHARSET = "ISO-8859-1"; + //ftp的端口,主机,用户名和密码 + private static final int port = 8022; + private static final String host = "192.168.5.18"; + private static final String username = "admin"; + private static final String password = "hbyt2025"; + + public void FTPDownload() { + ftpClient = new FTPClient(); + } + + + private static String encodePath(String path) throws UnsupportedEncodingException { + return new String(path.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1); + } + + /** + * Description: 向FTP服务器上传文件 + * + * @param basePath FTP服务器基础目录 + * @param filePath FTP服务器文件存放路径。例如分日期存放:/2015/01/01。文件的路径为basePath+filePath + * @param filename 上传到FTP服务器上的文件名 + * @param input 输入流 + * @return 成功返回true,否则返回false + */ + public static boolean uploadFile(String host, int port, String username, String password, + String basePath, String filePath, String filename, InputStream input) { + boolean result = false; + FTPClient ftpClient = new FTPClient(); + + try { + // 1. 连接并登录 + ftpClient.connect(host, port); + ftpClient.login(username, password); + + ftpClient.enterLocalPassiveMode(); // 设置被动模式 + ftpClient.setFileType(FTP.BINARY_FILE_TYPE); // 设置为二进制传输模式 + ftpClient.sendCommand("OPTS UTF8", "ON"); // 请求服务器启用 UTF-8 + ftpClient.setControlEncoding("UTF-8"); // 控制编码也设为 UTF-8 + + int reply = ftpClient.getReplyCode(); + if (!FTPReply.isPositiveCompletion(reply)) { + ftpClient.disconnect(); + System.err.println("FTP 登录失败,响应码:" + reply); + return false; + } +// ftpClient.changeWorkingDirectory(basePath); + + // 2. 尝试切换到目标目录,不存在就创建 + if (!ftpClient.changeWorkingDirectory(filePath)) { + String[] dirs = filePath.split("/"); + for (String dir : dirs) { + if (dir == null || dir.trim().isEmpty()) continue; + String encodedDir = new String(dir.getBytes(LOCAL_CHARSET), SERVER_CHARSET); + if (!ftpClient.changeWorkingDirectory(encodedDir)) { + if (!ftpClient.makeDirectory(encodedDir)) { + System.err.println("创建目录失败:" + dir); + return false; + } else { + ftpClient.changeWorkingDirectory(encodedDir); + } + } + } + } + + // 3. 编码与传输设置 + if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) { + ftpClient.setControlEncoding("UTF-8"); + } else { + ftpClient.setControlEncoding("GBK"); + } + + // 4. 文件名编码处理 + filename = new String(filename.getBytes(LOCAL_CHARSET), SERVER_CHARSET); + + // 5. 上传文件 + boolean stored = ftpClient.storeFile(filename, input); + if (!stored) { + System.err.println("上传失败,文件名:" + filename); + return false; + } + + result = true; + } catch (IOException e) { + System.err.println("上传异常:" + e.getMessage()); + e.printStackTrace(); + } finally { + // 6. 资源清理 + try { + if (input != null) input.close(); + if (ftpClient.isConnected()) { + ftpClient.logout(); + ftpClient.disconnect(); + } + } catch (IOException ex) { + ex.printStackTrace(); + } + } + return result; + } + /** + * 获取FTPClient对象 + * + * @param ftpHost FTP主机服务器 + * @param ftpPassword FTP 登录密码 + * @param ftpUserName FTP登录用户名 + * @param ftpPort FTP端口 默认为21 + * @return + */ + public static FTPSClient getFTPClient1(String ftpHost, int ftpPort, String ftpUserName, String ftpPassword) { + FTPSClient ftpClient = null; + try { + //创建SSL上下文 + SSLContext sslContext = SSLContext.getInstance("TLS"); + //自定义证书,忽略已过期证书 + X509TrustManager trustManager = new X509TrustManager() { + @Override + public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {} + @Override + public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {} + @Override + public X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];} + }; + //初始化 + sslContext.init(null, new X509TrustManager[] { trustManager }, null); + ftpClient = new FTPSClient(sslContext); + ftpClient.connect(ftpHost, ftpPort);// 连接FTP服务器 + Boolean login = ftpClient.login(ftpUserName, ftpPassword);// 登陆FTP服务器 + log.info("login: "+login); + if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) { + log.info("未连接到FTP,用户名或密码错误。"); + ftpClient.disconnect(); + } else { + log.info("FTP连接成功。"); + } + } catch (SocketException e) { + e.printStackTrace(); + log.info("FTP的IP地址可能错误,请正确配置。"); + } catch (IOException e) { + e.printStackTrace(); + log.info("FTP的端口错误,请正确配置。"); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (KeyManagementException e) { + e.printStackTrace(); + } + return ftpClient; + } + + + + + + private static final String encoding = System.getProperty("file.encoding"); + + /** + * 上传文件到FTP,自动创建目录 + * + * @param ftpHost FTP服务器地址 + * @param ftpUserName 用户名 + * @param ftpPassword 密码 + * @param ftpPort 端口 + * @param remoteDirPath 要上传到的远程目录(如:/upload/2025/图纸) + * @param fileName 要保存的文件名 + * @param inputStream 文件流 + * @return 是否上传成功 + */ + public static boolean uploadWithAutoMkdir(String ftpHost, String ftpUserName, String ftpPassword, int ftpPort, + String remoteDirPath, String fileName, InputStream inputStream) { + FTPClient ftpClient = null; + try { + ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort); + ftpClient.setControlEncoding("UTF-8"); + ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); + ftpClient.enterLocalPassiveMode(); + + String rootPath = "/电子档案/1.标准图纸存放文件夹"; + + // 改为逐级创建根目录 + String[] rootPaths = rootPath.split("/"); + String currentPath = ""; + for (String dir : rootPaths) { + if (dir == null || dir.trim().isEmpty()) continue; + currentPath += "/" + dir; + if (!ftpClient.changeWorkingDirectory(currentPath)) { + if (!ftpClient.makeDirectory(currentPath)) { + log.error("无法创建根目录: {}", currentPath); + return false; + } + ftpClient.changeWorkingDirectory(currentPath); + } + } + + // 继续创建 remoteDirPath(在rootPath之后) + String[] paths = remoteDirPath.split("/"); + for (String path : paths) { + if (path == null || path.trim().isEmpty()) continue; + currentPath += "/" + path; + if (!ftpClient.changeWorkingDirectory(currentPath)) { + if (!ftpClient.makeDirectory(currentPath)) { + log.error("无法创建目录: {}", currentPath); + return false; + } + ftpClient.changeWorkingDirectory(currentPath); + } + } + + // ✅ 上传文件 + boolean uploaded = ftpClient.storeFile(fileName, inputStream); + inputStream.close(); + ftpClient.logout(); + return uploaded; + } catch (Exception e) { + log.error("FTP上传异常", e); + return false; + } finally { + if (ftpClient != null && ftpClient.isConnected()) { + try { + ftpClient.disconnect(); + } catch (IOException e) { + log.error("FTP关闭异常", e); + } + } + } + } + + + public static boolean uploadFile(String url, int port, String username, + String password, String path, String filename, InputStream input) { + boolean result = false; + FTPClient ftpClient = null; + try { + int reply; + // 如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器 + ftpClient.connect(url); + ftpClient.connect(url, port);// 连接FTP服务器 + // 登录 + ftpClient.login(username, password); + ftpClient.setControlEncoding(encoding); + // 检验是否连接成功 + reply = ftpClient.getReplyCode(); + if (!FTPReply.isPositiveCompletion(reply)) { + System.out.println("连接失败"); + ftpClient.disconnect(); + return result; + } + + // 转移工作目录至指定目录下 + boolean change = ftpClient.changeWorkingDirectory(path); + ftpClient.setFileType(FTP.BINARY_FILE_TYPE); + if (change) { + result = ftpClient.storeFile(new String(filename.getBytes(encoding), "iso-8859-1"), input); + if (result) { + System.out.println("上传成功!"); + } + } + input.close(); + ftpClient.logout(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (ftpClient.isConnected()) { + try { + ftpClient.disconnect(); + } catch (IOException ioe) { + } + } + } + return result; + } + + + /** + * 获取FTPClient对象 + * + * @param ftpHost FTP主机服务器 + * @param ftpPassword FTP 登录密码 + * @param ftpUserName FTP登录用户名 + * @param ftpPort FTP端口 默认为21 + * @return + */ + public static FTPClient getFTPClient(String ftpHost, String ftpUserName, + String ftpPassword, int ftpPort) { + FTPClient ftpClient = new FTPClient(); + try { + ftpClient = new FTPClient(); + ftpClient.connect(ftpHost, ftpPort);// 连接FTP服务器 + ftpClient.login(ftpUserName, ftpPassword);// 登录FTP服务器 + if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) { + System.out.println("未连接到FTP,用户名或密码错误。"); + ftpClient.disconnect(); + } else { + System.out.println("FTP连接成功。"); + } + } catch (SocketException e) { + e.printStackTrace(); + System.out.println("FTP的IP地址可能错误,请正确配置。"); + } catch (IOException e) { + e.printStackTrace(); + System.out.println("FTP的端口错误,请正确配置。"); + } + return ftpClient; + } + + /* + * 从FTP服务器下载文件 + * + * @param ftpHost FTP IP地址 + * @param ftpUserName FTP 用户名 + * @param ftpPassword FTP用户名密码 + * @param ftpPort FTP端口 + * @param ftpPath FTP服务器中文件所在路径 格式: ftptest/aa + * @param localPath 下载到本地的位置 格式:H:/download + * @param fileName 文件名称 + */ + public static void downloadFtpFile(String ftpHost, String ftpUserName, + String ftpPassword, int ftpPort, String ftpPath, String localPath, + String fileName) { + + FTPClient ftpClient = null; + + try { + ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort); + ftpClient.setControlEncoding("UTF-8"); // 中文支持 + ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); + ftpClient.enterLocalPassiveMode(); + ftpClient.changeWorkingDirectory(ftpPath); + + File localFile = new File(localPath + File.separatorChar + fileName); + OutputStream os = new FileOutputStream(localFile); + ftpClient.retrieveFile(fileName, os); + os.close(); + ftpClient.logout(); + + } catch (FileNotFoundException e) { + System.out.println("没有找到" + ftpPath + "文件"); + e.printStackTrace(); + } catch (SocketException e) { + System.out.println("连接FTP失败."); + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + System.out.println("文件读取错误。"); + e.printStackTrace(); + } + + } + + + /** + * 从输入流中获取字节数组 + * + * @param inputStream + * @return + * @throws IOException + */ + public static byte[] readInputStream(InputStream inputStream) throws IOException { + byte[] buffer = new byte[1024]; + int len = 0; + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + while ((len = inputStream.read(buffer)) != -1) { + bos.write(buffer, 0, len); + } + bos.close(); + return bos.toByteArray(); + } + + /** + * Description: 向FTP服务器上传文件 + * + * @param ftpHost FTP服务器hostname + * @param ftpUserName 账号 + * @param ftpPassword 密码 + * @param ftpPort 端口 + * @param ftpPath FTP服务器中文件所在路径 格式: ftptest/aa + * @param fileName ftp文件名称 + * @param input 文件流 + * @return 成功返回true,否则返回false + */ + public static boolean uploadFile(String ftpHost, String ftpUserName, String ftpPassword, int ftpPort, String ftpPath, String fileName, InputStream input, String filePath, long filesize) { + boolean success = false; + FTPClient ftpClient = null; + String[] ftpPathDir = ftpPath.split("/");//ftp目录 + + String[] dir = filePath.split("/");//创建多级目录 + try { + int reply; + ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort); + reply = ftpClient.getReplyCode(); + + for (int i = 1; i < ftpPathDir.length; i++) { + ftpClient.makeDirectory(new String(ftpPathDir[i].getBytes("GBK"), "iso-8859-1")); + if (!FTPReply.isPositiveCompletion(reply)) { + ftpClient.disconnect(); + return success; + } + ftpClient.setControlEncoding("GBK"); // 中文支持 + ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); + ftpClient.enterLocalPassiveMode(); + //取消服务器获取自身Ip地址和提交的host进行匹配 当不一致时会抛出异常 + ftpClient.setRemoteVerificationEnabled(false); + ftpClient.changeWorkingDirectory(new String(ftpPathDir[i].getBytes("GBK"), "iso-8859-1")); + } + + for (int i = 0; i < dir.length; i++) { + if (!dir[i].equals("")) { + ftpClient.makeDirectory(new String(dir[i].getBytes("GBK"), "iso-8859-1")); + if (!FTPReply.isPositiveCompletion(reply)) { + ftpClient.disconnect(); + return success; + } + ftpClient.setControlEncoding("GBK"); // 中文支持 + ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); + ftpClient.enterLocalPassiveMode(); + ftpClient.changeWorkingDirectory(new String(dir[i].getBytes("GBK"), "iso-8859-1")); + } + + } + //默认FTP上传速度过慢,由于默认缓冲区大小1024字节,将缓冲区大小改为10M + ftpClient.setBufferSize(1024 * 1024 * 10); + ftpClient.storeFile(new String(fileName.getBytes("GBK"), "iso-8859-1"), input); + input.close(); + ftpClient.logout(); + success = true; + } catch (Exception e) { + e.printStackTrace(); + return success; + } finally { + if (ftpClient.isConnected()) { + try { + ftpClient.disconnect(); + } catch (IOException ioe) { + } + } + } + return success; + } + + public static void downloadFtpFolder(String ftpHost, String ftpUserName, + String ftpPassword, int ftpPort, String ftpPath, String localPath) { + + FTPClient ftpClient = null; + try { + ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort); + ftpClient.setControlEncoding("UTF-8"); // 中文支持 + ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); + ftpClient.enterLocalPassiveMode(); // 设置被动模式 + + // 确保进入指定的目标目录(例如 FS25040.03.0-PDF) + ftpClient.changeWorkingDirectory(ftpPath); // 切换到目标文件夹 + + // 获取文件夹中的内容 + FTPFile[] files = ftpClient.listFiles(); + if (files != null) { + for (FTPFile file : files) { + String fileName = file.getName(); + String remoteFilePath = ftpPath + "/" + fileName; + File localFile = new File(localPath + "/" + fileName); + + // 如果是文件,则下载 + if (file.isFile()) { + System.out.println("下载文件: " + remoteFilePath); + try (OutputStream os = new FileOutputStream(localFile)) { + ftpClient.retrieveFile(remoteFilePath, os); + } catch (IOException e) { + System.out.println("下载失败: " + remoteFilePath); + e.printStackTrace(); + } + } + // 如果是文件夹,递归调用(但仅当路径是我们需要的文件夹时才递归) + else if (file.isDirectory()) { + String subFolderPath = ftpPath + "/" + fileName; + File subLocalFolder = new File(localPath + "/" + fileName); + if (!subLocalFolder.exists()) { + subLocalFolder.mkdirs(); // 创建子文件夹 + } + + // 递归下载子文件夹 + downloadFtpFolder(ftpHost, ftpUserName, ftpPassword, ftpPort, subFolderPath, subLocalFolder.getAbsolutePath()); + } + } + } + ftpClient.logout(); + } catch (IOException e) { + System.out.println("FTP 操作失败"); + e.printStackTrace(); + } finally { + if (ftpClient != null && ftpClient.isConnected()) { + try { + ftpClient.disconnect(); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } + } + } + + /** + * 列出远程目录中的文件 + * + * @param remoteDir 远程目录路径 + * @return FTPFile列表 + * @throws IOException + */ + public FTPFile[] listFiles(String remoteDir) throws IOException { + return ftpClient.listFiles(remoteDir); + } + + /** + * 下载文件 + * + * @param remoteFile 远程文件路径 + * @param localFile 本地保存路径 + * @throws IOException + */ + public void downloadFile(String remoteFile, String localFile) throws IOException { + try (OutputStream os = new FileOutputStream(localFile)) { + ftpClient.retrieveFile(remoteFile, os); + System.out.println("文件下载成功: " + remoteFile); + } catch (IOException e) { + System.out.println("文件下载失败: " + remoteFile); + e.printStackTrace(); + } + } + + /** + * 下载整个目录中的所有文件 + * + * @param remoteDir 远程目录路径 + * @param localDir 本地保存目录 + */ + public void downloadFilesInDirectory(String remoteDir, String localDir) { + try { + FTPFile[] files = listFiles(remoteDir); + for (FTPFile file : files) { + String remoteFilePath = remoteDir + "/" + file.getName(); + String localFilePath = localDir + "/" + file.getName(); + + if (file.isFile()) { + downloadFile(remoteFilePath, localFilePath); + } else if (file.isDirectory()) { + // 递归下载文件夹 + File localFolder = new File(localFilePath); + if (!localFolder.exists()) { + localFolder.mkdirs(); // 创建本地文件夹 + } + downloadFilesInDirectory(remoteFilePath, localFilePath); // 递归下载子文件夹 + } + } + } catch (IOException e) { + System.out.println("列出文件失败: " + remoteDir); + e.printStackTrace(); + } + } + + /** + * 下载FTP指定目录中的所有文件到本地 + * + * @param ftpHost FTP服务器IP + * @param ftpUserName FTP用户名 + * @param ftpPassword FTP密码 + * @param ftpPort FTP端口 + * @param remoteDir 远程目录路径 + * @param localDir 本地保存目录 + * @return 下载结果 + */ + public static R downloadFtpDirectoryFiles(String ftpHost, String ftpUserName, + String ftpPassword, int ftpPort, + String remoteDir, String localDir) { + FTPClient ftpClient = null; + try { + // 1. 连接FTP服务器 + ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort); + if (ftpClient == null || !ftpClient.isConnected()) { + return R.fail("FTP连接失败"); + } + + // 2. 设置FTP参数 + ftpClient.setControlEncoding("UTF-8"); + ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); + ftpClient.enterLocalPassiveMode(); + + // 3. 切换到远程目录 + if (!ftpClient.changeWorkingDirectory(remoteDir)) { + return R.fail("远程目录不存在: " + remoteDir); + } + + // 4. 创建本地目录 + File localDirectory = new File(localDir); + if (!localDirectory.exists()) { + if (!localDirectory.mkdirs()) { + return R.fail("无法创建本地目录: " + localDir); + } + } + + // 5. 获取远程目录文件列表 + FTPFile[] files = ftpClient.listFiles(); + if (files == null || files.length == 0) { + return R.ok("远程目录为空,无需下载"); + } + + // 6. 遍历下载文件 + int successCount = 0; + int totalCount = files.length; + StringBuilder errorMsg = new StringBuilder(); + + for (FTPFile file : files) { + String fileName = file.getName(); + + // 跳过隐藏文件和目录 + if (fileName.startsWith(".") || file.isDirectory()) { + continue; + } + + try { + // 构建本地文件路径 + String localFilePath = localDir + File.separator + fileName; + File localFile = new File(localFilePath); + + // 下载文件 + try (OutputStream os = new FileOutputStream(localFile)) { + boolean downloadSuccess = ftpClient.retrieveFile(fileName, os); + if (downloadSuccess) { + successCount++; + log.info("文件下载成功: {}", fileName); + } else { + errorMsg.append("文件下载失败: ").append(fileName).append("; "); + log.error("文件下载失败: {}", fileName); + } + } + + } catch (Exception e) { + errorMsg.append("文件下载异常: ").append(fileName).append(" - ").append(e.getMessage()).append("; "); + log.error("文件下载异常: {}", fileName, e); + } + } + + // 7. 返回结果 + String resultMsg = String.format("下载完成: 成功%d个文件,共%d个文件", successCount, totalCount); + if (errorMsg.length() > 0) { + resultMsg += ",错误信息: " + errorMsg.toString(); + } + + return R.ok(resultMsg); + + } catch (Exception e) { + log.error("FTP下载过程中发生异常", e); + return R.fail("下载失败: " + e.getMessage()); + } finally { + // 8. 关闭FTP连接 + if (ftpClient != null && ftpClient.isConnected()) { + try { + ftpClient.logout(); + ftpClient.disconnect(); + } catch (IOException e) { + log.error("关闭FTP连接失败", e); + } + } + } + } + + /** + * 主方法 - 用于测试FTP目录文件下载功能 + */ + public static void main(String[] args) { + // FTP服务器配置 + String ftpHost = "192.168.5.18"; + String ftpUserName = "admin"; + String ftpPassword = "hbyt2025"; + int ftpPort = 21; + + // 远程目录和本地目录配置 + String remoteDir = "/FB-25-039-FS-01/40S-R-2720-T(FS039-25)-PDF"; // 远程目录路径 + String localDir = "F:/DownloadedFiles"; // 本地保存目录 + + System.out.println("开始下载FTP文件..."); + System.out.println("FTP服务器: " + ftpHost); + System.out.println("远程目录: " + remoteDir); + System.out.println("本地目录: " + localDir); + System.out.println("====================================="); + + // 调用下载方法 + R result = downloadFtpDirectoryFiles(ftpHost, ftpUserName, ftpPassword, ftpPort, remoteDir, localDir); + + // 输出结果 + if (result.getMsg().equals("1")) { + System.out.println("✅ 下载成功: " + result.getData()); + } else { + System.out.println("❌ 下载失败: " + result.getMsg()); + } + + System.out.println("====================================="); + System.out.println("下载完成!"); + } + + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/HttpUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/HttpUtils.java new file mode 100644 index 0000000..5733c61 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/HttpUtils.java @@ -0,0 +1,254 @@ +package com.ruoyi.common.utils; + +import com.ruoyi.common.constant.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.net.ssl.*; +import java.io.*; +import java.net.ConnectException; +import java.net.SocketTimeoutException; +import java.net.URL; +import java.net.URLConnection; +import java.security.cert.X509Certificate; + +/** + * 通用http发送方法 + * + * @author ruoyi + */ +public class HttpUtils +{ + private static final Logger log = LoggerFactory.getLogger(HttpUtils.class); + + /** + * 向指定 URL 发送GET方法的请求 + * + * @param url 发送请求的 URL + * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 + * @return 所代表远程资源的响应结果 + */ + public static String sendGet(String url, String param) + { + return sendGet(url, param, Constants.UTF8); + } + + /** + * 向指定 URL 发送GET方法的请求 + * + * @param url 发送请求的 URL + * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 + * @param contentType 编码类型 + * @return 所代表远程资源的响应结果 + */ + public static String sendGet(String url, String param, String contentType) + { + StringBuilder result = new StringBuilder(); + BufferedReader in = null; + try + { + String urlNameString = url + "?" + param; + log.info("sendGet - {}", urlNameString); + URL realUrl = new URL(urlNameString); + URLConnection connection = realUrl.openConnection(); + connection.setRequestProperty("accept", "*/*"); + connection.setRequestProperty("connection", "Keep-Alive"); + connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); + connection.connect(); + in = new BufferedReader(new InputStreamReader(connection.getInputStream(), contentType)); + String line; + while ((line = in.readLine()) != null) + { + result.append(line); + } + log.info("recv - {}", result); + } + catch (ConnectException e) + { + log.error("调用HttpUtils.sendGet ConnectException, url=" + url + ",param=" + param, e); + } + catch (SocketTimeoutException e) + { + log.error("调用HttpUtils.sendGet SocketTimeoutException, url=" + url + ",param=" + param, e); + } + catch (IOException e) + { + log.error("调用HttpUtils.sendGet IOException, url=" + url + ",param=" + param, e); + } + catch (Exception e) + { + log.error("调用HttpsUtil.sendGet Exception, url=" + url + ",param=" + param, e); + } + finally + { + try + { + if (in != null) + { + in.close(); + } + } + catch (Exception ex) + { + log.error("调用in.close Exception, url=" + url + ",param=" + param, ex); + } + } + return result.toString(); + } + + /** + * 向指定 URL 发送POST方法的请求 + * + * @param url 发送请求的 URL + * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 + * @return 所代表远程资源的响应结果 + */ + public static String sendPost(String url, String param) + { + PrintWriter out = null; + BufferedReader in = null; + StringBuilder result = new StringBuilder(); + try + { + String urlNameString = url; + log.info("sendPost - {}", urlNameString); + URL realUrl = new URL(urlNameString); + URLConnection conn = realUrl.openConnection(); + conn.setRequestProperty("Accept", "*/*"); + conn.setRequestProperty("connection", "Keep-Alive"); + conn.setRequestProperty("Accept-Charset", "UTF-8"); + conn.setRequestProperty("Accept-Encoding", "UTF-8"); + conn.setRequestProperty("Content-Type", "application/json"); + conn.setDoOutput(true); + conn.setDoInput(true); + out = new PrintWriter(conn.getOutputStream()); + out.print(param); + out.flush(); + in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8")); + String line; + while ((line = in.readLine()) != null) + { + result.append(line); + } + log.info("recv - {}", result); + } + catch (ConnectException e) + { + log.error("调用HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e); + } + catch (SocketTimeoutException e) + { + log.error("调用HttpUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e); + } + catch (IOException e) + { + log.error("调用HttpUtils.sendPost IOException, url=" + url + ",param=" + param, e); + } + catch (Exception e) + { + log.error("调用HttpsUtil.sendPost Exception, url=" + url + ",param=" + param, e); + } + finally + { + try + { + if (out != null) + { + out.close(); + } + if (in != null) + { + in.close(); + } + } + catch (IOException ex) + { + log.error("调用in.close Exception, url=" + url + ",param=" + param, ex); + } + } + return result.toString(); + } + + public static String sendSSLPost(String url, String param) + { + StringBuilder result = new StringBuilder(); + String urlNameString = url + "?" + param; + try + { + log.info("sendSSLPost - {}", urlNameString); + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom()); + URL console = new URL(urlNameString); + HttpsURLConnection conn = (HttpsURLConnection) console.openConnection(); + conn.setRequestProperty("accept", "*/*"); + conn.setRequestProperty("connection", "Keep-Alive"); + conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); + conn.setRequestProperty("Accept-Charset", "UTF-8"); + conn.setRequestProperty("contentType", "UTF-8"); + conn.setDoOutput(true); + conn.setDoInput(true); + + conn.setSSLSocketFactory(sc.getSocketFactory()); + conn.setHostnameVerifier(new TrustAnyHostnameVerifier()); + conn.connect(); + InputStream is = conn.getInputStream(); + BufferedReader br = new BufferedReader(new InputStreamReader(is)); + String ret = ""; + while ((ret = br.readLine()) != null) + { + if (ret != null && !ret.trim().equals("")) + { + result.append(new String(ret.getBytes("ISO-8859-1"), "UTF-8")); + } + } + log.info("recv - {}", result); + conn.disconnect(); + br.close(); + } + catch (ConnectException e) + { + log.error("调用HttpUtils.sendSSLPost ConnectException, url=" + url + ",param=" + param, e); + } + catch (SocketTimeoutException e) + { + log.error("调用HttpUtils.sendSSLPost SocketTimeoutException, url=" + url + ",param=" + param, e); + } + catch (IOException e) + { + log.error("调用HttpUtils.sendSSLPost IOException, url=" + url + ",param=" + param, e); + } + catch (Exception e) + { + log.error("调用HttpsUtil.sendSSLPost Exception, url=" + url + ",param=" + param, e); + } + return result.toString(); + } + + private static class TrustAnyTrustManager implements X509TrustManager + { + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) + { + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) + { + } + + @Override + public X509Certificate[] getAcceptedIssuers() + { + return new X509Certificate[] {}; + } + } + + private static class TrustAnyHostnameVerifier implements HostnameVerifier + { + @Override + public boolean verify(String hostname, SSLSession session) + { + return true; + } + } +} 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 a9a0035..a8de132 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 @@ -7,7 +7,11 @@ import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import javax.annotation.Resource; +import java.io.BufferedReader; import java.io.File; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; import java.util.*; @Slf4j @@ -62,7 +66,7 @@ public class WxRobotUtil { HashMap paramMap = new HashMap<>(); HashMap textMap = new HashMap<>(); textMap.put("content", msg); - + // 添加@所有人的配置 if (mentionAll) { textMap.put("mentioned_list", Collections.singletonList("@all")); @@ -70,7 +74,7 @@ public class WxRobotUtil { paramMap.put("msgtype", "text"); paramMap.put("text", textMap); - + String sendUrl = SEND_MESSAGE_URL + "?key=" + robotId; ResponseEntity result = httpRequestUtil.doPost(sendUrl, paramMap); JSONObject dataObject = JSONObject.parseObject(JSONObject.toJSONString(result.getBody())); @@ -128,26 +132,26 @@ public class WxRobotUtil { */ public void sendNewsToWeChatGroup(String title, String description, String url, String picUrl, String robotId) { HashMap paramMap = new HashMap<>(); - + // 创建文章对象 HashMap article = new HashMap<>(); article.put("title", title); article.put("description", description); article.put("url", url); article.put("picurl", picUrl); - + // 创建文章列表 List> articles = new ArrayList<>(); articles.add(article); - + // 创建news对象 HashMap newsMap = new HashMap<>(); newsMap.put("articles", articles); - + // 设置消息类型和内容 paramMap.put("msgtype", "news"); paramMap.put("news", newsMap); - + String sendUrl = SEND_MESSAGE_URL + "?key=" + robotId; ResponseEntity result = httpRequestUtil.doPost(sendUrl, paramMap); JSONObject dataObject = JSONObject.parseObject(JSONObject.toJSONString(result.getBody())); @@ -158,5 +162,39 @@ public class WxRobotUtil { log.error("企业微信推送图文消息失败,时间:" + new Date()); } } + public static String getAccessToken(String corpId, String corpSecret) { + try { + // 构建请求 URL + String urlStr = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + corpId + "&corpsecret=" + corpSecret; + URL url = new URL(urlStr); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.setConnectTimeout(5000); + connection.setReadTimeout(5000); + // 读取响应 + BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + String line; + StringBuilder response = new StringBuilder(); + while ((line = reader.readLine()) != null) { + response.append(line); + } + reader.close(); + + // 解析 JSON 响应 + JSONObject jsonResponse = new JSONObject(response.toString().isEmpty()); + int errcode = jsonResponse.getObject("errcode",int.class); + + if (errcode == 0) { + // 获取 access_token + return jsonResponse.getString("access_token"); + } else { + System.out.println("获取 access_token 失败: " + jsonResponse.getString("errmsg")); + return null; + } + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/DeleteFile.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/DeleteFile.java new file mode 100644 index 0000000..13c1683 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/DeleteFile.java @@ -0,0 +1,146 @@ + +package com.ruoyi.common.utils.file; + +import java.io.File; + +public class DeleteFile { + + /** + * 删除文件,可以是单个文件或文件夹 + * + * @param fileName + * 待删除的文件名 + * @return 文件删除成功返回true,否则返回false + */ + public static boolean delete(String fileName) { + File file = new File(fileName); + if (!file.exists()) { + System.out.println("删除文件失败:" + fileName + "文件不存在"); + return false; + } else { + if (file.isFile()) { + + return deleteFile(fileName); + } else { + return deleteDirectory(fileName); + } + } + } + + /** + * 删除单个文件 + * + * @param fileName + * 被删除文件的文件名 + * @return 单个文件删除成功返回true,否则返回false + */ + public static boolean deleteFile(String fileName) { + File file = new File(fileName); + if (file.isFile() && file.exists()) { + file.delete(); + System.out.println("删除单个文件" + fileName + "成功!"); + return true; + } else { + System.out.println("删除单个文件" + fileName + "失败!"); + return false; + } + } + + /** + * 删除目录(文件夹)以及目录下的文件 + * + * @param dir + * 被删除目录的文件路径 + * @return 目录删除成功返回true,否则返回false + */ + public static boolean deleteDirectory(String dir) { + // 如果dir不以文件分隔符结尾,自动添加文件分隔符 + if (!dir.endsWith(File.separator)) { + dir = dir + File.separator; + } + File dirFile = new File(dir); + // 如果dir对应的文件不存在,或者不是一个目录,则退出 + if (!dirFile.exists() || !dirFile.isDirectory()) { + System.out.println("删除目录失败" + dir + "目录不存在!"); + return false; + } + boolean flag = true; + // 删除文件夹下的所有文件(包括子目录) + File[] files = dirFile.listFiles(); + for (int i = 0; i < files.length; i++) { + // 删除子文件 + if (files[i].isFile()) { + flag = deleteFile(files[i].getAbsolutePath()); + if (!flag) { + break; + } + } + // 删除子目录 + else { + flag = deleteDirectory(files[i].getAbsolutePath()); + if (!flag) { + break; + } + } + } + + if (!flag) { + System.out.println("删除目录失败"); + return false; + } + + // 删除当前目录 + if (dirFile.delete()) { + System.out.println("删除目录" + dir + "成功!"); + return true; + } else { + System.out.println("删除目录" + dir + "失败!"); + return false; + } + } + // 删除文件夹 + // param folderPath 文件夹完整绝对路径 + + public static void delFolder(String folderPath) { + try { + delAllFile(folderPath); // 删除完里面所有内容 + String filePath = folderPath; + filePath = filePath.toString(); + File myFilePath = new File(filePath); + myFilePath.delete(); // 删除空文件夹 + } catch (Exception e) { + e.printStackTrace(); + } + } + + // 删除指定文件夹下所有文件 + // param path 文件夹完整绝对路径 + public static boolean delAllFile(String path) { + boolean flag = false; + File file = new File(path); + if (!file.exists()) { + return flag; + } + if (!file.isDirectory()) { + return flag; + } + String[] tempList = file.list(); + File temp = null; + for (int i = 0; i < tempList.length; i++) { + if (path.endsWith(File.separator)) { + temp = new File(path + tempList[i]); + } else { + temp = new File(path + File.separator + tempList[i]); + } + if (temp.isFile()) { + temp.delete(); + } + if (temp.isDirectory()) { + delAllFile(path + "/" + tempList[i]);// 先删除文件夹里面的文件 + delFolder(path + "/" + tempList[i]);// 再删除空文件夹 + flag = true; + } + } + return flag; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/PDFDocHelper.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/PDFDocHelper.java new file mode 100644 index 0000000..7ed10c8 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/PDFDocHelper.java @@ -0,0 +1,329 @@ +package com.ruoyi.common.utils.file; + +import com.itextpdf.text.*; +import com.itextpdf.text.pdf.*; +import com.itextpdf.text.pdf.PdfContentByte; +import com.itextpdf.text.pdf.PdfGState; +import com.itextpdf.text.pdf.PdfStamper; +import org.apache.pdfbox.io.MemoryUsageSetting; +import org.apache.pdfbox.multipdf.PDFMergerUtility; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.List; +import java.util.Map; + +/** + * @Author AlphaJunS + * @Date 19:25 2020/3/7 + * @Description 文档帮助类 + */ +public class PDFDocHelper { + private static BaseFont base = null; + // 获取基础文字 + public static BaseFont getBaseFont() throws DocumentException, IOException { + if (base == null) { + try { + base = BaseFont.createFont("/u01/config/simsun.ttc,1", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); + } catch (Throwable th) { + base = BaseFont.createFont("C:\\WINDOWS\\Fonts\\SIMSUN.TTC,1", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); + } + } + return base; + } + + /** + * 原始图路径 + * 水印内容集合 + * X坐标点集合 + * Y坐标点集合 + */ + public static String signPsw(String oldPswFilePath, List> reviews,float[] pswX,float[] pswY,String biaoji) throws IOException, DocumentException { + int pos = oldPswFilePath.lastIndexOf('.'); + // 获取文件后缀 + String suffix = oldPswFilePath.substring(pos + 1); + // 判断是否为pdf文件 + if (!"pdf".equalsIgnoreCase(suffix)) { + throw new RuntimeException("Not supported PSW file"); + } + return signSinglePsw(oldPswFilePath, reviews,pswX,pswY); + } + + //单个psw文件签名 + private static String signSinglePsw(String oldPswFilePath,List> reviews,float[] pswX,float[] pswY) throws IOException, DocumentException { + String newPswPath = oldPswFilePath; + int pos = oldPswFilePath.lastIndexOf('.'); + int ii = oldPswFilePath.lastIndexOf('/'); + // 获取文件后缀名 + String suffix = oldPswFilePath.substring(pos + 1); + //获取文件名 + String name = oldPswFilePath.substring(ii+1); + // 生成新的文件路径 + newPswPath =oldPswFilePath.substring(0, ii+1) + name; + File newfile = new File(newPswPath); + //获取父目录 + File fileParent = newfile.getParentFile().getParentFile(); + //判断是否存在 + if (!newfile.exists()) { + // 创建父目录文件夹 + newfile.mkdirs(); + } + + FileOutputStream fout = null; + if("1".equals(1)){ + + }else{ + File filesBom = new File(fileParent+"/bomThree/"); + if (!filesBom.exists()) { + filesBom.mkdir(); + } + fout = new FileOutputStream(filesBom+"/"+name); + } + PdfReader reader = new PdfReader(oldPswFilePath); + PdfStamper stp = new PdfStamper(reader, fout); + for (int i = 0; i < reader.getNumberOfPages(); ) { + // 需要从第一页开始,i放在循环中会报空指针异常 + i++; + PdfContentByte content = stp.getOverContent(i); + content.beginText(); + // 设置字体及字号 + content.setFontAndSize(getBaseFont(), 10); + for(int t = 0; t review = (Map) reviews.get(t); + addDeptReview(content, review,pswX[t],pswY[t]); + } + content.endText(); + } + stp.close(); + // 将输出流关闭 + fout.close(); + reader.close(); + // 文件读写结束 + System.out.println("PSW文件读写完毕"); + + return newPswPath; + } + + /** + * @Author AlphaJunS + * @Date 18:48 2020/3/7 + * @Description 添加水印 + * @param content + * @param review + * @return void + */ + private static void addDeptReview(PdfContentByte content, Map review,float pswX,float pswY) { + if (Integer.parseInt(String.valueOf(review.get("type"))) == 1) { + content.setColorFill(BaseColor.BLACK); + } else { + content.setColorFill(BaseColor.RED); + } + // 设置水印位置和内容 + String result = (String) review.get("result"); + System.out.println("水印内容:" + result); + System.out.println("打印位置坐标:" + pswX + "," + pswY); + content.showTextAligned(Element.ALIGN_LEFT, result, pswX, pswY, 0); + } + + /** + * 合并打印文字水印和图纸章水印 + * inputPath 原始图路径 + * outputPath 打上水印后的路径 + * images 水印图片路径 + * reviews 水印内容集合 + * pswX X坐标点集合 + * pswY Y坐标点集合 + */ + public static boolean imageWatermark(String inputPath, String outputPath,String images,List> reviews,float[] pswX,float[] pswY) throws IOException, DocumentException, com.itextpdf.text.DocumentException { + //打图纸章水印 + PdfReader reader = new PdfReader(inputPath); + PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputPath)); + PdfGState gs1 = new PdfGState(); + try{ + gs1.setFillOpacity(1f); + + Image image = Image.getInstance(images); + int n = reader.getNumberOfPages(); + PdfContentByte under; + // 获取pdf的宽和高 + Rectangle pageSize = reader.getPageSize(1); + float height = pageSize.getHeight(); + float width = pageSize.getWidth(); + PdfContentByte pdfContentByte = stamper.getOverContent(1); + // 获得PDF最顶层 + under = stamper.getOverContent(1); + pdfContentByte.setGState(gs1); + // 水印文字成45度角倾斜 + image.setRotation(30);// 旋转 弧度 + // 设置旋转角度 + image.setRotationDegrees(0);// 旋转 角度 + // 设置等比缩放 + under.setColorFill(BaseColor.RED); + //设置水印的大小,同比缩小 + // image.scaleToFit(180,280); + image.scaleToFit(100,190); + image.setRotation(45); + image.setAbsolutePosition(0, height-220); // set the first background image of the absolute + pdfContentByte.addImage(image); + }catch (Exception e){ + e.printStackTrace(); + return false; + }finally{ + stamper.close(); + reader.close(); + } + //打文字水印 + try { + signSinglePsw(outputPath,reviews,pswX,pswY); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return true; + } + + public static boolean imageWatermark(String inputPath, String outputPath,String name,String images,List> reviews,float[] pswX,float[] pswY) throws IOException, DocumentException { + //打图纸章水印 + PdfReader reader = new PdfReader(inputPath); + FileOutputStream foc = new FileOutputStream(outputPath+"/bom/"+ name); + PdfStamper stamper = new PdfStamper(reader, foc); + PdfGState gs1 = new PdfGState(); + float height = 0.0f; + try{ + gs1.setFillOpacity(1f); + Image image = Image.getInstance(images); + int n = reader.getNumberOfPages(); + PdfContentByte under; + // 获取pdf的宽和高 + Rectangle pageSize = reader.getPageSize(1); + height = pageSize.getHeight(); + PdfContentByte pdfContentByte = stamper.getOverContent(1); + PdfContentByte pdunder = stamper.getUnderContent(1); + // 获得PDF最顶层 + under = stamper.getOverContent(1); + pdfContentByte.setGState(gs1); + pdunder.setGState(gs1); + // 水印文字成45度角倾斜 + image.setRotation(30);// 旋转 弧度 + // 设置旋转角度 + image.setRotationDegrees(0);// 旋转 角度 + // 设置等比缩放 + under.setColorFill(BaseColor.RED); + //设置水印的大小,同比缩小 + image.scaleToFit(100,190); + image.setRotation(45); + image.setAbsolutePosition(0, height-190); // set the first background image of the absolute + pdfContentByte.addImage(image); + }catch (Exception e){ + e.printStackTrace(); + return false; + }finally{ + stamper.close(); + foc.close(); + reader.close(); + } + //打文字水印 + try { + signSinglePsw(outputPath,name,reviews,pswX,pswY); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return true; + } + /** + * pdf合并 + * @param files + * @param targetPath + * @return + * @throws IOException + */ + public static File mulFile2One(List files,String targetPath) throws IOException{ + // pdf合并工具类 + PDFMergerUtility mergePdf = new PDFMergerUtility(); + for (File f : files) { + if(f.exists() && f.isFile()){ + // 循环添加要合并的pdf + mergePdf.addSource(f); + } + } + // 设置合并生成pdf文件名称 + mergePdf.setDestinationFileName(targetPath); + // 合并pdf + mergePdf.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly()); + return new File(targetPath); + } + + private static String signSinglePsw(String oldPswFilePath,String name,List> reviews,float[] pswX,float[] pswY) throws IOException, DocumentException { + + PdfReader reader = new PdfReader(oldPswFilePath + "/bom/" + name); + FileOutputStream foc = new FileOutputStream(oldPswFilePath + "/zip/" + name); + PdfStamper stp = new PdfStamper(reader, foc); + for (int i = 0; i < reader.getNumberOfPages(); ) { + i++; + PdfContentByte content = stp.getOverContent(i); + content.beginText(); + // 设置字体及字号 + content.setFontAndSize(getBaseFont(), 10); + Map review = (Map) reviews.get(0); + addDeptReview(content, review,pswX[0],pswY[0]); + content.endText(); + } + stp.close(); + foc.close(); + reader.close(); + return oldPswFilePath + "/zip/" + name; + } + + /** + * 合并打印文字水印和图纸章水印 + * inputPath 原始图路径 + * outputPath 打上水印后的路径 + * images 水印图片路径 + * reviews 水印内容集合 + * pswX X坐标点集合 + * pswY Y坐标点集合 + */ + public static boolean imageWatermark(String inputPath, String outputPath,String images) throws IOException, DocumentException { + //打图纸章水印 + PdfReader reader = new PdfReader(inputPath); + PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputPath)); + PdfGState gs1 = new PdfGState(); + try{ + gs1.setFillOpacity(1f); + + Image image = Image.getInstance(images); + int n = reader.getNumberOfPages(); + PdfContentByte under; + // 获取pdf的宽和高 + Rectangle pageSize = reader.getPageSize(1); + float height = pageSize.getHeight(); + float width = pageSize.getWidth(); + PdfContentByte pdfContentByte = stamper.getOverContent(1); + // 获得PDF最顶层 + under = stamper.getOverContent(1); + pdfContentByte.setGState(gs1); + // 水印文字成45度角倾斜 + image.setRotation(30);// 旋转 弧度 + // 设置旋转角度 + image.setRotationDegrees(0);// 旋转 角度 + // 设置等比缩放 + under.setColorFill(BaseColor.RED); + //设置水印的大小,同比缩小 + // image.scaleToFit(180,280); + image.scaleToFit(100,190); + image.setRotation(45); + image.setAbsolutePosition(0, height-220); // set the first background image of the absolute + pdfContentByte.addImage(image); + }catch (Exception e){ + e.printStackTrace(); + return false; + }finally{ + stamper.close(); + reader.close(); + } + return true; + } + +} 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 index 9f7b3eb..842ecbc 100644 --- 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 @@ -8,11 +8,12 @@ import jcifs.smb.SmbFile; import java.io.*; import java.nio.file.Files; +import java.util.List; 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) { @@ -112,6 +113,7 @@ public class SmbUtil { } } + private static void transferFile(SmbFile remoteFile, File localFile) { System.out.printf("正在下载 [%s] => [%s]%n", remoteFile.getName(), 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 334d91b..7c1ab5b 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 @@ -449,7 +449,7 @@ public class BomDetailsController extends BaseController { // 1. 判断BOM是否为空 if (JDBomList == null || JDBomList.isEmpty()) { - log.error("BOM为空,物料编码: {}", fnumber); + log.error("未在金蝶中找到相同的BOM,需要上传,物料编码: {}", fnumber); return false; // BOM为空,需要上传 } @@ -466,8 +466,7 @@ public class BomDetailsController extends BaseController { BomDetails inputBomDetail = bomDetails.get(i); // 比较物料编码和名称 - if (!jdChild.getPartNumber().equals(inputBomDetail.getPartNumber()) || - !jdChild.getName().equals(inputBomDetail.getName())) { + if (!jdChild.getPartNumber().equals(inputBomDetail.getPartNumber()) || !jdChild.getName().equals(inputBomDetail.getName())) { isMatch = false; break; } 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 3a5d485..5a442bf 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 @@ -375,7 +375,7 @@ public class EleMaterialsController extends BaseController { entryID.forEach(jdEntryVmi -> { int fmaterialid = jdEntryVmi.getFMATERIALID(); int fEntryId1 = jdEntryVmi.getFEntryId1(); - int fMaxPOQty = vmi.getFMaxPOQty(); + int fMaxPOQty = vmi.getFMinPOQty(); int FSafeStock = vmi.getFSafeStock(); try { log.info("=====================>开始更新 " + vmi.getMaterialCode() + " 的安全库存"); diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/PcRigidChainController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/PcRigidChainController.java new file mode 100644 index 0000000..acc52ce --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/PcRigidChainController.java @@ -0,0 +1,106 @@ +package com.ruoyi.system.controller; + +import java.util.List; +import java.util.Arrays; + +import lombok.RequiredArgsConstructor; +import javax.servlet.http.HttpServletResponse; +import javax.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import com.ruoyi.common.annotation.RepeatSubmit; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.PageQuery; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.validate.AddGroup; +import com.ruoyi.common.core.validate.EditGroup; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.system.domain.vo.PcRigidChainVo; +import com.ruoyi.system.domain.bo.PcRigidChainBo; +import com.ruoyi.system.service.IPcRigidChainService; +import com.ruoyi.common.core.page.TableDataInfo; + +/** + * 销齿链型号管理 + * + * @author 田志阳 + * @date 2025-07-07 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/system/pcRigidChain") +public class PcRigidChainController extends BaseController { + + private final IPcRigidChainService iPcRigidChainService; + + /** + * 查询销齿链型号管理列表 + */ + @SaCheckPermission("system:pcRigidChain:list") + @GetMapping("/list") + public TableDataInfo list(PcRigidChainBo bo, PageQuery pageQuery) { + return iPcRigidChainService.queryPageList(bo, pageQuery); + } + + /** + * 导出销齿链型号管理列表 + */ + @SaCheckPermission("system:pcRigidChain:export") + @Log(title = "销齿链型号管理", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(PcRigidChainBo bo, HttpServletResponse response) { + List list = iPcRigidChainService.queryList(bo); + ExcelUtil.exportExcel(list, "销齿链型号管理", PcRigidChainVo.class, response); + } + + /** + * 获取销齿链型号管理详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("system:pcRigidChain:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(iPcRigidChainService.queryById(id)); + } + + /** + * 新增销齿链型号管理 + */ + @SaCheckPermission("system:pcRigidChain:add") + @Log(title = "销齿链型号管理", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody PcRigidChainBo bo) { + return toAjax(iPcRigidChainService.insertByBo(bo)); + } + + /** + * 修改销齿链型号管理 + */ + @SaCheckPermission("system:pcRigidChain:edit") + @Log(title = "销齿链型号管理", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody PcRigidChainBo bo) { + return toAjax(iPcRigidChainService.updateByBo(bo)); + } + + /** + * 删除销齿链型号管理 + * + * @param ids 主键串 + */ + @SaCheckPermission("system:pcRigidChain:remove") + @Log(title = "销齿链型号管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(iPcRigidChainService.deleteWithValidByIds(Arrays.asList(ids), true)); + } +} 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 9967df0..4cc76f2 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 @@ -1,20 +1,24 @@ package com.ruoyi.system.controller; import java.io.*; -import java.util.List; -import java.util.Arrays; +import java.net.URLEncoder; +import java.util.*; import com.alibaba.excel.EasyExcel; import com.ruoyi.common.excel.DefaultExcelListener; import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.file.SmbUtil; import com.ruoyi.system.domain.ProcessRoute; +import com.ruoyi.system.domain.bo.FigureSaveBo; import com.ruoyi.system.service.impl.ProductionOrderServiceImpl; import lombok.RequiredArgsConstructor; import javax.servlet.http.HttpServletResponse; import javax.validation.constraints.*; import cn.dev33.satoken.annotation.SaCheckPermission; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; import org.springframework.validation.annotation.Validated; import com.ruoyi.common.annotation.RepeatSubmit; @@ -30,6 +34,7 @@ import com.ruoyi.system.domain.vo.ProcessOrderProVo; import com.ruoyi.system.domain.bo.ProcessOrderProBo; import com.ruoyi.system.service.IProcessOrderProService; import com.ruoyi.common.core.page.TableDataInfo; +import org.springframework.web.multipart.MultipartFile; /** * 项目令号 @@ -39,6 +44,7 @@ import com.ruoyi.common.core.page.TableDataInfo; @Validated @RequiredArgsConstructor @RestController +@Slf4j @RequestMapping("/system/orderPro") public class ProcessOrderProController extends BaseController { @@ -161,8 +167,155 @@ public class ProcessOrderProController extends BaseController { */ @PostMapping("/batchUpdateProjectTimeRanges") public void batchUpdateProjectTimeRanges() { - iProcessOrderProService.batchUpdateProjectTimeRanges(); } + @SaCheckPermission("system:plan:add") + @Log(title = "排产计划", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping("/addProduct") + public R addProduct(@Validated(AddGroup.class) @RequestBody FigureSaveBo bo,@RequestBody ProcessOrderProBo orderPro) { + iProcessOrderProService.addProduct(bo,orderPro); + return R.ok(); + } + + @SaCheckPermission("system:plan:add") + @Log(title = "执行出图", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping("/executDrawing") + public R executDrawing(@RequestBody ProcessOrderProBo orderPro) { + String s = iProcessOrderProService.executDrawing(orderPro); + return R.ok(s); + } + /** + * 上传dwg图纸 + * @param code + * @param filePath + * @return + */ + @PostMapping("/uploadDwg") + @ResponseBody + public R uploadContractPDF(@RequestParam("id") Integer id, @RequestParam("file") MultipartFile filePath) { + String originalFilename = filePath.getOriginalFilename(); + if (StringUtils.isEmpty(originalFilename)) { + return R.fail("获取文件名称错误!!"); + } + //校验文件后缀 jpg jpeg pdf 格式的文件不允许上传 + String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1); + if (!"dwg".equals(suffix)) { + return R.fail("禁止非法文件上传!!"); + } + + String reslut = iProcessOrderProService.uploadContractPDF(id,originalFilename,filePath); + + return R.ok(reslut); + } + + /** + * 下载PDF并生成zip包 + */ + + @SaCheckPermission("system:processOrderPro:uploadPDF") + @Log(title = "上传PDF", businessType = BusinessType.UPDATE) + @GetMapping("/uploadPDF") + public void uploadPDF(@RequestParam Long id, HttpServletResponse response) { + try { + // 调用service方法获取文件路径 + R result = iProcessOrderProService.uploadPDF(id); + + if (result.getCode() != 200) { + response.setStatus(HttpStatus.BAD_REQUEST.value()); + response.setContentType("application/json;charset=UTF-8"); + response.getWriter().write("{\"code\":" + result.getCode() + ",\"msg\":\"" + result.getMsg() + "\"}"); + return; + } + + String filePath = result.getMsg(); + File file = new File(filePath); + + // 检查文件是否存在 + if (!file.exists()) { + response.setStatus(HttpStatus.NOT_FOUND.value()); + response.setContentType("application/json;charset=UTF-8"); + response.getWriter().write("{\"code\":404,\"msg\":\"文件不存在\"}"); + return; + } + + // 设置响应头 + response.setContentType("application/zip"); + response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(file.getName(), "UTF-8") + "\""); + response.setHeader("Content-Length", String.valueOf(file.length())); + + // 写入文件流 + try (FileInputStream fis = new FileInputStream(file); + OutputStream os = response.getOutputStream()) { + byte[] buffer = new byte[8192]; + int length; + while ((length = fis.read(buffer)) > 0) { + os.write(buffer, 0, length); + } + os.flush(); + } + + } catch (Exception e) { + log.error("下载PDF文件失败", e); + try { + response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); + response.getWriter().write("下载失败: " + e.getMessage()); + } catch (IOException ex) { + log.error("写入错误响应失败", ex); + } + } + } + /** + * 下载ZIP包 + */ + @SaCheckPermission("system:processOrderPro:downloadZip") + @Log(title = "下载ZIP包", businessType = BusinessType.OTHER) + @GetMapping("/downloadZip/{id}") + public void downloadZip(@PathVariable Long id, HttpServletResponse response) { + try { + // 获取ZIP包路径 + R result = iProcessOrderProService.uploadPDF(id); + if (result.getCode() != 200) { + response.setContentType("text/html;charset=utf-8"); + response.getWriter().write("生成ZIP包失败: " + result.getMsg()); + return; + } + + String zipPath = result.getData(); + File zipFile = new File(zipPath); + + if (!zipFile.exists()) { + response.setContentType("text/html;charset=utf-8"); + response.getWriter().write("ZIP文件不存在: " + zipPath); + return; + } + + // 设置响应头 + response.setContentType("application/zip"); + response.setHeader("Content-Disposition", "attachment; filename=" + + java.net.URLEncoder.encode(zipFile.getName(), "UTF-8")); + response.setContentLength((int) zipFile.length()); + + // 写入文件流 + try (FileInputStream fis = new FileInputStream(zipFile); + OutputStream os = response.getOutputStream()) { + byte[] buffer = new byte[1024]; + int length; + while ((length = fis.read(buffer)) > 0) { + os.write(buffer, 0, length); + } + os.flush(); + } + + } catch (Exception e) { + try { + response.setContentType("text/html;charset=utf-8"); + response.getWriter().write("下载失败: " + e.getMessage()); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + } } 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 0870d57..29af8d2 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 @@ -20,7 +20,6 @@ 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.ProcessOrderProBo; import com.ruoyi.system.domain.bo.ProcessRouteBo; import com.ruoyi.system.domain.dto.*; import com.ruoyi.system.domain.vo.*; @@ -29,7 +28,6 @@ import com.ruoyi.system.mapper.BomDetailsMapper; import com.ruoyi.system.mapper.MaterialBomMapper; import com.ruoyi.system.mapper.ProcessRouteMapper; import com.ruoyi.system.runner.JdUtil; -import com.ruoyi.system.service.IProcessOrderProService; import com.ruoyi.system.service.IProcessRouteService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -228,33 +226,25 @@ public class ProcessRouteController extends BaseController { 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, "工艺路线") @@ -577,11 +567,11 @@ public class ProcessRouteController extends BaseController { @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(); + 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) { + List list1 = listener.getExcelResult().getList(); + for (PcRigidChainVo pcRigidChainVO : list1) { log.info("数据 ===============>: " + JSONUtil.toJsonStr(pcRigidChainVO)); } @@ -644,7 +634,7 @@ public class ProcessRouteController extends BaseController { materialBom.setUnit(materialUsageDTO.getChildUnit()); materialBom.setMaterialType(materialUsageDTO.getCaizhi()); //保留四位小数 - materialBom.setQuantity( new BigDecimal(materialUsageDTO.getFenzi()).divide(new BigDecimal(materialUsageDTO.getFenmu()),4, RoundingMode.HALF_UP)); + materialBom.setQuantity(String.valueOf(new BigDecimal(materialUsageDTO.getFenzi()).divide(new BigDecimal(materialUsageDTO.getFenmu()),4, RoundingMode.HALF_UP))); return materialBom; } @@ -831,7 +821,7 @@ public class ProcessRouteController extends BaseController { materialBom.setMaterialName(materialUsageDTO.getMaterialName()); materialBom.setUnit(materialUsageDTO.getUnit()); materialBom.setMaterialType(materialUsageDTO.getItemType()); - materialBom.setQuantity(BigDecimal.valueOf(materialUsageDTO.getFNumerator())); + materialBom.setQuantity(String.valueOf(BigDecimal.valueOf(materialUsageDTO.getFNumerator()))); return materialBom; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysConfigIniController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysConfigIniController.java new file mode 100644 index 0000000..31a718d --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysConfigIniController.java @@ -0,0 +1,106 @@ +package com.ruoyi.system.controller; + +import java.util.List; +import java.util.Arrays; + +import lombok.RequiredArgsConstructor; +import javax.servlet.http.HttpServletResponse; +import javax.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import com.ruoyi.common.annotation.RepeatSubmit; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.PageQuery; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.validate.AddGroup; +import com.ruoyi.common.core.validate.EditGroup; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.system.domain.vo.SysConfigIniVo; +import com.ruoyi.system.domain.bo.SysConfigIniBo; +import com.ruoyi.system.service.ISysConfigIniService; +import com.ruoyi.common.core.page.TableDataInfo; + +/** + * 图纸配置 + * + * @author 田志阳 + * @date 2025-07-05 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/system/configIni") +public class SysConfigIniController extends BaseController { + + private final ISysConfigIniService iSysConfigIniService; + + /** + * 查询图纸配置列表 + */ + @SaCheckPermission("system:configIni:list") + @GetMapping("/list") + public TableDataInfo list(SysConfigIniBo bo, PageQuery pageQuery) { + return iSysConfigIniService.queryPageList(bo, pageQuery); + } + + /** + * 导出图纸配置列表 + */ + @SaCheckPermission("system:configIni:export") + @Log(title = "图纸配置", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(SysConfigIniBo bo, HttpServletResponse response) { + List list = iSysConfigIniService.queryList(bo); + ExcelUtil.exportExcel(list, "图纸配置", SysConfigIniVo.class, response); + } + + /** + * 获取图纸配置详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("system:configIni:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(iSysConfigIniService.queryById(id)); + } + + /** + * 新增图纸配置 + */ + @SaCheckPermission("system:configIni:add") + @Log(title = "图纸配置", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody SysConfigIniBo bo) { + return toAjax(iSysConfigIniService.insertByBo(bo)); + } + + /** + * 修改图纸配置 + */ + @SaCheckPermission("system:configIni:edit") + @Log(title = "图纸配置", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody SysConfigIniBo bo) { + return toAjax(iSysConfigIniService.updateByBo(bo)); + } + + /** + * 删除图纸配置 + * + * @param ids 主键串 + */ + @SaCheckPermission("system:configIni:remove") + @Log(title = "图纸配置", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(iSysConfigIniService.deleteWithValidByIds(Arrays.asList(ids), true)); + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/FigureSave.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/FigureSave.java index 9f5d0df..e6d0b56 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/FigureSave.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/FigureSave.java @@ -25,25 +25,36 @@ public class FigureSave extends BaseEntity { */ @TableId(value = "id", type = IdType.AUTO) private Long id; + /** + * 产品名称 + */ + private String figureName; /** * 生产令号 */ private String productionCode; /** - * + * 产品型号 */ private String figureNumber; /** - * - */ - private String figureName; - /** - * + * 数量 */ private Long figureNum; /** - * + * 图纸路径 + */ + private String drawPath; + /** + * 行程 */ private Long jdInventory; - + /** + * 类型 + */ + private String productType; + /** + * 关联项目表 + */ + private Long pid; } 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 9daa6e5..8feaa98 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 @@ -45,7 +45,7 @@ public class MaterialBom extends BaseEntity { * 用量 */ @ExcelProperty("用量") - private BigDecimal quantity; + private String quantity; /** * 单位 */ diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/PcRigidChain.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/PcRigidChain.java new file mode 100644 index 0000000..8962ef0 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/PcRigidChain.java @@ -0,0 +1,442 @@ +package com.ruoyi.system.domain; + +import com.baomidou.mybatisplus.annotation.*; +import com.ruoyi.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.jeecgframework.poi.excel.annotation.Excel; + +import java.math.BigDecimal; + +/** + * 销齿链型号管理对象 pc_rigid_chain + * + * @author 田志阳 + * @date 2025-07-07 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("pc_rigid_chain") +public class PcRigidChain extends BaseEntity { + + private static final long serialVersionUID=1L; + + /** 主键 */ + private Long id; + + /** 类型 */ + @Excel(name = "类型") + private String type; + + /** 型号全称 */ + @Excel(name = "型号") + private String typeName; + + /** 产品id */ + @Excel(name = "产品id") + private Long productId; + + /** 产品名称 */ + @Excel(name = "产品名称") + private String productName; + + /** 物料编码 */ + @Excel(name = "物料编码") + private String materialCode; + + + /** 轴向 */ + @Excel(name = "轴向") + private String axialDirection; + + /** 箱体 */ + @Excel(name = "箱体") + private String box; + + /** 行程(mm) */ + private Long journey; + + /** 标记号 */ + @Excel(name = "标记号") + private String lableNumber; + + /** L1(mm) */ + private Long lOne; + + /** L2(mm) */ + private Long lTwo; + + /** L3(mm) */ + private Long lThree; + + /** 总重量 */ + @Excel(name = "总重量") + private Long sumWeight; + + /** 链条自重 */ + @Excel(name = "链条自重") + private Long chainWeight; + + /** 动载荷(KN) */ + private Long dynamicLoad; + + /** 静载荷(KN) */ + private Long deadLoad; + + /** 每转上升高度(mm) */ + private Long riseInHeightPerRevolution; + + /** 速度(mm/s) */ + private Double speed; + + /** 系统效率(%) */ + private Long efficiency; + + /** 链条节距(mm) */ + private Long chainPitch; + + /** 节圆半径(mm) */ + private Long pitchRadius; + + /** 最低高度(mm) */ + private Long minimumAltitude; + + /** 一米链条自重(Kg/m) */ + private Double singleMeterChainWeight; + + /** 驱动箱重量(Kg) */ + private Long drivingBoxWeight; + + /** 链箱重量(Kg/m) */ + private Double chainBoxWeight; + + /** 单价 */ + @Excel(name = "单价") + private Double univalence; + + /** 图片 */ + @Excel(name = "图片") + private String picture; + + /** 部件id集合 */ + @Excel(name = "部件id集合") + private String partId; + + /** 备用字段1 */ + @Excel(name = "备用字段1") + private String sparedOne; + + /** 备用字段2 */ + @Excel(name = "备用字段2") + private String sparedTwo; + + /** 备用字段3 */ + @Excel(name = "备用字段3") + private Long sparedThree; + + /** 备用字段4 */ + @Excel(name = "备用字段4") + private Long sparedFour; + + /** 删除标记(0:未删除,1:已删除) */ + private Long delFlag; + + /** 行程 */ + @Excel(name = "行程") + private Long vOne; + + /** 设备总长 */ + @Excel(name = "设备总长") + private Long vTwo; + + /** 地脚位置1 */ + @Excel(name = "地脚位置1") + private Long vThree; + + /** 地脚位置2 */ + @Excel(name = "地脚位置2") + private Long vFour; + + /** 箱体装配长度 */ + @Excel(name = "箱体装配长度") + private Long vFive; + + /** 箱体地脚位置1 */ + @Excel(name = "箱体地脚位置1") + private Long vSix; + + /** 箱体地脚位置2 */ + @Excel(name = "箱体地脚位置2") + private Long vSeven; + + /** 铝箱长度1 */ + @Excel(name = "铝箱长度1") + private Long vEight; + + /** 铝箱长度2 */ + @Excel(name = "铝箱长度2") + private Long vNine; + + /** 导向条长度1 */ + @Excel(name = "导向条长度1") + private Long vTen; + + /** 导向条长度1数量 */ + @Excel(name = "导向条长度1数量") + private Long vEleven; + + /** 导向条长度2 */ + @Excel(name = "导向条长度2") + private Long vTwelve; + + /** 导向条长度2数量 */ + @Excel(name = "导向条长度2数量") + //@Excel(name = "导向条2数量") + private Long vThirteen; + + /** 导向条长度3 */ + @Excel(name = "导向条长度3") + private Long vFourteen; + + /** 导向条长度3数量 */ + @Excel(name = "导向条长度3数量") + //@Excel(name = "导向条3数量") + private Long vFifteen; + + /** 孔位总长1 */ + @Excel(name = "孔位总长1") + private Long vSixteen; + + /** 间隔数量1 */ + @Excel(name = "间隔数量1") + private Long vSeveteen; + + /** 孔位总长2 */ + @Excel(name = "孔位总长2") + private Long vEighteen; + + /** 间隔数量2 */ + @Excel(name = "间隔数量2") + private Long vNineteen; + + /** 铆钉数量 */ + @Excel(name = "铆钉数量") + private Long vTwenty; + + /** 待定义 */ + // @Excel(name = "待定义") + private Long vTwentyOne; + + /** 待定义 */ + // @Excel(name = "待定义") + private Long vTwentyTwo; + + /** 待定义 */ + // @Excel(name = "待定义") + private Long vTwentyThree; + + /** 待定义 */ + // @Excel(name = "待定义") + private Long vTwentyFour; + + /** 待定义 */ + // @Excel(name = "待定义") + private Long vTwentyFive; + + /** 待定义 */ + // @Excel(name = "待定义") + private Long vTwentySix; + + /** 待定义 */ + // @Excel(name = "待定义") + private Long vTwentySeven; + + /** 待定义 */ + // @Excel(name = "待定义") + private Long vTwentyEight; + + /** 待定义 */ + // @Excel(name = "待定义") + private Long vTwentyNine; + + /** 待定义 */ + // @Excel(name = "待定义") + private Long vThirty; + + /** 待定义 */ + // @Excel(name = "待定义") + private Long vThirtyOne; + + /** 待定义 */ + // @Excel(name = "待定义") + private Long vThirtyTwo; + + /** 待定义 */ + // @Excel(name = "待定义") + private Long vThirtyThree; + + /** 待定义 */ + // @Excel(name = "待定义") + private Long vThirtyFour; + + /** 待定义 */ + // @Excel(name = "待定义") + private Long vThirtyFive; + + /** 待定义 */ + // @Excel(name = "待定义") + private Long vThirtySix; + + /** 待定义 */ + // @Excel(name = "待定义") + private Long vThirtySeven; + + /** 待定义 */ + // @Excel(name = "待定义") + private Long vThirtyEight; + + /** 待定义 */ + // @Excel(name = "待定义") + private Long vThirtyNine; + + /** 待定义 */ + // @Excel(name = "待定义") + private Long vForty; + + /** X1 */ + @Excel(name = "X1") + private Long vFortyOne; + + /** X2 */ + @Excel(name = "X2") + private Long vFortyTwo; + + /** X3 */ + @Excel(name = "X3") + private Long vFortyThree; + + /** X4 */ + @Excel(name = "X4") + private Long vFortyFour; + + /** X5 */ + @Excel(name = "X5") + private Long vFortyFive; + + /** X6 */ + @Excel(name = "X6") + private Long vFortySix; + + /** X7 */ + @Excel(name = "X7") + private Long vFortySeven; + + /** X8 */ + @Excel(name = "X8") + private Long vFortyEight; + + /** X9 */ + @Excel(name = "X9") + private Long vFortyNine; + + /** X10 */ + @Excel(name = "X10") + private Long vFifty; + + /** X11 */ + @Excel(name = "X11") + private Long vFiftyOne; + + /** X12 */ + @Excel(name = "X12") + private Long vFiftyTwo; + + /** X13 */ + @Excel(name = "X13") + private Long vFiftyThree; + + /** 重量 */ + @Excel(name = "铝箱1重量") + private Double gOne; + + /** 重量 */ + @Excel(name = "铝箱2重量") + private Double gTwo; + + /** 重量 */ + // @Excel(name = "重量") + private Double gThree; + + /** 重量 */ + // @Excel(name = "重量") + private Double gFour; + + /** 重量 */ + @Excel(name = "导向条1单重") + private Double gFive; + + /** 重量 */ + @Excel(name = "导向条2单重") + private Double gSix; + + /** 重量 */ + @Excel(name = "导向条3单重") + private Double gSeven; + + /** 重量 */ +// // @Excel(name = "重量") + private Double gEight; + + /** 重量 */ +// // @Excel(name = "重量") + private Double gNine; + + /** 重量 */ +// // @Excel(name = "重量") + private Double gTen; + + /** 重量 */ +// // @Excel(name = "重量") + private Double gEleven; + + /** 重量 */ +// // @Excel(name = "重量") + private Double gTwelve; + + /** 重量 */ +// // @Excel(name = "重量") + private Double gThirteen; + + /** 重量 */ +// // @Excel(name = "重量") + private Double gFourteen; + + /** 重量 */ +// // @Excel(name = "重量") + private Double gFifteen; + + /** 重量 */ +// // @Excel(name = "重量") + private Double gSixteen; + + /** 重量 */ +// // @Excel(name = "重量") + private Double gSeveteen; + + /** 重量 */ +// // @Excel(name = "重量") + private Double gEighteen; + + /** 重量 */ +// // @Excel(name = "重量") + private Double gNineteen; + + /** 重量 */ +// // @Excel(name = "重量") + private Double gTwenty; + +// private Double vipLevel; + /* private String spline;*/ + //private Long number; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/ProcessOrderPro.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/ProcessOrderPro.java index e21f777..a1cdc90 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/ProcessOrderPro.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/ProcessOrderPro.java @@ -1,6 +1,8 @@ package com.ruoyi.system.domain; import com.baomidou.mybatisplus.annotation.*; +import com.ruoyi.common.annotation.Translation; +import com.ruoyi.common.constant.TransConstant; import com.ruoyi.common.core.domain.BaseEntity; import lombok.Data; import lombok.EqualsAndHashCode; @@ -51,4 +53,29 @@ public class ProcessOrderPro extends BaseEntity { * 计划开始时间 */ private Date planStartTime; + /** + * 图纸类型 + */ + private String drawingType; + /** + * 项目完成时间 + */ + private Date projectEndTime; + /** + * 计量单位 + */ + private String unit; + /** + * 数量 + */ + private Long quantity; + /** + * 是否企标 (0-否, 1-是) + */ + private Integer isEnterpriseStandard; + /** + * 图纸路径 + */ + @Translation(type = TransConstant.OSS_ID_TO_URL) + private String drawingPath; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysConfigIni.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysConfigIni.java new file mode 100644 index 0000000..56993eb --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysConfigIni.java @@ -0,0 +1,73 @@ +package com.ruoyi.system.domain; + +import com.baomidou.mybatisplus.annotation.*; +import com.ruoyi.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + + +/** + * 图纸配置对象 sys_config_ini + * + * @author 田志阳 + * @date 2025-07-05 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("sys_config_ini") +public class SysConfigIni extends BaseEntity { + + private static final long serialVersionUID=1L; + + /** + * 主键id + */ + @TableId(value = "id") + private Long id; + /** + * dir + */ + private String dir; + /** + * 路径 + */ + private String url; + /** + * 项目图纸路径 + */ + private String productDir; + /** + * 图纸类别 + */ + private String fileType; + /** + * 图纸路径 + */ + private String fileUrl; + /** + * 备注 + */ + private String remark; + /** + * 备用字段1 + */ + private String sparedOne; + /** + * 备用字段2 + */ + private String sparedTwo; + /** + * 备用字段3 + */ + private Long sparedThree; + /** + * 备用字段4 + */ + private Long sparedFour; + /** + * 删除标记(0:未删除,1:已删除) + */ + @TableLogic + private Long delFlag; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/FigureSaveBo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/FigureSaveBo.java index 6e2b904..c2916f9 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/FigureSaveBo.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/FigureSaveBo.java @@ -1,5 +1,7 @@ package com.ruoyi.system.domain.bo; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; import com.ruoyi.common.core.domain.BaseEntity; import com.ruoyi.common.core.validate.AddGroup; import com.ruoyi.common.core.validate.EditGroup; @@ -20,39 +22,52 @@ import javax.validation.constraints.NotNull; @EqualsAndHashCode(callSuper = true) public class FigureSaveBo extends BaseEntity { - /** - * - */ - @NotNull(message = "不能为空", groups = { EditGroup.class }) + + @TableId(value = "id", type = IdType.AUTO) private Long id; /** - * + * 产品名称 */ - @NotBlank(message = "不能为空", groups = { AddGroup.class, EditGroup.class }) - private String figureNumber; - - /** - * - */ - @NotBlank(message = "不能为空", groups = { AddGroup.class, EditGroup.class }) + @NotBlank(message = "产品名称不能为空", groups = { AddGroup.class, EditGroup.class }) private String figureName; - /** - * - */ - @NotNull(message = "不能为空", groups = { AddGroup.class, EditGroup.class }) - private Long figureNum; - - /** - * - */ - @NotNull(message = "不能为空", groups = { AddGroup.class, EditGroup.class }) - private Long jdInventory; /** * 生产令号 */ @NotBlank(message = "生产令号不能为空", groups = { AddGroup.class, EditGroup.class }) private String productionCode; + /** + * 产品型号 + */ + @NotBlank(message = "产品型号不能为空", groups = { AddGroup.class, EditGroup.class }) + private String figureNumber; + + /** + * 数量 + */ + @NotNull(message = "数量不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long figureNum; + + /** + * 行程 + */ + private Long jdInventory; + + /** + * 类型 + */ + @NotBlank(message = "类型不能为空", groups = { AddGroup.class, EditGroup.class }) + private String productType; + /** + * 图纸路径 + */ + private String drawPath; + + /** + * 关联项目表 + */ + @NotNull(message = "关联项目表不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long pid; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/PcRigidChainBo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/PcRigidChainBo.java new file mode 100644 index 0000000..e0d86c4 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/PcRigidChainBo.java @@ -0,0 +1,665 @@ +package com.ruoyi.system.domain.bo; + +import com.ruoyi.common.core.domain.BaseEntity; +import com.ruoyi.common.core.validate.AddGroup; +import com.ruoyi.common.core.validate.EditGroup; +import lombok.Data; +import lombok.EqualsAndHashCode; +import javax.validation.constraints.*; + +import java.math.BigDecimal; + +/** + * 销齿链型号管理业务对象 pc_rigid_chain + * + * @author 田志阳 + * @date 2025-07-07 + */ + +@Data +@EqualsAndHashCode(callSuper = true) +public class PcRigidChainBo extends BaseEntity { + + /** + * 主键 + */ + @NotNull(message = "主键不能为空", groups = { EditGroup.class }) + private Long id; + + /** + * 类型 + */ + @NotBlank(message = "类型不能为空", groups = { AddGroup.class, EditGroup.class }) + private String type; + + /** + * 型号全称 + */ + @NotBlank(message = "型号全称不能为空", groups = { AddGroup.class, EditGroup.class }) + private String typeName; + + /** + * 产品id + */ + @NotNull(message = "产品id不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long productId; + + /** + * 产品名称 + */ + @NotBlank(message = "产品名称不能为空", groups = { AddGroup.class, EditGroup.class }) + private String productName; + + /** + * 轴向 + */ + @NotBlank(message = "轴向不能为空", groups = { AddGroup.class, EditGroup.class }) + private String axialDirection; + + /** + * 箱体 + */ + @NotBlank(message = "箱体不能为空", groups = { AddGroup.class, EditGroup.class }) + private String box; + + /** + * 行程(mm) + */ + @NotNull(message = "行程(mm)不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long journey; + + /** + * 标记号 + */ + @NotBlank(message = "标记号不能为空", groups = { AddGroup.class, EditGroup.class }) + private String lableNumber; + + /** + * L1(mm) + */ + @NotNull(message = "L1(mm)不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long lOne; + + /** + * L2(mm) + */ + @NotNull(message = "L2(mm)不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long lTwo; + + /** + * L3(mm) + */ + @NotNull(message = "L3(mm)不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long lThree; + + /** + * 总重量 + */ + @NotNull(message = "总重量不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long sumWeight; + + /** + * 链条自重 + */ + @NotNull(message = "链条自重不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long chainWeight; + + /** + * 动载荷(KN) + */ + @NotNull(message = "动载荷(KN)不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long dynamicLoad; + + /** + * 静载荷(KN) + */ + @NotNull(message = "静载荷(KN)不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long deadLoad; + + /** + * 每转上升高度(mm) + */ + @NotNull(message = "每转上升高度(mm)不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long riseInHeightPerRevolution; + + /** + * 速度(mm/s) + */ + @NotNull(message = "速度(mm/s)不能为空", groups = { AddGroup.class, EditGroup.class }) + private BigDecimal speed; + + /** + * 系统效率(%) + */ + @NotNull(message = "系统效率(%)不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long efficiency; + + /** + * 链条节距(mm) + */ + @NotNull(message = "链条节距(mm)不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long chainPitch; + + /** + * 节圆半径(mm) + */ + @NotNull(message = "节圆半径(mm)不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long pitchRadius; + + /** + * 最低高度(mm) + */ + @NotNull(message = "最低高度(mm)不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long minimumAltitude; + + /** + * 一米链条自重(Kg/m) + */ + @NotNull(message = "一米链条自重(Kg/m)不能为空", groups = { AddGroup.class, EditGroup.class }) + private BigDecimal singleMeterChainWeight; + + /** + * 驱动箱重量(Kg) + */ + @NotNull(message = "驱动箱重量(Kg)不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long drivingBoxWeight; + + /** + * 链箱重量(Kg/m) + */ + @NotNull(message = "链箱重量(Kg/m)不能为空", groups = { AddGroup.class, EditGroup.class }) + private BigDecimal chainBoxWeight; + + /** + * 单价 + */ + @NotNull(message = "单价不能为空", groups = { AddGroup.class, EditGroup.class }) + private BigDecimal univalence; + + /** + * 图片 + */ + @NotBlank(message = "图片不能为空", groups = { AddGroup.class, EditGroup.class }) + private String picture; + + /** + * 部件id集合 + */ + @NotBlank(message = "部件id集合不能为空", groups = { AddGroup.class, EditGroup.class }) + private String partId; + + /** + * 备注 + */ + @NotBlank(message = "备注不能为空", groups = { AddGroup.class, EditGroup.class }) + private String remark; + + /** + * 备用字段1 + */ + @NotBlank(message = "备用字段1不能为空", groups = { AddGroup.class, EditGroup.class }) + private String sparedOne; + + /** + * 备用字段2 + */ + @NotBlank(message = "备用字段2不能为空", groups = { AddGroup.class, EditGroup.class }) + private String sparedTwo; + + /** + * 备用字段3 + */ + @NotNull(message = "备用字段3不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long sparedThree; + + /** + * 备用字段4 + */ + @NotNull(message = "备用字段4不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long sparedFour; + + /** + * 行程 + */ + private Long vOne; + + /** + * 设备总长 + */ + @NotNull(message = "设备总长不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vTwo; + + /** + * 地脚位置1 + */ + @NotNull(message = "地脚位置1不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vThree; + + /** + * 地脚位置2 + */ + @NotNull(message = "地脚位置2不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vFour; + + /** + * 箱体装配长度 + */ + @NotNull(message = "箱体装配长度不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vFive; + + /** + * 箱体地脚位置1 + */ + @NotNull(message = "箱体地脚位置1不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vSix; + + /** + * 箱体地脚位置2 + */ + @NotNull(message = "箱体地脚位置2不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vSeven; + + /** + * 铝箱长度1 + */ + @NotNull(message = "铝箱长度1不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vEight; + + /** + * 铝箱长度2 + */ + @NotNull(message = "铝箱长度2不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vNine; + + /** + * 导向条长度1 + */ + @NotNull(message = "导向条长度1不能为空", groups = { AddGroup.class, EditGroup.class }) + private BigDecimal vTen; + + /** + * 导向条长度1数量 + */ + @NotNull(message = "导向条长度1数量不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vEleven; + + /** + * 导向条长度2 + */ + @NotNull(message = "导向条长度2不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vTwelve; + + /** + * 导向条长度2数量 + */ + @NotNull(message = "导向条长度2数量不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vThirteen; + + /** + * 导向条长度3 + */ + @NotNull(message = "导向条长度3不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vFourteen; + + /** + * 导向条长度3数量 + */ + @NotNull(message = "导向条长度3数量不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vFifteen; + + /** + * 孔位总长1 + */ + @NotNull(message = "孔位总长1不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vSixteen; + + /** + * 间隔数量1 + */ + @NotNull(message = "间隔数量1不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vSeveteen; + + /** + * 孔位总长2 + */ + @NotNull(message = "孔位总长2不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vEighteen; + + /** + * 间隔数量2 + */ + @NotNull(message = "间隔数量2不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vNineteen; + + /** + * 铆钉数量 + */ + @NotNull(message = "铆钉数量不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vTwenty; + + /** + * v21 + */ + @NotNull(message = "v21不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vTwentyOne; + + /** + * v22 + */ + @NotNull(message = "v22不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vTwentyTwo; + + /** + * v23 + */ + @NotNull(message = "v23不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vTwentyThree; + + /** + * v24 + */ + @NotNull(message = "v24不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vTwentyFour; + + /** + * v25 + */ + @NotNull(message = "v25不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vTwentyFive; + + /** + * 26 + */ + @NotNull(message = "26不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vTwentySix; + + /** + * v27 + */ + @NotNull(message = "v27不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vTwentySeven; + + /** + * v28 + */ + @NotNull(message = "v28不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vTwentyEight; + + /** + * v29 + */ + @NotNull(message = "v29不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vTwentyNine; + + /** + * v30 + */ + @NotNull(message = "v30不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vThirty; + + /** + * v31 + */ + @NotNull(message = "v31不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vThirtyOne; + + /** + * v32 + */ + @NotNull(message = "v32不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vThirtyTwo; + + /** + * v33 + */ + @NotNull(message = "v33不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vThirtyThree; + + /** + * v34 + */ + @NotNull(message = "v34不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vThirtyFour; + + /** + * v35 + */ + @NotNull(message = "v35不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vThirtyFive; + + /** + * v36 + */ + @NotNull(message = "v36不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vThirtySix; + + /** + * v37 + */ + @NotNull(message = "v37不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vThirtySeven; + + /** + * v38 + */ + @NotNull(message = "v38不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vThirtyEight; + + /** + * v39 + */ + @NotNull(message = "v39不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vThirtyNine; + + /** + * v40 + */ + @NotNull(message = "v40不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vForty; + + /** + * X1 + */ + @NotNull(message = "X1不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vFortyOne; + + /** + * X2 + */ + @NotNull(message = "X2不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vFortyTwo; + + /** + * X3 + */ + @NotNull(message = "X3不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vFortyThree; + + /** + * X4 + */ + @NotNull(message = "X4不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vFortyFour; + + /** + * X5 + */ + @NotNull(message = "X5不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vFortyFive; + + /** + * X6 + */ + @NotNull(message = "X6不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vFortySix; + + /** + * X7 + */ + @NotNull(message = "X7不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vFortySeven; + + /** + * X8 + */ + @NotNull(message = "X8不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vFortyEight; + + /** + * X9 + */ + @NotNull(message = "X9不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vFortyNine; + + /** + * X10 + */ + @NotNull(message = "X10不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vFifty; + + /** + * X11 + */ + @NotNull(message = "X11不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vFiftyOne; + + /** + * X12 + */ + @NotNull(message = "X12不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vFiftyTwo; + + /** + * X13 + */ + @NotNull(message = "X13不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long vFiftyThree; + + /** + * 重量 + */ + @NotNull(message = "重量不能为空", groups = { AddGroup.class, EditGroup.class }) + private BigDecimal gOne; + + /** + * 重量 + */ + @NotNull(message = "重量不能为空", groups = { AddGroup.class, EditGroup.class }) + private BigDecimal gTwo; + + /** + * 重量 + */ + @NotNull(message = "重量不能为空", groups = { AddGroup.class, EditGroup.class }) + private BigDecimal gThree; + + /** + * 重量 + */ + @NotNull(message = "重量不能为空", groups = { AddGroup.class, EditGroup.class }) + private BigDecimal gFour; + + /** + * 重量 + */ + @NotNull(message = "重量不能为空", groups = { AddGroup.class, EditGroup.class }) + private BigDecimal gFive; + + /** + * 重量 + */ + @NotNull(message = "重量不能为空", groups = { AddGroup.class, EditGroup.class }) + private BigDecimal gSix; + + /** + * 重量 + */ + @NotNull(message = "重量不能为空", groups = { AddGroup.class, EditGroup.class }) + private BigDecimal gSeven; + + /** + * 重量 + */ + @NotNull(message = "重量不能为空", groups = { AddGroup.class, EditGroup.class }) + private BigDecimal gEight; + + /** + * 重量 + */ + @NotNull(message = "重量不能为空", groups = { AddGroup.class, EditGroup.class }) + private BigDecimal gNine; + + /** + * 重量 + */ + @NotNull(message = "重量不能为空", groups = { AddGroup.class, EditGroup.class }) + private BigDecimal gTen; + + /** + * 重量 + */ + @NotNull(message = "重量不能为空", groups = { AddGroup.class, EditGroup.class }) + private BigDecimal gEleven; + + /** + * 重量 + */ + @NotNull(message = "重量不能为空", groups = { AddGroup.class, EditGroup.class }) + private BigDecimal gTwelve; + + /** + * 重量 + */ + @NotNull(message = "重量不能为空", groups = { AddGroup.class, EditGroup.class }) + private BigDecimal gThirteen; + + /** + * 重量 + */ + @NotNull(message = "重量不能为空", groups = { AddGroup.class, EditGroup.class }) + private BigDecimal gFourteen; + + /** + * 重量 + */ + @NotNull(message = "重量不能为空", groups = { AddGroup.class, EditGroup.class }) + private BigDecimal gFifteen; + + /** + * 重量 + */ + @NotNull(message = "重量不能为空", groups = { AddGroup.class, EditGroup.class }) + private BigDecimal gSixteen; + + /** + * 重量 + */ + @NotNull(message = "重量不能为空", groups = { AddGroup.class, EditGroup.class }) + private BigDecimal gSeveteen; + + /** + * 重量 + */ + @NotNull(message = "重量不能为空", groups = { AddGroup.class, EditGroup.class }) + private BigDecimal gEighteen; + + /** + * 重量 + */ + @NotNull(message = "重量不能为空", groups = { AddGroup.class, EditGroup.class }) + private BigDecimal gNineteen; + + /** + * 重量 + */ + @NotNull(message = "重量不能为空", groups = { AddGroup.class, EditGroup.class }) + private BigDecimal gTwenty; + + /** + * 物料编码 + */ + @NotBlank(message = "物料编码不能为空", groups = { AddGroup.class, EditGroup.class }) + private String materialCode; + + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/ProcessOrderProBo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/ProcessOrderProBo.java index 6fc62ae..46f09c9 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/ProcessOrderProBo.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/ProcessOrderProBo.java @@ -1,5 +1,8 @@ package com.ruoyi.system.domain.bo; +import com.alibaba.excel.annotation.ExcelProperty; +import com.ruoyi.common.annotation.Translation; +import com.ruoyi.common.constant.TransConstant; import com.ruoyi.common.core.domain.BaseEntity; import com.ruoyi.common.core.validate.AddGroup; import com.ruoyi.common.core.validate.EditGroup; @@ -7,6 +10,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import javax.validation.constraints.*; import java.util.Date; +import java.util.List; /** @@ -26,28 +30,15 @@ public class ProcessOrderProBo extends BaseEntity { @NotNull(message = "主键ID,自动递增不能为空", groups = { EditGroup.class }) private Long id; - /** - * 生产令号 - */ - @NotBlank(message = "生产令号不能为空", groups = { AddGroup.class, EditGroup.class }) private String productionOrderNo; - /** - * 项目名称 - */ - @NotBlank(message = "项目名称不能为空", groups = { AddGroup.class, EditGroup.class }) + private String productionName; - /** - * 图号 - */ - @NotBlank(message = "图号不能为空", groups = { AddGroup.class, EditGroup.class }) + private String drawingNo; - /** - * 名称 - */ - @NotBlank(message = "名称不能为空", groups = { AddGroup.class, EditGroup.class }) + private String drawingName; /** * 计划结束时间 @@ -58,7 +49,36 @@ public class ProcessOrderProBo extends BaseEntity { * 计划开始时间 */ private Date planStartTime; + /** + * 图纸类型 + */ + private String drawingType; + /** + * 项目完成时间 + */ + private Date projectEndTime; + /** + * 计量单位 + */ + private String unit; + + /** + * 数量 + */ + private Long quantity; + + /** + * 是否企标 (0-否, 1-是) + */ + private Integer isEnterpriseStandard; + + private String drawingPath; + /** + * 图纸路径 + */ + @Translation(mapper = "drawingPath", type = TransConstant.OSS_ID_TO_URL) + private String drawingPathUrl; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/ProcessRouteBo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/ProcessRouteBo.java index 51577ec..2b4dfb8 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/ProcessRouteBo.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/ProcessRouteBo.java @@ -84,7 +84,7 @@ public class ProcessRouteBo extends BaseEntity { /** * 材料BOM用量 */ - private BigDecimal discUsage; + private String discUsage; /** * 工序说明(序描述) diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysConfigIniBo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysConfigIniBo.java new file mode 100644 index 0000000..3439d63 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysConfigIniBo.java @@ -0,0 +1,89 @@ +package com.ruoyi.system.domain.bo; + +import com.ruoyi.common.core.domain.BaseEntity; +import com.ruoyi.common.core.validate.AddGroup; +import com.ruoyi.common.core.validate.EditGroup; +import lombok.Data; +import lombok.EqualsAndHashCode; +import javax.validation.constraints.*; + + +/** + * 图纸配置业务对象 sys_config_ini + * + * @author 田志阳 + * @date 2025-07-05 + */ + +@Data +@EqualsAndHashCode(callSuper = true) +public class SysConfigIniBo extends BaseEntity { + + /** + * 主键id + */ + @NotNull(message = "主键id不能为空", groups = { EditGroup.class }) + private Long id; + + /** + * dir + */ + @NotBlank(message = "dir不能为空", groups = { AddGroup.class, EditGroup.class }) + private String dir; + + /** + * 路径 + */ + @NotBlank(message = "路径不能为空", groups = { AddGroup.class, EditGroup.class }) + private String url; + + /** + * 项目图纸路径 + */ + @NotBlank(message = "项目图纸路径不能为空", groups = { AddGroup.class, EditGroup.class }) + private String productDir; + + /** + * 图纸类别 + */ + @NotBlank(message = "图纸类别不能为空", groups = { AddGroup.class, EditGroup.class }) + private String fileType; + + /** + * 图纸路径 + */ + @NotBlank(message = "图纸路径不能为空", groups = { AddGroup.class, EditGroup.class }) + private String fileUrl; + + /** + * 备注 + */ + @NotBlank(message = "备注不能为空", groups = { AddGroup.class, EditGroup.class }) + private String remark; + + /** + * 备用字段1 + */ + @NotBlank(message = "备用字段1不能为空", groups = { AddGroup.class, EditGroup.class }) + private String sparedOne; + + /** + * 备用字段2 + */ + @NotBlank(message = "备用字段2不能为空", groups = { AddGroup.class, EditGroup.class }) + private String sparedTwo; + + /** + * 备用字段3 + */ + @NotNull(message = "备用字段3不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long sparedThree; + + /** + * 备用字段4 + */ + @NotNull(message = "备用字段4不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long sparedFour; + + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JDSafeStockDTO.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JDSafeStockDTO.java index 6d385e4..5cffd6b 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JDSafeStockDTO.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/JDSafeStockDTO.java @@ -24,6 +24,11 @@ public class JDSafeStockDTO { /** * 最高库存 */ - @ExcelProperty(value = "最大订货量") - private int FMaxPOQty; + /*@ExcelProperty(value = "最大订货量") + private int FMaxPOQty; */ + /** + * 最高库存 + */ + @ExcelProperty(value = "最小订货量") + private int FMinPOQty; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/excuteDrawing/DataInfo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/excuteDrawing/DataInfo.java new file mode 100644 index 0000000..e842dda --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/excuteDrawing/DataInfo.java @@ -0,0 +1,154 @@ +package com.ruoyi.system.domain.dto.excuteDrawing; + +import com.alibaba.fastjson.annotation.JSONField; +import lombok.Data; + +@Data +public class DataInfo { + @JSONField(name = "V1") + private String V1; + @JSONField(name = "V2") + private String V2; + @JSONField(name = "V3") + private String V3; + @JSONField(name = "V4") + private String V4; + @JSONField(name = "V5") + private String V5; + @JSONField(name = "V6") + private String V6; + @JSONField(name = "V7") + private String V7; + @JSONField(name = "V8") + private String V8; + @JSONField(name = "V9") + private String V9; + @JSONField(name = "V10") + private String V10; + @JSONField(name = "V11") + private String V11; + @JSONField(name = "V12") + private String V12; + @JSONField(name = "V13") + private String V13; + @JSONField(name = "V14") + private String V14; + @JSONField(name = "V15") + private String V15; + @JSONField(name = "V16") + private String V16; + @JSONField(name = "V17") + private String V17; + @JSONField(name = "V18") + private String V18; + @JSONField(name = "V19") + private String V19; + @JSONField(name = "V20") + private String V20; + @JSONField(name = "V21") + private String V21; + @JSONField(name = "V22") + private String V22; + @JSONField(name = "V23") + private String V23; + @JSONField(name = "V24") + private String V24; + @JSONField(name = "V25") + private String V25; + @JSONField(name = "V26") + private String V26; + @JSONField(name = "V27") + private String V27; + @JSONField(name = "V28") + private String V28; + @JSONField(name = "V29") + private String V29; + @JSONField(name = "V30") + private String V30; + @JSONField(name = "V31") + private String V31; + @JSONField(name = "V32") + private String V32; + @JSONField(name = "V33") + private String V33; + @JSONField(name = "V34") + private String V34; + @JSONField(name = "V35") + private String V35; + @JSONField(name = "V36") + private String V36; + @JSONField(name = "V37") + private String V37; + @JSONField(name = "V38") + private String V38; + @JSONField(name = "V39") + private String V39; + @JSONField(name = "V40") + private String V40; + @JSONField(name = "V41") + private String V41; + @JSONField(name = "V42") + private String V42; + @JSONField(name = "V43") + private String V43; + @JSONField(name = "V44") + private String V44; + @JSONField(name = "V45") + private String V45; + @JSONField(name = "V46") + private String V46; + @JSONField(name = "V47") + private String V47; + @JSONField(name = "V48") + private String V48; + @JSONField(name = "V49") + private String V49; + @JSONField(name = "V50") + private String V50; + @JSONField(name = "V51") + private String V51; + @JSONField(name = "V52") + private String V52; + @JSONField(name = "V53") + private String V53; + @JSONField(name = "G1") + private String G1; + @JSONField(name = "G2") + private String G2; + @JSONField(name = "G3") + private String G3; + @JSONField(name = "G4") + private String G4; + @JSONField(name = "G5") + private String G5; + @JSONField(name = "G6") + private String G6; + @JSONField(name = "G7") + private String G7; + @JSONField(name = "G8") + private String G8; + @JSONField(name = "G9") + private String G9; + @JSONField(name = "G10") + private String G10; + @JSONField(name = "G11") + private String G11; + @JSONField(name = "G12") + private String G12; + @JSONField(name = "G13") + private String G13; + @JSONField(name = "G14") + private String G14; + @JSONField(name = "G15") + private String G15; + @JSONField(name = "G16") + private String G16; + @JSONField(name = "G17") + private String G17; + @JSONField(name = "G18") + private String G18; + @JSONField(name = "G19") + private String G19; + @JSONField(name = "G20") + private String G20; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/excuteDrawing/ProductInfo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/excuteDrawing/ProductInfo.java new file mode 100644 index 0000000..e5e1d6a --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/excuteDrawing/ProductInfo.java @@ -0,0 +1,14 @@ +package com.ruoyi.system.domain.dto.excuteDrawing; +import lombok.Data; + +@Data +public class ProductInfo { + //型号名称 + private String assembledrawing; + //图纸文件路径 + private String sourcefile; + //数量 + private String number; + //变量信息 + private DataInfo vars; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/excuteDrawing/PwProductionBill.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/excuteDrawing/PwProductionBill.java new file mode 100644 index 0000000..3213368 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/excuteDrawing/PwProductionBill.java @@ -0,0 +1,19 @@ +package com.ruoyi.system.domain.dto.excuteDrawing; + +import lombok.Data; + +import java.util.List; + +@Data +public class PwProductionBill { + //令号 + private String producitonorder; + //图纸文件保存路径 输出路径 + private String destpath; + //发图时间 + private String releasedate; + //完成日期 + private String completedate; + //产品信息 + private List product; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/excuteDrawing/Subparts.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/excuteDrawing/Subparts.java new file mode 100644 index 0000000..25ea42f --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/excuteDrawing/Subparts.java @@ -0,0 +1,11 @@ +package com.ruoyi.system.domain.dto.excuteDrawing; + +import lombok.Data; + +@Data +public class Subparts { + //图号 + private String partname; + //数量 + private String number; +} 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 76c6a02..b81c08b 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 @@ -69,12 +69,13 @@ public class BomDetailsVo { @ExcelProperty(value = "属性") private String stats; /** - *子项数量 + *子项分子 */ @ExcelProperty(value = "子项分子") - private Double quantity; - + /** + *子项分母 + */ @ExcelProperty(value = "子项分母") private Double denominator; /** diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/FigureSaveVo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/FigureSaveVo.java index f8c1b3d..dc6ba54 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/FigureSaveVo.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/FigureSaveVo.java @@ -25,32 +25,48 @@ public class FigureSaveVo { private Long id; /** - * + * 产品名称 */ - @ExcelProperty(value = "") - private String figureNumber; - - /** - * - */ - @ExcelProperty(value = "") + @ExcelProperty(value = "产品名称") private String figureName; - /** - * - */ - @ExcelProperty(value = "") - private Long figureNum; - - /** - * - */ - @ExcelProperty(value = "") - private Long jdInventory; /** * 生产令号 */ @ExcelProperty(value = "生产令号") private String productionCode; + /** + * 产品型号 + */ + @ExcelProperty(value = "产品型号") + private String figureNumber; + + /** + * 数量 + */ + @ExcelProperty(value = "数量") + private Long figureNum; + + /** + * 行程 + */ + @ExcelProperty(value = "行程") + private Long jdInventory; + /** + * 图纸路径 + */ + @ExcelProperty(value = "图纸路径") + private String drawPath; + /** + * 类型 + */ + @ExcelProperty(value = "类型") + private String productType; + + /** + * 关联项目表 + */ + @ExcelProperty(value = "关联项目表") + private Long pid; } 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 similarity index 99% rename from ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/PcRigidChainVO.java rename to ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/PcRigidChainVo.java index a4d8dc2..2f320a7 100644 --- 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 @@ -15,7 +15,7 @@ import lombok.EqualsAndHashCode; */ @Data @EqualsAndHashCode(callSuper = true) -public class PcRigidChainVO extends BaseEntity +public class PcRigidChainVo extends BaseEntity { private static final long serialVersionUID = 1L; diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/ProcessOrderProVo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/ProcessOrderProVo.java index 2147886..d299587 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/ProcessOrderProVo.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/ProcessOrderProVo.java @@ -3,6 +3,8 @@ package com.ruoyi.system.domain.vo; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelProperty; import com.ruoyi.common.annotation.ExcelDictFormat; +import com.ruoyi.common.annotation.Translation; +import com.ruoyi.common.constant.TransConstant; import com.ruoyi.common.convert.ExcelDictConvert; import lombok.Data; @@ -61,6 +63,42 @@ public class ProcessOrderProVo { */ @ExcelProperty(value = "计划开始时间") private Date planStartTime; + /** + * 图纸类型 + */ + @ExcelProperty(value = "图纸类型") + private String drawingType; + /** + * 项目完成时间 + */ + @ExcelProperty(value = "项目完成时间") + private Date projectEndTime; + /** + * 计量单位 + */ + @ExcelProperty(value = "计量单位") + private String unit; + + /** + * 数量 + */ + @ExcelProperty(value = "数量") + private Long quantity; + + /** + * 是否企标 (0-否, 1-是) + */ + @ExcelProperty(value = "是否企标 (0-否, 1-是)") + private Integer isEnterpriseStandard; + + /** + * 图纸路径 + */ + @ExcelProperty(value = "图纸路径") + private String drawingPath; + + @Translation(mapper = "drawingPath", type = TransConstant.OSS_ID_TO_URL) + private String drawingPathUrl; } 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 8ed25b2..62ef5b6 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 @@ -104,7 +104,7 @@ public class ProcessRouteVo { */ @ColumnWidth(10) @ExcelProperty(value = { "材料BOM","用量"},index = 9) - private Double discUsage; + private String discUsage; /** * 材料BOM单位 */ diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysConfigIniVo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysConfigIniVo.java new file mode 100644 index 0000000..9e290db --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysConfigIniVo.java @@ -0,0 +1,89 @@ +package com.ruoyi.system.domain.vo; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import com.ruoyi.common.annotation.ExcelDictFormat; +import com.ruoyi.common.convert.ExcelDictConvert; +import lombok.Data; + + +/** + * 图纸配置视图对象 sys_config_ini + * + * @author 田志阳 + * @date 2025-07-05 + */ +@Data +@ExcelIgnoreUnannotated +public class SysConfigIniVo { + + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @ExcelProperty(value = "主键id") + private Long id; + + /** + * dir + */ + @ExcelProperty(value = "dir") + private String dir; + + /** + * 路径 + */ + @ExcelProperty(value = "路径") + private String url; + + /** + * 项目图纸路径 + */ + @ExcelProperty(value = "项目图纸路径") + private String productDir; + + /** + * 图纸类别 + */ + @ExcelProperty(value = "图纸类别") + private String fileType; + + /** + * 图纸路径 + */ + @ExcelProperty(value = "图纸路径") + private String fileUrl; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + /** + * 备用字段1 + */ + @ExcelProperty(value = "备用字段1") + private String sparedOne; + + /** + * 备用字段2 + */ + @ExcelProperty(value = "备用字段2") + private String sparedTwo; + + /** + * 备用字段3 + */ + @ExcelProperty(value = "备用字段3") + private Long sparedThree; + + /** + * 备用字段4 + */ + @ExcelProperty(value = "备用字段4") + private Long sparedFour; + + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/listener/FileToZip.java b/ruoyi-system/src/main/java/com/ruoyi/system/listener/FileToZip.java new file mode 100644 index 0000000..48318da --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/listener/FileToZip.java @@ -0,0 +1,52 @@ +package com.ruoyi.system.listener; + +import java.io.*; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +public class FileToZip { + + /** + * 将存放在sourceFilePath目录下的源文件,打包成fileName名称的zip文件,并存放到zipFilePath路径下 + * @param sourceFilePath :待压缩的文件路径 + * @param zipFilePath :压缩后存放路径 + * @param fileName :压缩后文件的名称 + * @return + */ + public static boolean fileToZip(String sourceDirPath, String zipDirPath, String zipFileName) { + File sourceDir = new File(sourceDirPath); + File zipFile = new File(zipDirPath, zipFileName + ".zip"); + try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile))) { + zipFileRecursive(sourceDir, sourceDir.getName() + "/", zos); + return true; + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + + private static void zipFileRecursive(File fileToZip, String fileName, ZipOutputStream zos) throws IOException { + if (fileToZip.isHidden()) return; + if (fileToZip.isDirectory()) { + if (!fileName.endsWith("/")) fileName += "/"; + zos.putNextEntry(new ZipEntry(fileName)); + zos.closeEntry(); + File[] children = fileToZip.listFiles(); + if (children != null) { + for (File childFile : children) { + zipFileRecursive(childFile, fileName + childFile.getName(), zos); + } + } + return; + } + try (FileInputStream fis = new FileInputStream(fileToZip)) { + ZipEntry zipEntry = new ZipEntry(fileName); + zos.putNextEntry(zipEntry); + byte[] bytes = new byte[1024]; + int length; + while ((length = fis.read(bytes)) >= 0) { + zos.write(bytes, 0, length); + } + } + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/listener/SmbUtils.java b/ruoyi-system/src/main/java/com/ruoyi/system/listener/SmbUtils.java new file mode 100644 index 0000000..45e33b5 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/listener/SmbUtils.java @@ -0,0 +1,232 @@ +package com.ruoyi.system.listener; + +import com.ruoyi.system.domain.FigureSave; +import jcifs.CIFSContext; +import jcifs.Configuration; +import jcifs.config.PropertyConfiguration; +import jcifs.context.BaseContext; +import jcifs.smb.SmbFile; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.util.List; +import java.util.Properties; + +public class SmbUtils { + // 配置常量 + + private static final String FILE_EXTENSION = ".xlsx"; // 目标文件后缀 + private static final String LOCAL_DIR = "D:/file"; + + public static void main(String[] args) { + // 要下载的文件信息 + String remoteFilePath = "smb://192.168.5.18/2025/FB-25-039-FS-01/FS25040.01.0-PDF"; + + String targetFileName = "FS25040.01.0-PDF"; // 目标文件名 + + 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"); + + PropertyConfiguration 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 remoteFile = new SmbFile(remoteFilePath, cifs); + + if (!remoteFile.exists() || !remoteFile.isFile()) { + System.err.println("目标文件不存在: " + remoteFile.getCanonicalPath()); + return; + } + + // 本地保存路径 + File localFile = new File(localDir, targetFileName); + transferFile(remoteFile, localFile); + + } catch (Exception e) { + System.err.println("操作失败: " + e.getMessage()); + e.printStackTrace(); + } + } + + + 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(); + } + } + + /** + * 下载文件夹 + */ + public static void downloadFolder(List list) { + 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()); + } + + String figureNumber = list.get(0).getProductionCode(); + // 定位到远程目标子目录 + SmbFile remoteDir = new SmbFile("smb://192.168.5.18/2025/", cifs); + + if (!remoteDir.exists() || !remoteDir.isDirectory()) { + System.err.println("远程目录不存在或不是一个目录: " + remoteDir.getCanonicalPath()); + } else { + for (FigureSave figureSave : list) { + String targetFileName = figureSave.getFigureNumber().replaceAll("/", "-"); + SmbFile smbFile = new SmbFile(remoteDir, figureSave.getProductionCode() + "/"); // 远程文件路径修正 + SmbFile remoteFile = new SmbFile(smbFile, figureSave.getFigureNumber()+"-PDF"); + + if (!remoteFile.exists() || !remoteFile.isFile()) { + System.err.println("目标文件不存在: " + remoteFile.getCanonicalPath()); + continue; + } + + // 本地保存路径 + 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())) { + + 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-system/src/main/java/com/ruoyi/system/mapper/PcRigidChainMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/PcRigidChainMapper.java new file mode 100644 index 0000000..dcc1fa7 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/PcRigidChainMapper.java @@ -0,0 +1,15 @@ +package com.ruoyi.system.mapper; + +import com.ruoyi.system.domain.PcRigidChain; +import com.ruoyi.system.domain.vo.PcRigidChainVo; +import com.ruoyi.common.core.mapper.BaseMapperPlus; + +/** + * 销齿链型号管理Mapper接口 + * + * @author 田志阳 + * @date 2025-07-07 + */ +public interface PcRigidChainMapper extends BaseMapperPlus { + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysConfigIniMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysConfigIniMapper.java new file mode 100644 index 0000000..fd18e2c --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysConfigIniMapper.java @@ -0,0 +1,15 @@ +package com.ruoyi.system.mapper; + +import com.ruoyi.system.domain.SysConfigIni; +import com.ruoyi.system.domain.vo.SysConfigIniVo; +import com.ruoyi.common.core.mapper.BaseMapperPlus; + +/** + * 图纸配置Mapper接口 + * + * @author 田志阳 + * @date 2025-07-05 + */ +public interface SysConfigIniMapper extends BaseMapperPlus { + +} 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 c0b4a09..6005ba9 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 @@ -1255,6 +1255,7 @@ public class JdUtil { needUpDateFields.add("SubHeadEntity3"); needUpDateFields.add("FStockPlaceId"); needUpDateFields.add("FStockId"); + needUpDateFields.add("FIsVmiBusiness"); //needUpDateFields.add("FIsVmiBusiness"); json.add("NeedUpDateFields", needUpDateFields); @@ -1277,11 +1278,11 @@ public class JdUtil { // 创建 FStockPlaceId 对象 JsonObject fStockPlaceId = new JsonObject(); - JsonObject fStockPlaceIdFF100003 = new JsonObject(); - fStockPlaceIdFF100003.addProperty("FNumber", cangWeiNum); + JsonObject fStockPlaceIdFF100002 = new JsonObject(); + fStockPlaceIdFF100002.addProperty("FNumber", cangWeiNum); // // fStockPlaceId.add("FSTOCKPLACEID__FF100002", fStockPlaceIdFF100002); - fStockPlaceId.add("FSTOCKPLACEID__FF100003", fStockPlaceIdFF100003); + fStockPlaceId.add("FSTOCKPLACEID__FF100002", fStockPlaceIdFF100002); subHeadEntity1.add("FStockPlaceId", fStockPlaceId); model.add("SubHeadEntity1", subHeadEntity1); @@ -1516,7 +1517,6 @@ public class JdUtil { String data = json.toString(); String result = api.save("PRD_MO", data); - System.out.println("========================================>>>>"+data); Gson gson = new Gson(); RepoRet sRet = gson.fromJson(result, RepoRet.class); if (sRet.isSuccessfully()) { diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/runner/PDFGenerator.java b/ruoyi-system/src/main/java/com/ruoyi/system/runner/PDFGenerator.java index 4065a13..5f6dd49 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/runner/PDFGenerator.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/runner/PDFGenerator.java @@ -25,13 +25,9 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.text.SimpleDateFormat; import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; +import java.util.*; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; -import java.util.HashSet; -import java.util.Set; public class PDFGenerator { @@ -138,7 +134,7 @@ public class PDFGenerator { endtime = combinedVo.getProcesses().get(0).getFPlanFinishTime(); materialCode = String.valueOf(combinedVo.getMaterialUsageDTOList().get(0).getBillNumber()); fmoQty = combinedVo.getProcesses().get(0).getFMOQty(); - fDepartmentName = combinedVo.getProcesses().get(0).getFDepartmentName(); + fDepartmentName = combinedVo.getProcesses().get(0).getFWorkCenterName(); // 其他代码... } else { // 处理列表为空的情况 @@ -151,20 +147,26 @@ public class PDFGenerator { fDepartmentName = ""; } - String pdfFileName = fProcessName + "_" + materialCode1.replace("/", "_") + "_独立" + ".pdf"; + String pdfFileName = fDepartmentName + "_" + materialCode1.replace("/", "_") + "_独立" + ".pdf"; - File existingFile = findFileWithMaterialCode(directoryPath, materialCode1); - String pdfPath; - - // 生成 PDF 文件路径 - if (existingFile == null) { - System.out.println("未找到物料编码对应的PDF文件: " + materialCode + "。将单独生成新PDF。"); - pdfPath = directoryPath + "\\" + pdfFileName; - } else { - pdfPath = directoryPath + "\\" + fProcessName + "_" + materialCode1.replace("/", "_") - + "_generated.pdf"; + // 1. 获取文件夹名 + String departmentFolderName = fDepartmentName; + if (departmentFolderName == null || departmentFolderName.trim().isEmpty()) { + // 兜底:从文件名取前四个字或以'_'分割第一个元素 + String[] parts = pdfFileName.split("_"); + departmentFolderName = parts.length > 0 ? parts[0] + : pdfFileName.substring(0, Math.min(4, pdfFileName.length())); } + // 2. 创建文件夹 + File departmentFolder = new File(directoryPath, departmentFolderName); + if (!departmentFolder.exists()) { + departmentFolder.mkdirs(); + } + + // 3. 直接生成 PDF 到该文件夹 + String pdfPath = departmentFolder.getAbsolutePath() + "\\" + fDepartmentName + "_" + materialCode1.replace("/", "_") + "_generated.pdf"; + try { // 创建 PDF 文件并写入内容 PDDocument document = new PDDocument(); @@ -304,16 +306,6 @@ public class PDFGenerator { contentStream.close(); document.save(pdfPath); pdfPaths.add(pdfPath); - System.out.println("PDF 生成成功: " + pdfPath); - - // 如果需要合并 PDF 文件 - if (existingFile != null) { - mergePdfToExisting(pdfPath, existingFile.getAbsolutePath()); - pdfPaths.add(existingFile.getAbsolutePath()); - } - - // 在生成并合并 PDF 后,调用重命名和移动文件的方法 - processMergedPdfFiles(directoryPath, combinedVo); } catch (IOException | WriterException e) { e.printStackTrace(); } @@ -322,12 +314,10 @@ public class PDFGenerator { // 生成ZIP文件 String zipFilePath = directoryPath + "\\" + rooteProdet + "_工序计划单.zip"; try { - createZipFile(pdfPaths, zipFilePath); - System.out.println("ZIP 文件生成成功: " + zipFilePath); + createZipFile(directoryPath, zipFilePath); // 传入整个目录 return zipFilePath; } catch (IOException e) { e.printStackTrace(); - System.err.println("ZIP 文件生成失败: " + e.getMessage()); return null; } @@ -335,11 +325,11 @@ public class PDFGenerator { /** * 创建ZIP文件 - * - * @param sourceFilePaths PDF文件路径列表 + * + * @param sourceDirPath PDF文件路径列表 * @param zipFilePath 目标ZIP文件路径 */ - private static void createZipFile(List sourceFilePaths, String zipFilePath) throws IOException { + private static void createZipFile(String sourceDirPath, String zipFilePath) throws IOException { // 确保目标目录存在 File zipFile = new File(zipFilePath); if (!zipFile.getParentFile().exists()) { @@ -348,34 +338,29 @@ public class PDFGenerator { Set fileNamesInZip = new HashSet<>(); - try (ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFilePath))) { + try (ZipOutputStream zipOut = new ZipOutputStream(Files.newOutputStream(Paths.get(zipFilePath)))) { // 设置压缩级别 zipOut.setLevel(ZipOutputStream.DEFLATED); - for (String filePath : sourceFilePaths) { - File fileToZip = new File(filePath); - if (fileToZip.exists()) { - String fileName = fileToZip.getName(); - if (fileNamesInZip.contains(fileName)) { - System.out.println("跳过重复文件: " + fileName); - continue; // 跳过重复文件 - } - fileNamesInZip.add(fileName); + File sourceDir = new File(sourceDirPath); + zipDirectory(sourceDir, sourceDir.getName() + "/", zipOut); + } + } - try (FileInputStream fis = new FileInputStream(fileToZip)) { - // 创建ZIP条目 - ZipEntry zipEntry = new ZipEntry(fileName); - zipOut.putNextEntry(zipEntry); + private static void zipDirectory(File folder, String parentFolder, ZipOutputStream zipOut) throws IOException { + for (File file : Objects.requireNonNull(folder.listFiles())) { + if (file.isDirectory()) { + zipDirectory(file, parentFolder + file.getName() + "/", zipOut); + } else { + try (FileInputStream fis = new FileInputStream(file)) { + ZipEntry zipEntry = new ZipEntry(parentFolder + file.getName()); + zipOut.putNextEntry(zipEntry); - // 写入文件内容 - byte[] bytes = new byte[1024]; - int length; - while ((length = fis.read(bytes)) >= 0) { - zipOut.write(bytes, 0, length); - } + byte[] bytes = new byte[1024]; + int length; + while ((length = fis.read(bytes)) >= 0) { + zipOut.write(bytes, 0, length); } - } else { - System.err.println("文件不存在: " + filePath); } } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/IFigureSaveService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/IFigureSaveService.java index 6b4fc3c..7bbc7b4 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/IFigureSaveService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/IFigureSaveService.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.FigureSave; import com.ruoyi.system.domain.bo.FigureSaveBo; import com.ruoyi.system.domain.vo.FigureSaveVo; @@ -45,4 +46,11 @@ public interface IFigureSaveService { * 校验并批量删除外购件临时信息 */ Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 根据父级id查产品类型集合 + * @param id + * @return + */ + List selectByFid(Long id); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/IPcRigidChainService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/IPcRigidChainService.java new file mode 100644 index 0000000..43601ec --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/IPcRigidChainService.java @@ -0,0 +1,60 @@ +package com.ruoyi.system.service; + +import com.ruoyi.system.domain.PcRigidChain; +import com.ruoyi.system.domain.vo.PcRigidChainVo; +import com.ruoyi.system.domain.bo.PcRigidChainBo; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.core.domain.PageQuery; + +import java.util.Collection; +import java.util.List; +import java.util.Set; + +/** + * 销齿链型号管理Service接口 + * + * @author 田志阳 + * @date 2025-07-07 + */ +public interface IPcRigidChainService { + + /** + * 查询销齿链型号管理 + */ + PcRigidChainVo queryById(Long id); + + /** + * 查询销齿链型号管理列表 + */ + TableDataInfo queryPageList(PcRigidChainBo bo, PageQuery pageQuery); + + /** + * 查询销齿链型号管理列表 + */ + List queryList(PcRigidChainBo bo); + + /** + * 新增销齿链型号管理 + */ + Boolean insertByBo(PcRigidChainBo bo); + + /** + * 修改销齿链型号管理 + */ + Boolean updateByBo(PcRigidChainBo bo); + + /** + * 校验并批量删除销齿链型号管理信息 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 根据型号名称查询销齿链型号管理 + */ + PcRigidChain selectPcRigidChainByTypeName(String figureNumber); + + /** + * 根据型号名称集合批量查询销齿链型号管理 + */ + List selectByTypeNames(Set typeNames); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/IProcessOrderProService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/IProcessOrderProService.java index e4eb8f6..2d7a9a9 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/IProcessOrderProService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/IProcessOrderProService.java @@ -3,11 +3,12 @@ package com.ruoyi.system.service; import com.ruoyi.common.core.domain.R; import com.ruoyi.system.domain.ProcessOrderPro; import com.ruoyi.system.domain.ProcessRoute; +import com.ruoyi.system.domain.bo.FigureSaveBo; import com.ruoyi.system.domain.vo.ProcessOrderProVo; import com.ruoyi.system.domain.bo.ProcessOrderProBo; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.domain.PageQuery; -import org.springframework.beans.PropertyValues; +import org.springframework.web.multipart.MultipartFile; import java.util.Collection; import java.util.List; @@ -58,4 +59,17 @@ public interface IProcessOrderProService { void batchUpdateProjectTimeRanges(); List selectByProjectNumbers(Set routeDescSet); + + void addProduct(FigureSaveBo bo, ProcessOrderProBo orderPro); + + String executDrawing(ProcessOrderProBo orderPro); + + /** + * 上传PDF并生成zip包 + * @param id 项目ID + * @return zip包路径 + */ + R uploadPDF(Long id); + + String uploadContractPDF(Integer id, String originalFilename, MultipartFile filePath); } 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 3ec9c33..dcfb4e4 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 @@ -8,14 +8,12 @@ import com.ruoyi.system.domain.MaterialBom; import com.ruoyi.system.domain.ProcessRoute; import com.ruoyi.system.domain.bo.ProcessRouteBo; import com.ruoyi.system.domain.dto.*; -import com.ruoyi.system.domain.vo.RouteVo; import com.ruoyi.system.jdmain.rouplan.Model; import com.ruoyi.system.domain.vo.ProcessRouteVo; import com.ruoyi.system.domain.vo.ProductionOrderVo; import java.util.Collection; import java.util.List; -import java.util.Map; /** * 工艺路线Service接口 @@ -131,6 +129,7 @@ public interface IProcessRouteService { Double getFaWorkTime(BomDetails material); //根据令号和物料编码 查询工艺路线 List getProcessRoutesByOrder(String productionOrderNo, String materialCode); + //根据物料编码查询工艺路线 List getSingleWeght( String materialCode); List updateProcesTime(String rooteProdet) throws Exception; @@ -140,5 +139,6 @@ public interface IProcessRouteService { List getProcessMaterialListAll(String routeDescription); List getProcessRouteGD(List list); - + //获取物料首个工序的工作中心 + String getRouteCode(String materialCode,String code); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/IProductionOrderService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/IProductionOrderService.java index a1f37ca..7a60c2e 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/IProductionOrderService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/IProductionOrderService.java @@ -1,6 +1,8 @@ package com.ruoyi.system.service; import com.ruoyi.system.domain.ProductionOrder; +import com.ruoyi.system.domain.bo.FigureSaveBo; +import com.ruoyi.system.domain.bo.ProcessOrderProBo; import com.ruoyi.system.domain.vo.ProductionOrderVo; import com.ruoyi.system.domain.bo.ProductionOrderBo; import com.ruoyi.common.core.page.TableDataInfo; @@ -52,4 +54,6 @@ public interface IProductionOrderService { List getGroupWeld(ProductionOrderVo productionOrderVo); List getGroupWeldSubset(ProductionOrderVo productionOrderVo); + + Boolean executDrawing(ProcessOrderProBo orderPro); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysConfigIniService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysConfigIniService.java new file mode 100644 index 0000000..f39702a --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysConfigIniService.java @@ -0,0 +1,49 @@ +package com.ruoyi.system.service; + +import com.ruoyi.system.domain.SysConfigIni; +import com.ruoyi.system.domain.vo.SysConfigIniVo; +import com.ruoyi.system.domain.bo.SysConfigIniBo; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.core.domain.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * 图纸配置Service接口 + * + * @author 田志阳 + * @date 2025-07-05 + */ +public interface ISysConfigIniService { + + /** + * 查询图纸配置 + */ + SysConfigIniVo queryById(Long id); + + /** + * 查询图纸配置列表 + */ + TableDataInfo queryPageList(SysConfigIniBo bo, PageQuery pageQuery); + + /** + * 查询图纸配置列表 + */ + List queryList(SysConfigIniBo bo); + + /** + * 新增图纸配置 + */ + Boolean insertByBo(SysConfigIniBo bo); + + /** + * 修改图纸配置 + */ + Boolean updateByBo(SysConfigIniBo bo); + + /** + * 校验并批量删除图纸配置信息 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/FigureSaveServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/FigureSaveServiceImpl.java index 1ecd1e8..60a5cf9 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/FigureSaveServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/FigureSaveServiceImpl.java @@ -15,6 +15,7 @@ import com.ruoyi.system.domain.FigureSave; import com.ruoyi.system.mapper.FigureSaveMapper; import com.ruoyi.system.service.IFigureSaveService; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Collection; @@ -61,10 +62,12 @@ public class FigureSaveServiceImpl implements IFigureSaveService { private LambdaQueryWrapper buildQueryWrapper(FigureSaveBo bo) { Map params = bo.getParams(); LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(bo.getPid() !=null, FigureSave::getPid, bo.getPid()); lqw.eq(StringUtils.isNotBlank(bo.getFigureNumber()), FigureSave::getFigureNumber, bo.getFigureNumber()); lqw.like(StringUtils.isNotBlank(bo.getFigureName()), FigureSave::getFigureName, bo.getFigureName()); lqw.eq(bo.getFigureNum() != null, FigureSave::getFigureNum, bo.getFigureNum()); lqw.eq(bo.getJdInventory() != null, FigureSave::getJdInventory, bo.getJdInventory()); + lqw.eq(StringUtils.isNotBlank(bo.getDrawPath()), FigureSave::getDrawPath, bo.getDrawPath()); lqw.eq(StringUtils.isNotBlank(bo.getProductionCode()), FigureSave::getProductionCode, bo.getProductionCode()); return lqw; } @@ -110,4 +113,16 @@ public class FigureSaveServiceImpl implements IFigureSaveService { } return baseMapper.deleteBatchIds(ids) > 0; } + + /** + * @param id + * @return + */ + @Override + public List selectByFid(Long id) { + LambdaQueryWrapper wa = new LambdaQueryWrapper<>(); + wa.eq(FigureSave::getPid,id); + + return baseMapper.selectList(wa); + } } 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 720cf4e..6a935c5 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 @@ -728,7 +728,7 @@ public class ImMaterialServiceImpl implements IImMaterialService { JSONArray materialsArray = new JSONArray(jsonArray.toString()); Map existingMaterialsMap = getMaterialsMapByCodes(materialsArray); - logger.info("获取全部物料条数为==> " + existingMaterialsMap.size() + " 条"); + logger.info("获取全部物料条数为==> {} 条", existingMaterialsMap.size()); List materialsToSave = new ArrayList<>(); int size = materialsArray.size(); diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/PcRigidChainServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/PcRigidChainServiceImpl.java new file mode 100644 index 0000000..7b02fa1 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/PcRigidChainServiceImpl.java @@ -0,0 +1,139 @@ +package com.ruoyi.system.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.ruoyi.common.core.page.TableDataInfo; +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.StringUtils; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import com.ruoyi.system.domain.bo.PcRigidChainBo; +import com.ruoyi.system.domain.vo.PcRigidChainVo; +import com.ruoyi.system.domain.PcRigidChain; +import com.ruoyi.system.mapper.PcRigidChainMapper; +import com.ruoyi.system.service.IPcRigidChainService; + +import java.util.List; +import java.util.Map; +import java.util.Collection; +import java.util.ArrayList; +import java.util.Set; + +/** + * 销齿链型号管理Service业务层处理 + * + * @author 田志阳 + * @date 2025-07-07 + */ +@RequiredArgsConstructor +@Service +public class PcRigidChainServiceImpl implements IPcRigidChainService { + + private final PcRigidChainMapper baseMapper; + + /** + * 查询销齿链型号管理 + */ + @Override + public PcRigidChainVo queryById(Long id){ + return baseMapper.selectVoById(id); + } + + /** + * 查询销齿链型号管理列表 + */ + @Override + public TableDataInfo queryPageList(PcRigidChainBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询销齿链型号管理列表 + */ + @Override + public List queryList(PcRigidChainBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(PcRigidChainBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(StringUtils.isNotBlank(bo.getType()), PcRigidChain::getType, bo.getType()); + lqw.like(StringUtils.isNotBlank(bo.getTypeName()), PcRigidChain::getTypeName, bo.getTypeName()); + lqw.like(StringUtils.isNotBlank(bo.getProductName()), PcRigidChain::getProductName, bo.getProductName()); + lqw.like(StringUtils.isNotBlank(bo.getMaterialCode()), PcRigidChain::getMaterialCode, bo.getMaterialCode()); + return lqw; + } + + /** + * 新增销齿链型号管理 + */ + @Override + public Boolean insertByBo(PcRigidChainBo bo) { + PcRigidChain add = BeanUtil.toBean(bo, PcRigidChain.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setId(add.getId()); + } + return flag; + } + + /** + * 修改销齿链型号管理 + */ + @Override + public Boolean updateByBo(PcRigidChainBo bo) { + PcRigidChain update = BeanUtil.toBean(bo, PcRigidChain.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(PcRigidChain entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 批量删除销齿链型号管理 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteBatchIds(ids) > 0; + } + + /** + * @param figureNumber + * @return + */ + @Override + public PcRigidChain selectPcRigidChainByTypeName(String figureNumber) { + LambdaQueryWrapper pcRigidChainLambdaQueryWrapper = new LambdaQueryWrapper<>(); + pcRigidChainLambdaQueryWrapper.eq(PcRigidChain::getTypeName, figureNumber); + return baseMapper.selectOne(pcRigidChainLambdaQueryWrapper); + + } + + /** + * 根据型号名称集合批量查询销齿链型号管理 + */ + @Override + public List selectByTypeNames(Set typeNames) { + if (typeNames == null || typeNames.isEmpty()) { + return new ArrayList<>(); + } + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.in(PcRigidChain::getTypeName, typeNames); + return baseMapper.selectList(wrapper); + } +} 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 dc7fb05..419e23f 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 @@ -1,277 +1,996 @@ -package com.ruoyi.system.service.impl; - -import cn.hutool.core.bean.BeanUtil; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.ruoyi.common.core.domain.R; -import com.ruoyi.common.core.page.TableDataInfo; -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.ProcessRoute; -import com.ruoyi.system.mapper.ProcessRouteMapper; -import com.ruoyi.system.service.IProcessRouteService; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.BeanUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import com.ruoyi.system.domain.bo.ProcessOrderProBo; -import com.ruoyi.system.domain.vo.ProcessOrderProVo; -import com.ruoyi.system.domain.ProcessOrderPro; -import com.ruoyi.system.mapper.ProcessOrderProMapper; -import com.ruoyi.system.service.IProcessOrderProService; -import com.ruoyi.common.utils.StringUtils; - -import java.util.*; -import java.util.stream.Collectors; - -/** - * 项目令号Service业务层处理 - * - * @author tzy - * @date 2024-10-22 - */ -@RequiredArgsConstructor -@Service -@Slf4j -public class ProcessOrderProServiceImpl implements IProcessOrderProService { - - private final ProcessOrderProMapper baseMapper; - @Autowired - private ProcessRouteMapper processRouteMapper; - - - private final IProcessRouteService iProcessRouteService; - /** - * 查询项目令号 - */ - @Override - public ProcessOrderProVo queryById(Long id){ - return baseMapper.selectVoById(id); - } - - /** - * 查询项目令号列表 - */ - @Override - public TableDataInfo queryPageList(ProcessOrderProBo bo, PageQuery pageQuery) { - LambdaQueryWrapper lqw = buildQueryWrapper(bo); - Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); - return TableDataInfo.build(result); - } - - /** - * 查询项目令号列表 - */ - @Override - public List queryList(ProcessOrderProBo bo) { - LambdaQueryWrapper lqw = buildQueryWrapper(bo); - return baseMapper.selectVoList(lqw); - } - - private LambdaQueryWrapper buildQueryWrapper(ProcessOrderProBo bo) { - Map params = bo.getParams(); - LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); - lqw.like(StringUtils.isNotBlank(bo.getProductionOrderNo()), ProcessOrderPro::getProductionOrderNo, bo.getProductionOrderNo()); - lqw.like(StringUtils.isNotBlank(bo.getProductionName()), ProcessOrderPro::getProductionName, bo.getProductionName()); - lqw.eq(StringUtils.isNotBlank(bo.getDrawingNo()), ProcessOrderPro::getDrawingNo, bo.getDrawingNo()); - lqw.like(StringUtils.isNotBlank(bo.getDrawingName()), ProcessOrderPro::getDrawingName, bo.getDrawingName()); - lqw.eq(bo.getPlanEndTime() != null, ProcessOrderPro::getPlanEndTime, bo.getPlanEndTime()); - lqw.eq(bo.getPlanStartTime() != null, ProcessOrderPro::getPlanStartTime, bo.getPlanStartTime()); - //按照创建时间排序,最新的在顶端 - lqw.orderByDesc(true,ProcessOrderPro::getCreateTime); - return lqw; - } - - /** - * 新增项目令号 - */ - @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); - boolean flag = baseMapper.insert(add) > 0; - if (flag) { - bo.setId(add.getId()); - } - return flag; - } - - /** - * 修改项目令号 - */ - @Override - public Boolean updateByBo(ProcessOrderProBo bo) { - ProcessOrderPro update = BeanUtil.toBean(bo, ProcessOrderPro.class); - validEntityBeforeSave(update); - return baseMapper.updateById(update) > 0; - } - - /** - * 保存前的数据校验 - */ - private void validEntityBeforeSave(ProcessOrderPro entity){ - //TODO 做一些数据校验,如唯一约束 - if (StringUtils.isBlank(entity.getProductionOrderNo()) ){ - throw new IllegalArgumentException("生产令号不能为空"); - } - LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.eq(ProcessOrderPro::getProductionOrderNo, entity.getProductionOrderNo()); - if (baseMapper.selectCount(queryWrapper) > 0) { - throw new IllegalArgumentException("生产令号已存在"); - } - } - - /** - * 批量删除项目令号 - */ - @Override - public R deleteWithValidByIds(Collection ids, Boolean isValid) { - for (Long id : ids) { - ProcessOrderProVo processOrderProVo = baseMapper.selectVoById(id); - if (processOrderProVo == null) { - log.warn("未找到对应的 ProcessOrderProVo,ID: {}", id); - continue; - } - String productionOrderNo = processOrderProVo.getProductionOrderNo(); - - // 调用 selectByProjectCode 方法并检查结果 - return iProcessRouteService.selectByProjectCode(productionOrderNo); - } - - if (isValid) { - // TODO: 执行业务校验逻辑 - // 例如,检查是否有未完成的订单等 - } - - // 执行批量删除操作 - boolean deleteResult = baseMapper.deleteBatchIds(ids) > 0; - if (deleteResult) { - log.info("成功删除 ID 列表: {}", ids); - } else { - log.error("删除 ID 列表失败: {}", ids); - } - - return R.fail(); - } - - @Override - public List selectProList(ProcessOrderProBo bo) { - LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); - LambdaQueryWrapper eq = wrapper.eq(ProcessRoute::getProcessDescription, bo.getProductionOrderNo()); - return processRouteMapper.selectList(wrapper); - } - - /** - * @param routeDescription - * @return - */ - /** - * @param routeDescription - * @return - */ - @Override - public ProcessOrderProBo selectByProjectNumber(String routeDescription) { - LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); - wrapper.eq(ProcessOrderPro::getProductionOrderNo, routeDescription); - ProcessOrderPro processOrderPro = baseMapper.selectOne(wrapper); - ProcessOrderProBo processOrderProBo = new ProcessOrderProBo(); - - // 添加null检查 - if (processOrderPro != null) { - BeanUtils.copyProperties(processOrderPro, processOrderProBo); - } - - return processOrderProBo; - } - - - /** - * - */ - @Override - public void batchUpdateProjectTimeRanges() { - LambdaQueryWrapper processRouteLambdaQueryWrapper = new LambdaQueryWrapper<>(); - processRouteLambdaQueryWrapper.ne(ProcessRoute::getRouteDescription, "") - .ne(ProcessRoute::getRouteDescription, null) - .ne(ProcessRoute::getXuEndTime, "") - .ne(ProcessRoute::getXuEndTime, null) - .ne(ProcessRoute::getXuStartTime, "") - .ne(ProcessRoute::getXuStartTime, null); - List processRoutes = processRouteMapper.selectList(); - - if (processRoutes == null || processRoutes.isEmpty()) { - log.warn("工艺路线列表为空,无法更新项目令号时间范围"); - return; - } - - // 按项目令号分组 - Map> routesByProject = processRoutes.stream() - .filter(route -> route.getRouteDescription() != null && !route.getRouteDescription().isEmpty()) - .collect(Collectors.groupingBy(ProcessRoute::getRouteDescription)); - - // 处理每个项目令号 - routesByProject.forEach((projectNumber, routes) -> { - try { - // 获取最早的开始时间 - Date earliestStartTime = routes.stream() - .filter(route -> route.getXuStartTime() != null) - .min(Comparator.comparing(ProcessRoute::getXuStartTime)) - .map(ProcessRoute::getXuStartTime) - .orElse(null); - - // 获取最晚的结束时间 - Date latestEndTime = routes.stream() - .filter(route -> route.getXuEndTime() != null) - .max(Comparator.comparing(ProcessRoute::getXuEndTime)) - .map(ProcessRoute::getXuEndTime) - .orElse(null); - - // 更新至计划模块中 - if (earliestStartTime != null && latestEndTime != null) { - ProcessOrderProBo processOrderPro = selectByProjectNumber(projectNumber); - - if (processOrderPro != null) { - processOrderPro.setPlanStartTime(earliestStartTime); - processOrderPro.setPlanEndTime(latestEndTime); - processOrderPro.setUpdateTime(new Date()); - - log.info("更新计划生成令号为:{}, 计划开始时间:{}, 计划结束时间:{}", - projectNumber, earliestStartTime, latestEndTime); - ProcessOrderPro processOrderPro1 = new ProcessOrderPro(); - BeanUtils.copyProperties(processOrderPro, processOrderPro1); - baseMapper.updateById(processOrderPro1); - } else { - log.warn("未找到项目令号为{}的计划信息", projectNumber); - } - } else { - log.warn("项目令号{}的工艺路线中没有有效的开始时间或结束时间,跳过更新", projectNumber); - } - } catch (Exception e) { - log.error("更新项目令号{}的时间范围时发生错误", projectNumber, e); - } - }); - } - - /** - * @param routeDescSet - * @return - */ - @Override - public List selectByProjectNumbers(Set routeDescSet) { - if (routeDescSet == null || routeDescSet.isEmpty()) { - return Collections.emptyList(); - } - QueryWrapper qw = new QueryWrapper<>(); - qw.in("production_order_no", routeDescSet); - return baseMapper.selectList(qw); - } - -} +package com.ruoyi.system.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.lowagie.text.Rectangle; +import com.lowagie.text.pdf.PdfReader; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.page.TableDataInfo; +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.FtpUtil; +import com.ruoyi.common.utils.HttpUtils; +import com.ruoyi.common.utils.WxRobotUtil; +import com.ruoyi.common.utils.file.DeleteFile; +import com.ruoyi.common.utils.file.PDFDocHelper; + +import com.ruoyi.system.domain.*; +import com.ruoyi.system.domain.bo.FigureSaveBo; +import com.ruoyi.system.domain.dto.excuteDrawing.DataInfo; +import com.ruoyi.system.domain.dto.excuteDrawing.ProductInfo; +import com.ruoyi.system.domain.dto.excuteDrawing.PwProductionBill; +import com.ruoyi.system.listener.FileToZip; +import com.ruoyi.system.listener.SmbUtils; +import com.ruoyi.system.mapper.FigureSaveMapper; +import com.ruoyi.system.mapper.ProcessRouteMapper; +import com.ruoyi.system.service.IFigureSaveService; +import com.ruoyi.system.service.IPcRigidChainService; +import com.ruoyi.system.service.IProcessRouteService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.system.domain.bo.ProcessOrderProBo; +import com.ruoyi.system.domain.vo.ProcessOrderProVo; +import com.ruoyi.system.mapper.ProcessOrderProMapper; +import com.ruoyi.system.service.IProcessOrderProService; +import com.ruoyi.common.utils.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import java.io.*; +import java.nio.file.Paths; +import java.util.*; +import java.util.stream.Collectors; +import java.util.function.Function; +import java.util.concurrent.CompletableFuture; + +/** + * 项目令号Service业务层处理 + * + * @author tzy + * @date 2024-10-22 + */ +@RequiredArgsConstructor +@Service +@Slf4j +public class ProcessOrderProServiceImpl implements IProcessOrderProService { + private final FigureSaveMapper figureSaveMapper; + + private final ProcessOrderProMapper baseMapper; + @Autowired + private ProcessRouteMapper processRouteMapper; + + @Autowired + private IPcRigidChainService pcRigidChainService; + private final IProcessRouteService iProcessRouteService; + + private static final String FILE_EXTENSION = ".xlsx"; // 目标文件后缀 + private static final String LOCAL_DIR = "D:/file/"; + private static final String ROBOTID = "8af8abea-3f21-4ca7-ad0a-5b7a2cf4d78e"; + // 企业ID + public static final String corpsecret = "ww3cd1a87df502cf3a"; + //应用ID + public static final String corpid = "1000002"; + + @Value("${app.drawing.base-path:F:}") + private String basePath; + + @Value("${app.drawing.year-prefix:20}") + private String yearPrefix; + + @Value("${app.drawing.api-url:http://192.168.5.18:9000/generatedrawingscompatible}") + private String apiUrl; + @Autowired + private IFigureSaveService iFigureSaveService; + + /** + * 查询项目令号 + */ + @Override + public ProcessOrderProVo queryById(Long id) { + return baseMapper.selectVoById(id); + } + + /** + * 查询项目令号列表 + */ + @Override + public TableDataInfo queryPageList(ProcessOrderProBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询项目令号列表 + */ + @Override + public List queryList(ProcessOrderProBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(ProcessOrderProBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.like(StringUtils.isNotBlank(bo.getProductionOrderNo()), ProcessOrderPro::getProductionOrderNo, bo.getProductionOrderNo()); + lqw.like(StringUtils.isNotBlank(bo.getProductionName()), ProcessOrderPro::getProductionName, bo.getProductionName()); + lqw.eq(StringUtils.isNotBlank(bo.getDrawingNo()), ProcessOrderPro::getDrawingNo, bo.getDrawingNo()); + lqw.like(StringUtils.isNotBlank(bo.getDrawingName()), ProcessOrderPro::getDrawingName, bo.getDrawingName()); + lqw.eq(bo.getPlanEndTime() != null, ProcessOrderPro::getPlanEndTime, bo.getPlanEndTime()); + lqw.eq(bo.getPlanStartTime() != null, ProcessOrderPro::getPlanStartTime, bo.getPlanStartTime()); + lqw.eq(StringUtils.isNotBlank(bo.getDrawingType()), ProcessOrderPro::getDrawingType, bo.getDrawingType()); + lqw.eq(bo.getProjectEndTime() != null, ProcessOrderPro::getProjectEndTime, bo.getProjectEndTime()); + lqw.eq(StringUtils.isNotBlank(bo.getUnit()), ProcessOrderPro::getUnit, bo.getUnit()); + lqw.eq(bo.getQuantity() != null, ProcessOrderPro::getQuantity, bo.getQuantity()); + lqw.eq(bo.getIsEnterpriseStandard() != null, ProcessOrderPro::getIsEnterpriseStandard, bo.getIsEnterpriseStandard()); + lqw.eq(bo.getDrawingPath() != null, ProcessOrderPro::getDrawingPath, bo.getDrawingPath()); + //按照创建时间排序,最新的在顶端 + lqw.orderByDesc(true, ProcessOrderPro::getCreateTime); + return lqw; + } + + /** + * 新增项目令号 + */ + @Override + public Boolean insertByBo(ProcessOrderProBo bo) { + // 下载excel文件 + log.info("下载excel文件.." + bo.getProductionOrderNo()); + SmbUtils.downloadExcelFiles(bo.getProductionOrderNo()); + /* //同时推送至企业微信群 + String fileName = LOCAL_DIR + "/" + bo.getProductionOrderNo()+"汇总表" + FILE_EXTENSION; + File file = new File(fileName); + wxRobotUtil.sendFileToWeChatGroup(file, ROBOTID); + //拼接要发送到的信息markdown格式 + String msg = "生产令号:" + bo.getProductionOrderNo() + "\n" + + "生产名称:" + bo.getProductionName() + "\n" + + "图纸号:" + bo.getDrawingNo() + "\n" + + "图纸名称:" + bo.getDrawingName() + "\n" + + "计划完工时间:" + bo.getPlanEndTime() + "\n" + + "计划开工时间:" + bo.getPlanStartTime() + "\n" ; + wxRobotUtil.sendMsgToWeChatGroup(msg, ROBOTID,true);*/ + ProcessOrderPro add = BeanUtil.toBean(bo, ProcessOrderPro.class); + + + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setId(add.getId()); + } + return flag; + } + + /** + * 修改项目令号 + */ + @Override + public Boolean updateByBo(ProcessOrderProBo bo) { + ProcessOrderPro update = BeanUtil.toBean(bo, ProcessOrderPro.class); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(ProcessOrderPro entity) { + //TODO 做一些数据校验,如唯一约束 + if (StringUtils.isBlank(entity.getProductionOrderNo())) { + throw new IllegalArgumentException("生产令号不能为空"); + } + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(ProcessOrderPro::getProductionOrderNo, entity.getProductionOrderNo()); + if (baseMapper.selectCount(queryWrapper) > 0) { + throw new IllegalArgumentException("生产令号已存在"); + } + } + + /** + * 批量删除项目令号 + */ + @Override + public R deleteWithValidByIds(Collection ids, Boolean isValid) { + for (Long id : ids) { + ProcessOrderProVo processOrderProVo = baseMapper.selectVoById(id); + if (processOrderProVo == null) { + log.warn("未找到对应的 ProcessOrderProVo,ID: {}", id); + continue; + } + String productionOrderNo = processOrderProVo.getProductionOrderNo(); + + // 调用 selectByProjectCode 方法并检查结果 + return iProcessRouteService.selectByProjectCode(productionOrderNo); + } + + if (isValid) { + // TODO: 执行业务校验逻辑 + // 例如,检查是否有未完成的订单等 + } + + // 执行批量删除操作 + boolean deleteResult = baseMapper.deleteBatchIds(ids) > 0; + if (deleteResult) { + log.info("成功删除 ID 列表: {}", ids); + } else { + log.error("删除 ID 列表失败: {}", ids); + } + + return R.fail(); + } + + @Override + public List selectProList(ProcessOrderProBo bo) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + LambdaQueryWrapper eq = wrapper.eq(ProcessRoute::getProcessDescription, bo.getProductionOrderNo()); + return processRouteMapper.selectList(wrapper); + } + + /** + * @param routeDescription + * @return + */ + /** + * @param routeDescription + * @return + */ + @Override + public ProcessOrderProBo selectByProjectNumber(String routeDescription) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(ProcessOrderPro::getProductionOrderNo, routeDescription); + ProcessOrderPro processOrderPro = baseMapper.selectOne(wrapper); + ProcessOrderProBo processOrderProBo = new ProcessOrderProBo(); + + // 添加null检查 + if (processOrderPro != null) { + BeanUtils.copyProperties(processOrderPro, processOrderProBo); + } + + return processOrderProBo; + } + + + /** + * + */ + @Override + public void batchUpdateProjectTimeRanges() { + LambdaQueryWrapper processRouteLambdaQueryWrapper = new LambdaQueryWrapper<>(); + processRouteLambdaQueryWrapper.ne(ProcessRoute::getRouteDescription, "").ne(ProcessRoute::getRouteDescription, null).ne(ProcessRoute::getXuEndTime, "").ne(ProcessRoute::getXuEndTime, null).ne(ProcessRoute::getXuStartTime, "").ne(ProcessRoute::getXuStartTime, null); + List processRoutes = processRouteMapper.selectList(); + + if (processRoutes == null || processRoutes.isEmpty()) { + log.warn("工艺路线列表为空,无法更新项目令号时间范围"); + return; + } + + // 按项目令号分组 + Map> routesByProject = processRoutes.stream().filter(route -> route.getRouteDescription() != null && !route.getRouteDescription().isEmpty()).collect(Collectors.groupingBy(ProcessRoute::getRouteDescription)); + + // 处理每个项目令号 + routesByProject.forEach((projectNumber, routes) -> { + try { + // 获取最早的开始时间 + Date earliestStartTime = routes.stream().filter(route -> route.getXuStartTime() != null).min(Comparator.comparing(ProcessRoute::getXuStartTime)).map(ProcessRoute::getXuStartTime).orElse(null); + + // 获取最晚的结束时间 + Date latestEndTime = routes.stream().filter(route -> route.getXuEndTime() != null).max(Comparator.comparing(ProcessRoute::getXuEndTime)).map(ProcessRoute::getXuEndTime).orElse(null); + + // 更新至计划模块中 + if (earliestStartTime != null && latestEndTime != null) { + ProcessOrderProBo processOrderPro = selectByProjectNumber(projectNumber); + + if (processOrderPro != null) { + processOrderPro.setPlanStartTime(earliestStartTime); + processOrderPro.setPlanEndTime(latestEndTime); + processOrderPro.setUpdateTime(new Date()); + + log.info("更新计划生成令号为:{}, 计划开始时间:{}, 计划结束时间:{}", projectNumber, earliestStartTime, latestEndTime); + ProcessOrderPro processOrderPro1 = new ProcessOrderPro(); + BeanUtils.copyProperties(processOrderPro, processOrderPro1); + baseMapper.updateById(processOrderPro1); + } else { + log.warn("未找到项目令号为{}的计划信息", projectNumber); + } + } else { + log.warn("项目令号{}的工艺路线中没有有效的开始时间或结束时间,跳过更新", projectNumber); + } + } catch (Exception e) { + log.error("更新项目令号{}的时间范围时发生错误", projectNumber, e); + } + }); + } + + /** + * @param routeDescSet + * @return + */ + @Override + public List selectByProjectNumbers(Set routeDescSet) { + if (routeDescSet == null || routeDescSet.isEmpty()) { + return Collections.emptyList(); + } + QueryWrapper qw = new QueryWrapper<>(); + qw.in("production_order_no", routeDescSet); + return baseMapper.selectList(qw); + } + + /** + * @param bo + */ + @Override + public void addProduct(FigureSaveBo bo, ProcessOrderProBo orderPro) { + FigureSave figureSave = new FigureSave(); + BeanUtils.copyProperties(bo, figureSave); + figureSaveMapper.insert(figureSave); + } + + /** + * @param orderPro + * @return + */ + @Override + public String executDrawing(ProcessOrderProBo orderPro) { + // 1. 参数验证 + validateOrderPro(orderPro); + + // 2. 查询生产令号是否重复 + ProcessOrderPro processOrderPro = checkProductionOrderExists(orderPro.getProductionOrderNo()); + + // 3. 构建路径 + String dirPath = buildDirectoryPath(orderPro.getProductionOrderNo()); + createDirectoryIfNotExists(dirPath); + + // 4. 构建生产单据 + PwProductionBill pwProductionBill = buildProductionBill(orderPro, dirPath); + + // 5. 获取产品信息 + List productInfos = buildProductInfos(orderPro.getId()); + pwProductionBill.setProduct(productInfos); + + // 6. 调用API + return callDrawingApi(pwProductionBill); + } + + + private void validateOrderPro(ProcessOrderProBo orderPro) { + if (orderPro == null || StringUtils.isBlank(orderPro.getProductionOrderNo())) { + throw new IllegalArgumentException("生产令号不能为空"); + } + if (orderPro.getProjectEndTime() == null) { + throw new IllegalArgumentException("项目结束时间不能为空"); + } + } + + private ProcessOrderPro checkProductionOrderExists(String productionOrderNo) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(ProcessOrderPro::getProductionOrderNo, productionOrderNo); + ProcessOrderPro processOrderPro = baseMapper.selectOne(wrapper); + + log.info("查询生产令号:{} 是否重复...", productionOrderNo); + return processOrderPro; + } + + private String buildDirectoryPath(String productionOrderNo) { + String yearPart = extractYearPart(productionOrderNo); + String dirPath = Paths.get(basePath, yearPrefix + yearPart).toString(); + log.info("生产令号:{} 生成路径:{}", productionOrderNo, dirPath); + return dirPath.replace(File.separator, "\\"); + } + + private String extractYearPart(String code) { + if (code.length() < 5 || !code.contains("-")) { + throw new IllegalArgumentException("生产令号格式不正确"); + } + return "-".equals(code.substring(2, 3)) ? code.substring(3, 5) : code.substring(2, 4); + } + + private void createDirectoryIfNotExists(String dirPath) { + //远程创建目录 + try { + File file = new File(dirPath); + if (!file.exists() && !file.mkdirs()) { + throw new RuntimeException("无法创建目录: " + dirPath); + } + } catch (Exception e) { + log.error("创建目录失败: {}", dirPath, e); + throw new RuntimeException("创建目录失败", e); + } + } + + private PwProductionBill buildProductionBill(ProcessOrderProBo orderPro, String dirPath) { + PwProductionBill pwProductionBill = new PwProductionBill(); + pwProductionBill.setDestpath(dirPath); + pwProductionBill.setProducitonorder(orderPro.getProductionOrderNo()); + pwProductionBill.setReleasedate(String.valueOf(orderPro.getProjectEndTime())); + return pwProductionBill; + } + + private List buildProductInfos(Long orderId) { + // 查询FigureSave + List productionOrders = figureSaveMapper.selectList(new LambdaQueryWrapper().eq(FigureSave::getPid, orderId)); + + // 批量查询PcRigidChain,避免N+1问题 + Set figureNumbers = productionOrders.stream().map(FigureSave::getFigureNumber).collect(Collectors.toSet()); + Map rigidChainMap = pcRigidChainService.selectByTypeNames(figureNumbers).stream().collect(Collectors.toMap(PcRigidChain::getTypeName, Function.identity())); + + return productionOrders.stream().map(figureSave -> buildProductInfo(figureSave, rigidChainMap.get(figureSave.getFigureNumber()))).collect(Collectors.toList()); + } + + private ProductInfo buildProductInfo(FigureSave figureSave, PcRigidChain rigidChain) { + ProductInfo productInfo = new ProductInfo(); + productInfo.setAssembledrawing(figureSave.getFigureNumber()); + productInfo.setNumber(String.valueOf(figureSave.getFigureNum())); + productInfo.setSourcefile( figureSave.getDrawPath().replace("/","\\")); + + log.info("项目生产令号为:{}查询产品型号信息: {}+ 产品名称: {}", figureSave.getProductionCode(), figureSave.getFigureNumber(), figureSave.getFigureName()); + + DataInfo datainfo = buildDataInfo(rigidChain); + productInfo.setVars(datainfo); + + return productInfo; + } + + private DataInfo buildDataInfo(PcRigidChain rigidChain) { + DataInfo datainfo = new DataInfo(); + if (rigidChain != null) { + setDataInfoFields(datainfo, rigidChain); + } + return datainfo; + } + + private void setDataInfoFields(DataInfo datainfo, PcRigidChain rigidChain) { + if (rigidChain == null) { + return; + } + + // 直接设置字段值到datainfo对象 + datainfo.setV1(String.valueOf(rigidChain.getVOne())); + datainfo.setV2(String.valueOf(rigidChain.getVTwo())); + datainfo.setV3(String.valueOf(rigidChain.getVThree())); + datainfo.setV4(String.valueOf(rigidChain.getVFour())); + datainfo.setV5(String.valueOf(rigidChain.getVFive())); + datainfo.setV6(String.valueOf(rigidChain.getVSix())); + datainfo.setV7(String.valueOf(rigidChain.getVSeven())); + datainfo.setV8(String.valueOf(rigidChain.getVEight())); + datainfo.setV9(String.valueOf(rigidChain.getVNine())); + datainfo.setV10(String.valueOf(rigidChain.getVTen())); + datainfo.setV11(String.valueOf(rigidChain.getVEleven())); + datainfo.setV12(String.valueOf(rigidChain.getVTwelve())); + datainfo.setV13(String.valueOf(rigidChain.getVThirteen())); + datainfo.setV14(String.valueOf(rigidChain.getVFourteen())); + datainfo.setV15(String.valueOf(rigidChain.getVFifteen())); + datainfo.setV16(String.valueOf(rigidChain.getVSixteen())); + datainfo.setV17(String.valueOf(rigidChain.getVSeveteen())); + datainfo.setV18(String.valueOf(rigidChain.getVEighteen())); + datainfo.setV19(String.valueOf(rigidChain.getVNineteen())); + datainfo.setV20(String.valueOf(rigidChain.getVTwenty())); + datainfo.setV21(String.valueOf(rigidChain.getVTwentyOne())); + datainfo.setV22(String.valueOf(rigidChain.getVTwentyTwo())); + datainfo.setV23(String.valueOf(rigidChain.getVTwentyThree())); + datainfo.setV24(String.valueOf(rigidChain.getVTwentyFour())); + datainfo.setV25(String.valueOf(rigidChain.getVTwentyFive())); + datainfo.setV26(String.valueOf(rigidChain.getVTwentySix())); + datainfo.setV27(String.valueOf(rigidChain.getVTwentySeven())); + datainfo.setV28(String.valueOf(rigidChain.getVTwentyEight())); + datainfo.setV29(String.valueOf(rigidChain.getVTwentyNine())); + datainfo.setV30(String.valueOf(rigidChain.getVThirty())); + datainfo.setV31(String.valueOf(rigidChain.getVThirtyOne())); + datainfo.setV32(String.valueOf(rigidChain.getVThirtyTwo())); + datainfo.setV33(String.valueOf(rigidChain.getVThirtyThree())); + datainfo.setV34(String.valueOf(rigidChain.getVThirtyFour())); + datainfo.setV35(String.valueOf(rigidChain.getVThirtyFive())); + datainfo.setV36(String.valueOf(rigidChain.getVThirtySix())); + datainfo.setV37(String.valueOf(rigidChain.getVThirtySeven())); + datainfo.setV38(String.valueOf(rigidChain.getVThirtyEight())); + datainfo.setV39(String.valueOf(rigidChain.getVThirtyNine())); + datainfo.setV40(String.valueOf(rigidChain.getVForty())); + datainfo.setV41(String.valueOf(rigidChain.getVFortyOne())); + datainfo.setV42(String.valueOf(rigidChain.getVFortyTwo())); + datainfo.setV43(String.valueOf(rigidChain.getVFortyThree())); + datainfo.setV44(String.valueOf(rigidChain.getVFortyFour())); + datainfo.setV45(String.valueOf(rigidChain.getVFortyFive())); + datainfo.setV46(String.valueOf(rigidChain.getVFortySix())); + datainfo.setV47(String.valueOf(rigidChain.getVFortySeven())); + datainfo.setV48(String.valueOf(rigidChain.getVFortyEight())); + datainfo.setV49(String.valueOf(rigidChain.getVFortyNine())); + datainfo.setV50(String.valueOf(rigidChain.getVFifty())); + datainfo.setV51(String.valueOf(rigidChain.getVFiftyOne())); + datainfo.setV52(String.valueOf(rigidChain.getVFiftyTwo())); + datainfo.setV53(String.valueOf(rigidChain.getVFiftyThree())); + + datainfo.setG1(String.valueOf(rigidChain.getGOne())); + datainfo.setG2(String.valueOf(rigidChain.getGTwo())); + datainfo.setG3(String.valueOf(rigidChain.getGThree())); + datainfo.setG4(String.valueOf(rigidChain.getGFour())); + datainfo.setG5(String.valueOf(rigidChain.getGFive())); + datainfo.setG6(String.valueOf(rigidChain.getGSix())); + datainfo.setG7(String.valueOf(rigidChain.getGSeven())); + datainfo.setG8(String.valueOf(rigidChain.getGEight())); + datainfo.setG9(String.valueOf(rigidChain.getGNine())); + datainfo.setG10(String.valueOf(rigidChain.getGTen())); + datainfo.setG11(String.valueOf(rigidChain.getGEleven())); + datainfo.setG12(String.valueOf(rigidChain.getGTwelve())); + datainfo.setG13(String.valueOf(rigidChain.getGThirteen())); + datainfo.setG14(String.valueOf(rigidChain.getGFourteen())); + datainfo.setG15(String.valueOf(rigidChain.getGFifteen())); + datainfo.setG16(String.valueOf(rigidChain.getGSixteen())); + datainfo.setG17(String.valueOf(rigidChain.getGSeveteen())); + datainfo.setG18(String.valueOf(rigidChain.getGEighteen())); + datainfo.setG19(String.valueOf(rigidChain.getGNineteen())); + datainfo.setG20(String.valueOf(rigidChain.getGTwenty())); + } + + private String callDrawingApi(PwProductionBill pwProductionBill) { + try { + String drawingDate = JSONObject.toJSONString(pwProductionBill); + log.info("请求出图报文=====>{}", drawingDate); + return HttpUtils.sendPost(apiUrl, drawingDate); + } catch (Exception e) { + log.error("调用图纸生成API失败", e); + throw new RuntimeException("图纸生成失败", e); + } + } + + /** + * @param id + */ + @Override + public R uploadPDF(Long id) { + try { + // 2. 查询项目信息 + ProcessOrderPro processOrderPro = baseMapper.selectById(id); + if (processOrderPro == null) { + return R.fail("项目不存在"); + } + + String code = processOrderPro.getProductionOrderNo(); + log.info("开始处理项目PDF文件,项目令号: {}", code); + + // 3. 查询产品信息 + List fiseList = iFigureSaveService.selectByFid(id); + if (fiseList == null || fiseList.isEmpty()) { + return R.fail("项目下没有找到产品信息"); + } + + // 4. 构建本地根目录 + String localBaseDir = "F:/2025/"; + // 5. 下载FTP文件到本地 + log.info("开始从FTP下载文件..."); + for (FigureSave figureSave : fiseList) { + try { + // 拼接远程文件夹路径 + String ftpPath = "/" + code + "/" + figureSave.getFigureNumber().replace("/", "-") + "-PDF"; + // 拼接本地存储路径 + String localPath = localBaseDir + code + "/" + figureSave.getFigureNumber().replace("/", "-") + "-PDF"; + + log.info("下载路径: {} -> {}", ftpPath, localPath); + + // 创建本地文件夹 + File localDir = new File(localPath); + if (!localDir.exists()) { + if (!localDir.mkdirs()) { + log.error("无法创建本地目录: {}", localPath); + return R.fail("无法创建本地目录: " + localPath); + } + } + + // 下载对应文件夹 + R downloadResult = FtpUtil.downloadFtpDirectoryFiles("192.168.5.18", "admin", "hbyt2025", 21, ftpPath, localPath); + + if (downloadResult.getCode() != 200) { + log.error("FTP下载失败: {}", downloadResult.getMsg()); + return R.fail("FTP下载失败: " + downloadResult.getMsg()); + } + + log.info("FTP下载成功: {}", downloadResult.getData()); + + } catch (Exception e) { + log.error("下载产品文件失败: {}", figureSave.getFigureNumber(), e); + return R.fail("下载产品文件失败: " + figureSave.getFigureNumber() + " - " + e.getMessage()); + } + } + + // 6. 构建工作目录 + String arr = buildWorkDirectory(code); + + // 7. 清理并创建工作目录 + if (!createWorkDirectories(arr, code)) { + return R.fail("创建工作目录失败"); + } + + // 8. 处理PDF文件 + if (!processPDFFiles(arr, code, fiseList)) { + return R.fail("处理PDF文件失败"); + } + + // 8.1 分类PDF到工作中心文件夹 + String pdfDir = arr + code + "/zip"; + classifyPdfByWorkCenter(pdfDir, code); + + // 9. 生成ZIP包 + String zipDir = arr + code + "/zip"; + String zipPath = arr + code + "/" + code + ".zip"; // 生成到外层目录 + boolean zipSuccess = FileToZip.fileToZip(zipDir, arr + code, code); // 目标目录为外层 + + if (!zipSuccess) { + return R.fail("生成ZIP包失败"); + } + + // 10. 验证ZIP文件是否存在 + File zipFile = new File(zipPath); + if (!zipFile.exists()) { + return R.fail("ZIP文件生成失败,文件不存在"); + } + + log.info("PDF处理完成,ZIP包路径: {}", zipPath); + return R.ok(zipPath); + + } catch (Exception e) { + log.error("uploadPDF处理失败", e); + return R.fail("处理失败: " + e.getMessage()); + } + } + + /** + * 构建工作目录路径 + */ + private String buildWorkDirectory(String code) { + String arr = ""; + if ("-".equals(code.substring(2, 3))) { + arr += "F:/20" + code.substring(3, 5); + } else { + arr += "F:/20" + code.substring(2, 4); + } + arr += "/"; + return arr; + } + + /** + * 创建工作目录 + */ + private boolean createWorkDirectories(String arr, String code) { + try { + // 清理并创建zip目录 + DeleteFile.deleteDirectory(arr + code + "/zip"); + File filesZip = new File(arr + code + "/zip"); + if (!filesZip.exists() && !filesZip.mkdirs()) { + log.error("无法创建zip目录: {}", filesZip.getAbsolutePath()); + return false; + } + + // 清理并创建bom目录 + DeleteFile.deleteDirectory(arr + code + "/bom"); + File bom = new File(arr + code + "/bom"); + if (!bom.exists() && !bom.mkdirs()) { + log.error("无法创建bom目录: {}, bom.getAbsolutePath()", bom.getAbsolutePath()); + return false; + } + + // 清理并创建bomThree目录 + DeleteFile.deleteDirectory(arr + code + "/bomThree"); + File bomThree = new File(arr + code + "/bomThree"); + if (!bomThree.exists() && !bomThree.mkdirs()) { + log.error("无法创建bomThree目录: {}", bomThree.getAbsolutePath()); + return false; + } + + return true; + } catch (Exception e) { + log.error("创建工作目录失败, e", e); + return false; + } + } + + /** + * 处理PDF文件 + */ + private boolean processPDFFiles(String arr, String code, List fiseList) { + try { + // 获取第一个产品的图号作为处理目录 + String replaceAll = fiseList.get(0).getFigureNumber().replaceAll("/", "-") + "-PDF"; + File f = new File(arr + code + "/" + replaceAll); + + if (!f.exists()) { + log.warn("PDF目录不存在: {}", f.getAbsolutePath()); + return true; // 目录不存在不算错误,可能没有PDF文件 + } + + File[] fa = f.listFiles(); + if (fa == null || fa.length == 0) { + log.warn("PDF目录为空: {}", f.getAbsolutePath()); + return true; + } + + PDFDocHelper pd = new PDFDocHelper(); + PdfReader reader = null; + + for (File fs : fa) { + String name = fs.getName(); + try { + // 读取PDF尺寸 + reader = new PdfReader(arr + code + "/" + replaceAll + "/" + name); + Rectangle pageSize = reader.getPageSize(1); + float height = pageSize.getHeight(); + float width = pageSize.getWidth(); + float[] pawX = {width - 100}; + float[] pawY = {height - 20}; + + // 添加水印信息 + List> reviews = new ArrayList<>(); + Map review = new HashMap<>(); + review.put("result", width + " * " + height); + review.put("type", "1"); + reviews.add(review); + + // 处理PDF文件 + PDFDocHelper.imageWatermark(arr + code + "/" + replaceAll + "/" + name, arr + code, name, "D:/java/tuzhizhang.png", reviews, pawX, pawY); + + // 生成三维BOM版本 + String threeDName = name.substring(name.indexOf("-") + 1); + PDFDocHelper.imageWatermark(arr + code + "/" + replaceAll + "/" + name, arr + code + "/bomThree/" + threeDName, "D:/java/tuzhizhang.png"); + + log.info("PDF处理成功: {}", name); + + } catch (Exception e) { + log.error("处理PDF文件失败: {}", name, e); + return false; + } finally { + if (reader != null) { + try { + reader.close(); + } catch (Exception e) { + log.error("关闭PDF读取器失败", e); + } + } + } + } + + return true; + } catch (Exception e) { + log.error("处理PDF文件过程中发生异常, e", e); + return false; + } + } + + private String extractMaterialCode(String fileName) { + int firstDash = fileName.indexOf("-"); + int dotPdf = fileName.lastIndexOf(".pdf"); + if (firstDash >= 0 && dotPdf > firstDash) { + String code = fileName.substring(firstDash + 1, dotPdf); + return code.replace("--", "/"); + } + return null; + } + + private void classifyPdfByWorkCenter(String pdfDir, String code) { + File dir = new File(pdfDir); + if (!dir.exists() || !dir.isDirectory()) return; + + File[] pdfFiles = dir.listFiles((d, name) -> name.endsWith(".pdf")); + if (pdfFiles == null) return; + + for (File pdf : pdfFiles) { + String materialCode = extractMaterialCode(pdf.getName()); + if (materialCode == null) continue; + + // 查询第一序工作中心 + String workCenter = iProcessRouteService.getRouteCode(materialCode,code); // 你可能需要调整参数 + if (workCenter == null || workCenter.isEmpty()) continue; + + // 创建工作中心文件夹 + File workCenterDir = new File(dir, workCenter); + if (!workCenterDir.exists()) workCenterDir.mkdirs(); + + // 移动PDF + File target = new File(workCenterDir, pdf.getName()); + if (pdf.renameTo(target)) { + log.info("PDF {} 移动到 {}", pdf.getName(), workCenterDir.getAbsolutePath()); + } else { + log.warn("PDF {} 移动失败", pdf.getName()); + } + } + } + + + /** + * @param code + * @param originalFilename + * @return + */ + /* @Override + public String uploadContractPDF1(Integer id, String originalFilename, MultipartFile filePath) { + //获取路径 + FigureSave figureSave1 = figureSaveMapper.selectById(id); + String code = figureSave1.getProductionCode(); + String path = Constants.BASIC_URL; + if (code.contains("XCL") && !code.contains("(")) { + path += Constants.BASIC_URL_BZ + Constants.XCL_URL + code; + } else if (code.contains("ELS")) { + path += Constants.BASIC_URL_BZ + Constants.ELS_URL + code; + } else if (code.contains("EDS")) { + path += Constants.BASIC_URL_BZ + Constants.EDS_URL + code; + } else if (code.contains("WB")) { + path += Constants.BASIC_URL_BZ + Constants.WB_URL + code; + } else if (code.contains("QD")) { + path += Constants.BASIC_URL_BZ + Constants.QD_URL + code; + } else if (code.contains("ZHD")) { + path += Constants.BASIC_URL_BZ + Constants.ZHD_URL + code; + } else if (code.contains("ETK")) { + path += Constants.BASIC_URL_BZ + Constants.ETK_URL + code; + } else if (code.contains("ETT")) { + path += Constants.BASIC_URL_BZ + Constants.ETT_URL + code; + } else if (code.contains("ETP")) { + path += Constants.BASIC_URL_BZ + Constants.ETP_URL + code; + } else if (code.contains("ETH")) { + path += Constants.BASIC_URL_BZ + Constants.ETH_URL + code; + } else { + path += Constants.BASIC_URL_FB ; + } + //创建文件夹 + File files = new File(path); + if (!files.exists()) { + files.mkdir(); + } + + path = path + "/" + originalFilename; + //上传到服务器 + + InputStream is = null; + FileOutputStream fos = null; + BufferedOutputStream bos = null; + try { + is = filePath.getInputStream(); + fos = new FileOutputStream(path); + bos = new BufferedOutputStream(fos); + // 读取输入流并写入文件 + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = is.read(buffer)) != -1) { + bos.write(buffer, 0, bytesRead); + } + + bos.flush(); + } catch (Exception e) { + return "文件上传失败"; + } finally { + try { + if (is != null) { + is.close(); + } + if (bos != null) { + bos.close(); + } + if (fos != null) { + fos.close(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + // 4. 上传到FTP + boolean ftpSuccess = false; + File localFile = new File(path); + try (FileInputStream fis = new FileInputStream(localFile)) { + ftpSuccess = FtpUtil.uploadWithAutoMkdir( + "192.168.5.18", "admin", "hbyt2025", 21, + path, originalFilename, fis + ); + } catch (Exception e) { + e.printStackTrace(); + return "上传到FTP失败"; + } + + if (!ftpSuccess) { + return "上传到FTP失败"; + } + //反写图纸 + figureSave1.setDrawPath(path); + int i = figureSaveMapper.updateById(figureSave1); + if (i == 1) { + return "上传成功"; + } else { + return "上传失败"; + } + + }*/ + @Override + public String uploadContractPDF(Integer id, String originalFilename, MultipartFile filePath) { + // 1. 获取数据 + FigureSave figureSave = figureSaveMapper.selectById(id); + ProcessOrderPro processOrderPro = baseMapper.selectById(figureSave); + if (figureSave == null) return "图纸信息不存在"; + + String code = figureSave.getProductionCode(); + + // 2. 拼接本地路径和FTP路径 + String localPath = Constants.BASIC_URL; + String ftpPath = ""; + + String basePath2 = ""; + if (code.contains("XCL") && !code.contains("(")) { + localPath += Constants.BASIC_URL_BZ + Constants.XCL_URL + code; + ftpPath += Constants.BASIC_URL_BZ + Constants.XCL_URL + code; + } else if (code.contains("ELS")) { + localPath += Constants.BASIC_URL_BZ + Constants.ELS_URL + code; + ftpPath += Constants.BASIC_URL_BZ + Constants.ELS_URL + code; + } else if (code.contains("EDS")) { + localPath += Constants.BASIC_URL_BZ + Constants.EDS_URL + code; + ftpPath += Constants.BASIC_URL_BZ + Constants.EDS_URL + code; + } else if (code.contains("WB")) { + localPath += Constants.BASIC_URL_BZ + Constants.WB_URL + code; + ftpPath += Constants.BASIC_URL_BZ + Constants.WB_URL + code; + } else if (code.contains("QD")) { + localPath += Constants.BASIC_URL_BZ + Constants.QD_URL + code; + ftpPath += Constants.BASIC_URL_BZ + Constants.QD_URL + code; + } else if (code.contains("ZHD")) { + localPath += Constants.BASIC_URL_BZ + Constants.ZHD_URL + code; + ftpPath += Constants.BASIC_URL_BZ + Constants.ZHD_URL + code; + } else if (code.contains("ETK")) { + localPath += Constants.BASIC_URL_BZ + Constants.ETK_URL + code; + ftpPath += Constants.BASIC_URL_BZ + Constants.ETK_URL + code; + } else if (code.contains("ETT")) { + localPath += Constants.BASIC_URL_BZ + Constants.ETT_URL + code; + ftpPath += Constants.BASIC_URL_BZ + Constants.ETT_URL + code; + } else if (code.contains("ETP")) { + localPath += Constants.BASIC_URL_BZ + Constants.ETP_URL + code; + ftpPath += Constants.BASIC_URL_BZ + Constants.ETP_URL + code; + } else if (code.contains("ETH")) { + localPath += Constants.BASIC_URL_BZ + Constants.ETH_URL + code; + ftpPath += Constants.BASIC_URL_BZ + Constants.ETH_URL + code; + } else { + localPath += Constants.BASIC_URL_FB + code; + ftpPath = Constants.BASIC_URL_FB+code; + } + + // 3. 创建本地目录并保存文件 + File localDir = new File(localPath); + if (!localDir.exists()) { + localDir.mkdirs(); // 多级目录 + } + + String fullLocalPath = "/" + originalFilename; + try (InputStream is = filePath.getInputStream(); + FileOutputStream fos = new FileOutputStream(fullLocalPath); + BufferedOutputStream bos = new BufferedOutputStream(fos)) { + + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = is.read(buffer)) != -1) { + bos.write(buffer, 0, bytesRead); + } + bos.flush(); + } catch (IOException e) { + e.printStackTrace(); + return "文件保存本地失败"; + } + String basePath = "/电子档案/1.标准图纸存放文件夹"; + // 4. 上传FTP + boolean ftpSuccess; + try (FileInputStream fis = new FileInputStream(fullLocalPath)) { + ftpSuccess = FtpUtil.uploadFile("192.168.5.18",8022,"admin","hbyt2025", + basePath,ftpPath,originalFilename, fis + ); + } catch (Exception e) { + e.printStackTrace(); + return "上传到FTP失败"; + } + + if (!ftpSuccess) { + return "上传到FTP失败"; + } + + // 5. 反写FTP路径到数据库 + figureSave.setDrawPath("E:"+basePath +ftpPath+ fullLocalPath); + int updateCount = figureSaveMapper.updateById(figureSave); + + return updateCount == 1 ? "上传成功" : "上传失败"; + } + +} 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 95814c7..04398f0 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 @@ -45,6 +45,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; +import java.math.RoundingMode; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; @@ -264,6 +265,25 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { } + + /** + * @param materialCode + * @return + */ + @Override + public String getRouteCode(String materialCode, String code) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(ProcessRoute::getMaterialCode, materialCode) + .eq(ProcessRoute::getRouteDescription, code) + .eq(ProcessRoute::getProcessNo, "10"); + ProcessRoute processRoute = baseMapper.selectOne(wrapper); + if (processRoute == null) { + return "无工段"; + } + return processRoute.getWorkCenter(); + } + + private String generateKey1(BomDetails bomDetail, ProcessRoute processRoute) { return String.format("%s:%s:%s", processRoute.getMaterialCode(), processRoute.getMaterialName(), bomDetail.getName(), bomDetail.getPartNumber()); } @@ -717,10 +737,13 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { // 保留4位小数,转换成米(当单位为 mm 时) if ("mm".equals(unit)) { // 将毫米转换为米并保留4位小数 - materialBom.setQuantity(new BigDecimal(quantity).divide(BigDecimal.valueOf(1000), 4, BigDecimal.ROUND_HALF_UP)); - } else { + materialBom.setQuantity(String.valueOf(new BigDecimal(quantity).divide(BigDecimal.valueOf(1000), 4, RoundingMode.HALF_UP))); + } else if("根".equals(unit)){ + //写入工艺表时分数的体现 直接取分母 以"/"为分割符,取第二个字符串 + materialBom.setQuantity(quantity); + }else { // 其他单位直接使用原值,保留2位小数 - materialBom.setQuantity(new BigDecimal(quantity).setScale(2, BigDecimal.ROUND_HALF_UP)); + materialBom.setQuantity(String.valueOf(new BigDecimal(quantity).setScale(2, RoundingMode.HALF_UP))); } @@ -760,9 +783,12 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { bomDetails.setPartNumber(productionOrderVo.getDrawingNo()); bomDetails.setName(productionOrderVo.getDrawingName()); Double quantity = productionOrderVo.getQuantity(); + bomDetails.setQuantity(quantity != null ? quantity : 0.0); + bomDetails.setDenominator(1.0); bomDetails.setMaterial(productionOrderVo.getMaterial()); String materialCode = productionOrderVo.getDrawingNo(); + if (iMaterialTotalService.getVMIByCode(materialCode)) { bomDetails.setRemarks("VMI"); } else { @@ -809,24 +835,28 @@ public class ProcessRouteServiceImpl implements IProcessRouteService { bomDetails.setFName(processRoute.getMaterialName()); bomDetails.setPartNumber(processRoute.getRawMaterialCode()); bomDetails.setName(processRoute.getRawMaterialName()); - // 添加单重验证和日志 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); // 转换为米 + bomDetails.setQuantity(Double.parseDouble(processRoute.getDiscUsage())/ 1000.0); // 转换为米 + bomDetails.setDenominator(1.0); // 转换为米 } else if ("根".equals(processRoute.getBomUnit())) { - bomDetails.setDenominator(processRoute.getDiscUsage()); - bomDetails.setQuantity(1.0); + // 写入工艺表时分数的体现 直接取分母 以"/"为分割符,取第二个字符串 + String quanity = processRoute.getDiscUsage().split("/")[0]; + String quanity2 = processRoute.getDiscUsage().split("/")[1]; + bomDetails.setQuantity(Double.parseDouble(quanity)); + bomDetails.setDenominator(Double.parseDouble(quanity2)); + bomDetails.setDenominator( Double.parseDouble(processRoute.getDiscUsage().split("/")[1])); + bomDetails.setQuantity(Double.parseDouble(processRoute.getDiscUsage().split("/")[0])); } else { - bomDetails.setQuantity(processRoute.getDiscUsage()); + bomDetails.setQuantity(Double.parseDouble(processRoute.getDiscUsage())); bomDetails.setDenominator(1.0); } - // 根据 RawMaterialCode 判断是否外购 if (isOutsourced(processRoute.getRawMaterialCode())) { bomDetails.setStats("外购"); diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ProductionOrderServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ProductionOrderServiceImpl.java index 186e05b..0904fe5 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ProductionOrderServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ProductionOrderServiceImpl.java @@ -1,15 +1,28 @@ package com.ruoyi.system.service.impl; import cn.hutool.core.bean.BeanUtil; +import com.alibaba.fastjson.JSONObject; import com.ruoyi.common.core.page.TableDataInfo; 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.HttpUtils; +import com.ruoyi.system.domain.FigureSave; +import com.ruoyi.system.domain.PcRigidChain; import com.ruoyi.system.domain.ProcessRoute; +import com.ruoyi.system.domain.bo.FigureSaveBo; +import com.ruoyi.system.domain.bo.ProcessOrderProBo; import com.ruoyi.system.domain.bo.ProcessRouteBo; +import com.ruoyi.system.domain.dto.excuteDrawing.DataInfo; +import com.ruoyi.system.domain.dto.excuteDrawing.ProductInfo; +import com.ruoyi.system.domain.dto.excuteDrawing.PwProductionBill; import com.ruoyi.system.domain.vo.ProcessOrderProVo; +import com.ruoyi.system.mapper.FigureSaveMapper; +import com.ruoyi.system.service.IPcRigidChainService; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.ruoyi.system.domain.bo.ProductionOrderBo; import com.ruoyi.system.domain.vo.ProductionOrderVo; @@ -18,6 +31,8 @@ import com.ruoyi.system.mapper.ProductionOrderMapper; import com.ruoyi.system.service.IProductionOrderService; import com.ruoyi.common.utils.StringUtils; +import java.io.File; +import java.nio.file.Paths; import java.sql.Array; import java.util.*; @@ -29,10 +44,13 @@ import java.util.*; */ @RequiredArgsConstructor @Service +@Slf4j public class ProductionOrderServiceImpl implements IProductionOrderService { private final ProductionOrderMapper baseMapper; - + private final FigureSaveMapper figureSaveMapper; + @Autowired + private IPcRigidChainService pcRigidChainService; /** * 查询生产订单 */ @@ -156,4 +174,140 @@ public class ProductionOrderServiceImpl implements IProductionOrderService { } + @Override + public Boolean executDrawing(ProcessOrderProBo orderPro) { + //查询是否有此令号 + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(ProductionOrder::getProductionOrderNo, orderPro.getProductionOrderNo()); + ProductionOrder productionOrder = baseMapper.selectOne(wrapper); + + log.info("查询生产令号:{} 是否重复...", orderPro.getProductionOrderNo()); + if (productionOrder != null) { + new Throwable("令号重复"); + return false; + } + PwProductionBill pwProductionBill = new PwProductionBill(); + String code = orderPro.getProductionOrderNo(); + String yearPart; + if ("-".equals(code.substring(2, 3))) { + yearPart = code.substring(3, 5); + } else { + yearPart = code.substring(2, 4); + } + String dirPath = Paths.get("F:", "20" + yearPart).toString(); + log.info("生产令号:{} 生成路径:{}", orderPro.getProductionOrderNo(), dirPath); + // pwProductionBill.setDestpath(dirPath.replace(File.separator, "\\")); + pwProductionBill.setDestpath("D:\\EVO_TECH\\EVO程序输出路径"); + // 创建目录(多级) + File file = new File(dirPath); + if (!file.exists()) { + file.mkdirs(); + } + //生产令号 + pwProductionBill.setProducitonorder(orderPro.getProductionOrderNo()); + //出图时间 + pwProductionBill.setReleasedate(String.valueOf(orderPro.getProjectEndTime())); + //产品集合 + List productInfos = new ArrayList<>(); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(FigureSave::getPid, orderPro.getId()); + List productionOrders = figureSaveMapper.selectList(queryWrapper); + ProductInfo productInfo =null; + for (FigureSave figureSave : productionOrders) { + productInfo.setAssembledrawing(figureSave.getFigureNumber()); + // productInfo.setNumber(String.valueOf(figureSave.getFigureNum())); + productInfo.setNumber(String.valueOf(2)); + productInfo.setSourcefile("D:\\EVO_TECH\\EVO程序图\\40S程序图.dwg"); + //设置变量信息 + log.info("项目生产令号为:{}查询产品型号信息: {}+ 产品名称: {}",figureSave.getProductionCode(), figureSave.getFigureNumber(), figureSave.getFigureName()); + PcRigidChain rigidChain = pcRigidChainService.selectPcRigidChainByTypeName(figureSave.getFigureNumber()); + DataInfo datainfo = new DataInfo(); + if(null!=rigidChain){ + datainfo = new DataInfo(); + datainfo.setV1(rigidChain.getVOne().toString()); + datainfo.setV2(rigidChain.getVTwo().toString()); + datainfo.setV3(rigidChain.getVThree().toString()); + datainfo.setV4(rigidChain.getVFour().toString()); + datainfo.setV5(rigidChain.getVFive().toString()); + datainfo.setV6(rigidChain.getVSix().toString()); + datainfo.setV7(rigidChain.getVSeven().toString()); + datainfo.setV8(rigidChain.getVEight().toString()); + datainfo.setV9(rigidChain.getVNine().toString()); + datainfo.setV10(rigidChain.getVTen().toString()); + datainfo.setV11(rigidChain.getVEleven().toString()); + datainfo.setV12(rigidChain.getVTwelve().toString()); + datainfo.setV13(rigidChain.getVThirteen().toString()); + datainfo.setV14(rigidChain.getVFourteen().toString()); + datainfo.setV15(rigidChain.getVFifteen().toString()); + datainfo.setV16(rigidChain.getVSixteen().toString()); + datainfo.setV17(rigidChain.getVSeveteen().toString()); + datainfo.setV18(rigidChain.getVEighteen().toString()); + datainfo.setV19(rigidChain.getVNineteen().toString()); + datainfo.setV20(rigidChain.getVTwenty().toString()); + datainfo.setV21(rigidChain.getVTwentyOne().toString()); + datainfo.setV22(rigidChain.getVTwentyTwo().toString()); + datainfo.setV23(rigidChain.getVTwentyThree().toString()); + datainfo.setV24(rigidChain.getVTwentyFour().toString()); + datainfo.setV25(rigidChain.getVTwentyFive().toString()); + datainfo.setV26(rigidChain.getVTwentySix().toString()); + datainfo.setV27(rigidChain.getVTwentySeven().toString()); + datainfo.setV28(rigidChain.getVTwentyEight().toString()); + datainfo.setV29(rigidChain.getVTwentyNine().toString()); + datainfo.setV30(rigidChain.getVThirty().toString()); + datainfo.setV31(rigidChain.getVThirtyOne().toString()); + datainfo.setV32(rigidChain.getVThirtyTwo().toString()); + datainfo.setV33(rigidChain.getVThirtyThree().toString()); + datainfo.setV34(rigidChain.getVThirtyFour().toString()); + datainfo.setV35(rigidChain.getVThirtyFive().toString()); + datainfo.setV36(rigidChain.getVThirtySix().toString()); + datainfo.setV37(rigidChain.getVThirtySeven().toString()); + datainfo.setV38(rigidChain.getVThirtyEight().toString()); + datainfo.setV39(rigidChain.getVThirtyNine().toString()); + datainfo.setV40(rigidChain.getVForty().toString()); + datainfo.setV41(rigidChain.getVFortyOne().toString()); + datainfo.setV42(rigidChain.getVFortyTwo().toString()); + datainfo.setV43(rigidChain.getVFortyThree().toString()); + datainfo.setV44(rigidChain.getVFortyFour().toString()); + datainfo.setV45(rigidChain.getVFortyFive().toString()); + datainfo.setV46(rigidChain.getVFortySix().toString()); + datainfo.setV47(rigidChain.getVFortySeven().toString()); + datainfo.setV48(rigidChain.getVFortyEight().toString()); + datainfo.setV49(rigidChain.getVFortyNine().toString()); + datainfo.setV50(rigidChain.getVFifty().toString()); + datainfo.setV51(rigidChain.getVFiftyOne().toString()); + datainfo.setV52(rigidChain.getVFiftyTwo().toString()); + datainfo.setV53(rigidChain.getVFiftyThree().toString()); + + datainfo.setG1(rigidChain.getGOne().toString()); + datainfo.setG2(rigidChain.getGTwo().toString()); + datainfo.setG3(rigidChain.getGThree().toString()); + datainfo.setG4(rigidChain.getGFour().toString()); + datainfo.setG5(rigidChain.getGFive().toString()); + datainfo.setG6(rigidChain.getGSix().toString()); + datainfo.setG7(rigidChain.getGSeven().toString()); + datainfo.setG8(rigidChain.getGEight().toString()); + datainfo.setG9(rigidChain.getGNine().toString()); + datainfo.setG10(rigidChain.getGTen().toString()); + datainfo.setG11(rigidChain.getGEleven().toString()); + datainfo.setG12(rigidChain.getGTwelve().toString()); + datainfo.setG13(rigidChain.getGThirteen().toString()); + datainfo.setG14(rigidChain.getGFifteen().toString()); + datainfo.setG15(rigidChain.getGFifteen().toString()); + datainfo.setG16(rigidChain.getGSixteen().toString()); + datainfo.setG17(rigidChain.getGSeveteen().toString()); + datainfo.setG18(rigidChain.getGEighteen().toString()); + datainfo.setG19(rigidChain.getGNineteen().toString()); + datainfo.setG20(rigidChain.getGTwenty().toString()); + } + productInfo.setVars(datainfo); + productInfos.add(productInfo); + } + pwProductionBill.setProduct(productInfos); + String dawingDate = JSONObject.toJSONString(pwProductionBill); + String dataResult = HttpUtils.sendPost("http://192.168.5.23:9000/generatedrawingscompatible", dawingDate); + + return null; + } + + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigIniServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigIniServiceImpl.java new file mode 100644 index 0000000..5fd7b5b --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigIniServiceImpl.java @@ -0,0 +1,111 @@ +package com.ruoyi.system.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.ruoyi.common.core.page.TableDataInfo; +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 lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import com.ruoyi.system.domain.bo.SysConfigIniBo; +import com.ruoyi.system.domain.vo.SysConfigIniVo; +import com.ruoyi.system.domain.SysConfigIni; +import com.ruoyi.system.mapper.SysConfigIniMapper; +import com.ruoyi.system.service.ISysConfigIniService; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 图纸配置Service业务层处理 + * + * @author 田志阳 + * @date 2025-07-05 + */ +@RequiredArgsConstructor +@Service +public class SysConfigIniServiceImpl implements ISysConfigIniService { + + private final SysConfigIniMapper baseMapper; + + /** + * 查询图纸配置 + */ + @Override + public SysConfigIniVo queryById(Long id){ + return baseMapper.selectVoById(id); + } + + /** + * 查询图纸配置列表 + */ + @Override + public TableDataInfo queryPageList(SysConfigIniBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询图纸配置列表 + */ + @Override + public List queryList(SysConfigIniBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(SysConfigIniBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(StringUtils.isNotBlank(bo.getProductDir()), SysConfigIni::getProductDir, bo.getProductDir()); + lqw.eq(StringUtils.isNotBlank(bo.getFileType()), SysConfigIni::getFileType, bo.getFileType()); + lqw.eq(StringUtils.isNotBlank(bo.getFileUrl()), SysConfigIni::getFileUrl, bo.getFileUrl()); + return lqw; + } + + /** + * 新增图纸配置 + */ + @Override + public Boolean insertByBo(SysConfigIniBo bo) { + SysConfigIni add = BeanUtil.toBean(bo, SysConfigIni.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setId(add.getId()); + } + return flag; + } + + /** + * 修改图纸配置 + */ + @Override + public Boolean updateByBo(SysConfigIniBo bo) { + SysConfigIni update = BeanUtil.toBean(bo, SysConfigIni.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(SysConfigIni entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 批量删除图纸配置 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteBatchIds(ids) > 0; + } +} diff --git a/ruoyi-system/src/main/resources/mapper/system/FigureSaveMapper.xml b/ruoyi-system/src/main/resources/mapper/system/FigureSaveMapper.xml index 334349a..9180074 100644 --- a/ruoyi-system/src/main/resources/mapper/system/FigureSaveMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/FigureSaveMapper.xml @@ -6,16 +6,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - + + + - + + - diff --git a/ruoyi-system/src/main/resources/mapper/system/PcRigidChainMapper.xml b/ruoyi-system/src/main/resources/mapper/system/PcRigidChainMapper.xml new file mode 100644 index 0000000..01b295a --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/system/PcRigidChainMapper.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ruoyi-system/src/main/resources/mapper/system/ProcessOrderProMapper.xml b/ruoyi-system/src/main/resources/mapper/system/ProcessOrderProMapper.xml index 586414e..4eef603 100644 --- a/ruoyi-system/src/main/resources/mapper/system/ProcessOrderProMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/ProcessOrderProMapper.xml @@ -16,6 +16,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + + + +