From f81c345f7bf058fdfe5fee6f0dfd5de0f4cb767c Mon Sep 17 00:00:00 2001
From: chenrui <1187576398@qq.com>
Date: 星期一, 12 五月 2025 16:29:02 +0800
Subject: [PATCH] Merge branch 'master' of http://114.132.189.42:9002/r/product-inventory-management-after

---
 src/main/java/com/ruoyi/sales/dto/SalesLedgerDto.java                  |    2 
 src/main/java/com/ruoyi/other/mapper/TempFileMapper.java               |    8 +
 src/main/java/com/ruoyi/other/pojo/TempFile.java                       |   15 ++
 src/main/java/com/ruoyi/other/service/impl/TempFileServiceImpl.java    |   80 +++++++++++
 src/main/java/com/ruoyi/sales/pojo/SalesLedgerFile.java                |   31 ++++
 src/main/java/com/ruoyi/common/config/IgnoreTableConfig.java           |    3 
 src/main/java/com/ruoyi/other/controller/TempFileController.java       |   29 ++++
 src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java    |   34 +---
 src/main/resources/application-druid.yml                               |    7 
 src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java |  179 +++++++++++++++++++-----
 src/main/java/com/ruoyi/other/service/TempFileService.java             |   10 +
 src/main/java/com/ruoyi/sales/mapper/SalesLedgerFileMapper.java        |    8 +
 src/main/java/com/ruoyi/RuoYiApplication.java                          |    3 
 13 files changed, 346 insertions(+), 63 deletions(-)

diff --git a/src/main/java/com/ruoyi/RuoYiApplication.java b/src/main/java/com/ruoyi/RuoYiApplication.java
index 32a9331..f865f20 100644
--- a/src/main/java/com/ruoyi/RuoYiApplication.java
+++ b/src/main/java/com/ruoyi/RuoYiApplication.java
@@ -3,12 +3,15 @@
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
 /**
  * 鍚姩绋嬪簭
  * 
  * @author ruoyi
  */
 @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
+@EnableScheduling
 public class RuoYiApplication
 {
     public static void main(String[] args)
diff --git a/src/main/java/com/ruoyi/common/config/IgnoreTableConfig.java b/src/main/java/com/ruoyi/common/config/IgnoreTableConfig.java
index 79ae6d6..e5eeb24 100644
--- a/src/main/java/com/ruoyi/common/config/IgnoreTableConfig.java
+++ b/src/main/java/com/ruoyi/common/config/IgnoreTableConfig.java
@@ -26,5 +26,8 @@
         IGNORE_TABLES.add("sys_post");
         IGNORE_TABLES.add("sys_user_post");
         IGNORE_TABLES.add("sales_ledger_product");
+        IGNORE_TABLES.add("sales_ledger_file");
+        IGNORE_TABLES.add("temp_file");
+
     }
 }
