From b3712bb9c618d3cb74b6a200fd83c2ba0577ac3d Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期五, 22 五月 2026 15:14:15 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_New_pro' into dev_New_pro

---
 src/main/java/com/ruoyi/account/mapper/AccountStatementMapper.java           |    3 
 doc/20260522_财务助手提问优化前端变更文档.md                                               |   59 ++++++
 src/main/resources/mapper/account/AccountStatementMapper.xml                 |   35 +++
 src/main/java/com/ruoyi/purchase/dto/VatDto.java                             |   17 +
 src/main/resources/mapper/sales/SalesLedgerMapper.xml                        |   16 +
 src/main/java/com/ruoyi/purchase/service/PurchaseReportService.java          |   14 +
 src/main/java/com/ruoyi/purchase/vo/PurchaseReportVo.java                    |   44 ++++
 src/main/java/com/ruoyi/account/bean/vo/AccountReportVo.java                 |   46 ++++
 src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java     |   31 +++
 src/main/java/com/ruoyi/account/service/impl/AccountingServiceImpl.java      |  181 ++++++++++++++++++-
 src/main/java/com/ruoyi/purchase/service/impl/PurchaseReportServiceImpl.java |   32 +++
 src/main/java/com/ruoyi/account/controller/AccountingController.java         |    4 
 src/main/java/com/ruoyi/purchase/controller/AccountingReportController.java  |   26 ++
 src/main/java/com/ruoyi/sales/mapper/SalesLedgerMapper.java                  |    4 
 src/main/resources/financial-agent-prompt.txt                                |    2 
 src/main/resources/application.yml                                           |    2 
 src/main/java/com/ruoyi/ai/assistant/FinancialIntentExecutor.java            |   22 ++
 17 files changed, 501 insertions(+), 37 deletions(-)

