From b17d24985527421ee9df504af8eccf24cf1aa7f3 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期三, 16 九月 2026 10:20:01 +0800
Subject: [PATCH] refactor(invoice): 重构开票登记导出功能

---
 src/main/java/com/ruoyi/sales/excel/InvoiceRegistrationExportVo.java           |   31 ++++++
 src/main/java/com/ruoyi/sales/dto/SalesLedgerDto.java                          |    3 
 /dev/null                                                                      |   73 --------------
 src/main/java/com/ruoyi/sales/service/impl/InvoiceRegistrationServiceImpl.java |   51 +++++++++-
 src/main/resources/mapper/sales/SalesLedgerMapper.xml                          |    6 +
 .gitignore                                                                     |    1 
 src/main/java/com/ruoyi/sales/mapper/InvoiceRegistrationMapper.java            |    9 -
 src/main/java/com/ruoyi/sales/service/InvoiceRegistrationService.java          |    4 
 docs/invoice_registration_export.md                                            |   72 ++++++++++++++
 src/main/resources/mapper/sales/InvoiceRegistrationMapper.xml                  |   35 -------
 src/main/java/com/ruoyi/sales/controller/InvoiceRegistrationController.java    |    6 
 11 files changed, 163 insertions(+), 128 deletions(-)

diff --git a/.gitignore b/.gitignore
index b60b03f..51a844d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,6 +18,7 @@
 .project
 .settings
 .springBeans
+.claude
 
 ### IntelliJ IDEA ###
 .idea