diff --git a/src/main/java/com/ruoyi/other/controller/TempFileController.java b/src/main/java/com/ruoyi/other/controller/TempFileController.java
new file mode 100644
index 0000000..6834d13
--- /dev/null
+++ b/src/main/java/com/ruoyi/other/controller/TempFileController.java
@@ -0,0 +1,29 @@
+package com.ruoyi.other.controller;
+
+
+import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.other.service.TempFileService;
+import lombok.AllArgsConstructor;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+
+@RestController
+@RequestMapping("/file")
+@AllArgsConstructor
+public class TempFileController {
+
+    private TempFileService tempFileService;
+
+    @PostMapping("/upload")
+    public AjaxResult uploadFile(MultipartFile file) {
+        try {
+            return AjaxResult.success(tempFileService.uploadFile(file));
+        }catch (Exception e) {
+            return AjaxResult.error(e.getMessage());
+        }
+    }
+
+}
diff --git a/src/main/java/com/ruoyi/other/mapper/TempFileMapper.java b/src/main/java/com/ruoyi/other/mapper/TempFileMapper.java
new file mode 100644
index 0000000..cc4cb92
--- /dev/null
+++ b/src/main/java/com/ruoyi/other/mapper/TempFileMapper.java
@@ -0,0 +1,8 @@
+package com.ruoyi.other.mapper;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.other.pojo.TempFile;
+
+public interface TempFileMapper extends BaseMapper<TempFile> {
+}
diff --git a/src/main/java/com/ruoyi/other/pojo/TempFile.java b/src/main/java/com/ruoyi/other/pojo/TempFile.java
new file mode 100644
index 0000000..6ce652d
--- /dev/null
+++ b/src/main/java/com/ruoyi/other/pojo/TempFile.java
@@ -0,0 +1,15 @@
+package com.ruoyi.other.pojo;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+@TableName("temp_file")
+public class TempFile {
+    private String tempId;         // 涓存椂鏂囦欢ID锛圲UID锛�
+    private String originalName;   // 鍘熷鏂囦欢鍚�
+    private String tempPath;       // 涓存椂瀛樺偍璺緞
+    private LocalDateTime expireTime; // 杩囨湡鏃堕棿
+}
diff --git a/src/main/java/com/ruoyi/other/service/TempFileService.java b/src/main/java/com/ruoyi/other/service/TempFileService.java
new file mode 100644
index 0000000..756a8c5
--- /dev/null
+++ b/src/main/java/com/ruoyi/other/service/TempFileService.java
@@ -0,0 +1,10 @@
+package com.ruoyi.other.service;
+
+import com.ruoyi.other.pojo.TempFile;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+
+public interface TempFileService {
+    TempFile uploadFile(MultipartFile file) throws IOException;
+}
diff --git a/src/main/java/com/ruoyi/other/service/impl/TempFileServiceImpl.java b/src/main/java/com/ruoyi/other/service/impl/TempFileServiceImpl.java
new file mode 100644
index 0000000..f228680
--- /dev/null
+++ b/src/main/java/com/ruoyi/other/service/impl/TempFileServiceImpl.java
@@ -0,0 +1,80 @@
+package com.ruoyi.other.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.other.mapper.TempFileMapper;
+import com.ruoyi.other.pojo.TempFile;
+import com.ruoyi.other.service.TempFileService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.UUID;
+
+@Service
+@Slf4j
+public class TempFileServiceImpl extends ServiceImpl<TempFileMapper, TempFile> implements TempFileService {
+
+    @Autowired
+    private TempFileMapper tempFileMapper;
+
+    @Value("${file.temp-dir}")
+    private String tempDir;
+
+    // 涓婁紶鍒颁复鏃剁洰褰�
+    @Override
+    public TempFile uploadFile(MultipartFile file) throws IOException {
+        // 1. 鐢熸垚涓存椂鏂囦欢ID鍜岃矾寰�
+        String tempId = UUID.randomUUID().toString();
+        Path tempFilePath = Paths.get(tempDir, tempId + "_" + file.getOriginalFilename());
+
+        // 2. 纭繚鐩綍瀛樺湪
+        Path parentDir = tempFilePath.getParent();
+        if (parentDir != null) {
+            Files.createDirectories(parentDir); // 閫掑綊鍒涘缓鐩綍
+        }
+
+        // 3. 淇濆瓨鏂囦欢鍒颁复鏃剁洰褰�
+        file.transferTo(tempFilePath.toFile());
+
+        // 4. 淇濆瓨涓存椂鏂囦欢璁板綍
+        TempFile tempFileRecord = new TempFile();
+        tempFileRecord.setTempId(tempId);
+        tempFileRecord.setOriginalName(file.getOriginalFilename());
+        tempFileRecord.setTempPath(tempFilePath.toString());
+        tempFileRecord.setExpireTime(LocalDateTime.now().plusHours(2)); // 2灏忔椂鍚庤繃鏈�
+        tempFileMapper.insert(tempFileRecord);
+
+        return tempFileRecord;
+    }
+
+    @Scheduled(cron = "0 0 3 * * ?") // 姣忓ぉ鍑屾櫒3鐐规墽琛�
+    public void cleanupExpiredTempFiles() {
+        LambdaQueryWrapper<TempFile> wrapper = new LambdaQueryWrapper<>();
+        wrapper.lt(TempFile::getExpireTime, LocalDateTime.now()); // expireTime < 褰撳墠鏃堕棿
+
+        List<TempFile> expiredFiles = tempFileMapper.selectList(wrapper);
+        for (TempFile file : expiredFiles) {
+            try {
+                // 鍒犻櫎鐗╃悊鏂囦欢
+                Files.deleteIfExists(Paths.get(file.getTempPath()));
+                // 鍒犻櫎鏁版嵁搴撹褰�
+                tempFileMapper.deleteById(file);
+                log.info("宸叉竻鐞嗚繃鏈熶复鏃舵枃浠�: {}", file.getTempPath());
+            } catch (IOException e) {
+                log.error("鍒犻櫎鏂囦欢澶辫触: {}", file.getTempPath(), e);
+                // 鍙�夋嫨璁板綍澶辫触鏃ュ織鎴栭噸璇�
+            }
+        }
+        log.info("杩囨湡涓存椂鏂囦欢娓呯悊瀹屾垚锛屽叡娓呯悊 {} 涓枃浠�", expiredFiles.size());
+    }
+}
diff --git a/src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java b/src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java
index 19122e8..18ad04f 100644
--- a/src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java
+++ b/src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java
@@ -1,6 +1,6 @@
 package com.ruoyi.sales.controller;
 