diff --git "a/doc/20260522_\350\264\242\345\212\241\345\212\251\346\211\213\346\217\220\351\227\256\344\274\230\345\214\226\345\211\215\347\253\257\345\217\230\346\233\264\346\226\207\346\241\243.md" "b/doc/20260522_\350\264\242\345\212\241\345\212\251\346\211\213\346\217\220\351\227\256\344\274\230\345\214\226\345\211\215\347\253\257\345\217\230\346\233\264\346\226\207\346\241\243.md"
new file mode 100644
index 0000000..ad4656e
--- /dev/null
+++ "b/doc/20260522_\350\264\242\345\212\241\345\212\251\346\211\213\346\217\220\351\227\256\344\274\230\345\214\226\345\211\215\347\253\257\345\217\230\346\233\264\346\226\207\346\241\243.md"
@@ -0,0 +1,59 @@
+# 璐㈠姟鍔╂墜鎻愰棶浼樺寲鍓嶇鍙樻洿鏂囨。
+
+鏇存柊鏃堕棿锛�2026-05-22  
+閫傜敤妯″潡锛氳储鍔℃櫤鑳藉姪鎵嬶紙`/financial-ai`锛�
+
+## 1. 鑳屾櫙
+
+褰撳墠棣栭〉璐㈠姟鍔╂墜蹇嵎鎻愰棶涓猴細
+
+1. `鐢熸垚鏈懆缁忚惀鍛ㄦ姤`
+2. `涓轰粈涔堝埄娑︿笅闄峘
+3. `鍝釜瀹㈡埛鏈�璧氶挶`
+
+闂鐐癸細
+
+- 绗� 3 鏉¢棶娉曞湪閮ㄥ垎鍦烘櫙涓嬫剰鍥惧懡涓笉绋冲畾锛屽鏄撹蛋鏅�氭枃鏈洖绛旓紝瀵艰嚧鍥捐〃閾炬帴浠ュ師濮� Markdown 鏂囨湰灞曠ず锛堝 `![...](https://local/generate_chart?options=...)`锛夈��
+- 蹇嵎鎻愰棶缂哄皯鏃堕棿鑼冨洿鍜屽垎鏋愮洰鏍囷紝缁撴灉绋冲畾鎬т笌鍙В閲婃�ц緝寮便��
+
+## 2. 鍓嶇蹇嵎鎻愰棶鏂囨浼樺寲锛堝繀鏀癸級
+
+寤鸿灏嗛粯璁や笁鏉″揩鎹锋彁闂皟鏁翠负锛�
+
+1. `鐢熸垚鏈懆缁忚惀鍛ㄦ姤锛堝埄娑︿笌鐜伴噾娴侊級`
+2. `鍒嗘瀽鏈湀鍒╂鼎涓嬮檷鍘熷洜`
+3. `杩�30澶╁摢涓鎴峰埄娑﹁础鐚渶楂榒
+
+璇存槑锛�
+
+- 涓夋潯闂硶鍧囧甫鏃堕棿鑼冨洿鎴栧垎鏋愮洰鏍囷紝鍚庣鍛戒腑鏇寸ǔ瀹氥��
+- 绗� 3 鏉′笌鈥滄渶璧氶挶瀹㈡埛鈥濊涔変竴鑷达紝浣嗏�滃埄娑﹁础鐚渶楂樷�濇洿鏄庣‘锛岄�傚悎鐩存帴椹卞姩鍒╂鼎鍒嗘瀽缁撴灉椤点��
+
+## 3. 涓庡悗绔兘鍔涙槧灏�
+
+| 蹇嵎鎻愰棶 | 棰勬湡鍛戒腑鑳藉姏 | 棰勬湡 `type` |
+| --- | --- | --- |
+| 鐢熸垚鏈懆缁忚惀鍛ㄦ姤锛堝埄娑︿笌鐜伴噾娴侊級 | 缁忚惀鎶ュ憡鐢熸垚 | `financial_operation_report` |
+| 鍒嗘瀽鏈湀鍒╂鼎涓嬮檷鍘熷洜 | 璁㈠崟鍒╂鼎鍒嗘瀽 | `financial_order_profit_analysis` |
+| 杩�30澶╁摢涓鎴峰埄娑﹁础鐚渶楂� | 璁㈠崟鍒╂鼎鍒嗘瀽 | `financial_order_profit_analysis` |
+
+鍚庣宸插悓姝ュ寮衡�滄渶璧氶挶瀹㈡埛/瀹㈡埛鍒╂鼎鏈�楂�/鍒╂鼎璐$尞鏈�楂樷�濈瓑鍚屼箟闂硶璇嗗埆锛屽墠绔寜浠ヤ笂鏂囨鏀归�犲悗鍙洿鎺ヨ仈璋冦��
+
+## 4. 鑱婂ぉ鍐呭娓叉煋鍏滃簳锛堝缓璁敼锛�
+
+閽堝鑱婂ぉ杩斿洖鏂囨湰涓嚭鐜扮殑鍥捐〃 Markdown 閾炬帴锛坄https://local/generate_chart?options=...`锛夛紝寤鸿鍓嶇澧炲姞鍏滃簳澶勭悊锛�
+
+1. 璇嗗埆 Markdown 鍥剧墖璇硶涓殑 `local/generate_chart` 閾炬帴銆�
+2. 瑙f瀽 `options` 鍙傛暟骞惰浆鎹负 ECharts `option` 鍚庢覆鏌撳浘琛ㄧ粍浠躲��
+3. 瑙f瀽澶辫触鏃朵笉灞曠ず鍘熷闀块摼鎺ユ枃鏈紝灞曠ず缁熶竴绌烘�佹彁绀恒��
+
+## 5. 鑱旇皟鍥炲綊娓呭崟
+
+1. 鐐瑰嚮蹇嵎鎻愰棶 `鐢熸垚鏈懆缁忚惀鍛ㄦ姤锛堝埄娑︿笌鐜伴噾娴侊級`  
+   - 鏍¢獙杩斿洖 `type=financial_operation_report`锛屽苟姝e父娓叉煋鎽樿/寤鸿/鍥捐〃銆�
+2. 鐐瑰嚮蹇嵎鎻愰棶 `鍒嗘瀽鏈湀鍒╂鼎涓嬮檷鍘熷洜`  
+   - 鏍¢獙杩斿洖 `type=financial_order_profit_analysis`锛屽苟灞曠ず浜忔崯璁㈠崟涓庡鎴峰埄娑︽帓琛屻��
+3. 鐐瑰嚮蹇嵎鎻愰棶 `杩�30澶╁摢涓鎴峰埄娑﹁础鐚渶楂榒  
+   - 鏍¢獙杩斿洖 `type=financial_order_profit_analysis`锛宍summary.topCustomerByProfit` 鏈夊�笺��
+4. 鎵嬪伐杈撳叆 `鍝釜瀹㈡埛鏈�璧氶挶`銆乣鍝釜瀹㈡埛鍒╂鼎鏈�楂榒  
+   - 鏍¢獙浠嶅懡涓� `financial_order_profit_analysis`锛屼笉鍐嶅嚭鐜板師濮嬪浘琛� Markdown 閾炬帴鐩村嚭銆�
diff --git a/src/main/java/com/ruoyi/account/bean/vo/AccountReportVo.java b/src/main/java/com/ruoyi/account/bean/vo/AccountReportVo.java
index 6d09a31..f7b39d8 100644
--- a/src/main/java/com/ruoyi/account/bean/vo/AccountReportVo.java
+++ b/src/main/java/com/ruoyi/account/bean/vo/AccountReportVo.java
@@ -4,6 +4,7 @@
 import lombok.Data;
 
 import java.math.BigDecimal;
+import java.util.List;
 
 
 @Data
@@ -16,13 +17,50 @@
     @Schema(description = "鎬绘敮鍑�")
     private BigDecimal totalExpense;
 
-    @Schema(description = "鎬绘敹鍏ョ瑪鏁�")
-    private Integer incomeNumber;
+    @Schema(description = "搴旀敹璐︽")
+    private BigDecimal accountsReceivable;
 
-    @Schema(description = "鎬绘敮鍑虹瑪鏁�")
-    private Integer expenseNumber;
+    @Schema(description = "搴斾粯璐︽")
+    private BigDecimal accountsPayable;
 
     @Schema(description = "鍑�鏀跺叆")
     private BigDecimal netRevenue;
 
+    // --- 鎶樼嚎鍥撅細鏈堝害瓒嬪娍鏁版嵁 ---
+    @Schema(description = "鏈堝害瓒嬪娍鏁版嵁鍒楄〃")
+    private List<MonthlyTrendVO> monthlyTrendList;
+
+    // --- 鏌辩姸鍥撅細搴旀敹搴斾粯鏈堝害鏁版嵁 ---
+    @Schema(description = "搴旀敹搴斾粯鏈堝害鏁版嵁鍒楄〃")
+    private List<ReceivablePayableVO> receivablePayableList;
+
+    @Data
+    @Schema(description = "鏈堝害瓒嬪娍VO锛堟姌绾垮浘鐢級")
+    public static class MonthlyTrendVO {
+        @Schema(description = "鏈堜唤锛屾牸寮忥細yyyy-MM")
+        private String month;
+
+        @Schema(description = "褰撴湀钀ユ敹")
+        private BigDecimal income;
+
+        @Schema(description = "褰撴湀鏀嚭")
+        private BigDecimal expense;
+
+        @Schema(description = "褰撴湀鍑�鍒╂鼎")
+        private BigDecimal profit;
+    }
+
+    @Data
+    @Schema(description = "搴旀敹搴斾粯鏈堝害VO锛堟煴鐘跺浘鐢級")
+    public static class ReceivablePayableVO {
+        @Schema(description = "鏈堜唤锛屾牸寮忥細yyyy-MM")
+        private String month;
+
+        @Schema(description = "搴旀敹璐︽閲戦")
+        private BigDecimal receivable;
+
+        @Schema(description = "搴斾粯璐︽閲戦")
+        private BigDecimal payable;
+    }
+
 }
diff --git a/src/main/java/com/ruoyi/account/controller/AccountingController.java b/src/main/java/com/ruoyi/account/controller/AccountingController.java
index 8ab5229..9eeb208 100644
--- a/src/main/java/com/ruoyi/account/controller/AccountingController.java
+++ b/src/main/java/com/ruoyi/account/controller/AccountingController.java
@@ -50,8 +50,8 @@
     /*****************************************璐㈠姟鎶ヨ〃******************************************************************************/
 
     @GetMapping("/accountStatementDetailsByMonth")
-    @Log(title = "缁熻鎬诲簲鏀�+鎬绘敮鍑�+鎬绘敹鍏ョ瑪鏁�+鎬绘敮鍑虹瑪鏁�+鍑�鏀跺叆", businessType = BusinessType.OTHER)
-    @Operation(summary = "璐㈠姟鎶ヨ〃--缁熻鎬诲簲鏀�+鎬绘敮鍑�+鎬绘敹鍏ョ瑪鏁�+鎬绘敮鍑虹瑪鏁�+鍑�鏀跺叆")
+    @Log(title = "璐㈠姟鎶ヨ〃", businessType = BusinessType.OTHER)
+    @Operation(summary = "璐㈠姟鎶ヨ〃")
     public R getAccountStatementDetailsByMonth(AccountReportDto accountReportDto) {
         return R.ok(accountingService.getAccountStatementDetailsByMonth(accountReportDto));
     }
