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 鏂囨湰灞曠ず锛堝 ``锛夈��
+- 蹇嵎鎻愰棶缂哄皯鏃堕棿鑼冨洿鍜屽垎鏋愮洰鏍囷紝缁撴灉绋冲畾鎬т笌鍙В閲婃�ц緝寮便��
+
+## 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