From dd3c0399c9f3c2e70bfd0072cddadcd8d34f18bb Mon Sep 17 00:00:00 2001
From: yuan <123@>
Date: 星期日, 24 五月 2026 18:11:21 +0800
Subject: [PATCH] 测试类

---
 .gitignore                                                                    |    1 
 src/test/java/com/ruoyi/stock/service/impl/StockOutRecordBatchUpdateTest.java |  254 ++++++++++++++++++++++++++++++++++++
 src/test/java/com/ruoyi/approve/service/impl/ApproveProcessIdModifyTest.java  |  117 ++++++++++++++++
 3 files changed, 371 insertions(+), 1 deletions(-)

diff --git a/.gitignore b/.gitignore
index 797d1c7..d3f800c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,7 +6,6 @@
 !gradle/wrapper/gradle-wrapper.jar
 claude.md
 target/
-test/
 !.mvn/wrapper/maven-wrapper.jar
 
 ######################################################################
diff --git a/src/test/java/com/ruoyi/approve/service/impl/ApproveProcessIdModifyTest.java b/src/test/java/com/ruoyi/approve/service/impl/ApproveProcessIdModifyTest.java
new file mode 100644
index 0000000..b8c4f3b
--- /dev/null
+++ b/src/test/java/com/ruoyi/approve/service/impl/ApproveProcessIdModifyTest.java
@@ -0,0 +1,117 @@
+package com.ruoyi.approve.service.impl;
+
+import com.ruoyi.approve.mapper.ApproveNodeMapper;
+import com.ruoyi.approve.mapper.ApproveProcessMapper;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+import java.sql.Timestamp;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+@SpringBootTest
+public class ApproveProcessIdModifyTest {
+
+    @Autowired
+    private JdbcTemplate jdbcTemplate;
+
+    @Autowired
+    private ApproveProcessMapper approveProcessMapper;
+
+    @Autowired
+    private ApproveNodeMapper approveNodeMapper;
+
+    /**
+     * 淇敼瀹℃壒娴佺▼缂栧彿
+     */
+    @Test
+    void testModifyApproveId() {
+        Map<String, String> modifyMap = new LinkedHashMap<>();
+        modifyMap.put("20260523020", "2026-05-09");
+        modifyMap.put("20260523019", "2026-04-29");
+        modifyMap.put("20260523018", "2026-04-16");
+        modifyMap.put("20260523009", "2026-05-07");
+        modifyMap.put("20260523008", "2026-04-11");
+        modifyMap.put("20260523007", "2026-04-10");
+        modifyMap.put("20260523006", "2026-04-07");
+        modifyMap.put("20260523003", "2026-04-07");
+
+        for (Map.Entry<String, String> entry : modifyMap.entrySet()) {
+            processOne(entry.getKey(), entry.getValue());
+        }
+        System.out.println("鍏ㄩ儴瀹屾垚锛�");
+    }
+
+    private void processOne(String oldApproveId, String targetDateStr) {
+        LocalDate targetDate = LocalDate.parse(targetDateStr);
+        String datePrefix = targetDate.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
+
+        String maxId = jdbcTemplate.queryForObject(
+                "SELECT MAX(approve_id) FROM approve_process WHERE approve_id LIKE ?",
+                String.class, datePrefix + "%");
+
+        long nextSeq = 1;
+        if (maxId != null && maxId.length() >= 11) {
+            nextSeq = Long.parseLong(maxId.substring(8)) + 1;
+        }
+        String newApproveId = datePrefix + String.format("%03d", nextSeq);
+
+        System.out.println("鏃ф壒鍙�: " + oldApproveId + " -> 鏂版壒鍙�: " + newApproveId);
+
+        List<Map<String, Object>> processList = jdbcTemplate.queryForList(
+                "SELECT * FROM approve_process WHERE approve_id = ?", oldApproveId);
+
+        if (processList.isEmpty()) {
+            System.out.println("  鈿� 鏈壘鍒拌褰曪紝璺宠繃");
+            return;
+        }
+
+        Map<String, Object> process = processList.get(0);
+
+        Timestamp newApproveTime = replaceDate(process.get("approve_time"), targetDate);
+        Timestamp newApproveOverTime = replaceDate(process.get("approve_over_time"), targetDate);
+        Timestamp newCreateTime = replaceDate(process.get("create_time"), targetDate);
+
+        jdbcTemplate.update(
+                "UPDATE approve_process SET approve_id = ?, approve_time = ?, approve_over_time = ?, create_time = ? WHERE approve_id = ?",
+                newApproveId, newApproveTime, newApproveOverTime, newCreateTime, oldApproveId);
+        System.out.println("  鉁� approve_process 宸叉洿鏂�");
+
+        List<Map<String, Object>> nodeList = jdbcTemplate.queryForList(
+                "SELECT * FROM approve_node WHERE approve_process_id = ?", oldApproveId);
+
+        if (!nodeList.isEmpty()) {
+            Map<String, Object> node = nodeList.get(0);
+
+            Timestamp newNodeTime = replaceDate(node.get("approve_node_time"), targetDate);
+            Timestamp newNodeCreateTime = replaceDate(node.get("create_time"), targetDate);
+            Timestamp newNodeUpdateTime = replaceDate(node.get("update_time"), targetDate);
+
+            jdbcTemplate.update(
+                    "UPDATE approve_node SET approve_process_id = ?, approve_node_time = ?, create_time = ?, update_time = ? WHERE approve_process_id = ?",
+                    newApproveId, newNodeTime, newNodeCreateTime, newNodeUpdateTime, oldApproveId);
+            System.out.println("  鉁� approve_node 宸叉洿鏂� (" + nodeList.size() + " 鏉�)");
+        } else {
+            System.out.println("  - approve_node 鏃犺褰�");
+        }
+    }
+
+    private static Timestamp replaceDate(Object dateObj, LocalDate targetDate) {
+        if (dateObj == null) return null;
+        LocalDateTime ldt;
+        if (dateObj instanceof Timestamp ts) {
+            ldt = ts.toLocalDateTime();
+        } else if (dateObj instanceof LocalDateTime dt) {
+            ldt = dt;
+        } else {
+            return null;
+        }
+        return Timestamp.valueOf(LocalDateTime.of(targetDate, ldt.toLocalTime()));
+    }
+}
diff --git a/src/test/java/com/ruoyi/stock/service/impl/StockOutRecordBatchUpdateTest.java b/src/test/java/com/ruoyi/stock/service/impl/StockOutRecordBatchUpdateTest.java
new file mode 100644
index 0000000..352818d
--- /dev/null
+++ b/src/test/java/com/ruoyi/stock/service/impl/StockOutRecordBatchUpdateTest.java
@@ -0,0 +1,254 @@
+package com.ruoyi.stock.service.impl;
+
+import com.ruoyi.production.mapper.ProductionOrderMapper;
+import com.ruoyi.production.mapper.ProductionOrderPickMapper;
+import com.ruoyi.production.pojo.ProductionOrder;
+import com.ruoyi.production.pojo.ProductionOrderPick;
+import com.ruoyi.purchase.mapper.PurchaseReturnOrdersMapper;
+import com.ruoyi.purchase.pojo.PurchaseReturnOrders;
+import com.ruoyi.sales.mapper.SalesLedgerMapper;
+import com.ruoyi.sales.mapper.ShippingInfoMapper;
+import com.ruoyi.sales.pojo.SalesLedger;
+import com.ruoyi.sales.pojo.ShippingInfo;
+import com.ruoyi.stock.mapper.StockOutRecordMapper;
+import com.ruoyi.stock.pojo.StockOutRecord;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@SpringBootTest
+public class StockOutRecordBatchUpdateTest {
+
+    @Autowired
+    private JdbcTemplate jdbcTemplate;
+
+    @Autowired
+    private StockOutRecordMapper stockOutRecordMapper;
+
+    @Autowired
+    private PurchaseReturnOrdersMapper purchaseReturnOrdersMapper;
+
+    @Autowired
+    private ShippingInfoMapper shippingInfoMapper;
+
+    @Autowired
+    private SalesLedgerMapper salesLedgerMapper;
+
+    @Autowired
+    private ProductionOrderPickMapper productionOrderPickMapper;
+
+    @Autowired
+    private ProductionOrderMapper productionOrderMapper;
+
+    /**
+     * 鏇存柊鍑哄簱鍗曟椂闂�
+     */
+    @Test
+    void testUpdateStockOutRecords() {
+        List<StockOutRecord> allRecords = stockOutRecordMapper.selectList(null);
+        System.out.println("鎬昏褰曟暟: " + allRecords.size());
+
+        List<RecordWithDate> recordWithDates = new ArrayList<>();
+
+        for (StockOutRecord record : allRecords) {
+            String type = record.getRecordType();
+            if (type == null) continue;
+
+            switch (type) {
+                case "1":
+                case "10":
+                    recordWithDates.add(resolveType1or10(record, type));
+                    break;
+                case "3":
+                    System.out.println("绫诲瀷3锛堢敓浜ф姤宸�-鍑哄簱锛夐鐣欏垎鏀紝褰撳墠鏃犳暟鎹紝璺宠繃");
+                    break;
+                case "8":
+                    System.out.println("绫诲瀷8锛堥攢鍞�-鍑哄簱锛夐鐣欏垎鏀紝褰撳墠鏃犳暟鎹紝璺宠繃");
+                    break;
+                case "9":
+                    recordWithDates.add(resolveType9(record));
+                    break;
+                case "13":
+                    recordWithDates.add(resolveType13(record));
+                    break;
+                case "14":
+                    recordWithDates.add(resolveType14or15(record));
+                    break;
+                case "15":
+                    recordWithDates.add(resolveType14or15(record));
+                    break;
+                default:
+                    System.out.println("鏈煡绫诲瀷 " + type + "锛岃烦杩� ID=" + record.getId());
+            }
+        }
+
+        Map<LocalDate, List<RecordWithDate>> byDate = recordWithDates.stream()
+                .collect(Collectors.groupingBy(
+                        rwd -> rwd.dateTime.toLocalDate(),
+                        LinkedHashMap::new,
+                        Collectors.toList()
+                ));
+
+        int totalUpdated = 0;
+        for (Map.Entry<LocalDate, List<RecordWithDate>> dateEntry : byDate.entrySet()) {
+            LocalDate date = dateEntry.getKey();
+            List<RecordWithDate> records = dateEntry.getValue();
+            records.sort(Comparator.comparing(rwd -> rwd.dateTime));
+
+            assignRandomTimes(records, date);
+
+            records.sort(Comparator.comparing(rwd -> rwd.dateTime));
+
+            int seq = 1;
+            for (RecordWithDate rwd : records) {
+                StockOutRecord record = rwd.record;
+                String type = record.getRecordType();
+                String batchNo = "CK" + date.format(DateTimeFormatter.ofPattern("yyyyMMdd")) + String.format("%03d", seq++);
+                LocalDateTime createTime = rwd.dateTime;
+
+                jdbcTemplate.update(
+                        "UPDATE stock_out_record SET outbound_batches = ?, create_time = ?, update_time = ? WHERE id = ?",
+                        batchNo, createTime, createTime, record.getId());
+
+                System.out.println("ID=" + record.getId()
+                        + " type=" + type
+                        + " batch=" + batchNo
+                        + " time=" + createTime);
+                totalUpdated++;
+            }
+        }
+
+        System.out.println("鍏ㄩ儴瀹屾垚锛佸叡鏇存柊 " + totalUpdated + " 鏉¤褰�");
+    }
+
+    private void assignRandomTimes(List<RecordWithDate> records, LocalDate date) {
+        List<RecordWithDate> individual = new ArrayList<>();
+        Map<Long, List<RecordWithDate>> grouped = new LinkedHashMap<>();
+
+        for (RecordWithDate rwd : records) {
+            String type = rwd.record.getRecordType();
+            if (!"1".equals(type) && !"9".equals(type) && !"10".equals(type)
+                    && !"13".equals(type) && !"14".equals(type) && !"15".equals(type)) {
+                continue;
+            }
+            if (("14".equals(type) || "15".equals(type)) && rwd.record.getRecordId() != null) {
+                grouped.computeIfAbsent(rwd.record.getRecordId(), k -> new ArrayList<>()).add(rwd);
+            } else {
+                individual.add(rwd);
+            }
+        }
+
+        List<TimeSlot> slots = new ArrayList<>();
+        for (RecordWithDate rwd : individual) {
+            slots.add(new TimeSlot(rwd.record.getId(), List.of(rwd)));
+        }
+        for (Map.Entry<Long, List<RecordWithDate>> entry : grouped.entrySet()) {
+            long minId = entry.getValue().stream()
+                    .mapToLong(rwd -> rwd.record.getId())
+                    .min().orElse(0);
+            slots.add(new TimeSlot(minId, entry.getValue()));
+        }
+
+        if (slots.isEmpty()) return;
+
+        slots.sort(Comparator.comparingLong(s -> s.sortKey));
+
+        int totalMinutes = 480;
+        for (int i = 0; i < slots.size(); i++) {
+            int offsetMinutes = (int) ((long) i * totalMinutes / slots.size());
+            int jitter = (int) (Math.random() * 6 - 3);
+            offsetMinutes = Math.max(0, Math.min(479, offsetMinutes + jitter));
+
+            LocalTime time;
+            if (offsetMinutes < 240) {
+                time = LocalTime.of(8, 0).plusMinutes(offsetMinutes);
+            } else {
+                time = LocalTime.of(14, 0).plusMinutes(offsetMinutes - 240);
+            }
+            LocalDateTime dt = LocalDateTime.of(date, time);
+            for (RecordWithDate rwd : slots.get(i).members) {
+                rwd.dateTime = dt;
+            }
+        }
+    }
+
+    private static class TimeSlot {
+        final long sortKey;
+        final List<RecordWithDate> members;
+
+        TimeSlot(long sortKey, List<RecordWithDate> members) {
+            this.sortKey = sortKey;
+            this.members = members;
+        }
+    }
+
+    private RecordWithDate resolveType1or10(StockOutRecord record, String type) {
+        LocalDate date = record.getCreateTime() != null
+                ? record.getCreateTime().toLocalDate()
+                : LocalDate.now();
+        return new RecordWithDate(record, LocalDateTime.of(date, LocalTime.of(8, 0)));
+    }
+
+    private RecordWithDate resolveType9(StockOutRecord record) {
+        Long recordId = record.getRecordId();
+        if (recordId != null) {
+            PurchaseReturnOrders pro = purchaseReturnOrdersMapper.selectById(recordId);
+            if (pro != null && pro.getPreparedAt() != null) {
+                return new RecordWithDate(record, LocalDateTime.of(pro.getPreparedAt(), LocalTime.of(8, 0)));
+            }
+        }
+        return fallbackDateTime(record);
+    }
+
+    private RecordWithDate resolveType13(StockOutRecord record) {
+        Long recordId = record.getRecordId();
+        if (recordId != null) {
+            ShippingInfo shippingInfo = shippingInfoMapper.selectById(recordId);
+            if (shippingInfo != null && shippingInfo.getSalesLedgerId() != null) {
+                SalesLedger salesLedger = salesLedgerMapper.selectById(shippingInfo.getSalesLedgerId());
+                if (salesLedger != null && salesLedger.getDeliveryDate() != null) {
+                    return new RecordWithDate(record, LocalDateTime.of(salesLedger.getDeliveryDate(), LocalTime.of(8, 0)));
+                }
+            }
+        }
+        return fallbackDateTime(record);
+    }
+
+    private RecordWithDate resolveType14or15(StockOutRecord record) {
+        Long recordId = record.getRecordId();
+        if (recordId != null) {
+            ProductionOrderPick pick = productionOrderPickMapper.selectById(recordId);
+            if (pick != null && pick.getProductionOrderId() != null) {
+                ProductionOrder order = productionOrderMapper.selectById(pick.getProductionOrderId());
+                if (order != null && order.getStartTime() != null) {
+                    return new RecordWithDate(record, LocalDateTime.of(order.getStartTime().toLocalDate(), LocalTime.of(8, 0)));
+                }
+            }
+        }
+        return fallbackDateTime(record);
+    }
+
+    private RecordWithDate fallbackDateTime(StockOutRecord record) {
+        return record.getCreateTime() != null
+                ? new RecordWithDate(record, record.getCreateTime())
+                : new RecordWithDate(record, LocalDateTime.now());
+    }
+
+    private static class RecordWithDate {
+        final StockOutRecord record;
+        LocalDateTime dateTime;
+
+        RecordWithDate(StockOutRecord record, LocalDateTime dateTime) {
+            this.record = record;
+            this.dateTime = dateTime;
+        }
+    }
+}

--
Gitblit v1.9.3