diff --git a/src/main/java/com/ruoyi/account/mapper/AccountStatementMapper.java b/src/main/java/com/ruoyi/account/mapper/AccountStatementMapper.java
index 307cf1a..89730cb 100644
--- a/src/main/java/com/ruoyi/account/mapper/AccountStatementMapper.java
+++ b/src/main/java/com/ruoyi/account/mapper/AccountStatementMapper.java
@@ -6,6 +6,7 @@
 import com.ruoyi.account.bean.dto.StatementAccountDto;
 import com.ruoyi.account.bean.vo.StatementAccountVo;
 import com.ruoyi.account.pojo.AccountStatement;
+import com.ruoyi.purchase.dto.VatDto;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
@@ -22,4 +23,6 @@
 
 
     IPage<StatementAccountVo> listPageAccountStatement(Page page, @Param("req") StatementAccountDto statementAccountDto);
+
+    IPage<VatDto> selectVatDtoPage(Page page, @Param("month") String month);
 }
diff --git a/src/main/java/com/ruoyi/account/service/impl/AccountingServiceImpl.java b/src/main/java/com/ruoyi/account/service/impl/AccountingServiceImpl.java
index 911c808..f42599a 100644
--- a/src/main/java/com/ruoyi/account/service/impl/AccountingServiceImpl.java
+++ b/src/main/java/com/ruoyi/account/service/impl/AccountingServiceImpl.java
@@ -8,7 +8,15 @@
 import com.ruoyi.account.bean.dto.AccountReportDto;
 import com.ruoyi.account.bean.dto.DeviceTypeDetail;
 import com.ruoyi.account.bean.dto.DeviceTypeDistributionVO;
+import com.ruoyi.account.bean.dto.purchase.PurchaseInboundDto;
+import com.ruoyi.account.bean.dto.purchase.PurchaseReturnDto;
+import com.ruoyi.account.bean.dto.sales.SalesOutboundDto;
+import com.ruoyi.account.bean.dto.sales.SalesReturnDto;
 import com.ruoyi.account.bean.vo.AccountReportVo;
+import com.ruoyi.account.bean.vo.purchase.PurchaseInboundVo;
+import com.ruoyi.account.bean.vo.purchase.PurchaseReturnVo;
+import com.ruoyi.account.bean.vo.sales.SalesOutboundVo;
+import com.ruoyi.account.bean.vo.sales.SalesReturnVo;
 import com.ruoyi.account.mapper.purchase.AccountPurchasePaymentMapper;
 import com.ruoyi.account.mapper.sales.AccountSalesCollectionMapper;
 import com.ruoyi.account.pojo.purchase.AccountPurchasePayment;
@@ -20,16 +28,22 @@
 import com.ruoyi.procurementrecord.mapper.CustomStorageMapper;
 import com.ruoyi.procurementrecord.mapper.ProcurementRecordMapper;
 import com.ruoyi.procurementrecord.mapper.ProcurementRecordOutMapper;
+import com.ruoyi.procurementrecord.mapper.ReturnManagementMapper;
 import com.ruoyi.procurementrecord.pojo.CustomStorage;
 import com.ruoyi.procurementrecord.pojo.ProcurementRecordOut;
 import com.ruoyi.procurementrecord.pojo.ProcurementRecordStorage;
+import com.ruoyi.purchase.mapper.PurchaseReturnOrdersMapper;
+import com.ruoyi.stock.mapper.StockInRecordMapper;
+import com.ruoyi.stock.mapper.StockOutRecordMapper;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
+import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.Year;
+import java.time.format.DateTimeFormatter;
 import java.time.temporal.ChronoUnit;
 import java.util.*;
 import java.util.stream.Collectors;
@@ -49,6 +63,10 @@
     private final ProcurementRecordOutMapper procurementRecordOutMapper;
     private final AccountSalesCollectionMapper accountSalesCollectionMapper;
     private final AccountPurchasePaymentMapper accountPurchasePaymentMapper;
+    private final StockOutRecordMapper stockOutRecordMapper;
+    private final ReturnManagementMapper returnManagementMapper;
+    private final StockInRecordMapper stockInRecordMapper;
+    private final PurchaseReturnOrdersMapper purchaseReturnOrdersMapper;
 
 
     @Override