-import java.util.List;
+import java.util.*;
 import javax.servlet.http.HttpServletResponse;
 
 import com.ruoyi.common.utils.poi.ExcelUtil;
@@ -8,12 +8,7 @@
 import com.ruoyi.sales.pojo.SalesLedger;
 import com.ruoyi.sales.service.ISalesLedgerService;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 import com.ruoyi.framework.aspectj.lang.annotation.Log;
 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
 import com.ruoyi.framework.web.controller.BaseController;
@@ -22,14 +17,13 @@
 
 /**
  * 閿�鍞彴璐ontroller
- * 
+ *
  * @author ruoyi
  * @date 2025-05-08
  */
 @RestController
 @RequestMapping("/sales/ledger")
-public class SalesLedgerController extends BaseController
-{
+public class SalesLedgerController extends BaseController {
     @Autowired
     private ISalesLedgerService salesLedgerService;
 
@@ -37,8 +31,7 @@
      * 鏌ヨ閿�鍞彴璐﹀垪琛�
      */
     @GetMapping("/list")
-    public TableDataInfo list(SalesLedgerDto salesLedgerDto)
-    {
+    public TableDataInfo list(SalesLedgerDto salesLedgerDto) {
         startPage();
         List<SalesLedger> list = salesLedgerService.selectSalesLedgerList(salesLedgerDto);
         return getDataTable(list);
@@ -48,8 +41,8 @@
      * 鏌ヨ閿�鍞彴璐﹀拰浜у搧鐖跺瓙鍒楄〃
      */
     @GetMapping("/getSalesLedgerWithProducts")
-    public SalesLedgerDto getSalesLedgerWithProducts(SalesLedgerDto salesLedgerDto){
-        return  salesLedgerService.getSalesLedgerWithProducts(salesLedgerDto);
+    public SalesLedgerDto getSalesLedgerWithProducts(SalesLedgerDto salesLedgerDto) {
+        return salesLedgerService.getSalesLedgerWithProducts(salesLedgerDto);
     }
 
     /**
@@ -57,8 +50,7 @@
      */
     @Log(title = "閿�鍞彴璐�", businessType = BusinessType.EXPORT)
     @PostMapping("/export")
-    public void export(HttpServletResponse response, SalesLedgerDto salesLedgerDto)
-    {
+    public void export(HttpServletResponse response, SalesLedgerDto salesLedgerDto) {
         List<SalesLedger> list = salesLedgerService.selectSalesLedgerList(salesLedgerDto);
         ExcelUtil<SalesLedger> util = new ExcelUtil<SalesLedger>(SalesLedger.class);
         util.exportExcel(response, list, "閿�鍞彴璐︽暟鎹�");
@@ -68,9 +60,8 @@
      * 鏂板淇敼閿�鍞彴璐�
      */
     @Log(title = "閿�鍞彴璐�", businessType = BusinessType.INSERT)
-    @PostMapping ("/addOrUpdateSalesLedger")
-    public AjaxResult add(@RequestBody SalesLedgerDto salesLedgerDto)
-    {
+    @PostMapping("/addOrUpdateSalesLedger")
+    public AjaxResult add(@RequestBody SalesLedgerDto salesLedgerDto) {
         return toAjax(salesLedgerService.addOrUpdateSalesLedger(salesLedgerDto));
     }
 
@@ -78,9 +69,8 @@
      * 鍒犻櫎閿�鍞彴璐�
      */
     @Log(title = "閿�鍞彴璐�", businessType = BusinessType.DELETE)
-	@DeleteMapping("/delLedger")
-    public AjaxResult remove(@RequestBody Long[] ids)
-    {
+    @DeleteMapping("/delLedger")
+    public AjaxResult remove(@RequestBody Long[] ids) {
         if (ids == null || ids.length == 0) {
             return AjaxResult.error("璇蜂紶鍏ヨ鍒犻櫎鐨処D");
         }
diff --git a/src/main/java/com/ruoyi/sales/dto/SalesLedgerDto.java b/src/main/java/com/ruoyi/sales/dto/SalesLedgerDto.java
index d1a5c9c..c069104 100644
--- a/src/main/java/com/ruoyi/sales/dto/SalesLedgerDto.java
+++ b/src/main/java/com/ruoyi/sales/dto/SalesLedgerDto.java
@@ -23,4 +23,6 @@
     private String attachmentMaterials;
     private Boolean hasChildren = false;
     private List<SalesLedgerProduct> productData;
+
+    private List<String> tempFileIds;
 }
diff --git a/src/main/java/com/ruoyi/sales/mapper/SalesLedgerFileMapper.java b/src/main/java/com/ruoyi/sales/mapper/SalesLedgerFileMapper.java
new file mode 100644
index 0000000..a5cf660
--- /dev/null
+++ b/src/main/java/com/ruoyi/sales/mapper/SalesLedgerFileMapper.java
@@ -0,0 +1,8 @@
+package com.ruoyi.sales.mapper;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.sales.pojo.SalesLedgerFile;
+
+public interface SalesLedgerFileMapper extends BaseMapper<SalesLedgerFile> {
+}
diff --git a/src/main/java/com/ruoyi/sales/pojo/SalesLedgerFile.java b/src/main/java/com/ruoyi/sales/pojo/SalesLedgerFile.java
new file mode 100644
index 0000000..2ee36d7
--- /dev/null
+++ b/src/main/java/com/ruoyi/sales/pojo/SalesLedgerFile.java
@@ -0,0 +1,31 @@
+package com.ruoyi.sales.pojo;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+@TableName("sales_ledger_file")
+public class SalesLedgerFile {
+
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    /** 閿�鍞彴璐D */
+    private Long ledgerId;
+
+    /** 鏂囦欢鍚嶇О */
+    private String fileName;
+
+    /** 鏂囦欢璺緞 */
+    private String filePath;
+
+    /** 鍒涘缓鏃堕棿 */
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    /** 鏇存柊鏃堕棿 */
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updateTime;
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
index 52ec03e..38ab1d8 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -8,22 +8,33 @@
 import com.ruoyi.basic.pojo.Customer;
 import com.ruoyi.common.exception.base.BaseException;
 import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.other.mapper.TempFileMapper;
+import com.ruoyi.other.pojo.TempFile;
 import com.ruoyi.sales.dto.SalesLedgerDto;
+import com.ruoyi.sales.mapper.SalesLedgerFileMapper;
 import com.ruoyi.sales.mapper.SalesLedgerMapper;
 import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
 import com.ruoyi.sales.pojo.SalesLedger;
+import com.ruoyi.sales.pojo.SalesLedgerFile;
 import com.ruoyi.sales.pojo.SalesLedgerProduct;
 import com.ruoyi.sales.service.ISalesLedgerService;
-import lombok.AllArgsConstructor;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.io.FilenameUtils;
 import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.script.DefaultRedisScript;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.io.FileNotFoundException;
+import java.io.IOException;
 import java.lang.reflect.Field;
 import java.math.BigDecimal;
+import java.nio.file.*;
 import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
@@ -37,14 +48,22 @@
  * @date 2025-05-08
  */
 @Service
-@AllArgsConstructor
+@RequiredArgsConstructor
+@Slf4j
 public class SalesLedgerServiceImpl extends ServiceImpl<SalesLedgerMapper, SalesLedger> implements ISalesLedgerService {
 
-    private SalesLedgerMapper salesLedgerMapper;
+    private final  SalesLedgerMapper salesLedgerMapper;
 
-    private CustomerMapper customerMapper;
+    private final  CustomerMapper customerMapper;
 
-    private SalesLedgerProductMapper salesLedgerProductMapper;
+    private final  SalesLedgerProductMapper salesLedgerProductMapper;
+
+    private final SalesLedgerFileMapper salesLedgerFileMapper;
+
+    private final TempFileMapper tempFileMapper;
+
+    @Value("${file.upload-dir}")
+    private String uploadDir;
 
     private static final String LOCK_PREFIX = "contract_no_lock:";
     private static final long LOCK_WAIT_TIMEOUT = 10; // 閿佺瓑寰呰秴鏃舵椂闂达紙绉掞級
@@ -102,46 +121,126 @@
         return salesLedgerMapper.deleteBatchIds(idList);
     }
 
+    @Override
     @Transactional(rollbackFor = Exception.class)
     public int addOrUpdateSalesLedger(SalesLedgerDto salesLedgerDto) {
-        // 1. 鏍¢獙瀹㈡埛淇℃伅
-        Customer customer = customerMapper.selectById(salesLedgerDto.getCustomerId());
-        if (customer == null) {
-            throw new BaseException("瀹㈡埛涓嶅瓨鍦�");
+        try {
+            // 1. 鏍¢獙瀹㈡埛淇℃伅
+            Customer customer = customerMapper.selectById(salesLedgerDto.getCustomerId());
+            if (customer == null) {
+                throw new BaseException("瀹㈡埛涓嶅瓨鍦�");
+            }
+
+            // 2. DTO杞珽ntity
+            SalesLedger salesLedger = convertToEntity(salesLedgerDto);
+            salesLedger.setCustomerName(customer.getCustomerName());
+            salesLedger.setTenantId(customer.getTenantId());
+
+            // 3. 鏂板鎴栨洿鏂颁富琛�
+            if (salesLedger.getId() == null) {
+                String contractNo = generateSalesContractNo();
+                salesLedger.setSalesContractNo(contractNo);
+                salesLedgerMapper.insert(salesLedger);
+            } else {
+                salesLedgerMapper.updateById(salesLedger);
+            }
+
+            // 4. 澶勭悊瀛愯〃鏁版嵁
+            List<SalesLedgerProduct> productList = salesLedgerDto.getProductData();
+            if (productList != null && !productList.isEmpty()) {
+                handleSalesLedgerProducts(salesLedger.getId(), productList);
+                updateMainContractAmount(
+                        salesLedger.getId(),
+                        productList,
+                        SalesLedgerProduct::getTaxInclusiveTotalPrice,
+                        salesLedgerMapper,
+                        SalesLedger.class
+                );
+            }
+
+            // 5. 杩佺Щ涓存椂鏂囦欢鍒版寮忕洰褰�
+            if (salesLedgerDto.getTempFileIds() != null && !salesLedgerDto.getTempFileIds().isEmpty()) {
+                migrateTempFilesToFormal(salesLedger.getId(), salesLedgerDto.getTempFileIds());
+            }
+
+            return 1;
+        } catch (IOException e) {
+            throw new BaseException("鏂囦欢杩佺Щ澶辫触: " + e.getMessage());
         }
-
-        // 2. DTO杞珽ntity
-        SalesLedger salesLedger = convertToEntity(salesLedgerDto);
-        salesLedger.setCustomerName(customer.getCustomerName());
-        salesLedger.setTenantId(customer.getTenantId());
-
-        // 3. 鏂板鎴栨洿鏂颁富琛�
-        if (salesLedger.getId() == null) {
-            // 鐢熸垚鍚堝悓缂栧彿
-            String contractNo = generateSalesContractNo();
-            salesLedger.setSalesContractNo(contractNo);
-            salesLedgerMapper.insert(salesLedger);
-        } else {
-            salesLedgerMapper.updateById(salesLedger);
-        }
-
-        // 4. 澶勭悊瀛愯〃鏁版嵁
-        List<SalesLedgerProduct> productList = salesLedgerDto.getProductData();
-        if (productList != null && !productList.isEmpty()) {
-            handleSalesLedgerProducts(salesLedger.getId(), productList);
-
-            // 鉁� 璋冪敤閫氱敤鏂规硶鏇存柊涓昏〃閲戦
-            updateMainContractAmount(
-                    salesLedger.getId(),
-                    productList,
-                    SalesLedgerProduct::getTaxInclusiveTotalPrice,
-                    salesLedgerMapper,
-                    SalesLedger.class
-            );
-        }
-        return 1; // 鎿嶄綔鎴愬姛杩斿洖1
     }
 
+    // 鏂囦欢杩佺Щ鏂规硶
+
+    /**
+     * 灏嗕复鏃舵枃浠惰縼绉诲埌姝e紡鐩綍
+     *
+     * @param businessId  涓氬姟ID锛堥攢鍞彴璐D锛�
+     * @param tempFileIds 涓存椂鏂囦欢ID鍒楄〃
+     * @throws IOException 鏂囦欢鎿嶄綔寮傚父
+     */
+    private void migrateTempFilesToFormal(Long businessId, List<String> tempFileIds) throws IOException {
+        if (CollectionUtils.isEmpty(tempFileIds)) {
+            return;
+        }
+
+        // 鏋勫缓姝e紡鐩綍璺緞锛堟寜涓氬姟绫诲瀷鍜屾棩鏈熷垎缁勶級
+        String formalDir = uploadDir + LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE);
+
+        Path formalDirPath = Paths.get(formalDir);
+
+        // 纭繚姝e紡鐩綍瀛樺湪锛堥�掑綊鍒涘缓锛�
+        if (!Files.exists(formalDirPath)) {
+            Files.createDirectories(formalDirPath);
+        }
+
+        for (String tempFileId : tempFileIds) {
+            // 鏌ヨ涓存椂鏂囦欢璁板綍
+            TempFile tempFile = tempFileMapper.selectById(tempFileId);
+            if (tempFile == null) {
+                throw new FileNotFoundException("涓存椂鏂囦欢涓嶅瓨鍦�: " + tempFileId);
+            }
+
+            // 鏋勫缓姝e紡鏂囦欢鍚嶏紙鍖呭惈涓氬姟ID鍜屾椂闂存埑锛岄伩鍏嶅啿绐侊級
+            String originalFilename = tempFile.getOriginalName();
+            String fileExtension = FilenameUtils.getExtension(originalFilename);
+            String formalFilename = businessId + "_" +
+                    System.currentTimeMillis() + "_" +
+                    UUID.randomUUID().toString().substring(0, 8) +
+                    (StringUtils.hasText(fileExtension) ? "." + fileExtension : "");
+
+            Path formalFilePath = formalDirPath.resolve(formalFilename);
+
+            try {
+                // 鎵ц鏂囦欢杩佺Щ锛堜娇鐢ㄥ師瀛愭搷浣滅‘淇濆畨鍏ㄦ�э級
+                Files.move(
+                        Paths.get(tempFile.getTempPath()),
+                        formalFilePath,
+                        StandardCopyOption.REPLACE_EXISTING,
+                        StandardCopyOption.ATOMIC_MOVE
+                );
+                log.info("鏂囦欢杩佺Щ鎴愬姛: {} -> {}", tempFile.getTempPath(), formalFilePath);
+
+                // 鏇存柊鏂囦欢璁板綍锛堝叧鑱斿埌涓氬姟ID锛�
+                SalesLedgerFile fileRecord = new SalesLedgerFile();
+                fileRecord.setLedgerId(businessId);
+                fileRecord.setFileName(originalFilename);
+                fileRecord.setFilePath(formalFilePath.toString());
+                fileRecord.setCreateTime(LocalDateTime.now());
+                salesLedgerFileMapper.insert(fileRecord);
+
+                // 鍒犻櫎涓存椂鏂囦欢璁板綍
+                tempFileMapper.deleteById(tempFile);
+
+                log.info("鏂囦欢杩佺Щ鎴愬姛: {} -> {}", tempFile.getTempPath(), formalFilePath);
+            } catch (IOException e) {
+                log.error("鏂囦欢杩佺Щ澶辫触: {}", tempFile.getTempPath(), e);
+                // 鍙�夋嫨鍥炴粴浜嬪姟鎴栬褰曞け璐ユ枃浠�
+                throw new IOException("鏂囦欢杩佺Щ寮傚父", e);
+            }
+        }
+    }
+
+
     private void handleSalesLedgerProducts(Long salesLedgerId, List<SalesLedgerProduct> products) {
         // 鎸塈D鍒嗙粍锛屽尯鍒嗘柊澧炲拰鏇存柊鐨勮褰�
         Map<Boolean, List<SalesLedgerProduct>> partitionedProducts = products.stream()
diff --git a/src/main/resources/application-druid.yml b/src/main/resources/application-druid.yml
index 364911a..e5ca849 100644
--- a/src/main/resources/application-druid.yml
+++ b/src/main/resources/application-druid.yml
@@ -6,7 +6,8 @@
         druid:
             # 涓诲簱鏁版嵁婧�
             master:
-                url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+#                url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                url: jdbc:mysql://114.132.189.42:9004/product-inventory-management?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
                 username: root
                 password: 123456
             # 浠庡簱鏁版嵁婧�
@@ -59,3 +60,7 @@
                 wall:
                     config:
                         multi-statement-allow: true
+
+file:
+    temp-dir: D:/ruoyi/temp/uploads   # 涓存椂鐩綍
+    upload-dir: D:/ruoyi/prod/uploads # 姝e紡鐩綍

--
Gitblit v1.9.3