diff --git a/docs/invoice_registration_export.md b/docs/invoice_registration_export.md
new file mode 100644
index 0000000..8c65646
--- /dev/null
+++ b/docs/invoice_registration_export.md
@@ -0,0 +1,72 @@
+# 寮�绁ㄧ櫥璁板垪琛ㄥ鍑�
+
+## 娑夊強椤甸潰
+
+- 閿�鍞鐞� 鈫� 寮�绁ㄧ櫥璁帮紙`src/views/salesManagement/invoiceRegistration/index.vue`锛�
+
+## API
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| POST | /invoiceRegistration/export | 瀵煎嚭寮�绁ㄧ櫥璁板垪琛紙涓庨〉闈㈠垪琛ㄥ彛寰勪竴鑷达級 |
+
+**璇锋眰鍙傛暟锛坒orm 琛ㄥ崟锛夛細**
+
+瀵煎嚭鑼冨洿瑙勫垯锛�**鍕鹃�変簡琛屽垯鎸夊嬀閫夊鍑猴紙浼� ids锛夛紱鏈嬀閫夊鍑哄叏閮ㄦ暟鎹紙涓嶄紶鍙傛暟锛�**銆�
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| ids | List&lt;Long&gt; | 鍚� | 鍕鹃�夌殑閿�鍞彴璐� ID 闆嗗悎锛宖orm 搴忓垪鍖栧舰濡� `ids[0]=1&ids[1]=2`锛涗紶浜嗗垯浠呭鍑鸿繖浜涜锛屼笉浼犲鍑哄叏閮� |
+
+**鍝嶅簲锛�** Excel 浜岃繘鍒舵祦锛坆lob锛夛紝鏂囦欢鍚嶅缓璁� `寮�绁ㄧ櫥璁颁俊鎭�.xlsx`锛屽垪鍥哄畾涓猴細
+
+| 鍒楀悕 | 璇存槑 |
+|------|------|
+| 閿�鍞悎鍚屽彿 | sales_contract_no |
+| 瀹㈡埛鍚堝悓鍙� | customer_contract_no |
+| 瀹㈡埛鍚嶇О | customer_name |
+| 鍚堝悓閲戦 | sales_ledger.contract_amount |
+| 宸插紑绁ㄩ噾棰� | 寮�绁ㄥ彴璐� invoice_ledger 姹囨�伙紝鍙e緞鍚屽垪琛ㄩ〉 |
+| 鏈紑绁ㄩ噾棰� | 鍚堝悓閲戦 - 宸插紑绁ㄩ噾棰� |
+
+## 鍓嶇淇敼鐐�
+
+### 1. 鎼滅储鍖烘柊澧炲鍑烘寜閽�
+
+```html
+<el-form-item>
+  <el-button type="primary" @click="handleQuery"> 鎼滅储 </el-button>
+  <el-button @click="resetForm"> 閲嶇疆 </el-button>
+  <el-button @click="handleOut" type="primary">瀵煎嚭</el-button>
+</el-form-item>
+```
+
+### 2. 瀵煎嚭鏂规硶
+
+```js
+// 瀵煎嚭锛氬嬀閫夊垯瀵煎嚭閫変腑琛岋紝鏈嬀閫夊鍑哄叏閮�
+const handleOut = () => {
+  const exportIds = selectedRows.value.map((item) => item.id);
+  const confirmMsg = exportIds.length
+    ? `宸查�変腑 ${exportIds.length} 鏉℃暟鎹紝灏嗗鍑洪�変腑鍐呭锛屾槸鍚︾‘璁わ紵`
+    : "鏈�変腑鏁版嵁锛屽皢瀵煎嚭鍏ㄩ儴鏁版嵁锛屾槸鍚︾‘璁わ紵";
+  ElMessageBox.confirm(confirmMsg, "瀵煎嚭", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  })
+    .then(() => {
+      const params = exportIds.length ? { ids: exportIds } : {};
+      proxy.download("/invoiceRegistration/export", params, "寮�绁ㄧ櫥璁颁俊鎭�.xlsx");
+    })
+    .catch(() => {
+      proxy.$modal.msg("宸插彇娑�");
+    });
+};
+```
+
+## 娉ㄦ剰浜嬮」
+
+- 鎺ュ彛涓� POST锛坒orm 琛ㄥ崟锛夛紝浣跨敤椤圭洰鍐呯疆 `proxy.download` 鍗冲彲锛屼笉瑕佹寜 GET 璋冪敤銆�
+- 瀵煎嚭涓庨〉闈㈡悳绱㈡潯浠舵棤鍏筹細鍕鹃�夊閫変腑锛屼笉鍕鹃�夊鍏ㄩ儴銆�
+- 鍒楄〃椤垫暟鎹簮涓� `/sales/ledger/listPage`锛屽鍑轰笌鍏跺彛寰勪竴鑷达紱鎺ュ彛璺緞涓嶅彉锛坄/invoiceRegistration/export`锛夛紝浠呰繑鍥炲垪鍐呭鐢卞師鏉ョ殑"寮�绁ㄧ櫥璁�+浜у搧鏄庣粏"鏀逛负鍚堝悓缁村害 6 鍒椼��
diff --git a/src/main/java/com/ruoyi/sales/controller/InvoiceRegistrationController.java b/src/main/java/com/ruoyi/sales/controller/InvoiceRegistrationController.java
index 71724b0..87c0102 100644
--- a/src/main/java/com/ruoyi/sales/controller/InvoiceRegistrationController.java
+++ b/src/main/java/com/ruoyi/sales/controller/InvoiceRegistrationController.java
@@ -86,10 +86,10 @@
     /**
      * 寮�绁ㄧ櫥璁板鍑�
      * @param response
-     * @param invoiceRegistrationDto
+     * @param salesLedgerDto
      */
     @PostMapping("/export")
-    public void invoiceRegistrationExport(HttpServletResponse response, InvoiceRegistrationDto invoiceRegistrationDto) {
-        invoiceRegistrationService.invoiceRegistrationExport(response, invoiceRegistrationDto);
+    public void invoiceRegistrationExport(HttpServletResponse response, SalesLedgerDto salesLedgerDto) {
+        invoiceRegistrationService.invoiceRegistrationExport(response, salesLedgerDto);
     }
 }
diff --git a/src/main/java/com/ruoyi/sales/dto/SalesLedgerDto.java b/src/main/java/com/ruoyi/sales/dto/SalesLedgerDto.java
index 486ffcb..ad70878 100644
--- a/src/main/java/com/ruoyi/sales/dto/SalesLedgerDto.java
+++ b/src/main/java/com/ruoyi/sales/dto/SalesLedgerDto.java
@@ -54,4 +54,7 @@
 
     @ApiModelProperty(value = "浠樻鏂瑰紡")
     private String paymentMethod;
+
+    @ApiModelProperty(value = "鎸囧畾瀵煎嚭鐨勯攢鍞彴璐D闆嗗悎")
+    private List<Long> ids;
 }
diff --git a/src/main/java/com/ruoyi/sales/excel/InvoiceRegisAndProductExcelDto.java b/src/main/java/com/ruoyi/sales/excel/InvoiceRegisAndProductExcelDto.java
deleted file mode 100644
index 8f042c6..0000000
--- a/src/main/java/com/ruoyi/sales/excel/InvoiceRegisAndProductExcelDto.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package com.ruoyi.sales.excel;
-
-import com.fasterxml.jackson.annotation.JsonFormat;
-import com.ruoyi.framework.aspectj.lang.annotation.Excel;
-import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
-import org.springframework.format.annotation.DateTimeFormat;
-
-import java.math.BigDecimal;
-import java.time.LocalDateTime;
-
-@Data
-public class InvoiceRegisAndProductExcelDto {
-
-    @Excel(name = "閿�鍞悎鍚屽彿")
-    private String salesContractNo;
-
-    @Excel(name = "瀹㈡埛鍚堝悓鍙�")
-    private String customerContractNo;
-
-    @Excel(name = "瀹㈡埛鍚嶇О")
-    private String customerName;
-
-    @Excel(name =  "涓氬姟鍛�")
-    private String salesman;
-
-    @Excel(name = "椤圭洰鍚嶇О")
-    private String projectName;
-
-    @Excel(name =  "鍚堝悓閲戦")
-    private BigDecimal contractAmount;
-
-    @Excel(name =  "浜у搧澶х被")
-    private String productCategory;
-
-    @Excel(name =  "瑙勬牸鍨嬪彿")
-    private String specificationModel;
-
-    @Excel(name =  "鍗曚綅")
-    private String unit;
-
-    @Excel(name =  "鏁伴噺")
-    private BigDecimal quantity;
-
-    @Excel(name =  "绋庣巼%")
-    private BigDecimal taxRate;
-
-    @Excel(name = "鍚◣鍗曚环")
-    private BigDecimal taxInclusiveUnitPrice;
-
-    @Excel(name = "鍚◣鎬讳环")
-    private BigDecimal taxInclusiveTotalPrice;
-
-    @Excel(name ="涓嶅惈绋庢�讳环")
-    private BigDecimal taxExclusiveTotalPrice;
-
-    @Excel(name ="鍙戠エ绫诲瀷")
-    private String invoiceType;
-
-    @Excel(name ="寮�绁ㄦ暟")
-    private Integer invoiceNum;
-
-    @Excel(name ="鏈紑绁ㄦ暟")
-    private Integer noInvoiceNum;
-
-    @Excel(name ="寮�绁ㄩ噾棰�")
-    private BigDecimal invoiceAmount;
-
-    @Excel(name ="鏈紑绁ㄩ噾棰�")
-    private BigDecimal noInvoiceAmount;
-
-
-}
diff --git a/src/main/java/com/ruoyi/sales/excel/InvoiceRegistrationExportVo.java b/src/main/java/com/ruoyi/sales/excel/InvoiceRegistrationExportVo.java
new file mode 100644
index 0000000..50f8223
--- /dev/null
+++ b/src/main/java/com/ruoyi/sales/excel/InvoiceRegistrationExportVo.java
@@ -0,0 +1,31 @@
+package com.ruoyi.sales.excel;
+
+import com.ruoyi.framework.aspectj.lang.annotation.Excel;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 寮�绁ㄧ櫥璁板垪琛ㄥ鍑哄璞�
+ */
+@Data
+public class InvoiceRegistrationExportVo {
+
+    @Excel(name = "閿�鍞悎鍚屽彿")
+    private String salesContractNo;
+
+    @Excel(name = "瀹㈡埛鍚堝悓鍙�")
+    private String customerContractNo;
+
+    @Excel(name = "瀹㈡埛鍚嶇О")
+    private String customerName;
+
+    @Excel(name = "鍚堝悓閲戦")
+    private BigDecimal contractAmount;
+
+    @Excel(name = "宸插紑绁ㄩ噾棰�")
+    private BigDecimal invoiceTotal;
+
+    @Excel(name = "鏈紑绁ㄩ噾棰�")
+    private BigDecimal noInvoiceAmountTotal;
+}
diff --git a/src/main/java/com/ruoyi/sales/mapper/InvoiceRegistrationMapper.java b/src/main/java/com/ruoyi/sales/mapper/InvoiceRegistrationMapper.java
index 54425c4..88a3ebf 100644
--- a/src/main/java/com/ruoyi/sales/mapper/InvoiceRegistrationMapper.java
+++ b/src/main/java/com/ruoyi/sales/mapper/InvoiceRegistrationMapper.java
@@ -4,11 +4,8 @@
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.sales.dto.InvoiceRegistrationDto;
-import com.ruoyi.sales.excel.InvoiceRegisAndProductExcelDto;
 import com.ruoyi.sales.pojo.InvoiceRegistration;
 import org.apache.ibatis.annotations.Param;
-
-import java.util.List;
 
 public interface InvoiceRegistrationMapper extends BaseMapper<InvoiceRegistration> {
 
@@ -19,10 +16,4 @@
      * @return
      */
     IPage<InvoiceRegistrationDto> invoiceRegistrationListPage(Page page, @Param("invoiceRegistrationDto") InvoiceRegistrationDto invoiceRegistrationDto);
-
-    /**
-     * 寮�绁ㄧ櫥璁板鍑烘暟鎹煡璇�
-     * @return
-     */
-    List<InvoiceRegisAndProductExcelDto> invoiceRegisAndProductExcelDtoList();
 }
diff --git a/src/main/java/com/ruoyi/sales/service/InvoiceRegistrationService.java b/src/main/java/com/ruoyi/sales/service/InvoiceRegistrationService.java
index 19af693..e8cf815 100644
--- a/src/main/java/com/ruoyi/sales/service/InvoiceRegistrationService.java
+++ b/src/main/java/com/ruoyi/sales/service/InvoiceRegistrationService.java
@@ -59,7 +59,7 @@
     /**
      * 寮�绁ㄧ櫥璁板鍑�
      * @param response
-     * @param invoiceRegistrationDto
+     * @param salesLedgerDto
      */
-    void invoiceRegistrationExport(HttpServletResponse response, InvoiceRegistrationDto invoiceRegistrationDto);
+    void invoiceRegistrationExport(HttpServletResponse response, SalesLedgerDto salesLedgerDto);
 }
diff --git a/src/main/java/com/ruoyi/sales/service/impl/InvoiceRegistrationServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/InvoiceRegistrationServiceImpl.java
index 56003b7..85451b8 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/InvoiceRegistrationServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/InvoiceRegistrationServiceImpl.java
@@ -7,14 +7,16 @@
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.sales.dto.InvoiceLedgerDto;
 import com.ruoyi.sales.dto.InvoiceRegistrationDto;
 import com.ruoyi.sales.dto.InvoiceRegistrationProductDto;
 import com.ruoyi.sales.dto.SalesLedgerDto;
-import com.ruoyi.sales.excel.InvoiceRegisAndProductExcelDto;
+import com.ruoyi.sales.excel.InvoiceRegistrationExportVo;
 import com.ruoyi.sales.mapper.*;
 import com.ruoyi.sales.pojo.InvoiceLedger;
 import com.ruoyi.sales.pojo.InvoiceRegistration;
 import com.ruoyi.sales.pojo.InvoiceRegistrationProduct;
+import com.ruoyi.sales.pojo.SalesLedger;
 import com.ruoyi.sales.pojo.SalesLedgerProduct;
 import com.ruoyi.sales.service.InvoiceRegistrationService;
 import org.apache.commons.collections4.CollectionUtils;
@@ -26,7 +28,10 @@
 
 import javax.servlet.http.HttpServletResponse;
 import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 @Service
@@ -43,6 +48,9 @@
 
     @Autowired
     private InvoiceLedgerMapper invoiceLedgerMapper;
+
+    @Autowired
+    private SalesLedgerMapper salesLedgerMapper;
 
     /**
      * 寮�绁ㄧ櫥璁拌褰曟柊澧�
@@ -178,13 +186,44 @@
 
     /**
      * 寮�绁ㄧ櫥璁板鍑�
+     * 瀵煎嚭鍒楋細閿�鍞悎鍚屽彿銆佸鎴峰悎鍚屽彿銆佸鎴峰悕绉般�佸悎鍚岄噾棰濄�佸凡寮�绁ㄩ噾棰濄�佹湭寮�绁ㄩ噾棰�
+     * 宸插紑绁�/鏈紑绁ㄩ噾棰濆彛寰勪笌 /sales/ledger/listPage 椤甸潰涓�鑷�
      * @param response
-     * @param invoiceRegistrationDto
+     * @param salesLedgerDto
      */
     @Override
-    public void invoiceRegistrationExport(HttpServletResponse response, InvoiceRegistrationDto invoiceRegistrationDto) {
-        List<InvoiceRegisAndProductExcelDto> invoiceRegisAndProductExcelDtoList = invoiceRegistrationMapper.invoiceRegisAndProductExcelDtoList();
-        ExcelUtil<InvoiceRegisAndProductExcelDto> util = new ExcelUtil<InvoiceRegisAndProductExcelDto>(InvoiceRegisAndProductExcelDto.class);
-        util.exportExcel(response, invoiceRegisAndProductExcelDtoList, "寮�绁ㄧ櫥璁颁俊鎭�");
+    public void invoiceRegistrationExport(HttpServletResponse response, SalesLedgerDto salesLedgerDto) {
+        Page page = new Page();
+        page.setCurrent(-1);
+        page.setSize(-1);
+        IPage<SalesLedger> iPage = salesLedgerMapper.selectSalesLedgerListPage(page, salesLedgerDto);
+        List<SalesLedger> records = iPage.getRecords();
+
+        // 鎸夐攢鍞彴璐︽眹鎬诲凡寮�绁ㄩ噾棰�
+        Map<Integer, BigDecimal> invoicedMap = new HashMap<>();
+        List<Long> salesLedgerIds = records.stream().map(SalesLedger::getId).collect(Collectors.toList());
+        if (CollectionUtils.isNotEmpty(salesLedgerIds)) {
+            List<InvoiceLedgerDto> invoiceLedgerDtoList = invoiceLedgerMapper.invoicedTotal(salesLedgerIds);
+            for (InvoiceLedgerDto invoiceLedgerDto : invoiceLedgerDtoList) {
+                invoicedMap.put(invoiceLedgerDto.getSalesLedgerId(), invoiceLedgerDto.getInvoiceTotal());
+            }
+        }
+
+        List<InvoiceRegistrationExportVo> exportList = new ArrayList<>();
+        for (SalesLedger record : records) {
+            BigDecimal contractAmount = record.getContractAmount() == null ? BigDecimal.ZERO : record.getContractAmount();
+            BigDecimal invoiceTotal = invoicedMap.getOrDefault(record.getId().intValue(), BigDecimal.ZERO);
+            BigDecimal noInvoiceAmountTotal = contractAmount.subtract(invoiceTotal);
+            InvoiceRegistrationExportVo exportVo = new InvoiceRegistrationExportVo();
+            exportVo.setSalesContractNo(record.getSalesContractNo());
+            exportVo.setCustomerContractNo(record.getCustomerContractNo());
+            exportVo.setCustomerName(record.getCustomerName());
+            exportVo.setContractAmount(contractAmount);
+            exportVo.setInvoiceTotal(invoiceTotal);
+            exportVo.setNoInvoiceAmountTotal(noInvoiceAmountTotal);
+            exportList.add(exportVo);
+        }
+        ExcelUtil<InvoiceRegistrationExportVo> util = new ExcelUtil<InvoiceRegistrationExportVo>(InvoiceRegistrationExportVo.class);
+        util.exportExcel(response, exportList, "寮�绁ㄧ櫥璁颁俊鎭�");
     }
 }
diff --git a/src/main/resources/mapper/sales/InvoiceRegistrationMapper.xml b/src/main/resources/mapper/sales/InvoiceRegistrationMapper.xml
index 9edbea4..9624827 100644
--- a/src/main/resources/mapper/sales/InvoiceRegistrationMapper.xml
+++ b/src/main/resources/mapper/sales/InvoiceRegistrationMapper.xml
@@ -34,39 +34,4 @@
         ) T4 ON T1.id = T4.invoice_registration_id
     </select>
 
-    <select id="invoiceRegisAndProductExcelDtoList" resultType="com.ruoyi.sales.excel.InvoiceRegisAndProductExcelDto">
-        SELECT
-            T1.id              ,
-            T1.sales_ledger_id   ,
-            T1.sales_contract_no ,
-            T1.customer_id       ,
-            T1.salesman          ,
-            T1.project_name      ,
-            T1.create_time       ,
-            T1.create_user       ,
-            T1.update_time       ,
-            T1.update_user       ,
-            T1.tenant_id,
-            T2.customer_contract_no,
-            T3.customer_name,
-            T2.contract_amount,
-            T4.product_category,
-            T4.specification_model,
-            T4.unit,
-            T4.quantity,
-            T4.tax_rate,
-            T4.tax_inclusive_unit_price,
-            T4.tax_inclusive_total_price,
-            T4.tax_exclusive_total_price,
-            T4.invoice_type,
-            T4.invoice_num,
-            T4.invoice_amount,
-            T4.no_invoice_num,
-            T4.no_invoice_amount
-        FROM invoice_registration T1
-                 JOIN sales_ledger T2 ON T1.sales_ledger_id = T2.id
-                 JOIN customer T3 ON T1.customer_id = T3.id
-                JOIN invoice_registration_product T4 ON T1.id = T4.invoice_registration_id
-        ORDER BY T1.id ASC
-    </select>
 </mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/sales/SalesLedgerMapper.xml b/src/main/resources/mapper/sales/SalesLedgerMapper.xml
index 7ce76a8..28fb3ed 100644
--- a/src/main/resources/mapper/sales/SalesLedgerMapper.xml
+++ b/src/main/resources/mapper/sales/SalesLedgerMapper.xml
@@ -81,6 +81,12 @@
             <if test="salesLedgerDto.entryDateEnd != null and salesLedgerDto.entryDateEnd != '' ">
                 AND  T1.entry_date &lt;= DATE_FORMAT(#{salesLedgerDto.entryDateEnd},'%Y-%m-%d')
             </if>
+            <if test="salesLedgerDto.ids != null and salesLedgerDto.ids.size() > 0">
+                AND T1.id IN
+                <foreach collection="salesLedgerDto.ids" item="item" open="(" close=")" separator=",">
+                    #{item}
+                </foreach>
+            </if>
         </where>
     </select>
 </mapper>
\ No newline at end of file

--
Gitblit v1.9.3