@@ -285,20 +303,155 @@
     @Override
     public AccountReportVo getAccountStatementDetailsByMonth(AccountReportDto accountReportDto) {
         AccountReportVo accountReportVo = new AccountReportVo();
-        //鎬昏惀鏀�=鏀舵鍗曟�婚噾棰�
-        //鎬绘敹鍏ョ瑪鏁�=鏀舵鍗曟�荤瑪鏁�
-        List<AccountSalesCollection> accountSalesCollections = accountSalesCollectionMapper.selectList(Wrappers.<AccountSalesCollection>lambdaQuery()
-                .between(AccountSalesCollection::getCollectionDate, accountReportDto.getEntryDateStart(), accountReportDto.getEntryDateEnd()));
-        accountReportVo.setTotalIncome(accountSalesCollections.stream().map(AccountSalesCollection::getCollectionAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
-        accountReportVo.setIncomeNumber(accountSalesCollections.size());
-        //鎬绘敮鍑�=浠樻鍗曟�婚噾棰�
-        //鎬绘敮鍑虹瑪鏁�=浠樻鍗曟�荤瑪鏁�
-        List<AccountPurchasePayment> accountPurchasePayments = accountPurchasePaymentMapper.selectList(Wrappers.<AccountPurchasePayment>lambdaQuery()
-                .between(AccountPurchasePayment::getPaymentDate, accountReportDto.getEntryDateStart(), accountReportDto.getEntryDateEnd()));
-        accountReportVo.setTotalExpense(accountPurchasePayments.stream().map(AccountPurchasePayment::getPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
-        accountReportVo.setExpenseNumber(accountPurchasePayments.size());
-        //鍑�鍒╂鼎=鎬昏惀鏀�-鎬绘敮鍑�
-        accountReportVo.setNetRevenue(accountReportVo.getTotalIncome().subtract(accountReportVo.getTotalExpense()));
+        LocalDate start = accountReportDto.getEntryDateStart();
+        LocalDate end = accountReportDto.getEntryDateEnd();
+        DateTimeFormatter monthFormatter = DateTimeFormatter.ofPattern("yyyy-MM");
+
+        // ========== 1. 椤堕儴鍗$墖鏁版嵁 ==========
+        // 1.1 鎬昏惀鏀� = 鏀舵鍗曟�婚噾棰�
+        List<AccountSalesCollection> accountSalesCollections = accountSalesCollectionMapper.selectList(
+                Wrappers.<AccountSalesCollection>lambdaQuery()
+                        .between(AccountSalesCollection::getCollectionDate, start, end)
+        );
+        BigDecimal totalIncome = Optional.of(
+                accountSalesCollections.stream()
+                        .map(AccountSalesCollection::getCollectionAmount)
+                        .filter(Objects::nonNull)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add)
+        ).orElse(BigDecimal.ZERO);
+        accountReportVo.setTotalIncome(totalIncome);
+        // 1.2 鎬绘敮鍑� = 浠樻鍗曟�婚噾棰�
+        List<AccountPurchasePayment> accountPurchasePayments = accountPurchasePaymentMapper.selectList(
+                Wrappers.<AccountPurchasePayment>lambdaQuery()
+                        .between(AccountPurchasePayment::getPaymentDate, start, end)
+        );
+        BigDecimal totalExpense = Optional.of(
+                accountPurchasePayments.stream()
+                        .map(AccountPurchasePayment::getPaymentAmount)
+                        .filter(Objects::nonNull)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add)
+        ).orElse(BigDecimal.ZERO);
+        accountReportVo.setTotalExpense(totalExpense);
+        // 1.3 搴旀敹璐︽ = 閿�鍞嚭搴撻噾棰濆悎璁� - 閿�鍞��璐ч噾棰濆悎璁�
+        SalesOutboundDto salesOutboundDto = new SalesOutboundDto();
+        salesOutboundDto.setStartDate(accountReportDto.getEntryDateStart());
+        salesOutboundDto.setEndDate(accountReportDto.getEntryDateEnd());
+        List<SalesOutboundVo> salesOutboundVos = stockOutRecordMapper.listPageAccountSales(new Page(1, -1), salesOutboundDto).getRecords();
+        BigDecimal salesOutAmount = Optional.of(
+                salesOutboundVos.stream()
+                        .map(SalesOutboundVo::getOutboundAmount)
+                        .filter(Objects::nonNull)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add)
+        ).orElse(BigDecimal.ZERO);
+        SalesReturnDto salesReturnDto = new SalesReturnDto();
+        salesReturnDto.setStartDate(accountReportDto.getEntryDateStart());
+        salesReturnDto.setEndDate(accountReportDto.getEntryDateEnd());
+        List<SalesReturnVo> salesReturnVos = returnManagementMapper.listPageAccountSalesReturn(new Page(1, -1), salesReturnDto).getRecords();
+        BigDecimal salesReturnAmount = Optional.of(
+                salesReturnVos.stream()
+                        .map(SalesReturnVo::getRefundAmount)
+                        .filter(Objects::nonNull)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add)
+        ).orElse(BigDecimal.ZERO);
+        accountReportVo.setAccountsReceivable(salesOutAmount.subtract(salesReturnAmount));
+        // 1.4 搴斾粯璐︽ = 閲囪喘鍏ュ簱閲戦鍚堣 - 閲囪喘閫�璐ч噾棰濆悎璁�
+        PurchaseInboundDto purchaseInboundDto = new PurchaseInboundDto();
+        purchaseInboundDto.setStartDate(accountReportDto.getEntryDateStart());
+        purchaseInboundDto.setEndDate(accountReportDto.getEntryDateEnd());
+        List<PurchaseInboundVo> purchaseInboundVos = stockInRecordMapper.listPageAccountPurchase(new Page(1, -1), purchaseInboundDto).getRecords();
+        BigDecimal purchaseInAmount = Optional.of(
+                purchaseInboundVos.stream()
+                        .map(PurchaseInboundVo::getInboundAmount)
+                        .filter(Objects::nonNull)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add)
+        ).orElse(BigDecimal.ZERO);
+        PurchaseReturnDto purchaseReturnDto = new PurchaseReturnDto();
+        purchaseReturnDto.setStartDate(accountReportDto.getEntryDateStart());
+        purchaseReturnDto.setEndDate(accountReportDto.getEntryDateEnd());
+        List<PurchaseReturnVo> purchaseReturnVos = purchaseReturnOrdersMapper.listPageAccountPurchaseReturn(new Page(1, -1), purchaseReturnDto).getRecords();
+        BigDecimal purchaseReturnAmount = Optional.of(
+                purchaseReturnVos.stream()
+                        .map(PurchaseReturnVo::getTotalAmount)
+                        .filter(Objects::nonNull)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add)
+        ).orElse(BigDecimal.ZERO);
+        accountReportVo.setAccountsPayable(purchaseInAmount.subtract(purchaseReturnAmount));
+        // 1.5 鍑�鍒╂鼎 = 鎬昏惀鏀� - 鎬绘敮鍑�
+        BigDecimal netProfit = totalIncome.subtract(totalExpense);
+        accountReportVo.setNetRevenue(netProfit);
+
+        // ========== 2. 鎶樼嚎鍥撅細鏈堝害钀ユ敹/鏀嚭/鍑�鍒╂鼎瓒嬪娍 ==========
+        Map<String, BigDecimal> monthIncomeMap = new HashMap<>();
+        Map<String, BigDecimal> monthExpenseMap = new HashMap<>();
+        // 鏈堝害钀ユ敹
+        accountSalesCollections.forEach(item -> {
+            String month = item.getCollectionDate().format(monthFormatter);
+            monthIncomeMap.put(month, monthIncomeMap.getOrDefault(month, BigDecimal.ZERO)
+                    .add(Optional.ofNullable(item.getCollectionAmount()).orElse(BigDecimal.ZERO)));
+        });
+        // 鏈堝害鏀嚭
+        accountPurchasePayments.forEach(item -> {
+            String month = item.getPaymentDate().format(monthFormatter);
+            monthExpenseMap.put(month, monthExpenseMap.getOrDefault(month, BigDecimal.ZERO)
+                    .add(Optional.ofNullable(item.getPaymentAmount()).orElse(BigDecimal.ZERO)));
+        });
+        // 鐢熸垚杩炵画鏈堜唤鍒楄〃
+        List<String> monthList = new ArrayList<>();
+        LocalDate current = start.withDayOfMonth(1);
+        while (!current.isAfter(end.withDayOfMonth(1))) {
+            monthList.add(current.format(monthFormatter));
+            current = current.plusMonths(1);
+        }
+        // 缁勮瓒嬪娍鏁版嵁
+        List<AccountReportVo.MonthlyTrendVO> trendList = new ArrayList<>();
+        for (String month : monthList) {
+            BigDecimal income = monthIncomeMap.getOrDefault(month, BigDecimal.ZERO);
+            BigDecimal expense = monthExpenseMap.getOrDefault(month, BigDecimal.ZERO);
+            AccountReportVo.MonthlyTrendVO trend = new AccountReportVo.MonthlyTrendVO();
+            trend.setMonth(month);
+            trend.setIncome(income);
+            trend.setExpense(expense);
+            trend.setProfit(income.subtract(expense));
+            trendList.add(trend);
+        }
+        accountReportVo.setMonthlyTrendList(trendList);
+
+        // ========== 3. 鏌辩姸鍥撅細鏈堝害搴旀敹/搴斾粯鏁版嵁 ==========
+        Map<String, BigDecimal> monthReceivableMap = new HashMap<>();
+        Map<String, BigDecimal> monthPayableMap = new HashMap<>();
+        // 鏈堝害搴旀敹锛堥攢鍞嚭搴�-閫�璐э級
+        salesOutboundVos.forEach(item -> {
+            String month = item.getShippingDate().format(monthFormatter);
+            monthReceivableMap.put(month, monthReceivableMap.getOrDefault(month, BigDecimal.ZERO)
+                    .add(Optional.ofNullable(item.getOutboundAmount()).orElse(BigDecimal.ZERO)));
+        });
+        salesReturnVos.forEach(item -> {
+            String month = item.getMakeTime().format(monthFormatter);
+            monthReceivableMap.put(month, monthReceivableMap.getOrDefault(month, BigDecimal.ZERO)
+                    .subtract(Optional.ofNullable(item.getRefundAmount()).orElse(BigDecimal.ZERO)));
+        });
+
+        // 鏈堝害搴斾粯锛堥噰璐叆搴�-閫�璐э級
+        purchaseInboundVos.forEach(item -> {
+            String month = item.getInboundDate().format(monthFormatter);
+            monthPayableMap.put(month, monthPayableMap.getOrDefault(month, BigDecimal.ZERO)
+                    .add(Optional.ofNullable(item.getInboundAmount()).orElse(BigDecimal.ZERO)));
+        });
+        purchaseReturnVos.forEach(item -> {
+            String month = item.getPreparedAt().format(monthFormatter);
+            monthPayableMap.put(month, monthPayableMap.getOrDefault(month, BigDecimal.ZERO)
+                    .subtract(Optional.ofNullable(item.getTotalAmount()).orElse(BigDecimal.ZERO)));
+        });
+        // 缁勮搴旀敹搴斾粯鏁版嵁
+        List<AccountReportVo.ReceivablePayableVO> rpList = new ArrayList<>();
+        for (String month : monthList) {
+            AccountReportVo.ReceivablePayableVO rp = new AccountReportVo.ReceivablePayableVO();
+            rp.setMonth(month);
+            rp.setReceivable(monthReceivableMap.getOrDefault(month, BigDecimal.ZERO));
+            rp.setPayable(monthPayableMap.getOrDefault(month, BigDecimal.ZERO));
+            rpList.add(rp);
+        }
+        accountReportVo.setReceivablePayableList(rpList);
         return accountReportVo;
     }
 }
