| src/main/java/com/ruoyi/production/service/impl/ProductionBomStructureServiceImpl.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/ruoyi/project/system/service/impl/SysUserServiceImpl.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/resources/application-lt.yml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/main/java/com/ruoyi/production/service/impl/ProductionBomStructureServiceImpl.java
@@ -31,6 +31,7 @@ import com.ruoyi.technology.pojo.TechnologyOperationParam; import com.ruoyi.technology.pojo.TechnologyParam; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -49,6 +50,7 @@ * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-04-21 03:55:52 */ @Slf4j @Service @RequiredArgsConstructor() public class ProductionBomStructureServiceImpl extends ServiceImpl<ProductionBomStructureMapper, ProductionBomStructure> implements ProductionBomStructureService { @@ -137,6 +139,9 @@ entity.setProductionOrderBomId(orderBomId); if (item.getId() == null) { entity.setParentId(null); // æ°å¢èç¹çéæ±éç±å端æBOMæ å½¢ç»æéæ°è®¡ç®ï¼ä¸æ¸ 空å¯è½å¯¼è´åç«¯ä¼ ç弿º¢åº entity.setDemandedQuantity(null); entity.setId(null); insertList.add(entity); tempEntityMap.put(item.getTempId(), entity); } else { @@ -146,6 +151,11 @@ // æ¹éæ°å¢ï¼æ¿å°æ°æ®åºçæççå®ID if (!insertList.isEmpty()) { for (ProductionBomStructure entity : insertList) { log.info("å夿°å¢BOMç»æèç¹: productModelId={}, technologyOperationId={}, unitQuantity={}, demandedQuantity={}, unit={}", entity.getProductModelId(), entity.getTechnologyOperationId(), entity.getUnitQuantity(), entity.getDemandedQuantity(), entity.getUnit()); } this.saveBatch(insertList); } @@ -216,24 +226,76 @@ if (structureList == null || structureList.isEmpty()) { return; } List<ProductionBomStructure> updateList = new ArrayList<>(); BigDecimal lastProcessDemandedQuantity = orderQuantity; log.info("å¼å§æBOMæ å½¢ç»æè®¡ç®éæ±éï¼è®¢åæ°é={}, BOMèç¹æ»æ°={}", orderQuantity, structureList.size()); // æå»º id â structure æ å°å parentId â children æ å° Map<Long, ProductionBomStructure> structureById = new HashMap<>(); Map<Long, List<ProductionBomStructure>> childrenMap = new LinkedHashMap<>(); for (ProductionBomStructure structure : structureList) { if (structure == null || structure.getId() == null) { continue; } structureById.put(structure.getId(), structure); Long parentId = structure.getParentId(); childrenMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(structure); } BigDecimal demandedQuantity = lastProcessDemandedQuantity.multiply(defaultDecimal(structure.getUnitQuantity())); // if (compareDecimal(structure.getDemandedQuantity(), demandedQuantity) == 0) { // continue; // } List<ProductionBomStructure> updateList = new ArrayList<>(); // 仿 ¹èç¹å¼å§ï¼ææ å½¢å±çº§éå±è®¡ç®éæ±é // æ ¹èç¹ parentId 为 null æ 0 Deque<Long> queue = new ArrayDeque<>(); List<ProductionBomStructure> rootNodes = childrenMap.get(null); if (rootNodes != null) { for (ProductionBomStructure root : rootNodes) { queue.add(root.getId()); } } // parentId=0 çä¹è§ä¸ºæ ¹èç¹ List<ProductionBomStructure> zeroParentNodes = childrenMap.get(0L); if (zeroParentNodes != null) { for (ProductionBomStructure root : zeroParentNodes) { if (!queue.contains(root.getId())) { queue.add(root.getId()); } } } while (!queue.isEmpty()) { Long nodeId = queue.poll(); ProductionBomStructure node = structureById.get(nodeId); if (node == null) { continue; } // 计ç®å½åèç¹çéæ±æ°é = ç¶èç¹éæ±é à èªèº« unitQuantity // æ ¹èç¹ï¼éæ±é = è®¢åæ°é à unitQuantity BigDecimal parentDemandedQuantity = orderQuantity; Long parentId = node.getParentId(); if (parentId != null && parentId != 0L) { ProductionBomStructure parent = structureById.get(parentId); if (parent != null && parent.getDemandedQuantity() != null) { parentDemandedQuantity = parent.getDemandedQuantity(); } } BigDecimal demandedQuantity = parentDemandedQuantity.multiply(defaultDecimal(node.getUnitQuantity())); log.info("BOMéæ±é计ç®: nodeId={}, parentId={}, parentDemandedQuantity={}, unitQuantity={}, demandedQuantity={}", node.getId(), node.getParentId(), parentDemandedQuantity, defaultDecimal(node.getUnitQuantity()), demandedQuantity); ProductionBomStructure update = new ProductionBomStructure(); update.setId(structure.getId()); update.setId(node.getId()); update.setDemandedQuantity(demandedQuantity); updateList.add(update); structure.setDemandedQuantity(demandedQuantity); lastProcessDemandedQuantity = demandedQuantity; node.setDemandedQuantity(demandedQuantity); // å°åèç¹å å ¥éå List<ProductionBomStructure> children = childrenMap.get(nodeId); if (children != null) { for (ProductionBomStructure child : children) { queue.add(child.getId()); } } } if (!updateList.isEmpty()) { this.updateBatchById(updateList); } src/main/java/com/ruoyi/production/service/impl/ProductionOrderServiceImpl.java
@@ -439,9 +439,54 @@ productionOrderBomMapper.insert(orderBom); Map<Long, Long> idMap = new HashMap<>(); BigDecimal lastProcessDemandedQuantity = orderQuantity; // æå»º sourceId â sourceNode æ å° å parentId â children æ å° Map<Long, TechnologyBomStructure> sourceById = new HashMap<>(); Map<Long, List<TechnologyBomStructure>> childrenMap = new LinkedHashMap<>(); for (TechnologyBomStructure source : structureList) { // åèç¹ parentId éè¦æ å°ææ°å¿«ç §èç¹ idï¼æè½ä¿çåå§ BOM å±çº§ã if (source == null || source.getId() == null) { continue; } sourceById.put(source.getId(), source); Long parentId = source.getParentId(); childrenMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(source); } // BFS 仿 ¹èç¹å¼å§ï¼ç¶èç¹å äºåèç¹å¤ç Deque<TechnologyBomStructure> queue = new ArrayDeque<>(); List<TechnologyBomStructure> rootNodes = childrenMap.get(null); if (rootNodes != null) { queue.addAll(rootNodes); } // parentId=0 çä¹è§ä¸ºæ ¹èç¹ List<TechnologyBomStructure> zeroParentNodes = childrenMap.get(0L); if (zeroParentNodes != null) { for (TechnologyBomStructure node : zeroParentNodes) { if (!queue.contains(node)) { queue.add(node); } } } while (!queue.isEmpty()) { TechnologyBomStructure source = queue.poll(); if (source == null || source.getId() == null) { continue; } // 计ç®éæ±é = ç¶èç¹éæ±é à èªèº« unitQuantity BigDecimal parentDemandedQuantity = orderQuantity; Long sourceParentId = source.getParentId(); if (sourceParentId != null && sourceParentId != 0L) { Long parentTargetId = idMap.get(sourceParentId); if (parentTargetId != null) { // ç¶èç¹å·²ç»æå ¥ï¼ç¨ç¶èç¹ç targetId ä»å·²æå ¥åè¡¨æ¾ // è¿éæä»¬ç´æ¥ç¨å䏿¥çç¶èç¹éæ±é TechnologyBomStructure parentSource = sourceById.get(sourceParentId); if (parentSource != null && parentSource.getDemandedQuantity() != null) { parentDemandedQuantity = parentSource.getDemandedQuantity(); } } } ProductionBomStructure target = new ProductionBomStructure(); target.setProductionOrderId(productionOrder.getId()); target.setProductionOrderBomId(orderBom.getId()); @@ -449,11 +494,20 @@ target.setProductModelId(source.getProductModelId()); target.setTechnologyOperationId(source.getOperationId()); target.setUnitQuantity(source.getUnitQuantity()); target.setDemandedQuantity(lastProcessDemandedQuantity.multiply(source.getUnitQuantity())); target.setDemandedQuantity(parentDemandedQuantity.multiply(defaultDecimal(source.getUnitQuantity()))); target.setUnit(source.getUnit()); productionBomStructureMapper.insert(target); idMap.put(source.getId(), target.getId()); lastProcessDemandedQuantity = target.getDemandedQuantity(); // å°å½åèç¹ç demandedQuantity ååå° source 对象ä¸ï¼ä¾åèç¹è®¡ç®ä½¿ç¨ source.setDemandedQuantity(target.getDemandedQuantity()); // å°åèç¹å å ¥éå List<TechnologyBomStructure> children = childrenMap.get(source.getId()); if (children != null) { for (TechnologyBomStructure child : children) { queue.add(child); } } } return orderBom; } src/main/java/com/ruoyi/project/system/service/impl/SysUserServiceImpl.java
@@ -51,7 +51,7 @@ * @return ç¨æ·ä¿¡æ¯éåä¿¡æ¯ */ @Override @DataScope(deptAlias = "d", userAlias = "u") @DataScope(userAlias = "u") public List<SysUser> selectUserList(SysUser user) { return userMapper.selectUserList(user); src/main/resources/application-lt.yml
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,268 @@ # 项ç®ç¸å ³é ç½® ruoyi: # åç§° name: RuoYi # çæ¬ version: 3.8.9 # çæå¹´ä»½ copyrightYear: 2025 # æä»¶è·¯å¾ 示ä¾ï¼ Windowsé ç½®D:/ruoyi/uploadPathï¼Linuxé ç½® /home/ruoyi/uploadPathï¼ profile: /data/javaWork/product-inventory-management/file # è·åipå°åå¼å ³ addressEnabled: false # éªè¯ç ç±»å math æ°åè®¡ç® char å符éªè¯ captchaType: math # åå审æ¹ç¼å·åç¼(é ç½®æä»¶åç¼å½å) approvalNumberPrefix: NEW # ä¸ªæ¨ Unipush é ç½® getui: appId: PfjyAAE0FK64FaO1w2CMb1 appKey: zTMb831OEL6J4GK1uE3Ob4 masterSecret: K1GFtsv42v61tXGnF7SGE5 domain: https://restapi.getui.cn/v2/ # 离线æ¨é使ç¨çå å/ç»ä»¶å intentComponent: uni.app.UNI099A590/io.dcloud.PandoraEntry # å¼åç¯å¢é ç½® server: # æå¡å¨çHTTP端å£ï¼é»è®¤ä¸º8080 port: 9003 servlet: # åºç¨ç访é®è·¯å¾ context-path: / tomcat: # tomcatçURIç¼ç uri-encoding: UTF-8 # è¿æ¥æ°æ»¡åçæéæ°ï¼é»è®¤ä¸º100 accept-count: 1000 threads: # tomcatæå¤§çº¿ç¨æ°ï¼é»è®¤ä¸º200 max: 800 # Tomcatå¯å¨åå§åççº¿ç¨æ°ï¼é»è®¤å¼10 min-spare: 100 # æ¥å¿é ç½® logging: level: com.ruoyi: warn org.springframework: warn minio: endpoint: http://114.132.189.42/ port: 7019 secure: false accessKey: admin secretKey: 12345678 preview-expiry: 24 # é¢è§å°åé»è®¤24å°æ¶ default-bucket: jxc # ç¨æ·é ç½® user: password: # å¯ç æå¤§éè¯¯æ¬¡æ° maxRetryCount: 5 # å¯ç é宿¶é´ï¼é»è®¤10åéï¼ lockTime: 10 # Springé ç½® spring: datasource: type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.cj.jdbc.Driver druid: # ä¸»åºæ°æ®æº master: url: jdbc:mysql://172.17.0.1:11101/product-inventory-management-lt?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 username: root password: xd@123456.. # ä»åºæ°æ®æº slave: # 仿°æ®æºå¼å ³/é»è®¤å ³é enabled: false url: username: password: # åå§è¿æ¥æ° initialSize: 5 # æå°è¿æ¥æ± æ°é minIdle: 10 # æå¤§è¿æ¥æ± æ°é maxActive: 20 # é ç½®è·åè¿æ¥çå¾ è¶ æ¶çæ¶é´ maxWait: 60000 # é ç½®è¿æ¥è¶ æ¶æ¶é´ connectTimeout: 30000 # é ç½®ç½ç»è¶ æ¶æ¶é´ socketTimeout: 60000 # é ç½®é´éå¤ä¹ æè¿è¡ä¸æ¬¡æ£æµï¼æ£æµéè¦å ³éç空é²è¿æ¥ï¼å使¯æ¯«ç§ timeBetweenEvictionRunsMillis: 60000 # é ç½®ä¸ä¸ªè¿æ¥å¨æ± 䏿å°çåçæ¶é´ï¼å使¯æ¯«ç§ minEvictableIdleTimeMillis: 300000 # é ç½®ä¸ä¸ªè¿æ¥å¨æ± 䏿大çåçæ¶é´ï¼å使¯æ¯«ç§ maxEvictableIdleTimeMillis: 900000 # é ç½®æ£æµè¿æ¥æ¯å¦ææ validationQuery: SELECT 1 FROM DUAL testWhileIdle: true testOnBorrow: false testOnReturn: false webStatFilter: enabled: true statViewServlet: enabled: true # 设置ç½ååï¼ä¸å¡«åå 许ææè®¿é® allow: url-pattern: /druid/* # æ§å¶å°ç®¡çç¨æ·ååå¯ç login-username: ruoyi login-password: 123456 filter: stat: enabled: true # æ ¢SQLè®°å½ log-slow-sql: true slow-sql-millis: 1000 merge-sql: true wall: config: multi-statement-allow: true # èµæºä¿¡æ¯ messages: # å½é åèµæºæä»¶è·¯å¾ basename: i18n/messages # æä»¶ä¸ä¼ servlet: multipart: # å个æä»¶å¤§å° max-file-size: 1GB # 设置æ»ä¸ä¼ çæä»¶å¤§å° max-request-size: 2GB # æå¡æ¨¡å devtools: restart: # çé¨ç½²å¼å ³ enabled: false # redis é ç½® data: mongodb: uri: mongodb://114.132.189.42:9028/chat_memory_db_lt # redis é ç½® redis: # å°å # host: 127.0.0.1 host: 172.17.0.1 # 端å£ï¼é»è®¤ä¸º6379 port: 11102 # æ°æ®åºç´¢å¼ database: 0 # å¯ç # password: root2022! password: # è¿æ¥è¶ æ¶æ¶é´ timeout: 10s lettuce: pool: # è¿æ¥æ± ä¸çæå°ç©ºé²è¿æ¥ min-idle: 0 # è¿æ¥æ± ä¸çæå¤§ç©ºé²è¿æ¥ max-idle: 8 # è¿æ¥æ± çæå¤§æ°æ®åºè¿æ¥æ° max-active: 8 # #è¿æ¥æ± æå¤§é»å¡çå¾ æ¶é´ï¼ä½¿ç¨è´å¼è¡¨ç¤ºæ²¡æéå¶ï¼ max-wait: -1ms # Quartz宿¶ä»»å¡é ç½®ï¼æ°å¢é¨åï¼ quartz: job-store-type: jdbc # ä½¿ç¨æ°æ®åºåå¨ jdbc: initialize-schema: never # 馿¬¡è¿è¡æ¶èªå¨åå»ºè¡¨ç»æï¼æååæ¹ä¸ºnever schema: classpath:org/quartz/impl/jdbcjobstore/tables_mysql_innodb.sql # MySQLè¡¨ç»æèæ¬ properties: org: quartz: scheduler: instanceName: RuoYiScheduler instanceId: AUTO jobStore: class: org.quartz.impl.jdbcjobstore.JobStoreTX driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate # MySQLéé tablePrefix: qrtz_ # 表ååç¼ï¼ä¸èæ¬ä¸è´ isClustered: false # åèç¹æ¨¡å¼ï¼éç¾¤éæ¹ä¸ºtrueï¼ clusterCheckinInterval: 10000 txIsolationLevelSerializable: true threadPool: class: org.quartz.simpl.SimpleThreadPool threadCount: 10 # çº¿ç¨æ± å¤§å° threadPriority: 5 makeThreadsDaemons: true updateCheck: false # å ³éçæ¬æ£æ¥ # tokené ç½® token: # 令çèªå®ä¹æ è¯ header: Authorization # 令çå¯é¥ secret: xpAVjhCjQDaDB7mjPAzMDSbQWXNu2zYkTdDNUsPMS5Xx8QMmQVYN7n74eZrYJxDJ # ä»¤çæææï¼é»è®¤30åéï¼ expireTime: 450 # MyBatis Plusé ç½® mybatis-plus: # æç´¢æå®å å«å æ ¹æ®èªå·±çé¡¹ç®æ¥ typeAliasesPackage: com.ruoyi.**.pojo # é ç½®mapperçæ«æï¼æ¾å°ææçmapper.xmlæ å°æä»¶ mapperLocations: classpath*:mapper/**/*Mapper.xml # å è½½å ¨å±çé ç½®æä»¶ configLocation: classpath:mybatis/mybatis-config.xml global-config: enable-sql-runner: true db-config: id-type: auto # PageHelperå页æä»¶ pagehelper: helperDialect: mysql supportMethodsArguments: true params: count=countSql # Swaggeré ç½® swagger: # æ¯å¦å¼å¯swagger enabled: true # 请æ±åç¼ pathMapping: /dev-api # 鲿¢XSSæ»å» xss: # è¿æ»¤å¼å ³ enabled: true # æé¤é¾æ¥ï¼å¤ä¸ªç¨éå·åéï¼ excludes: /system/notice # å¹é 龿¥ urlPatterns: /system/*,/monitor/*,/tool/* # 代ç çæ gen: # ä½è author: ruoyi # é»è®¤çæå è·¯å¾ system éæ¹æèªå·±ç模ååç§° å¦ system monitor tool packageName: com.ruoyi.project.system # èªå¨å»é¤è¡¨åç¼ï¼é»è®¤æ¯true autoRemovePre: false # 表åç¼ï¼çæç±»åä¸ä¼å å«è¡¨åç¼ï¼å¤ä¸ªç¨éå·åéï¼ tablePrefix: sys_ # æ¯å¦å è®¸çææä»¶è¦çå°æ¬å°ï¼èªå®ä¹è·¯å¾ï¼ï¼é»è®¤ä¸å 许 allowOverwrite: false # æä»¶ä¸ä¼ é ç½® file: temp-dir: /data/javaWork/product-inventory-management/file/temp/uploads # 临æ¶ç®å½ upload-dir: /data/javaWork/product-inventory-management/file/prod/uploads # æ£å¼ç®å½ path: /data/javaWork/product-inventory-management/file # ä¸ä¼ ç®å½ urlPrefix: /prod-api/common # 龿¥åç¼ domain: http://36.213.180.217:9200 # åååç¼ expired: 120 # è¿ææ¶é´(åä½:åé) useLimit: 10 # ä½¿ç¨æ¬¡æ° compress: true # æ¯å¦å缩 needCompressSize: 10MB # å缩éå¼ compressQuality: 0.5 # å缩质é(0.0-1.0)