diff --git a/src/main/java/com/ruoyi/ai/assistant/FinancialIntentExecutor.java b/src/main/java/com/ruoyi/ai/assistant/FinancialIntentExecutor.java
index c1f349c..9afadff 100644
--- a/src/main/java/com/ruoyi/ai/assistant/FinancialIntentExecutor.java
+++ b/src/main/java/com/ruoyi/ai/assistant/FinancialIntentExecutor.java
@@ -45,7 +45,8 @@
         if (containsAny(text, "鎴愭湰鏍哥畻", "浜у搧鎴愭湰", "宸ュ簭鎴愭湰", "浜哄伐鎴愭湰", "鎶樻棫", "鏉愭枡鎹熻��")) {
             return financialAgentTools.calculateIntelligentCost(memoryId, startDate, endDate, timeRange, keyword, limit);
         }
-        if (containsAny(text, "鍒╂鼎鍒嗘瀽", "璁㈠崟鍒╂鼎", "浜忔崯璁㈠崟", "浣庡埄娑�", "鏈�璧氶挶瀹㈡埛", "鍒╂鼎涓嬮檷")) {
+        if (containsAny(text, "鍒╂鼎鍒嗘瀽", "璁㈠崟鍒╂鼎", "浜忔崯璁㈠崟", "浣庡埄娑�",
+                "鏈�璧氶挶瀹㈡埛", "鍝釜瀹㈡埛鏈�璧氶挶", "瀹㈡埛鏈�璧氶挶", "鍒╂鼎鏈�楂樺鎴�", "鍒╂鼎璐$尞鏈�楂樺鎴�", "鍒╂鼎涓嬮檷")) {
             return financialAgentTools.analyzeOrderProfit(memoryId, startDate, endDate, timeRange, keyword, limit);
         }
         if (containsAny(text, "搴撳瓨璧勯噾", "搴撳瓨绉帇", "鍛嗘粸搴撳瓨", "璧勯噾鍗犵敤", "鍛ㄨ浆鐜�", "搴撳瓨鍛ㄨ浆")) {
@@ -86,6 +87,15 @@
         }
         if ("涓轰粈涔堝埄娑︿笅闄�".equals(normalized)) {
             DateRange range = monthRange();
+            return financialAgentTools.analyzeOrderProfit(memoryId, range.startDate(), range.endDate(), range.label(), null, 20);
+        }
+        if ("鍝釜瀹㈡埛鏈�璧氶挶".equals(normalized)
+                || "鏈�杩戝摢涓鎴锋渶璧氶挶".equals(normalized)
+                || "鏈湀鍝釜瀹㈡埛鏈�璧氶挶".equals(normalized)
+                || "杩�30澶╁摢涓鎴锋渶璧氶挶".equals(normalized)
+                || "鍝釜瀹㈡埛鍒╂鼎鏈�楂�".equals(normalized)
+                || "鍝釜瀹㈡埛鍒╂鼎璐$尞鏈�楂�".equals(normalized)) {
+            DateRange range = extractDateRange(text);
             return financialAgentTools.analyzeOrderProfit(memoryId, range.startDate(), range.endDate(), range.label(), null, 20);
         }
         return null;
@@ -216,6 +226,16 @@
                 .replace("璇�", "")
                 .replace("涓�涓�", "")
                 .replace("涓轰粈涔�", "")
+                .replace("鍝釜瀹㈡埛鏈�璧氶挶", "")
+                .replace("鏈�杩戝摢涓鎴锋渶璧氶挶", "")
+                .replace("鏈湀鍝釜瀹㈡埛鏈�璧氶挶", "")
+                .replace("杩�30澶╁摢涓鎴锋渶璧氶挶", "")
+                .replace("鏈�璧氶挶瀹㈡埛", "")
+                .replace("瀹㈡埛鏈�璧氶挶", "")
+                .replace("鍝釜瀹㈡埛鍒╂鼎鏈�楂�", "")
+                .replace("鍒╂鼎鏈�楂樺鎴�", "")
+                .replace("鍝釜瀹㈡埛鍒╂鼎璐$尞鏈�楂�", "")
+                .replace("鍒╂鼎璐$尞鏈�楂樺鎴�", "")
                 .replace("鏈湀", "")
                 .replace("鏈懆", "")
                 .replace("鏈勾", "")
diff --git a/src/main/java/com/ruoyi/purchase/controller/AccountingReportController.java b/src/main/java/com/ruoyi/purchase/controller/AccountingReportController.java
index f265ab0..798112b 100644
--- a/src/main/java/com/ruoyi/purchase/controller/AccountingReportController.java
+++ b/src/main/java/com/ruoyi/purchase/controller/AccountingReportController.java
@@ -2,10 +2,13 @@
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.basic.service.ISupplierService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.framework.aspectj.lang.annotation.Log;
 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
-import com.ruoyi.framework.web.domain.AjaxResult;
 import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.purchase.dto.VatDto;
+import com.ruoyi.purchase.service.PurchaseReportService;
+import com.ruoyi.purchase.vo.PurchaseReportVo;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import jakarta.servlet.http.HttpServletResponse;
@@ -15,6 +18,8 @@
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.util.List;
+
 @RestController
 @Tag(name = "閲囪喘鎶ヨ〃")
 @RequestMapping("/purchase/report")
@@ -22,31 +27,38 @@
 public class AccountingReportController {
 
     private final ISupplierService supplierService;
+    private final PurchaseReportService purchaseReportService;
 
 
     @GetMapping("/list")
     @Log(title = "閲囪喘鎶ヨ〃-椤圭洰鍒╂鼎", businessType = BusinessType.OTHER)
-    public AjaxResult list(Page page) {
-        return AjaxResult.success();
+    public R list(Page page, String customerName) {
+        return R.ok(purchaseReportService.list(page,customerName));
     }
 
     @Log(title = "閲囪喘鎶ヨ〃-椤圭洰鍒╂鼎瀵煎嚭", businessType = BusinessType.EXPORT)
     @PostMapping("/export")
     @Operation(summary = "閲囪喘鎶ヨ〃-椤圭洰鍒╂鼎瀵煎嚭")
-    public void export(HttpServletResponse response) {
+    public void export(HttpServletResponse response, String customerName) {
+        List<PurchaseReportVo> list = purchaseReportService.list(new Page(1,-1),customerName).getRecords();
+        ExcelUtil<PurchaseReportVo> util = new ExcelUtil<>(PurchaseReportVo.class);
+        util.exportExcel(response, list , "椤圭洰鍒╂鼎");
 
     }
 
     @Log(title = "閲囪喘鎶ヨ〃-澧炲�肩◣姣斿", businessType = BusinessType.OTHER)
     @GetMapping("/listVat")
-    public AjaxResult listVat(Page page,String month) {
-        return AjaxResult.success();
+    public R listVat(Page page,String month) {
+        return R.ok(purchaseReportService.listVat(page,month));
     }
 
     @Log(title = "閲囪喘鎶ヨ〃-澧炲�肩◣姣斿", businessType = BusinessType.EXPORT)
     @PostMapping("/exportTwo")
     @Operation(summary = "閲囪喘鎶ヨ〃-澧炲�肩◣姣斿")
-    public void exportTwo(HttpServletResponse response) {
+    public void exportTwo(HttpServletResponse response,String month) {
+        List<VatDto> list = purchaseReportService.listVat(new Page(1,-1),month).getRecords();
+        ExcelUtil<VatDto> util = new ExcelUtil<>(VatDto.class);
+        util.exportExcel(response, list , "澧炲�肩◣姣斿");
     }
 
     @GetMapping("/supplierTransactions")
diff --git a/src/main/java/com/ruoyi/purchase/dto/VatDto.java b/src/main/java/com/ruoyi/purchase/dto/VatDto.java
index c70ebeb..3564183 100644
--- a/src/main/java/com/ruoyi/purchase/dto/VatDto.java
+++ b/src/main/java/com/ruoyi/purchase/dto/VatDto.java
@@ -1,27 +1,30 @@
 package com.ruoyi.purchase.dto;
 
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
 import com.ruoyi.framework.aspectj.lang.annotation.Excel;
+import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
 import java.math.BigDecimal;
-import java.time.LocalDate;
-
 @Data
+@Schema(name = "VatDto", description = "绠$悊椹鹃┒鑸�--澧炲�肩◣姣斿鍙傛暟")
+@ExcelIgnoreUnannotated
 public class VatDto {
 
-    //鏈堜唤
     @Excel(name = "鏈堜唤")
+    @Schema(description = "鏈堜唤")
     private String month ;
 
-    //杩涢」绋�
-    @Excel(name = "杩涢」绋庨")
+    @Excel(name = "閿�椤圭◣棰�")
+    @Schema(description = "閿�椤圭◣棰�")
     private BigDecimal jTaxAmount;
 
-    //閿�椤圭◣
-    @Excel(name = "閿�椤圭◣棰�")
+    @Excel(name = "杩涢」绋庨")
+    @Schema(description = "杩涢」绋庨")
     private BigDecimal xTaxAmount;
 
     @Excel(name = "閿�-杩�")
+    @Schema(description = "閿�-杩�")
     private BigDecimal taxAmount;
 
 }
diff --git a/src/main/java/com/ruoyi/purchase/service/PurchaseReportService.java b/src/main/java/com/ruoyi/purchase/service/PurchaseReportService.java
new file mode 100644
index 0000000..4ec6522
--- /dev/null
+++ b/src/main/java/com/ruoyi/purchase/service/PurchaseReportService.java
@@ -0,0 +1,14 @@
+package com.ruoyi.purchase.service;
+
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.purchase.dto.VatDto;
+import com.ruoyi.purchase.vo.PurchaseReportVo;
+
+public interface PurchaseReportService {
+
+    IPage<PurchaseReportVo> list(Page page, String customerName);
+
+    IPage<VatDto> listVat(Page page, String month);
+}
diff --git a/src/main/java/com/ruoyi/purchase/service/impl/PurchaseReportServiceImpl.java b/src/main/java/com/ruoyi/purchase/service/impl/PurchaseReportServiceImpl.java
new file mode 100644
index 0000000..676cf46
--- /dev/null
+++ b/src/main/java/com/ruoyi/purchase/service/impl/PurchaseReportServiceImpl.java
@@ -0,0 +1,32 @@
+package com.ruoyi.purchase.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.account.mapper.AccountStatementMapper;
+import com.ruoyi.purchase.dto.VatDto;
+import com.ruoyi.purchase.service.PurchaseReportService;
+import com.ruoyi.purchase.vo.PurchaseReportVo;
+import com.ruoyi.sales.mapper.SalesLedgerMapper;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+
+@Service
+@Slf4j
+@RequiredArgsConstructor
+public class PurchaseReportServiceImpl implements PurchaseReportService {
+
+    private final SalesLedgerMapper salesLedgerMapper;
+    private final AccountStatementMapper accountStatementMapper;
+
+    @Override
+    public IPage<PurchaseReportVo> list(Page page, String customerName) {
+        return salesLedgerMapper.selectPurchaseReportVoPage(page, customerName);
+    }
+
+    @Override
+    public IPage<VatDto> listVat(Page page, String month) {
+        return accountStatementMapper.selectVatDtoPage(page, month);
+    }
+}
diff --git a/src/main/java/com/ruoyi/purchase/vo/PurchaseReportVo.java b/src/main/java/com/ruoyi/purchase/vo/PurchaseReportVo.java
new file mode 100644
index 0000000..afe7f98
--- /dev/null
+++ b/src/main/java/com/ruoyi/purchase/vo/PurchaseReportVo.java
@@ -0,0 +1,44 @@
+package com.ruoyi.purchase.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.ruoyi.framework.aspectj.lang.annotation.Excel;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+@Schema(name = "PurchaseReportVo", description = "绠$悊椹鹃┒鑸�--椤圭洰鍒╂鼎鍙傛暟")
+@ExcelIgnoreUnannotated
+public class PurchaseReportVo {
+
+    @Schema(description = "閿�鍞悎鍚屽彿")
+    @Excel(name = "閿�鍞悎鍚屽彿")
+    private String customerContractNo;
+
+    @Schema(description = "瀹㈡埛鍚嶇О")
+    @Excel(name = "瀹㈡埛鍚嶇О")
+    private String customerName;
+
+    @Schema(description = "椤圭洰鍚嶇О")
+    @Excel(name = "椤圭洰鍚嶇О")
+    private String projectName;
+
+    @Excel(name = "鍚堝悓閲戦")
+    @Schema(description = "鍚堝悓閲戦")
+    private BigDecimal contractAmount;
+
+    @Excel(name = "閲囪喘閲戦")
+    @Schema(description = "閲囪喘閲戦")
+    private BigDecimal purchaseAmount;
+
+    @Schema(description = "鍒╂鼎")
+    @Excel(name = "鍒╂鼎")
+    private BigDecimal balance;
+
+    @Schema(description = "鍒╂鼎鐜�")
+    @Excel(name = "鍒╂鼎鐜�")
+    private BigDecimal balanceRatio;
+
+
+}
diff --git a/src/main/java/com/ruoyi/sales/mapper/SalesLedgerMapper.java b/src/main/java/com/ruoyi/sales/mapper/SalesLedgerMapper.java
index 9f49265..5518290 100644
--- a/src/main/java/com/ruoyi/sales/mapper/SalesLedgerMapper.java
+++ b/src/main/java/com/ruoyi/sales/mapper/SalesLedgerMapper.java
@@ -6,6 +6,7 @@
 import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.home.dto.IncomeExpenseAnalysisDto;
+import com.ruoyi.purchase.vo.PurchaseReportVo;
 import com.ruoyi.sales.dto.SalesLedgerDto;
 import com.ruoyi.sales.dto.SalesTrendDto;
 import com.ruoyi.sales.dto.StatisticsTableDto;
@@ -86,4 +87,7 @@
     List<SalesTrendDto> statisticsTable(@Param("statisticsTableDto")StatisticsTableDto statisticsTableDto);
 
     IPage<SalesLedgerDto> listSalesLedgerAndShipped(Page page, @Param("ew") SalesLedgerDto salesLedgerDto);
+
+    IPage<PurchaseReportVo> selectPurchaseReportVoPage(Page page, @Param("customerName") String customerName);
+
 }
diff --git a/src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java b/src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java
index 7051075..91bce0d 100644
--- a/src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java
+++ b/src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java
@@ -17,6 +17,8 @@
 import com.ruoyi.stock.dto.StockInventoryDto;
 import com.ruoyi.stock.dto.StockUninventoryDto;
 import com.ruoyi.stock.execl.StockInRecordExportData;
+import com.ruoyi.production.mapper.ProductionOrderPickMapper;
+import com.ruoyi.production.pojo.ProductionOrderPick;
 import com.ruoyi.stock.mapper.StockInRecordMapper;
 import com.ruoyi.stock.mapper.StockInventoryMapper;
 import com.ruoyi.stock.mapper.StockUninventoryMapper;
@@ -30,6 +32,7 @@
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 @Service
@@ -39,6 +42,7 @@
     private StockInRecordMapper stockInRecordMapper;
     private StockInventoryMapper stockInventoryMapper;
     private StockUninventoryMapper stockUninventoryMapper;
+    private ProductionOrderPickMapper productionOrderPickMapper;
 
     @Override
     public IPage<StockInRecordDto> listPage(Page page, StockInRecordDto stockInRecordDto) {
@@ -186,6 +190,33 @@
             }
             stockInRecord.setApprovalStatus(approvalStatus);
             stockInRecordMapper.updateById(stockInRecord);
+
+            // 瀹℃壒椹冲洖鏃讹紝濡傛灉鏄敓浜ч��鏂欏叆搴擄紝闇�瑕佸洖婊氶鏂欒褰曠殑閫�鏂欐暟閲�
+            if (ReviewStatusEnum.REJECTED.getCode().equals(approvalStatus) &&
+                StockInQualifiedRecordTypeEnum.FEED_RETURN_IN.getCode().equals(stockInRecord.getRecordType())) {
+                // 鎵惧埌瀵瑰簲鐨勯鏂欒褰�
+                ProductionOrderPick productionOrderPick = productionOrderPickMapper.selectById(stockInRecord.getRecordId());
+                if (productionOrderPick != null) {
+                    // 鍥炴粴閫�鏂欐暟閲�
+                    BigDecimal returnQty = productionOrderPick.getReturnQty();
+                    if (returnQty == null) {
+                        returnQty = BigDecimal.ZERO;
+                    }
+                    BigDecimal newReturnQty = returnQty.subtract(stockInRecord.getStockInNum());
+                    if (newReturnQty.compareTo(BigDecimal.ZERO) < 0) {
+                        newReturnQty = BigDecimal.ZERO;
+                    }
+                    productionOrderPick.setReturnQty(newReturnQty);
+                    // 閲嶆柊璁$畻瀹為檯鐢ㄩ噺
+                    BigDecimal actualQty = productionOrderPick.getQuantity().add(
+                        productionOrderPick.getFeedingQty() != null ? productionOrderPick.getFeedingQty() : BigDecimal.ZERO)
+                        .subtract(newReturnQty);
+                    productionOrderPick.setActualQty(actualQty);
+                    productionOrderPick.setReturned(newReturnQty.compareTo(BigDecimal.ZERO) > 0);
+                    productionOrderPickMapper.updateById(productionOrderPick);
+                }
+            }
+
             // 瀹℃壒閫氳繃鏃讹紝搴撳瓨澧炲姞
             if (ReviewStatusEnum.APPROVED.getCode().equals(approvalStatus)) {
                 if ("0".equals(stockInRecord.getType())) {
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 70324c6..ad66a65 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -3,7 +3,7 @@
   main:
     allow-circular-references: true
   profiles:
-    active: dev
+    active: dev-pro
 langchain4j:
   mcp:
     # MCP 鏈嶅姟绔湴鍧�锛堟牴鎹疄闄呴儴缃茬殑 MCP 鏈嶅姟璋冩暣锛�
diff --git a/src/main/resources/financial-agent-prompt.txt b/src/main/resources/financial-agent-prompt.txt
index 2627da3..c7a4a3f 100644
--- a/src/main/resources/financial-agent-prompt.txt
+++ b/src/main/resources/financial-agent-prompt.txt
@@ -6,6 +6,6 @@
 2. 鍛戒腑鎴愭湰銆佸埄娑︺�佸簱瀛樿祫閲戙�佺幇閲戞祦銆侀璀︺�侀┚椹惰埍銆佹棩鎶ュ懆鎶ュ満鏅椂锛屼紭鍏堣皟鐢ㄥ搴斿伐鍏枫��
 3. 宸ュ叿杩斿洖 JSON 鏃讹紝鐩存帴杈撳嚭鍘熷 JSON 瀛楃涓诧紝涓嶈棰濆鍖呰9 Markdown锛屼篃涓嶈鍦ㄥ墠鍚庤拷鍔犺В閲婃枃鏈��
 4. 褰撶敤鎴烽棶棰樼己灏戞椂闂磋寖鍥存椂锛岄粯璁や娇鐢ㄥ伐鍏峰唴缃彛寰勶紙濡傝繎30澶┿�佹湰鏈堛�佽繎90澶╋級锛屽苟鍦ㄥ悗缁彲鎻愰啋鐢ㄦ埛琛ュ厖鑼冨洿銆�
-5. 鐢ㄦ埛闂�滀负浠�涔堝埄娑︿笅闄嶁�濃�滃摢涓鍗曚簭鎹熲�濃�滃摢涓鎴锋渶璧氶挶鈥濃�滃摢涓溅闂�/宸ュ簭鎴愭湰鏈�楂樷�濈瓑闂鏃讹紝浼樺厛鍩轰簬璁㈠崟鍒╂鼎涓庡伐搴忔垚鏈垎鏋愬伐鍏蜂綔绛斻��
+5. 鐢ㄦ埛闂�滀负浠�涔堝埄娑︿笅闄嶁�濃�滃摢涓鍗曚簭鎹熲�濃�滃摢涓鎴锋渶璧氶挶鈥濃�滃摢涓鎴峰埄娑﹁础鐚渶楂樷�濃�滃摢涓溅闂�/宸ュ簭鎴愭湰鏈�楂樷�濈瓑闂鏃讹紝浼樺厛鍩轰簬璁㈠崟鍒╂鼎涓庡伐搴忔垚鏈垎鏋愬伐鍏蜂綔绛斻��
 6. 鍥炵瓟蹇呴』浣跨敤涓枃锛涜嫢鏁版嵁涓嶈冻浠ュ緱鍑虹粨璁猴紝鏄庣‘鎸囧嚭缂哄皯鍝簺鍏抽敭瀛楁鎴栫瓫閫夋潯浠躲��
 7. 鐢ㄦ埛鎻愬埌鈥滀粖骞�/鏈湀/浠婂ぉ/鏈�杩�/涓婃湀/鍘诲勾鈥濈瓑鐩稿鏃堕棿鏃讹紝蹇呴』涓ユ牸鍩轰簬鈥滃綋鍓嶆棩鏈熲�濇崲绠楋紝绂佹鑷鍋囪骞翠唤銆�
diff --git a/src/main/resources/mapper/account/AccountStatementMapper.xml b/src/main/resources/mapper/account/AccountStatementMapper.xml
index 331c61b..32b1621 100644
--- a/src/main/resources/mapper/account/AccountStatementMapper.xml
+++ b/src/main/resources/mapper/account/AccountStatementMapper.xml
@@ -40,4 +40,39 @@
             </if>
     ORDER BY lj.statement_month DESC
     </select>
+    <select id="selectVatDtoPage" resultType="com.ruoyi.purchase.dto.VatDto">
+    SELECT
+        month,
+        jTaxAmount,
+        xTaxAmount,
+        (jTaxAmount - xTaxAmount) AS taxAmount
+    FROM (
+        SELECT
+            month,
+            SUM(IF(type = 'purchase', tax_price, 0)) AS xTaxAmount,
+            SUM(IF(type = 'sales', tax_price, 0)) AS jTaxAmount
+        FROM (
+            SELECT
+                DATE_FORMAT(issue_date, '%Y-%m') AS month,
+                tax_price,
+                'sales' AS type
+            FROM account_sales_invoice
+            WHERE status != 1
+            UNION ALL
+            SELECT
+                DATE_FORMAT(issue_date, '%Y-%m') AS month,
+                tax_price,
+                'purchase' AS type
+            FROM account_purchase_invoice
+            WHERE status != 1
+        ) AS all_data
+    GROUP BY month
+    ) AS TT
+     <where>
+            <if test="month != null">
+                and TT.month = #{month}
+            </if>
+     </where>
+    ORDER BY TT.month
+    </select>
 </mapper>
diff --git a/src/main/resources/mapper/sales/SalesLedgerMapper.xml b/src/main/resources/mapper/sales/SalesLedgerMapper.xml
index e08632a..c145e0a 100644
--- a/src/main/resources/mapper/sales/SalesLedgerMapper.xml
+++ b/src/main/resources/mapper/sales/SalesLedgerMapper.xml
@@ -121,5 +121,21 @@
         </if>
         order by sl.execution_date desc
     </select>
+    <select id="selectPurchaseReportVoPage" resultType="com.ruoyi.purchase.vo.PurchaseReportVo">
+        select sl.sales_contract_no customerContractNo,
+               c.customer_name,
+               sl.project_name,
+               sl.contract_amount contractAmount,
+               pl.contract_amount purchaseAmount,
+               sl.contract_amount-pl.contract_amount balance,
+               (sl.contract_amount-pl.contract_amount)/sl.contract_amount balanceRatio
+        from sales_ledger sl
+        left join purchase_ledger pl on sl.id = pl.sales_ledger_id
+        left join customer c on sl.customer_id = c.id
+        where 1=1
+        <if test="customerName != null and customerName != '' ">
+            and c.customer_name like concat('%',#{customerName},'%')
+        </if>
+    </select>
 
 </mapper>

--
Gitblit v1.9.3