From bb1d7eeda426e66393cf4403cb3ef082db696bd9 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期五, 07 八月 2026 15:42:19 +0800
Subject: [PATCH] feat(report): 新增会计报表功能并完善设备维护和首页统计
---
src/main/java/com/ruoyi/account/mapper/AccountStatementMapper.java | 18
src/main/java/com/ruoyi/device/dto/DeviceMaintenanceBatchCompleteDto.java | 24 +
src/main/java/com/ruoyi/home/mapper/HomeMapper.java | 10
src/main/resources/mapper/account/AccountStatementMapper.xml | 135 ++++
src/main/java/com/ruoyi/inspectiontask/service/impl/InspectionTaskServiceImpl.java | 54 ++
src/main/java/com/ruoyi/measuringinstrumentledger/dto/SparePartsOutboundDto.java | 21
src/main/java/com/ruoyi/home/controller/HomeController.java | 42 +
src/main/java/com/ruoyi/device/dto/DeviceMaintenanceDto.java | 3
src/main/java/com/ruoyi/common/enums/SparePartsRequisitionRecordSourceTypeEnum.java | 3
src/main/java/com/ruoyi/measuringinstrumentledger/service/SparePartsRequisitionRecordService.java | 11
src/main/java/com/ruoyi/purchase/service/PurchaseReportService.java | 10
src/main/java/com/ruoyi/purchase/dto/VatSummaryDto.java | 23
src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java | 253 +++++++--
src/main/resources/mapper/sales/SalesLedgerProductMapper.xml | 44 +
src/main/java/com/ruoyi/purchase/service/impl/PurchaseReportServiceImpl.java | 16
doc/旭宝峰系统功能优化需求整理.md | 23
src/main/java/com/ruoyi/purchase/controller/AccountingReportController.java | 42 +
src/main/java/com/ruoyi/sales/mapper/SalesLedgerMapper.java | 1
src/main/java/com/ruoyi/device/service/impl/DeviceMaintenanceServiceImpl.java | 85 +++
src/main/resources/application-dev.yml | 2
src/main/resources/mapper/home/HomeMapper.xml | 24 +
src/main/java/com/ruoyi/device/controller/DeviceMaintenanceController.java | 20
src/main/java/com/ruoyi/purchase/dto/VatDto.java | 69 ++
src/main/java/com/ruoyi/device/service/IDeviceMaintenanceService.java | 7
src/main/java/com/ruoyi/inspectiontask/pojo/InspectionTask.java | 3
src/main/java/com/ruoyi/measuringinstrumentledger/service/impl/SparePartsRequisitionRecordServiceImpl.java | 45 +
src/main/java/com/ruoyi/inspectiontask/service/InspectionTaskService.java | 8
src/main/java/com/ruoyi/inspectiontask/controller/InspectionTaskController.java | 35
doc/旭宝峰系统功能优化-前端联调文档.md | 349 ++++++++++++++
src/main/java/com/ruoyi/home/service/HomeService.java | 14
src/main/java/com/ruoyi/measuringinstrumentledger/controller/SparePartsRequisitionRecordController.java | 20
src/main/java/com/ruoyi/sales/mapper/SalesLedgerProductMapper.java | 4
32 files changed, 1,217 insertions(+), 201 deletions(-)
diff --git "a/doc/\346\227\255\345\256\235\345\263\260\347\263\273\347\273\237\345\212\237\350\203\275\344\274\230\345\214\226-\345\211\215\347\253\257\350\201\224\350\260\203\346\226\207\346\241\243.md" "b/doc/\346\227\255\345\256\235\345\263\260\347\263\273\347\273\237\345\212\237\350\203\275\344\274\230\345\214\226-\345\211\215\347\253\257\350\201\224\350\260\203\346\226\207\346\241\243.md"
new file mode 100644
index 0000000..aa9deec
--- /dev/null
+++ "b/doc/\346\227\255\345\256\235\345\263\260\347\263\273\347\273\237\345\212\237\350\203\275\344\274\230\345\214\226-\345\211\215\347\253\257\350\201\224\350\260\203\346\226\207\346\241\243.md"
@@ -0,0 +1,349 @@
+# 鏃疂宄扮郴缁熷姛鑳戒紭鍖� - 鍓嶇鑱旇皟鏂囨。
+
+---
+
+## 涓�銆佸浠剁鐞� - 澶囦欢鐙珛鍑哄簱
+
+### 1.1 鏂板鎺ュ彛
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| POST | `/sparePartsRequisitionRecord/outbound` | 澶囦欢鐙珛鍑哄簱锛堜笉渚濊禆缁翠慨/淇濆吇锛� |
+
+### 1.2 璇锋眰鍙傛暟
+
+```json
+{
+ "sparePartsId": 10, // 澶囦欢ID (Long, 蹇呭~)
+ "quantity": 5, // 鍑哄簱鏁伴噺 (Integer, 蹇呭~)
+ "deviceLedgerId": 1, // 璁惧鍙拌处ID (Long, 鍙��)
+ "remark": "鎵嬪姩鍑哄簱澶囨敞" // 澶囨敞 (String, 鍙��)
+}
+```
+
+### 1.3 杩斿洖鍊�
+
+鎴愬姛杩斿洖 `AjaxResult.success()`锛屽け璐ユ姏鍑� `IllegalArgumentException`锛�"澶囦欢涓嶅瓨鍦�" / "澶囦欢 xxx 搴撳瓨涓嶈冻"锛夛紝鍓嶇鐢� `msg` 灞曠ず銆�
+
+### 1.4 鏋氫妇鍙樻洿
+
+`sourceType` 鏂板 `2` = "鐩存帴鍑哄簱"锛坄SparePartsRequisitionRecordSourceTypeEnum`锛夈�傚垪琛ㄦ帴鍙� `/listPage` 杩斿洖鐨� `sourceText` 浼氳嚜鍔ㄦ槧灏勩��
+
+### 1.5 鍓嶇鏀归�犳寚寮�
+
+**鏂囦欢**: `src/views/equipmentManagement/spareParts/index.vue`
+
+- Tab銆屽浠堕鐢ㄨ褰曘�嶅尯鍩熸柊澧� **銆岀洿鎺ュ嚭搴撱��** 鎸夐挳
+- 鐐瑰嚮寮瑰嚭琛ㄥ崟寮圭獥锛屽瓧娈碉細
+ - 澶囦欢閫夋嫨锛坄el-select`锛屽繀濉級
+ - 鍑哄簱鏁伴噺锛坄el-input-number`锛宮in=1锛屽繀濉級
+ - 璁惧閫夋嫨锛堝彲閫夛紝鍙笉鍏宠仈璁惧锛�
+ - 澶囨敞锛堝彲閫夛級
+- 鎻愪氦鍓嶆牎楠屾暟閲� > 0 涓斾笉瓒呰繃搴撳瓨
+- 鎴愬姛鍚庡埛鏂板垪琛�
+
+**API 灏佽** (`src/api/equipmentManagement/sparePartsUsage.js`):
+
+```js
+export function outboundSpareParts(data) {
+ return request({
+ url: '/sparePartsRequisitionRecord/outbound',
+ method: 'post',
+ data
+ })
+}
+```
+
+---
+
+## 浜屻�佽澶囦繚鍏� - 淇濆吇瀹屾垚 / 鎵归噺瀹屾垚
+
+### 2.1 鏂板鎺ュ彛
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| PUT | `/device/maintenance/complete/{id}` | 鍗曟潯淇濆吇瀹屾垚 |
+| PUT | `/device/maintenance/batchComplete` | 涓�閿繚鍏诲畬鎴愶紙鎸夊垱寤烘棩鏈熸壒閲忥級 |
+
+### 2.2 鍗曟潯瀹屾垚 `PUT /complete/{id}`
+
+- Path 鍙傛暟: `id` 鈥� 淇濆吇璁板綍ID
+- 鏃� RequestBody
+- 鍚庣鑷姩璁剧疆 `status=1`銆乣maintenanceActuallyName`=褰撳墠鐧诲綍鐢ㄦ埛銆乣maintenanceActuallyTime`=褰撳墠鏃堕棿
+- 杩斿洖: 鎴愬姛 `AjaxResult.success()`锛屽け璐� `AjaxResult.error("淇濆吇璁板綍涓嶅瓨鍦�" / "璇ヤ繚鍏昏褰曞凡瀹屾垚")`
+
+### 2.3 鎵归噺瀹屾垚 `PUT /batchComplete`
+
+- Query 鍙傛暟: `dateStr` 鈥� 鏃ユ湡瀛楃涓诧紝鏍煎紡 `yyyy-MM-dd`
+- 鍚庣鎸� `createTime` 鏃ユ湡鑼冨洿鏌ヨ璇ユ棩鎵�鏈� `status=0` 璁板綍锛屾壒閲忚缃负瀹岀粨
+- 杩斿洖: 鎴愬姛 `AjaxResult.success("宸插畬鎴� N 鏉′繚鍏昏褰�")`锛屽け璐� `AjaxResult.error("鏃ユ湡鍙傛暟涓嶈兘涓虹┖" / "璇ユ棩鏈熶笅娌℃湁寰呭畬鎴愮殑淇濆吇璁板綍")`
+
+### 2.4 瀹炰綋鍙樻洿
+
+`DeviceMaintenanceDto` 鏂板 `dateStr` 瀛楁锛堟牸寮� `yyyy-MM-dd`锛夛紝鍒楄〃鏌ヨ鏃跺凡鑷姩濉厖锛屽墠绔彲鐢ㄤ簬鏃ユ湡鍒嗙粍銆�
+
+### 2.5 鍓嶇鏀归�犳寚寮�
+
+**鏂囦欢**: `src/views/equipmentManagement/upkeep/index.vue`
+
+1. **鎸� `dateStr` 鏃ユ湡鍒嗙粍鎶樺彔灞曠ず**锛堝弬鐓ч攢鍞彴璐� `type="expand"` 妯″紡锛�
+ - 涓昏鏄剧ず锛氭棩鏈熴�佽褰曟暟銆�**銆屼竴閿繚鍏诲畬鎴愩��** 鎸夐挳
+ - 灞曞紑鍚庡瓙琛ㄦ樉绀烘瘡鏉℃槑缁嗗強 **銆屼繚鍏诲畬鎴愩��** 鎸夐挳
+
+2. **鍗曟潯淇濆吇瀹屾垚鎸夐挳**
+ - 姣忔潯鏄庣粏鎿嶄綔鍒楁柊澧炪�屼繚鍏诲畬鎴愩��
+ - 浠� `status === 0`锛堝緟淇濆吇锛夋椂鏄剧ず
+ - 鐐瑰嚮纭鍚庤皟鐢� `PUT /device/maintenance/complete/{id}`
+
+3. **涓�閿繚鍏诲畬鎴愭寜閽�**
+ - 鍒嗙粍琛屼笂鏄剧ず锛屼紶鍏ヨ鍒嗙粍鐨� `dateStr`
+ - 鐐瑰嚮纭鍚庤皟鐢� `PUT /device/maintenance/batchComplete?dateStr=2026-08-07`
+
+**API 灏佽** (`src/api/equipmentManagement/upkeep.js`):
+
+```js
+export function completeMaintenance(id) {
+ return request({
+ url: '/device/maintenance/complete/' + id,
+ method: 'put'
+ })
+}
+
+export function batchCompleteMaintenance(dateStr) {
+ return request({
+ url: '/device/maintenance/batchComplete',
+ method: 'put',
+ params: { dateStr }
+ })
+}
+```
+
+---
+
+## 涓夈�佽澶囧贰妫� - 宸℃瀹屾垚 / 鎵归噺瀹屾垚
+
+### 3.1 鏂板鎺ュ彛
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| PUT | `/inspectionTask/complete/{id}` | 鍗曟潯宸℃瀹屾垚 |
+| PUT | `/inspectionTask/batchComplete` | 涓�閿贰妫�瀹屾垚锛堟寜鍒涘缓鏃ユ湡鎵归噺锛� |
+
+### 3.2 鍗曟潯瀹屾垚 `PUT /complete/{id}`
+
+- Path 鍙傛暟: `id` 鈥� 宸℃浠诲姟ID
+- 鏃� RequestBody
+- 鍚庣璁剧疆 `status=1`锛岃嫢 `inspectionResult` 涓虹┖鍒欓粯璁よ涓� `"1"`锛堟甯革級
+- 杩斿洖: `R.ok(鍙楀奖鍝嶈鏁�)`锛屽凡瀹屾垚鐨勮褰曚細鎶ラ敊
+
+### 3.3 鎵归噺瀹屾垚 `PUT /batchComplete`
+
+- Query 鍙傛暟: `dateStr` 鈥� 鏃ユ湡瀛楃涓诧紝鏍煎紡 `yyyy-MM-dd`
+- 鍚庣鎸� `createTime` 鏃ユ湡鑼冨洿鏌ヨ璇ユ棩鎵�鏈� `status=0` 璁板綍锛岄�愭潯璁剧疆涓� `status=1`
+- 杩斿洖: `R.ok(瀹屾垚鐨勮褰曟暟)`锛屾棤璁板綍鏃舵姤閿�
+
+### 3.4 瀹炰綋鍙樻洿
+
+`InspectionTask` 鏂板瀛楁锛�
+
+| 瀛楁 | 绫诲瀷 | 璇存槑 |
+|------|------|------|
+| status | Integer | 鐘舵�侊細0=寰呭贰妫�锛�1=宸插畬鎴� |
+
+> `GET /inspectionTask/list` 杩斿洖涓凡鍖呭惈 `status` 瀛楁鍜� `dateStr` 鍒嗙粍瀛楁銆�
+
+### 3.5 鏁版嵁搴撳彉鏇达紙闇� DBA 鎵ц锛�
+
+```sql
+ALTER TABLE `inspection_task`
+ADD COLUMN `status` tinyint NULL DEFAULT 0
+COMMENT '鐘舵�� 0=寰呭贰妫�, 1=宸插畬鎴�';
+```
+
+### 3.6 鍓嶇鏀归�犳寚寮�
+
+**鏂囦欢**: `src/views/equipmentManagement/inspectionManagement/index.vue`
+
+1. **鎸� `dateStr` 鏃ユ湡鍒嗙粍鎶樺彔灞曠ず**
+2. **鍗曟潯宸℃瀹屾垚鎸夐挳** 鈥� 浠� `status === 0` 鏃舵樉绀猴紝璋冪敤 `PUT /inspectionTask/complete/{id}`
+3. **涓�閿贰妫�瀹屾垚鎸夐挳** 鈥� 鍒嗙粍琛屼笂鏄剧ず锛岃皟鐢� `PUT /inspectionTask/batchComplete?dateStr=xxx`
+4. **鐘舵�佸垪** 鈥� 浣跨敤 `status` 瀛楁锛�0=寰呭贰妫�(warning)銆�1=宸插畬鎴�(success)
+
+**API 灏佽** (`src/api/inspectionManagement/index.js`):
+
+```js
+export function completeInspection(id) {
+ return request({
+ url: '/inspectionTask/complete/' + id,
+ method: 'put'
+ })
+}
+
+export function batchCompleteInspection(dateStr) {
+ return request({
+ url: '/inspectionTask/batchComplete',
+ method: 'put',
+ params: { dateStr }
+ })
+}
+```
+
+---
+
+## 鍥涖�佸鍊肩◣瀵规瘮椤甸潰
+
+### 4.1 鏂板鎺ュ彛
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| GET | `/purchase/report/listVatDetail` | 澧炲�肩◣鏄庣粏锛堟寜鍙戠エ/璁㈠崟灞曠ず锛� |
+
+### 4.2 `GET /listVatDetail` 璇锋眰鍙傛暟
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| current | int | 鍚� | 椤电爜 |
+| size | int | 鍚� | 姣忛〉鏉℃暟 |
+| month | String | 鍚� | 鏈堜唤绛涢�夛紝鏍煎紡 `yyyy-MM` |
+
+### 4.3 `GET /listVatDetail` 杩斿洖缁撴瀯
+
+```json
+{
+ "records": [
+ {
+ "invoiceNo": "CG202608001", // 鍙戠エ鍙凤紙閲囪喘鍚堝悓鍙�/閿�鍞悎鍚屽彿锛�
+ "salesContractNo": "XS202608001", // 閿�鍞悎鍚屽彿
+ "supplierName": "XX渚涘簲鍟�", // 渚涘簲鍟嗗悕绉帮紙杩涢」鏃舵湁鍊硷級
+ "customerName": "XX瀹㈡埛", // 瀹㈡埛鍚嶇О锛堥攢椤规椂鏈夊�硷級
+ "orderType": "杩涢」", // 杩涢」 / 閿�椤�
+ "invoiceDate": "2026-08-03", // 寮�绁ㄦ棩鏈�
+ "taxRate": 13.00, // 绋庣巼
+ "jTaxAmount": 13000.00, // 杩涢」绋庨
+ "xTaxAmount": 0.00, // 閿�椤圭◣棰�
+ "taxAmount": 13000.00 // 绋庨
+ }
+ ]
+}
+```
+
+### 4.4 宸叉湁鎺ュ彛锛堜繚鎸佷笉鍙橈級
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| GET | `/purchase/report/listVat` | 澧炲�肩◣鍙戠エ姹囨�� |
+| GET | `/purchase/report/vatChart` | 澧炲�肩◣杩涢攢椤瑰浘琛ㄦ暟鎹紙鎸夋湀鑱氬悎锛� |
+
+### 4.5 鍓嶇鏀归�犳寚寮�
+
+**鏂囦欢**: `src/views/reportAnalysis/taxComparison/index.vue`
+
+1. 鏂板 **Tab 鍒囨崲**:銆屾眹鎬昏鍥俱��/銆屾槑缁嗚鍥俱��
+ - 姹囨�昏鍥� 鈫� 璋冪敤鍘熸湁 `listVat` 鎺ュ彛
+ - 鏄庣粏瑙嗗浘 鈫� 璋冪敤鏂板 `listVatDetail` 鎺ュ彛
+2. 鏄庣粏瑙嗗浘琛ㄦ牸鍒�: 鍙戠エ鍙枫�侀攢鍞悎鍚屽彿銆佸鎴�/渚涘簲鍟嗐�佺被鍨�(tag)銆佸紑绁ㄦ棩鏈熴�佺◣鐜囥�佺◣棰�
+3. 淇濈暀鏈堜唤绛涢�夊拰鍥捐〃鍖哄煙
+
+**API 灏佽** (`src/api/procurementManagement/taxComparison.js`):
+
+```js
+export function getVatDetail(query) {
+ return request({
+ url: '/purchase/report/listVatDetail',
+ method: 'get',
+ params: query // { current, size, month }
+ })
+}
+```
+
+---
+
+## 浜斻�佺鐞嗛┚椹惰埍锛堥椤� PSI 鏁版嵁鍒嗘瀽澶у睆锛�
+
+### 5.1 鍚庣鍙樻洿
+
+浠ヤ笅鎺ュ彛鏂板鍙�夋棩鏈熻寖鍥村弬鏁� `startDate` / `endDate`锛堟牸寮� `yyyy-MM-dd`锛夛紝涓嶄紶鍒欐寜鍘熸湁 type 閫昏緫璁$畻锛堝懆/鏈�/瀛e害锛夛細
+
+| 鏂规硶 | 璺緞 | 鍙樻洿璇存槑 |
+|------|------|----------|
+| GET | `/home/supplierPurchaseRanking` | 鏂板 `startDate`/`endDate` 鍙�夊弬鏁� |
+| GET | `/home/customerContributionRanking` | 鏂板 `startDate`/`endDate` 鍙�夊弬鏁� |
+| GET | `/home/productSalesAnalysis` | 鏂板 `startDate`/`endDate` 鍙�夊弬鏁� |
+| GET | `/home/rawMaterialPurchaseAmountRatio` | 鏂板 `startDate`/`endDate` 鍙�夊弬鏁� |
+| GET | `/home/salesPurchaseStorageProductCount` | 鏂板 `startDate`/`endDate` 鍙�夊弬鏁帮紱label 鏀逛负"閿�鍞鍗曟暟" |
+| GET | `/home/productInOutAnalysis` | 鏂板 `startDate`/`endDate` 鍙�夊弬鏁� |
+| GET | `/home/productTurnoverDays` | 鏂板 `startDate`/`endDate` 鍙�夊弬鏁� |
+
+### 5.2 鍏抽敭鍙樻洿璇︽儏
+
+**`/home/salesPurchaseStorageProductCount`**:
+
+- 绗竴涓寚鏍囦粠銆岄攢鍞骇鍝佹暟銆嶆敼涓� **銆岄攢鍞鍗曟暟銆�**锛堢粺璁� `sales_ledger` 琛ㄨ鍗曟暟锛岄潪浜у搧鏁帮級
+- Query 鍙傛暟锛堝潎涓哄彲閫夛級:
+ - `startDate`: 寮�濮嬫棩鏈� `yyyy-MM-dd`
+ - `endDate`: 缁撴潫鏃ユ湡 `yyyy-MM-dd`
+ - `type`: 涓嶄紶鏃ユ湡鍙傛暟鏃朵娇鐢紙1=鍛�, 2=鏈�, 3=瀛e害锛�
+- 杩斿洖缁撴瀯涓嶅彉 (`List<MapDto>`): `[{ name, value, rate }]`
+
+**`/home/productCategoryDistribution`**:
+
+- 閲囪喘鍝佸ぇ绫诲垎甯冪幆褰㈠浘鏁版嵁宸蹭慨澶嶏紝灏忕被鐨� `value`/`rate` 鐜板湪鍖呭惈鐪熷疄閲囪喘鏁版嵁
+- 鏃犻渶鍓嶇鏀瑰姩
+
+### 5.3 鍓嶇鏀归�犳寚寮�
+
+**鏂囦欢**: `src/views/reportAnalysis/PSIDataAnalysis/index.vue`
+
+1. **鏃ユ湡绛涢�夋帶浠�**
+ - 椤甸潰椤堕儴鏂板 `el-date-picker`锛堢被鍨� `daterange`锛屾牸寮� `yyyy-MM-dd`锛�
+ - 蹇嵎閫夐」: 鏈湀銆佽繎7澶┿�佽繎30澶┿�佽繎90澶�
+ - 閫氳繃 props / provide 灏嗛�変腑鏃ユ湡浼犵粰鍚勫瓙缁勪欢
+
+2. **鏍囩鏂囧瓧淇敼** (`components/center-top.vue`)
+ - 绗竴寮犲崱鐗囨爣棰�: 銆岄攢鍞骇鍝佹暟銆嶁啋 **銆岄攢鍞鍗曟暟銆�**
+
+3. **API 璋冪敤鏇存柊**
+ - 鍚勫瓙缁勪欢璋冪敤鎺ュ彛鏃朵紶鍏� `startDate` / `endDate` 鍙傛暟
+
+**API 灏佽绀轰緥** (`src/api/viewIndex.js`):
+
+```js
+export function getSalesPurchaseStorageProductCount(params) {
+ return request({
+ url: '/home/salesPurchaseStorageProductCount',
+ method: 'get',
+ params // { startDate, endDate } 鎴� { type } 浜岄�変竴
+ })
+}
+```
+
+> 鎵�鏈� `/home` 鎺ュ彛鍧囬伒寰浉鍚屾ā寮忥細浼� `startDate`/`endDate` 鏃朵笉浼� `type`锛屽弽涔嬩害鐒躲��
+
+---
+
+## 鍏�佹敼鍔ㄦ枃浠舵竻鍗�
+
+| 椤甸潰 | 鏂囦欢璺緞 | 鏀瑰姩绫诲瀷 |
+|------|----------|----------|
+| 澶囦欢绠$悊 | `src/views/equipmentManagement/spareParts/index.vue` | 鏂板銆岀洿鎺ュ嚭搴撱�嶆寜閽�+寮圭獥 |
+| 澶囦欢API | `src/api/equipmentManagement/sparePartsUsage.js` | 鏂板 `outboundSpareParts` |
+| 璁惧淇濆吇 | `src/views/equipmentManagement/upkeep/index.vue` | 鏃ユ湡鍒嗙粍+淇濆吇瀹屾垚+涓�閿繚鍏诲畬鎴� |
+| 淇濆吇API | `src/api/equipmentManagement/upkeep.js` | 鏂板 `completeMaintenance` / `batchCompleteMaintenance` |
+| 璁惧宸℃ | `src/views/equipmentManagement/inspectionManagement/index.vue` | 鏃ユ湡鍒嗙粍+宸℃瀹屾垚+涓�閿贰妫�瀹屾垚 |
+| 宸℃API | `src/api/inspectionManagement/index.js` | 鏂板 `completeInspection` / `batchCompleteInspection` |
+| 澧炲�肩◣瀵规瘮 | `src/views/reportAnalysis/taxComparison/index.vue` | 鏂板鏄庣粏瑙嗗浘 Tab |
+| 澧炲�肩◣API | `src/api/procurementManagement/taxComparison.js` | 鏂板 `getVatDetail` |
+| PSI澶у睆 | `src/views/reportAnalysis/PSIDataAnalysis/index.vue` | 鏂板鏃ユ湡绛涢�夋帶浠� |
+| PSI缁熻鍗� | `src/views/reportAnalysis/PSIDataAnalysis/components/center-top.vue` | 鏍囩鏀�"閿�鍞鍗曟暟"+鏃ユ湡鍙傛暟 |
+| 澶у睆API | `src/api/viewIndex.js` | 鎵�鏈夋帴鍙e鍔� `startDate`/`endDate` 鍙傛暟 |
+
+---
+
+## 涓冦�佹敞鎰忎簨椤�
+
+1. **宸℃ DDL**: 闇�閫氱煡 DBA 鎵ц `ALTER TABLE inspection_task ADD COLUMN status tinyint ...`
+2. **HTTP 鏂规硶**: 瀹屾垚绫绘帴鍙d娇鐢� **PUT**锛屾柊澧炲嚭搴撲娇鐢� **POST**锛屾煡璇娇鐢� **GET**
+3. **鏃ユ湡鏍煎紡**: 鎵�鏈夋棩鏈熷弬鏁颁娇鐢� `yyyy-MM-dd` 瀛楃涓叉牸寮�
+4. **绌哄弬鏁板吋瀹�**: 鏃ユ湡鍙傛暟鍧囦负鍙�夛紝涓嶄紶鍒欎繚鎸佸師鏈� type 閫昏緫
+5. **鎵归噺瀹屾垚**: 淇濆吇/宸℃鐨勬壒閲忓畬鎴愬潎鎸� `createTime` 鏃ユ湡鑼冨洿鍖归厤锛岄潪 `planTime`
+6. **閿欒澶勭悊**: 澶囦欢鍑哄簱澶辫触浼氭姏寮傚父锛堥潪 AjaxResult锛夛紝鍓嶇闇�鍦� catch 涓睍绀洪敊璇俊鎭�
diff --git "a/doc/\346\227\255\345\256\235\345\263\260\347\263\273\347\273\237\345\212\237\350\203\275\344\274\230\345\214\226\351\234\200\346\261\202\346\225\264\347\220\206.md" "b/doc/\346\227\255\345\256\235\345\263\260\347\263\273\347\273\237\345\212\237\350\203\275\344\274\230\345\214\226\351\234\200\346\261\202\346\225\264\347\220\206.md"
new file mode 100644
index 0000000..7332c0c
--- /dev/null
+++ "b/doc/\346\227\255\345\256\235\345\263\260\347\263\273\347\273\237\345\212\237\350\203\275\344\274\230\345\214\226\351\234\200\346\261\202\346\225\264\347\220\206.md"
@@ -0,0 +1,23 @@
+# 涓�銆佽澶囩鐞嗘ā鍧�
+
+## 1\. 澶囦欢绠$悊 - 澶囦欢棰嗙敤璁板綍
+
+鐜版湁澶囦欢鍑哄簱浠呰兘渚濇墭璁惧妫�淇満鏅紝鍑哄簱娓犻亾瀛樺湪灞�闄愶紝闇�鏂板鐙珛澶囦欢鍑哄簱鍔熻兘鍏ュ彛锛屾敮鎸佺洿鎺ュ畬鎴愬浠堕鐢ㄥ嚭搴撴搷浣溿��
+
+## 澶囦欢棰嗙敤璁板綍椤甸潰2. 璁惧淇濆吇 - 淇濆吇浠诲姟
+
+淇濆吇浠诲姟涓嬪彂鍚庯紝椤甸潰鍙傜収閿�鍞� / 閲囪喘璁㈠崟鏍峰紡锛屾敮鎸佹寜鏃ユ湡鍒嗙粍鎶樺彔灞曠ず锛屽垎缁勬潯鐩彲灞曞紑鏌ョ湅鏄庣粏锛涘崟鏉℃槑缁嗚鏈熬澧炲姞銆愪繚鍏诲畬鎴愩�戞搷浣滄寜閽紝鍙崟鐙姙缁撳崟鏉′繚鍏讳换鍔★紱鎶樺彔姹囨�荤姸鎬佷笅锛屾柊澧炪�愪竴閿繚鍏诲畬鎴愩�戞壒閲忔搷浣滄寜閽紝蹇�熷姙缁撳綋鍓嶅垎缁勫叏閮ㄤ繚鍏婚」銆�
+
+## 淇濆吇浠诲姟椤甸潰3. 璁惧宸℃ - 宸℃浠诲姟
+
+宸℃浠诲姟涓嬪彂瀹屾垚鍚庯紝椤甸潰鍙傜収閿�鍞� / 閲囪喘璁㈠崟甯冨眬锛屾寜鏃ユ湡鍒嗙粍鎶樺彔灞曠ず锛屽垎缁勬敮鎸佸睍寮�鏌ョ湅鏄庣粏锛涙瘡鏉″贰妫�鏄庣粏鍚庡璁俱�愬贰妫�瀹屾垚銆戞寜閽紝鏀寔鍗曠嫭鍔炵粨鍗曟潯宸℃璁板綍锛涘垎缁勬姌鍙犳湭灞曞紑鐘舵�佷笅锛屾彁渚涖�愪竴閿贰妫�瀹屾垚銆戞壒閲忔搷浣滐紝缁熶竴鍔炵粨璇ュ垎缁勪笅鎵�鏈夊贰妫�浠诲姟銆�
+
+# 浜屻�佸喅绛栧垎鏋愭ā鍧�
+
+## 1\. 澧炲�肩◣瀵规瘮椤甸潰
+
+褰撳墠椤甸潰鏌ヨ鏃犳暟鎹紝鎸夌洃鐞嗚姹備紭鍖栨暟鎹睍绀洪�昏緫锛屽垪琛ㄥ睍绀哄悇璁㈠崟澧炲�肩◣鏄庣粏锛涢〉闈㈠彸渚ф柊澧炴煴鐘跺彲瑙嗗寲鍥捐〃锛岀洿瑙傚姣旇繘閿�椤瑰鍊肩◣鏁版嵁銆�
+
+## 澧炲�肩◣瀵规瘮椤甸潰2. 绠$悊椹鹃┒鑸憋紙PSI 鏁版嵁鍒嗘瀽澶у睆锛�
+
+鎸囨爣淇敼锛氬皢椤堕儴銆岄攢鍞骇鍝佹暟銆嶈皟鏁翠负銆岄攢鍞鍗曟暟銆嶏紱鏃堕棿绛涢�夛細椤甸潰宸︿笂瑙掓柊澧炴棩鏈熻寖鍥翠笅鎷夌瓫閫夋帶浠讹紝鎵�鏈夌粺璁℃寚鏍囨爣娉ㄥ綋鍓嶇瓫閫夋椂娈碉紱鏁版嵁淇锛氳В鍐炽�岄噰璐搧鍒嗗竷銆嶇幆褰㈠浘鏃犳暟鎹睍绀洪棶棰樸��
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/account/mapper/AccountStatementMapper.java b/src/main/java/com/ruoyi/account/mapper/AccountStatementMapper.java
index 89730cb..7c66129 100644
--- a/src/main/java/com/ruoyi/account/mapper/AccountStatementMapper.java
+++ b/src/main/java/com/ruoyi/account/mapper/AccountStatementMapper.java
@@ -7,22 +7,20 @@
import com.ruoyi.account.bean.vo.StatementAccountVo;
import com.ruoyi.account.pojo.AccountStatement;
import com.ruoyi.purchase.dto.VatDto;
+import com.ruoyi.purchase.dto.VatSummaryDto;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
-/**
- * <p>
- * Mapper 鎺ュ彛
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-05-19 09:42:47
- */
+import java.util.List;
+
@Mapper
public interface AccountStatementMapper extends BaseMapper<AccountStatement> {
-
IPage<StatementAccountVo> listPageAccountStatement(Page page, @Param("req") StatementAccountDto statementAccountDto);
- IPage<VatDto> selectVatDtoPage(Page page, @Param("month") String month);
+ IPage<VatDto> selectVatDtoPage(Page page, @Param("month") String month, @Param("type") String type);
+
+ List<VatSummaryDto> selectVatSummary(@Param("year") String year);
+
+ IPage<VatDto> listVatDetail(Page page, @Param("month") String month);
}
diff --git a/src/main/java/com/ruoyi/common/enums/SparePartsRequisitionRecordSourceTypeEnum.java b/src/main/java/com/ruoyi/common/enums/SparePartsRequisitionRecordSourceTypeEnum.java
index b9acc40..d853453 100644
--- a/src/main/java/com/ruoyi/common/enums/SparePartsRequisitionRecordSourceTypeEnum.java
+++ b/src/main/java/com/ruoyi/common/enums/SparePartsRequisitionRecordSourceTypeEnum.java
@@ -5,7 +5,8 @@
@Getter
public enum SparePartsRequisitionRecordSourceTypeEnum implements BaseEnum<Integer> {
SparePartsRequisitionRecordSourceTypeRepair(0, "缁翠慨"),
- SparePartsRequisitionRecordSourceTypeMaintenance(1, "淇濆吇");
+ SparePartsRequisitionRecordSourceTypeMaintenance(1, "淇濆吇"),
+ SparePartsRequisitionRecordSourceTypeDirectOutbound(2, "鐩存帴鍑哄簱");
private final Integer code;
private final String value;
diff --git a/src/main/java/com/ruoyi/device/controller/DeviceMaintenanceController.java b/src/main/java/com/ruoyi/device/controller/DeviceMaintenanceController.java
index e34fc37..28e9b0d 100644
--- a/src/main/java/com/ruoyi/device/controller/DeviceMaintenanceController.java
+++ b/src/main/java/com/ruoyi/device/controller/DeviceMaintenanceController.java
@@ -2,6 +2,7 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.device.dto.DeviceMaintenanceBatchCompleteDto;
import com.ruoyi.device.dto.DeviceMaintenanceDto;
import com.ruoyi.device.pojo.DeviceLedger;
import com.ruoyi.device.pojo.DeviceMaintenance;
@@ -12,6 +13,7 @@
import io.swagger.v3.oas.annotations.Operation;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
+import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
@@ -79,5 +81,23 @@
deviceMaintenanceService.export(response, ids);
}
+ @PostMapping("/batchComplete")
+ @Operation(summary = "涓�閿繚鍏诲畬鎴�")
+ @Transactional(rollbackFor = Exception.class)
+ public AjaxResult batchComplete(@RequestBody DeviceMaintenanceBatchCompleteDto dto) {
+ return deviceMaintenanceService.batchComplete(dto);
+ }
+
+ @PutMapping("/complete/{id}")
+ @Operation(summary = "淇濆吇瀹屾垚")
+ public AjaxResult complete(@PathVariable Long id) {
+ return deviceMaintenanceService.complete(id);
+ }
+
+ @PutMapping("/batchComplete")
+ @Operation(summary = "涓�閿繚鍏诲畬鎴�")
+ public AjaxResult batchComplete(String dateStr) {
+ return deviceMaintenanceService.batchComplete(dateStr);
+ }
}
diff --git a/src/main/java/com/ruoyi/device/dto/DeviceMaintenanceBatchCompleteDto.java b/src/main/java/com/ruoyi/device/dto/DeviceMaintenanceBatchCompleteDto.java
new file mode 100644
index 0000000..b3e7aff
--- /dev/null
+++ b/src/main/java/com/ruoyi/device/dto/DeviceMaintenanceBatchCompleteDto.java
@@ -0,0 +1,24 @@
+package com.ruoyi.device.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+
+@Data
+@Schema(name = "璁惧淇濆吇鎵归噺瀹屾垚璇锋眰")
+public class DeviceMaintenanceBatchCompleteDto {
+
+ @Schema(description = "璁″垝淇濆吇鏃ユ湡", requiredMode = Schema.RequiredMode.REQUIRED)
+ private LocalDate maintenancePlanDate;
+
+ @Schema(description = "瀹為檯淇濆吇浜�")
+ private String maintenanceActuallyName;
+
+ @Schema(description = "瀹為檯淇濆吇鏃堕棿")
+ private LocalDateTime maintenanceActuallyTime;
+
+ @Schema(description = "淇濆吇缁撴灉")
+ private String maintenanceResult;
+}
diff --git a/src/main/java/com/ruoyi/device/dto/DeviceMaintenanceDto.java b/src/main/java/com/ruoyi/device/dto/DeviceMaintenanceDto.java
index 127d82b..81d34a0 100644
--- a/src/main/java/com/ruoyi/device/dto/DeviceMaintenanceDto.java
+++ b/src/main/java/com/ruoyi/device/dto/DeviceMaintenanceDto.java
@@ -53,5 +53,8 @@
@Schema(description = "淇濆吇鍥剧墖")
private List<StorageBlobDTO> storageBlobDTOs;
+ @Schema(description = "鏃ユ湡鍒嗙粍瀛楁(yyyy-MM-dd)")
+ private String dateStr;
+
}
diff --git a/src/main/java/com/ruoyi/device/service/IDeviceMaintenanceService.java b/src/main/java/com/ruoyi/device/service/IDeviceMaintenanceService.java
index e5a4080..3f1d770 100644
--- a/src/main/java/com/ruoyi/device/service/IDeviceMaintenanceService.java
+++ b/src/main/java/com/ruoyi/device/service/IDeviceMaintenanceService.java
@@ -3,6 +3,7 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.device.dto.DeviceMaintenanceBatchCompleteDto;
import com.ruoyi.device.dto.DeviceMaintenanceDto;
import com.ruoyi.device.pojo.DeviceMaintenance;
import com.ruoyi.device.vo.DeviceMaintenanceVo;
@@ -21,4 +22,10 @@
void export(HttpServletResponse response, Long[] ids);
DeviceMaintenanceVo detailById(Long id);
+
+ AjaxResult batchComplete(DeviceMaintenanceBatchCompleteDto dto);
+
+ AjaxResult complete(Long id);
+
+ AjaxResult batchComplete(String dateStr);
}
diff --git a/src/main/java/com/ruoyi/device/service/impl/DeviceMaintenanceServiceImpl.java b/src/main/java/com/ruoyi/device/service/impl/DeviceMaintenanceServiceImpl.java
index fbf03ad..e426bfe 100644
--- a/src/main/java/com/ruoyi/device/service/impl/DeviceMaintenanceServiceImpl.java
+++ b/src/main/java/com/ruoyi/device/service/impl/DeviceMaintenanceServiceImpl.java
@@ -1,13 +1,16 @@
package com.ruoyi.device.service.impl;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.basic.enums.RecordTypeEnum;
import com.ruoyi.basic.utils.FileUtil;
+import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.device.dto.DeviceMaintenanceBatchCompleteDto;
import com.ruoyi.device.dto.DeviceMaintenanceDto;
import com.ruoyi.device.execl.DeviceMaintenanceExeclDto;
import com.ruoyi.device.mapper.DeviceMaintenanceMapper;
@@ -27,6 +30,9 @@
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
@@ -95,6 +101,11 @@
}
}
+ // 鑻ヨ缃簡瀹為檯淇濆吇鏃ユ湡锛屽垯鑷姩鏍囪涓哄畬缁�
+ if (deviceMaintenance.getMaintenanceActuallyTime() != null && deviceMaintenance.getStatus() == null) {
+ deviceMaintenance.setStatus(1);
+ }
+
if (this.updateById(deviceMaintenance)) {
// 澶勭悊鍥剧墖涓婁紶
fileUtil.saveStorageAttachmentByRecordTypeAndRecordId("file", RecordTypeEnum.DEVICE_MAINTENANCE, deviceMaintenance.getId(), deviceMaintenance.getStorageBlobDTOs());
@@ -104,6 +115,80 @@
}
@Override
+ @Transactional(rollbackFor = Exception.class)
+ public AjaxResult complete(Long id) {
+ DeviceMaintenance record = this.getById(id);
+ if (record == null) {
+ return AjaxResult.error("淇濆吇璁板綍涓嶅瓨鍦�");
+ }
+ if (record.getStatus() != null && record.getStatus() == 1) {
+ return AjaxResult.error("璇ヤ繚鍏昏褰曞凡瀹屾垚");
+ }
+ record.setStatus(1);
+ record.setMaintenanceActuallyName(SecurityUtils.getLoginUser().getNickName());
+ record.setMaintenanceActuallyTime(LocalDateTime.now());
+ this.updateById(record);
+ return AjaxResult.success();
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public AjaxResult batchComplete(String dateStr) {
+ if (StringUtils.isBlank(dateStr)) {
+ return AjaxResult.error("鏃ユ湡鍙傛暟涓嶈兘涓虹┖");
+ }
+ LocalDate date = LocalDate.parse(dateStr);
+ LocalDateTime startOfDay = date.atStartOfDay();
+ LocalDateTime endOfDay = date.atTime(LocalTime.MAX);
+ List<DeviceMaintenance> records = this.lambdaQuery()
+ .eq(DeviceMaintenance::getStatus, 0)
+ .ge(DeviceMaintenance::getCreateTime, startOfDay)
+ .le(DeviceMaintenance::getCreateTime, endOfDay)
+ .list();
+ if (records.isEmpty()) {
+ return AjaxResult.error("璇ユ棩鏈熶笅娌℃湁寰呭畬鎴愮殑淇濆吇璁板綍");
+ }
+ String nickName = SecurityUtils.getLoginUser().getNickName();
+ LocalDateTime now = LocalDateTime.now();
+ for (DeviceMaintenance record : records) {
+ record.setStatus(1);
+ record.setMaintenanceActuallyName(nickName);
+ record.setMaintenanceActuallyTime(now);
+ }
+ this.updateBatchById(records);
+ return AjaxResult.success("宸插畬鎴� " + records.size() + " 鏉′繚鍏昏褰�");
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public AjaxResult batchComplete(DeviceMaintenanceBatchCompleteDto dto) {
+ if (dto.getMaintenancePlanDate() == null) {
+ return AjaxResult.error("璁″垝淇濆吇鏃ユ湡涓嶈兘涓虹┖");
+ }
+ LambdaQueryWrapper<DeviceMaintenance> wrapper = new LambdaQueryWrapper<>();
+ wrapper.eq(DeviceMaintenance::getStatus, 0)
+ .apply("DATE(maintenance_plan_time) = {0}", dto.getMaintenancePlanDate().toString());
+ List<DeviceMaintenance> list = this.list(wrapper);
+ if (list.isEmpty()) {
+ return AjaxResult.success("璇ユ棩鏈熶笅娌℃湁寰呬繚鍏荤殑璁板綍");
+ }
+ list.forEach(task -> {
+ task.setStatus(1);
+ if (StringUtils.isNotBlank(dto.getMaintenanceActuallyName())) {
+ task.setMaintenanceActuallyName(dto.getMaintenanceActuallyName());
+ }
+ if (dto.getMaintenanceActuallyTime() != null) {
+ task.setMaintenanceActuallyTime(dto.getMaintenanceActuallyTime());
+ }
+ if (StringUtils.isNotBlank(dto.getMaintenanceResult())) {
+ task.setMaintenanceResult(dto.getMaintenanceResult());
+ }
+ });
+ this.updateBatchById(list);
+ return AjaxResult.success("鍏卞畬鎴� " + list.size() + " 鏉′繚鍏昏褰�");
+ }
+
+ @Override
public void export(HttpServletResponse response, Long[] ids) {
List<DeviceMaintenance> supplierManageList = deviceMaintenanceMapper.selectList(null);
ArrayList<DeviceMaintenanceExeclDto> deviceLedgerExeclDtos = new ArrayList<>();
diff --git a/src/main/java/com/ruoyi/home/controller/HomeController.java b/src/main/java/com/ruoyi/home/controller/HomeController.java
index 48a2185..e5f8513 100644
--- a/src/main/java/com/ruoyi/home/controller/HomeController.java
+++ b/src/main/java/com/ruoyi/home/controller/HomeController.java
@@ -103,8 +103,10 @@
/********************************************************钀ラ攢閲囪喘绫�**************************************************/
@GetMapping("/supplierPurchaseRanking")
@Operation(summary = "渚涘簲鍟嗛噰璐帓鍚�")
- public R supplierPurchaseRanking(@DefaultType Integer type) {
- List<SupplierPurchaseRankingDto> list = homeService.supplierPurchaseRanking(type);
+ public R supplierPurchaseRanking(@DefaultType Integer type,
+ @RequestParam(required = false) String startDate,
+ @RequestParam(required = false) String endDate) {
+ List<SupplierPurchaseRankingDto> list = homeService.supplierPurchaseRanking(type, startDate, endDate);
return R.ok(list);
}
@@ -117,22 +119,28 @@
@GetMapping("/customerContributionRanking")
@Operation(summary = "瀹㈡埛閲戦璐$尞鎺掑悕")
- public R customerContributionRanking(@DefaultType Integer type) {
- List<CustomerContributionRankingDto> list = homeService.customerContributionRanking(type);
+ public R customerContributionRanking(@DefaultType Integer type,
+ @RequestParam(required = false) String startDate,
+ @RequestParam(required = false) String endDate) {
+ List<CustomerContributionRankingDto> list = homeService.customerContributionRanking(type, startDate, endDate);
return R.ok(list);
}
@GetMapping("/productSalesAnalysis")
@Operation(summary = "鍚勪骇鍝侀攢鍞噾棰濆垎鏋�")
- public R productSalesAnalysis() {
- List<MapDto> list = homeService.productSalesAnalysis();
+ public R productSalesAnalysis(
+ @RequestParam(required = false) String startDate,
+ @RequestParam(required = false) String endDate) {
+ List<MapDto> list = homeService.productSalesAnalysis(startDate, endDate);
return R.ok(list);
}
@GetMapping("/rawMaterialPurchaseAmountRatio")
@Operation(summary = "鍘熸潗鏂欓噰璐噾棰濆崰姣�")
- public R rawMaterialPurchaseAmountRatio(){
- List<MapDto> list = homeService.rawMaterialPurchaseAmountRatio();
+ public R rawMaterialPurchaseAmountRatio(
+ @RequestParam(required = false) String startDate,
+ @RequestParam(required = false) String endDate){
+ List<MapDto> list = homeService.rawMaterialPurchaseAmountRatio(startDate, endDate);
return R.ok(list);
}
@@ -473,22 +481,28 @@
@GetMapping("/salesPurchaseStorageProductCount")
@Operation(summary = "閿�鍞�-閲囪喘-鍌ㄥ瓨浜у搧鏁�")
- public R salesPurchaseStorageProductCount(){
- List<MapDto> list = homeService.salesPurchaseStorageProductCount();
+ public R salesPurchaseStorageProductCount(
+ @RequestParam(required = false) String startDate,
+ @RequestParam(required = false) String endDate){
+ List<MapDto> list = homeService.salesPurchaseStorageProductCount(startDate, endDate);
return R.ok(list);
}
@GetMapping("/productInOutAnalysis")
@Operation(summary = "浜у搧鍑哄叆搴撳垎鏋�")
- public R productInOutAnalysis(@DefaultType Integer type){
- List<Map<String, Object>> result = homeService.productInOutAnalysis(type);
+ public R productInOutAnalysis(@DefaultType Integer type,
+ @RequestParam(required = false) String startDate,
+ @RequestParam(required = false) String endDate){
+ List<Map<String, Object>> result = homeService.productInOutAnalysis(type, startDate, endDate);
return R.ok(result);
}
@GetMapping("/productTurnoverDays")
@Operation(summary = "浜у搧鍛ㄨ浆澶╂暟")
- public R productTurnoverDays(){
- List<MapDto> list = homeService.productTurnoverDays();
+ public R productTurnoverDays(
+ @RequestParam(required = false) String startDate,
+ @RequestParam(required = false) String endDate){
+ List<MapDto> list = homeService.productTurnoverDays(startDate, endDate);
return R.ok(list);
}
diff --git a/src/main/java/com/ruoyi/home/mapper/HomeMapper.java b/src/main/java/com/ruoyi/home/mapper/HomeMapper.java
index 1bf30e4..2014da6 100644
--- a/src/main/java/com/ruoyi/home/mapper/HomeMapper.java
+++ b/src/main/java/com/ruoyi/home/mapper/HomeMapper.java
@@ -2,6 +2,7 @@
import com.ruoyi.dto.MapDto;
import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
@@ -17,4 +18,13 @@
* @return 浜у搧鍛ㄨ浆澶╂暟鍒楄〃
*/
List<MapDto> productTurnoverDays();
+
+ List<MapDto> productTurnoverDaysByDate(@Param("startDate") String startDate, @Param("endDate") String endDate);
+
+ /**
+ * 鏌ヨ閲囪喘鍝佸ぇ绫诲垎甯冿紙鍚勪骇鍝佸皬绫荤殑閲囪喘鏁伴噺/閲戦锛�
+ *
+ * @return 閲囪喘鍒嗗竷鍒楄〃
+ */
+ List<MapDto> selectPurchaseCategoryDistribution();
}
diff --git a/src/main/java/com/ruoyi/home/service/HomeService.java b/src/main/java/com/ruoyi/home/service/HomeService.java
index 2c3c89b..ce335b2 100644
--- a/src/main/java/com/ruoyi/home/service/HomeService.java
+++ b/src/main/java/com/ruoyi/home/service/HomeService.java
@@ -38,23 +38,23 @@
HomeSummaryDto summaryStatistics();
- List<SupplierPurchaseRankingDto> supplierPurchaseRanking(Integer type);
+ List<SupplierPurchaseRankingDto> supplierPurchaseRanking(Integer type, String startDate, String endDate);
CustomerRevenueAnalysisDto customerRevenueAnalysis(Long customerId, Integer type);
ProductCategoryDistributionDto productCategoryDistribution();
- List<CustomerContributionRankingDto> customerContributionRanking(Integer type);
+ List<CustomerContributionRankingDto> customerContributionRanking(Integer type, String startDate, String endDate);
- List<MapDto> productSalesAnalysis();
+ List<MapDto> productSalesAnalysis(String startDate, String endDate);
- List<MapDto> rawMaterialPurchaseAmountRatio();
+ List<MapDto> rawMaterialPurchaseAmountRatio(String startDate, String endDate);
- List<MapDto> salesPurchaseStorageProductCount();
+ List<MapDto> salesPurchaseStorageProductCount(String startDate, String endDate);
- List<Map<String, Object>> productInOutAnalysis(Integer type);
+ List<Map<String, Object>> productInOutAnalysis(Integer type, String startDate, String endDate);
- List<MapDto> productTurnoverDays();
+ List<MapDto> productTurnoverDays(String startDate, String endDate);
List<Map<String, Object>> incomeExpenseAnalysis(Integer type);
diff --git a/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java b/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
index 8aa7871..c24d322 100644
--- a/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
+++ b/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
@@ -697,36 +697,39 @@
}
@Override
- public List<SupplierPurchaseRankingDto> supplierPurchaseRanking(Integer type) {
- LocalDate today = LocalDate.now();
+ public List<SupplierPurchaseRankingDto> supplierPurchaseRanking(Integer type, String startDateStr, String endDateStr) {
LocalDate startDate;
LocalDate endDate;
- switch (type) {
- case 1: // 鍛�
- startDate = today.with(DayOfWeek.MONDAY);
- endDate = today.with(DayOfWeek.SUNDAY);
- break;
- case 2: // 鏈�
- startDate = today.with(TemporalAdjusters.firstDayOfMonth());
- endDate = today.with(TemporalAdjusters.lastDayOfMonth());
- break;
- case 3: // 瀛e害
- Month currentMonth = today.getMonth();
- Month firstMonthOfQuarter = currentMonth.firstMonthOfQuarter();
- Month lastMonthOfQuarter = Month.of(firstMonthOfQuarter.getValue() + 2);
-
- startDate = today.withMonth(firstMonthOfQuarter.getValue()).with(TemporalAdjusters.firstDayOfMonth());
- endDate = today.withMonth(lastMonthOfQuarter.getValue()).with(TemporalAdjusters.lastDayOfMonth());
- break;
- default:
- return new ArrayList<>();
+ if (com.ruoyi.common.utils.StringUtils.isNotBlank(startDateStr) && com.ruoyi.common.utils.StringUtils.isNotBlank(endDateStr)) {
+ startDate = LocalDate.parse(startDateStr);
+ endDate = LocalDate.parse(endDateStr);
+ } else {
+ LocalDate today = LocalDate.now();
+ switch (type) {
+ case 1: // 鍛�
+ startDate = today.with(DayOfWeek.MONDAY);
+ endDate = today.with(DayOfWeek.SUNDAY);
+ break;
+ case 2: // 鏈�
+ startDate = today.with(TemporalAdjusters.firstDayOfMonth());
+ endDate = today.with(TemporalAdjusters.lastDayOfMonth());
+ break;
+ case 3: // 瀛e害
+ Month currentMonth = today.getMonth();
+ Month firstMonthOfQuarter = currentMonth.firstMonthOfQuarter();
+ Month lastMonthOfQuarter = Month.of(firstMonthOfQuarter.getValue() + 2);
+ startDate = today.withMonth(firstMonthOfQuarter.getValue()).with(TemporalAdjusters.firstDayOfMonth());
+ endDate = today.withMonth(lastMonthOfQuarter.getValue()).with(TemporalAdjusters.lastDayOfMonth());
+ break;
+ default:
+ return new ArrayList<>();
+ }
}
QueryWrapper<PurchaseLedger> queryWrapper = new QueryWrapper<>();
queryWrapper.select("supplier_name", "SUM(contract_amount) as total_amount")
.ge("entry_date", startDate)
.le("entry_date", endDate)
- // .ne("approval_status", 3)
.groupBy("supplier_name")
.orderByDesc("total_amount")
.last("LIMIT 5");
@@ -862,17 +865,81 @@
majorDto.setRate("0.00");
}
+ // 鏌ヨ鍚勪骇鍝佸皬绫荤殑閲囪喘鏁伴噺
+ Map<String, BigDecimal> purchaseDataMap = new java.util.HashMap<>();
+ List<com.ruoyi.dto.MapDto> purchaseDistribution = homeMapper.selectPurchaseCategoryDistribution();
+ if (purchaseDistribution != null) {
+ for (com.ruoyi.dto.MapDto item : purchaseDistribution) {
+ if (item.getName() != null && item.getValue() != null) {
+ purchaseDataMap.put(item.getName(), new BigDecimal(item.getValue()));
+ }
+ }
+ }
+
+ BigDecimal majorTotalChildrenValue = BigDecimal.ZERO;
List<ProductCategoryDistributionDto.MinorCategoryDto> minorDtos = new ArrayList<>();
for (Product minor : children) {
ProductCategoryDistributionDto.MinorCategoryDto minorDto = new ProductCategoryDistributionDto.MinorCategoryDto();
minorDto.setName(minor.getProductName());
- minorDto.setValue("0");
+ BigDecimal minorValue = purchaseDataMap.getOrDefault(minor.getProductName(), BigDecimal.ZERO);
+ minorDto.setValue(minorValue.toString());
minorDto.setRate("0.00");
minorDto.setChildren(new ArrayList<>());
minorDtos.add(minorDto);
+ majorTotalChildrenValue = majorTotalChildrenValue.add(minorValue);
}
majorDto.setChildren(minorDtos);
+ // 浣跨敤瀹為檯閲囪喘鏁版嵁鏇存柊澶х被鐨� value
+ if (majorTotalChildrenValue.compareTo(BigDecimal.ZERO) > 0) {
+ majorDto.setValue(majorTotalChildrenValue.toString());
+ }
majorItems.add(majorDto);
+ }
+
+ // 璁$畻澶х被鍗犳瘮
+ BigDecimal totalAllValue = BigDecimal.ZERO;
+ for (ProductCategoryDistributionDto.MajorCategoryDto m : majorItems) {
+ try {
+ totalAllValue = totalAllValue.add(new BigDecimal(m.getValue()));
+ } catch (NumberFormatException ignored) {
+ }
+ }
+ if (totalAllValue.compareTo(BigDecimal.ZERO) > 0) {
+ for (ProductCategoryDistributionDto.MajorCategoryDto m : majorItems) {
+ try {
+ BigDecimal val = new BigDecimal(m.getValue());
+ m.setRate(val.divide(totalAllValue, 4, RoundingMode.HALF_UP)
+ .multiply(new BigDecimal("100"))
+ .setScale(2, RoundingMode.HALF_UP)
+ .toString());
+ } catch (NumberFormatException ignored) {
+ }
+ }
+ }
+ // 璁$畻灏忕被鍗犳瘮锛堝湪鍚屽ぇ绫诲唴锛�
+ for (ProductCategoryDistributionDto.MajorCategoryDto m : majorItems) {
+ if (m.getChildren() == null || m.getChildren().isEmpty()) {
+ continue;
+ }
+ BigDecimal parentVal = BigDecimal.ZERO;
+ for (ProductCategoryDistributionDto.MinorCategoryDto child : m.getChildren()) {
+ try {
+ parentVal = parentVal.add(new BigDecimal(child.getValue()));
+ } catch (NumberFormatException ignored) {
+ }
+ }
+ if (parentVal.compareTo(BigDecimal.ZERO) > 0) {
+ for (ProductCategoryDistributionDto.MinorCategoryDto child : m.getChildren()) {
+ try {
+ BigDecimal childVal = new BigDecimal(child.getValue());
+ child.setRate(childVal.divide(parentVal, 4, RoundingMode.HALF_UP)
+ .multiply(new BigDecimal("100"))
+ .setScale(2, RoundingMode.HALF_UP)
+ .toString());
+ } catch (NumberFormatException ignored) {
+ }
+ }
+ }
}
dto.setItems(majorItems);
@@ -880,38 +947,42 @@
}
@Override
- public List<CustomerContributionRankingDto> customerContributionRanking(Integer type) {
- LocalDate today = LocalDate.now();
- LocalDate startDate = null;
- LocalDate endDate = null;
- switch (type) {
- case 1:
- startDate = today.with(DayOfWeek.MONDAY);
- endDate = today.with(DayOfWeek.SUNDAY);
- break;
- case 2:
- startDate = today.with(TemporalAdjusters.firstDayOfMonth());
- endDate = today.with(TemporalAdjusters.lastDayOfMonth());
- break;
- case 3:
- Month currentMonth = today.getMonth();
- Month firstMonthOfQuarter = currentMonth.firstMonthOfQuarter();
- Month lastMonthOfQuarter = Month.of(firstMonthOfQuarter.getValue() + 2);
- startDate = today.withMonth(firstMonthOfQuarter.getValue()).with(TemporalAdjusters.firstDayOfMonth());
- endDate = today.withMonth(lastMonthOfQuarter.getValue()).with(TemporalAdjusters.lastDayOfMonth());
- break;
+ public List<CustomerContributionRankingDto> customerContributionRanking(Integer type, String startDateStr, String endDateStr) {
+ LocalDate startDate;
+ LocalDate endDate;
+ if (com.ruoyi.common.utils.StringUtils.isNotBlank(startDateStr) && com.ruoyi.common.utils.StringUtils.isNotBlank(endDateStr)) {
+ startDate = LocalDate.parse(startDateStr);
+ endDate = LocalDate.parse(endDateStr);
+ } else {
+ LocalDate today = LocalDate.now();
+ switch (type) {
+ case 1:
+ startDate = today.with(DayOfWeek.MONDAY);
+ endDate = today.with(DayOfWeek.SUNDAY);
+ break;
+ case 2:
+ startDate = today.with(TemporalAdjusters.firstDayOfMonth());
+ endDate = today.with(TemporalAdjusters.lastDayOfMonth());
+ break;
+ case 3:
+ Month currentMonth = today.getMonth();
+ Month firstMonthOfQuarter = currentMonth.firstMonthOfQuarter();
+ Month lastMonthOfQuarter = Month.of(firstMonthOfQuarter.getValue() + 2);
+ startDate = today.withMonth(firstMonthOfQuarter.getValue()).with(TemporalAdjusters.firstDayOfMonth());
+ endDate = today.withMonth(lastMonthOfQuarter.getValue()).with(TemporalAdjusters.lastDayOfMonth());
+ break;
+ default:
+ return new ArrayList<>();
+ }
}
QueryWrapper<SalesLedger> queryWrapper = new QueryWrapper<>();
queryWrapper.select("customer_name", "SUM(contract_amount) as total_amount")
.isNotNull("customer_name")
+ .between("entry_date", startDate, endDate)
.groupBy("customer_name")
.orderByDesc("total_amount")
.last("LIMIT 5");
-
- if (startDate != null && endDate != null) {
- queryWrapper.between("entry_date", startDate, endDate);
- }
List<Map<String, Object>> maps = salesLedgerMapper.selectMaps(queryWrapper);
List<CustomerContributionRankingDto> result = new ArrayList<>();
@@ -927,9 +998,13 @@
}
@Override
- public List<MapDto> productSalesAnalysis() {
- // 鑾峰彇鎵�鏈変骇鍝佸ぇ绫荤殑閿�鍞
- List<Map<String, Object>> analysisResults = salesLedgerProductMapper.selectProductSalesAnalysis();
+ public List<MapDto> productSalesAnalysis(String startDateStr, String endDateStr) {
+ List<Map<String, Object>> analysisResults;
+ if (com.ruoyi.common.utils.StringUtils.isNotBlank(startDateStr) && com.ruoyi.common.utils.StringUtils.isNotBlank(endDateStr)) {
+ analysisResults = salesLedgerProductMapper.selectProductSalesAnalysisByDate(startDateStr, endDateStr);
+ } else {
+ analysisResults = salesLedgerProductMapper.selectProductSalesAnalysis();
+ }
if (CollectionUtils.isEmpty(analysisResults)) {
return new ArrayList<>();
}
@@ -964,9 +1039,13 @@
}
@Override
- public List<MapDto> rawMaterialPurchaseAmountRatio() {
- // 鑾峰彇鎵�鏈夊師鏉愭枡鐨勯噰璐
- List<Map<String, Object>> analysisResults = salesLedgerProductMapper.selectRawMaterialPurchaseAnalysis();
+ public List<MapDto> rawMaterialPurchaseAmountRatio(String startDateStr, String endDateStr) {
+ List<Map<String, Object>> analysisResults;
+ if (com.ruoyi.common.utils.StringUtils.isNotBlank(startDateStr) && com.ruoyi.common.utils.StringUtils.isNotBlank(endDateStr)) {
+ analysisResults = salesLedgerProductMapper.selectRawMaterialPurchaseAnalysisByDate(startDateStr, endDateStr);
+ } else {
+ analysisResults = salesLedgerProductMapper.selectRawMaterialPurchaseAnalysis();
+ }
if (CollectionUtils.isEmpty(analysisResults)) {
return new ArrayList<>();
}
@@ -1001,25 +1080,47 @@
}
@Override
- public List<MapDto> salesPurchaseStorageProductCount() {
+ public List<MapDto> salesPurchaseStorageProductCount(String startDate, String endDate) {
LocalDateTime now = LocalDateTime.now();
- LocalDateTime currentMonthStart = now.with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN);
- LocalDateTime lastMonth = now.minusMonths(1);
- LocalDateTime lastMonthStart = lastMonth.with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN);
- LocalDateTime lastMonthEnd = lastMonth.with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX);
+ LocalDateTime currentMonthStart;
+ LocalDateTime currentMonthEnd;
+ LocalDateTime lastMonthStart;
+ LocalDateTime lastMonthEnd;
- // 閿�鍞�
- int currentSales = salesLedgerProductMapper.selectProductCountByTypeAndDate(1, currentMonthStart, now);
- int lastSales = salesLedgerProductMapper.selectProductCountByTypeAndDate(1, lastMonthStart, lastMonthEnd);
- // 閲囪喘
- int currentPurchase = salesLedgerProductMapper.selectProductCountByTypeAndDate(2, currentMonthStart, now);
+ if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) {
+ LocalDate start = LocalDate.parse(startDate);
+ LocalDate end = LocalDate.parse(endDate);
+ currentMonthStart = start.atStartOfDay();
+ currentMonthEnd = end.atTime(LocalTime.MAX);
+ long daysBetween = java.time.temporal.ChronoUnit.DAYS.between(start, end) + 1;
+ LocalDate lastStart = start.minusDays(daysBetween);
+ LocalDate lastEnd = start.minusDays(1);
+ lastMonthStart = lastStart.atStartOfDay();
+ lastMonthEnd = lastEnd.atTime(LocalTime.MAX);
+ } else {
+ currentMonthStart = now.with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN);
+ currentMonthEnd = now;
+ LocalDateTime lastMonth = now.minusMonths(1);
+ lastMonthStart = lastMonth.with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN);
+ lastMonthEnd = lastMonth.with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX);
+ }
+
+ // 閿�鍞鍗曟暟锛堢粺璁ales_ledger琛級
+ int currentSales = Math.toIntExact(salesLedgerMapper.selectCount(new LambdaQueryWrapper<SalesLedger>()
+ .ge(SalesLedger::getEntryDate, currentMonthStart)
+ .le(SalesLedger::getEntryDate, currentMonthEnd)));
+ int lastSales = Math.toIntExact(salesLedgerMapper.selectCount(new LambdaQueryWrapper<SalesLedger>()
+ .ge(SalesLedger::getEntryDate, lastMonthStart)
+ .le(SalesLedger::getEntryDate, lastMonthEnd)));
+ // 閲囪喘浜у搧鏁�
+ int currentPurchase = salesLedgerProductMapper.selectProductCountByTypeAndDate(2, currentMonthStart, currentMonthEnd);
int lastPurchase = salesLedgerProductMapper.selectProductCountByTypeAndDate(2, lastMonthStart, lastMonthEnd);
- // 鍌ㄥ瓨
- int currentStorage = stockInventoryMapper.selectStorageProductCountByDate(currentMonthStart, now);
+ // 鍌ㄥ瓨浜у搧鏁�
+ int currentStorage = stockInventoryMapper.selectStorageProductCountByDate(currentMonthStart, currentMonthEnd);
int lastStorage = stockInventoryMapper.selectStorageProductCountByDate(lastMonthStart, lastMonthEnd);
List<MapDto> list = new ArrayList<>();
- list.add(createMapDto("閿�鍞骇鍝佹暟", currentSales, lastSales));
+ list.add(createMapDto("閿�鍞鍗曟暟", currentSales, lastSales));
list.add(createMapDto("閲囪喘浜у搧鏁�", currentPurchase, lastPurchase));
list.add(createMapDto("鍌ㄥ瓨浜у搧鏁�", currentStorage, lastStorage));
@@ -1048,7 +1149,7 @@
}
@Override
- public List<Map<String, Object>> productInOutAnalysis(Integer type) {
+ public List<Map<String, Object>> productInOutAnalysis(Integer type, String startDateStr, String endDateStr) {
String targetName;
if (type == 1) {
targetName = "鍘熸潗鏂�";
@@ -1073,8 +1174,17 @@
LocalDate now = LocalDate.now();
DateTimeFormatter displayDtf = DateTimeFormatter.ofPattern("M/d");
- String startDate = now.minusDays(6).toString();
- String endDate = now.toString();
+ LocalDate start;
+ LocalDate end;
+ if (com.ruoyi.common.utils.StringUtils.isNotBlank(startDateStr) && com.ruoyi.common.utils.StringUtils.isNotBlank(endDateStr)) {
+ start = LocalDate.parse(startDateStr);
+ end = LocalDate.parse(endDateStr);
+ } else {
+ end = now;
+ start = now.minusDays(6);
+ }
+ String startDate = start.toString();
+ String endDate = end.toString();
List<Map<String, Object>> inCounts = stockInventoryMapper.selectDailyStockInCounts(rootCategoryId, startDate,
endDate + " 23:59:59");
@@ -1111,7 +1221,10 @@
}
@Override
- public List<MapDto> productTurnoverDays() {
+ public List<MapDto> productTurnoverDays(String startDateStr, String endDateStr) {
+ if (com.ruoyi.common.utils.StringUtils.isNotBlank(startDateStr) && com.ruoyi.common.utils.StringUtils.isNotBlank(endDateStr)) {
+ return homeMapper.productTurnoverDaysByDate(startDateStr, endDateStr);
+ }
return homeMapper.productTurnoverDays();
}
diff --git a/src/main/java/com/ruoyi/inspectiontask/controller/InspectionTaskController.java b/src/main/java/com/ruoyi/inspectiontask/controller/InspectionTaskController.java
index be8dda5..42d2d4e 100644
--- a/src/main/java/com/ruoyi/inspectiontask/controller/InspectionTaskController.java
+++ b/src/main/java/com/ruoyi/inspectiontask/controller/InspectionTaskController.java
@@ -15,12 +15,6 @@
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
-import java.io.IOException;
-
-/**
- * @author :yys
- * @date : 2025/9/19 10:52
- */
@RestController
@Tag(name = "宸℃浠诲姟璁板綍")
@RequestMapping("/inspectionTask")
@@ -29,20 +23,13 @@
private InspectionTaskService inspectionTaskService;
- /**
- * 宸℃浠诲姟琛ㄨ〃鏌ヨ
- */
@GetMapping("/list")
- @Operation(summary = "宸℃浠诲姟琛ㄨ〃鏌ヨ")
+ @Operation(summary = "宸℃浠诲姟琛ㄦ煡璇�")
public R<IPage<InspectionTaskDto>> list(Page<InspectionTask> page, InspectionTaskDto inspectionTaskDto) {
IPage<InspectionTaskDto> list = inspectionTaskService.selectInspectionTaskList(page, inspectionTaskDto);
return R.ok(list);
}
-
- /**
- * 瀵煎嚭
- */
@PostMapping("/export")
@Operation(summary = "瀵煎嚭瀹氭椂浠诲姟璁板綍")
public void export(HttpServletResponse response) {
@@ -53,9 +40,6 @@
util.exportExcel(response, list.getRecords(), "瀵煎嚭瀹氭椂浠诲姟璁板綍");
}
- /**
- * 宸℃浠诲姟琛ㄦ柊澧炰慨鏀�
- */
@PostMapping("/addOrEditInspectionTask")
@Operation(summary = "宸℃浠诲姟琛ㄦ柊澧炰慨鏀�")
@Transactional(rollbackFor = Exception.class)
@@ -63,9 +47,6 @@
return R.ok(inspectionTaskService.addOrEditInspectionTask(inspectionTaskDto));
}
- /**
- * 宸℃浠诲姟琛ㄥ垹闄�
- */
@DeleteMapping("/delInspectionTask")
@Operation(summary = "宸℃浠诲姟琛ㄥ垹闄�")
@Transactional(rollbackFor = Exception.class)
@@ -73,4 +54,18 @@
return R.ok(inspectionTaskService.delByIds(ids));
}
+ @PutMapping("/complete/{id}")
+ @Operation(summary = "宸℃瀹屾垚")
+ @Transactional(rollbackFor = Exception.class)
+ public R complete(@PathVariable Long id) {
+ return R.ok(inspectionTaskService.complete(id));
+ }
+
+ @PutMapping("/batchComplete")
+ @Operation(summary = "涓�閿贰妫�瀹屾垚")
+ @Transactional(rollbackFor = Exception.class)
+ public R batchComplete(String dateStr) {
+ return R.ok(inspectionTaskService.batchComplete(dateStr));
+ }
+
}
diff --git a/src/main/java/com/ruoyi/inspectiontask/pojo/InspectionTask.java b/src/main/java/com/ruoyi/inspectiontask/pojo/InspectionTask.java
index 4e7efad..d5b265a 100644
--- a/src/main/java/com/ruoyi/inspectiontask/pojo/InspectionTask.java
+++ b/src/main/java/com/ruoyi/inspectiontask/pojo/InspectionTask.java
@@ -82,6 +82,9 @@
@Schema(description = "宸℃鍦扮偣璇︾粏鎻忚堪")
private String inspectionLocation;
+ @Schema(description = "鐘舵�� 0=寰呭贰妫�, 1=宸插畬鎴�")
+ private Integer status;
+
@Schema(description = "杞垹闄ゆ爣蹇楋紝0=鏈垹闄わ紝1=宸插垹闄�")
private Integer deleted;
diff --git a/src/main/java/com/ruoyi/inspectiontask/service/InspectionTaskService.java b/src/main/java/com/ruoyi/inspectiontask/service/InspectionTaskService.java
index de175f2..23d4b62 100644
--- a/src/main/java/com/ruoyi/inspectiontask/service/InspectionTaskService.java
+++ b/src/main/java/com/ruoyi/inspectiontask/service/InspectionTaskService.java
@@ -6,10 +6,6 @@
import com.ruoyi.inspectiontask.dto.InspectionTaskDto;
import com.ruoyi.inspectiontask.pojo.InspectionTask;
-/**
- * @author :yys
- * @date : 2025/9/19 10:49
- */
public interface InspectionTaskService extends IService<InspectionTask> {
IPage<InspectionTaskDto> selectInspectionTaskList(Page<InspectionTask> page, InspectionTaskDto inspectionTaskDto);
@@ -17,4 +13,8 @@
int addOrEditInspectionTask(InspectionTaskDto inspectionTaskDto);
int delByIds(Long[] ids);
+
+ int complete(Long id);
+
+ int batchComplete(String dateStr);
}
diff --git a/src/main/java/com/ruoyi/inspectiontask/service/impl/InspectionTaskServiceImpl.java b/src/main/java/com/ruoyi/inspectiontask/service/impl/InspectionTaskServiceImpl.java
index 9729b40..3335de3 100644
--- a/src/main/java/com/ruoyi/inspectiontask/service/impl/InspectionTaskServiceImpl.java
+++ b/src/main/java/com/ruoyi/inspectiontask/service/impl/InspectionTaskServiceImpl.java
@@ -187,9 +187,63 @@
// 淇濆瓨鏂囦欢锛堝瓧娈典笉浼犲垯淇濈暀鍘嗗彶锛�
saveInspectionAttachments(inspectionTask.getId(), inspectionTaskDto);
+ // 宸℃缁撴灉璁剧疆鍚庯紝鑷姩鏍囪涓哄凡瀹屾垚
+ if (StringUtils.isNotBlank(inspectionTaskDto.getInspectionResult())) {
+ InspectionTask statusUpdate = new InspectionTask();
+ statusUpdate.setId(inspectionTask.getId());
+ statusUpdate.setStatus(1);
+ inspectionTaskMapper.updateById(statusUpdate);
+ }
+
return i;
}
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public int complete(Long id) {
+ InspectionTask task = inspectionTaskMapper.selectById(id);
+ if (task == null) {
+ throw new IllegalArgumentException("宸℃浠诲姟涓嶅瓨鍦�");
+ }
+ if (task.getStatus() != null && task.getStatus() == 1) {
+ throw new IllegalArgumentException("璇ュ贰妫�浠诲姟宸插畬鎴�");
+ }
+ task.setStatus(1);
+ if (task.getInspectionResult() == null) {
+ task.setInspectionResult("1");
+ }
+ return inspectionTaskMapper.updateById(task);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public int batchComplete(String dateStr) {
+ if (StringUtils.isBlank(dateStr)) {
+ throw new IllegalArgumentException("鏃ユ湡鍙傛暟涓嶈兘涓虹┖");
+ }
+ java.time.LocalDate date = java.time.LocalDate.parse(dateStr);
+ java.time.LocalDateTime startOfDay = date.atStartOfDay();
+ java.time.LocalDateTime endOfDay = date.atTime(java.time.LocalTime.MAX);
+ List<InspectionTask> tasks = inspectionTaskMapper.selectList(
+ new LambdaQueryWrapper<InspectionTask>()
+ .eq(InspectionTask::getStatus, 0)
+ .ge(InspectionTask::getCreateTime, startOfDay)
+ .le(InspectionTask::getCreateTime, endOfDay));
+ if (tasks.isEmpty()) {
+ throw new IllegalArgumentException("璇ユ棩鏈熶笅娌℃湁寰呭畬鎴愮殑宸℃璁板綍");
+ }
+ int count = 0;
+ for (InspectionTask task : tasks) {
+ task.setStatus(1);
+ if (task.getInspectionResult() == null) {
+ task.setInspectionResult("1");
+ }
+ inspectionTaskMapper.updateById(task);
+ count++;
+ }
+ return count;
+ }
+
private void validateInspectionInput(InspectionTaskDto inspectionTaskDto, InspectionTask oldInspectionTask) {
String inspectionResult = inspectionTaskDto.getInspectionResult();
if (StringUtils.isBlank(inspectionResult) && oldInspectionTask != null) {
diff --git a/src/main/java/com/ruoyi/measuringinstrumentledger/controller/SparePartsRequisitionRecordController.java b/src/main/java/com/ruoyi/measuringinstrumentledger/controller/SparePartsRequisitionRecordController.java
index 26195a4..ddebfa1 100644
--- a/src/main/java/com/ruoyi/measuringinstrumentledger/controller/SparePartsRequisitionRecordController.java
+++ b/src/main/java/com/ruoyi/measuringinstrumentledger/controller/SparePartsRequisitionRecordController.java
@@ -3,23 +3,18 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.measuringinstrumentledger.dto.SparePartsOutboundDto;
import com.ruoyi.measuringinstrumentledger.dto.SparePartsRequisitionRecordDto;
import com.ruoyi.measuringinstrumentledger.service.SparePartsRequisitionRecordService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
-/**
- * <p>
- * 鍓嶇鎺у埗鍣�
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-02 03:59:56
- */
@RestController
@RequestMapping("/sparePartsRequisitionRecord")
@Tag(name = "澶囦欢棰嗙敤璁板綍鎺ュ彛")
@@ -28,9 +23,16 @@
private SparePartsRequisitionRecordService sparePartsRequisitionRecordService;
@GetMapping("/listPage")
- @Operation(summary = "澶囦欢鍒嗙被-鍒嗛〉鏌ヨ")
+ @Operation(summary = "澶囦欢棰嗙敤璁板綍-鍒嗛〉鏌ヨ")
public AjaxResult listPage(Page page, SparePartsRequisitionRecordDto sparePartsRequisitionRecordDto){
IPage<SparePartsRequisitionRecordDto> listPage = sparePartsRequisitionRecordService.listPage(page, sparePartsRequisitionRecordDto);
return AjaxResult.success(listPage);
}
+
+ @PostMapping("/outbound")
+ @Operation(summary = "澶囦欢鐙珛鍑哄簱")
+ public AjaxResult outbound(@RequestBody SparePartsOutboundDto dto){
+ sparePartsRequisitionRecordService.outbound(dto);
+ return AjaxResult.success();
+ }
}
diff --git a/src/main/java/com/ruoyi/measuringinstrumentledger/dto/SparePartsOutboundDto.java b/src/main/java/com/ruoyi/measuringinstrumentledger/dto/SparePartsOutboundDto.java
new file mode 100644
index 0000000..fbd62fa
--- /dev/null
+++ b/src/main/java/com/ruoyi/measuringinstrumentledger/dto/SparePartsOutboundDto.java
@@ -0,0 +1,21 @@
+package com.ruoyi.measuringinstrumentledger.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Data
+@Schema(name = "澶囦欢鍑哄簱璇锋眰")
+public class SparePartsOutboundDto {
+
+ @Schema(description = "澶囦欢ID", requiredMode = Schema.RequiredMode.REQUIRED)
+ private Long sparePartsId;
+
+ @Schema(description = "鍑哄簱鏁伴噺", requiredMode = Schema.RequiredMode.REQUIRED)
+ private Integer quantity;
+
+ @Schema(description = "璁惧ID锛堝彲閫夛級")
+ private Long deviceLedgerId;
+
+ @Schema(description = "澶囨敞锛堝彲閫夛級")
+ private String remark;
+}
diff --git a/src/main/java/com/ruoyi/measuringinstrumentledger/service/SparePartsRequisitionRecordService.java b/src/main/java/com/ruoyi/measuringinstrumentledger/service/SparePartsRequisitionRecordService.java
index 2306a3a..38a681a 100644
--- a/src/main/java/com/ruoyi/measuringinstrumentledger/service/SparePartsRequisitionRecordService.java
+++ b/src/main/java/com/ruoyi/measuringinstrumentledger/service/SparePartsRequisitionRecordService.java
@@ -3,17 +3,12 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.measuringinstrumentledger.dto.SparePartsOutboundDto;
import com.ruoyi.measuringinstrumentledger.dto.SparePartsRequisitionRecordDto;
import com.ruoyi.measuringinstrumentledger.pojo.SparePartsRequisitionRecord;
-/**
- * <p>
- * 鏈嶅姟绫�
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-02 03:59:56
- */
public interface SparePartsRequisitionRecordService extends IService<SparePartsRequisitionRecord> {
IPage<SparePartsRequisitionRecordDto> listPage(Page page, SparePartsRequisitionRecordDto sparePartsRequisitionRecordDto);
+
+ void outbound(SparePartsOutboundDto dto);
}
diff --git a/src/main/java/com/ruoyi/measuringinstrumentledger/service/impl/SparePartsRequisitionRecordServiceImpl.java b/src/main/java/com/ruoyi/measuringinstrumentledger/service/impl/SparePartsRequisitionRecordServiceImpl.java
index 19746f5..4942ef9 100644
--- a/src/main/java/com/ruoyi/measuringinstrumentledger/service/impl/SparePartsRequisitionRecordServiceImpl.java
+++ b/src/main/java/com/ruoyi/measuringinstrumentledger/service/impl/SparePartsRequisitionRecordServiceImpl.java
@@ -4,35 +4,58 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.enums.SparePartsRequisitionRecordSourceTypeEnum;
+import com.ruoyi.measuringinstrumentledger.dto.SparePartsOutboundDto;
import com.ruoyi.measuringinstrumentledger.dto.SparePartsRequisitionRecordDto;
+import com.ruoyi.measuringinstrumentledger.mapper.SparePartsMapper;
import com.ruoyi.measuringinstrumentledger.mapper.SparePartsRequisitionRecordMapper;
+import com.ruoyi.measuringinstrumentledger.pojo.SpareParts;
import com.ruoyi.measuringinstrumentledger.pojo.SparePartsRequisitionRecord;
import com.ruoyi.measuringinstrumentledger.service.SparePartsRequisitionRecordService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
-/**
- * <p>
- * 鏈嶅姟瀹炵幇绫�
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-02 03:59:56
- */
+import java.math.BigDecimal;
+
@Service
@RequiredArgsConstructor
public class SparePartsRequisitionRecordServiceImpl extends ServiceImpl<SparePartsRequisitionRecordMapper, SparePartsRequisitionRecord> implements SparePartsRequisitionRecordService {
private final SparePartsRequisitionRecordMapper sparePartsRequisitionRecordMapper;
+ private final SparePartsMapper sparePartsMapper;
@Override
public IPage<SparePartsRequisitionRecordDto> listPage(Page page, SparePartsRequisitionRecordDto sparePartsRequisitionRecordDto) {
IPage<SparePartsRequisitionRecordDto> result = sparePartsRequisitionRecordMapper.listPage(page, sparePartsRequisitionRecordDto);
- // 澶勭悊鏉ユ簮绫诲瀷鏂囨湰
result.getRecords().forEach(record -> {
if (record.getSourceType() != null) {
- record.setSourceText(SparePartsRequisitionRecordSourceTypeEnum.getByCode(record.getSourceType()).getValue());
+ SparePartsRequisitionRecordSourceTypeEnum typeEnum = SparePartsRequisitionRecordSourceTypeEnum.getByCode(record.getSourceType());
+ if (typeEnum != null) {
+ record.setSourceText(typeEnum.getValue());
+ }
}
});
return result;
}
-}
\ No newline at end of file
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void outbound(SparePartsOutboundDto dto) {
+ SpareParts spareParts = sparePartsMapper.selectById(dto.getSparePartsId());
+ if (spareParts == null) {
+ throw new IllegalArgumentException("澶囦欢涓嶅瓨鍦�");
+ }
+ if (spareParts.getQuantity().compareTo(new BigDecimal(dto.getQuantity())) < 0) {
+ throw new IllegalArgumentException("澶囦欢 " + spareParts.getName() + " 搴撳瓨涓嶈冻");
+ }
+ // 鎵e噺搴撳瓨
+ spareParts.setQuantity(spareParts.getQuantity().subtract(new BigDecimal(dto.getQuantity())));
+ sparePartsMapper.updateById(spareParts);
+ // 鍒涘缓棰嗙敤璁板綍
+ SparePartsRequisitionRecord record = new SparePartsRequisitionRecord();
+ record.setSourceType(SparePartsRequisitionRecordSourceTypeEnum.SparePartsRequisitionRecordSourceTypeDirectOutbound.getCode());
+ record.setSparePartsId(dto.getSparePartsId());
+ record.setQuantity(dto.getQuantity());
+ record.setDeviceLedgerId(dto.getDeviceLedgerId());
+ this.save(record);
+ }
+}
diff --git a/src/main/java/com/ruoyi/purchase/controller/AccountingReportController.java b/src/main/java/com/ruoyi/purchase/controller/AccountingReportController.java
index 798112b..bc2aa48 100644
--- a/src/main/java/com/ruoyi/purchase/controller/AccountingReportController.java
+++ b/src/main/java/com/ruoyi/purchase/controller/AccountingReportController.java
@@ -1,12 +1,15 @@
package com.ruoyi.purchase.controller;
+import com.baomidou.mybatisplus.core.metadata.IPage;
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.dto.VatSummaryDto;
import com.ruoyi.purchase.service.PurchaseReportService;
import com.ruoyi.purchase.vo.PurchaseReportVo;
import io.swagger.v3.oas.annotations.Operation;
@@ -29,49 +32,62 @@
private final ISupplierService supplierService;
private final PurchaseReportService purchaseReportService;
-
@GetMapping("/list")
@Log(title = "閲囪喘鎶ヨ〃-椤圭洰鍒╂鼎", businessType = BusinessType.OTHER)
public R list(Page page, String customerName) {
- return R.ok(purchaseReportService.list(page,customerName));
+ return R.ok(purchaseReportService.list(page, customerName));
}
@Log(title = "閲囪喘鎶ヨ〃-椤圭洰鍒╂鼎瀵煎嚭", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@Operation(summary = "閲囪喘鎶ヨ〃-椤圭洰鍒╂鼎瀵煎嚭")
public void export(HttpServletResponse response, String customerName) {
- List<PurchaseReportVo> list = purchaseReportService.list(new Page(1,-1),customerName).getRecords();
+ List<PurchaseReportVo> list = purchaseReportService.list(new Page(1, -1), customerName).getRecords();
ExcelUtil<PurchaseReportVo> util = new ExcelUtil<>(PurchaseReportVo.class);
- util.exportExcel(response, list , "椤圭洰鍒╂鼎");
-
+ util.exportExcel(response, list, "椤圭洰鍒╂鼎");
}
@Log(title = "閲囪喘鎶ヨ〃-澧炲�肩◣姣斿", businessType = BusinessType.OTHER)
@GetMapping("/listVat")
- public R listVat(Page page,String month) {
- return R.ok(purchaseReportService.listVat(page,month));
+ public R listVat(Page page, String month, String type) {
+ return R.ok(purchaseReportService.listVat(page, month, type));
}
@Log(title = "閲囪喘鎶ヨ〃-澧炲�肩◣姣斿", businessType = BusinessType.EXPORT)
@PostMapping("/exportTwo")
- @Operation(summary = "閲囪喘鎶ヨ〃-澧炲�肩◣姣斿")
- public void exportTwo(HttpServletResponse response,String month) {
- List<VatDto> list = purchaseReportService.listVat(new Page(1,-1),month).getRecords();
+ @Operation(summary = "閲囪喘鎶ヨ〃-澧炲�肩◣姣斿瀵煎嚭")
+ public void exportTwo(HttpServletResponse response, String month) {
+ List<VatDto> list = purchaseReportService.listVat(new Page(1, -1), month, null).getRecords();
ExcelUtil<VatDto> util = new ExcelUtil<>(VatDto.class);
- util.exportExcel(response, list , "澧炲�肩◣姣斿");
+ util.exportExcel(response, list, "澧炲�肩◣姣斿");
+ }
+
+ @Log(title = "閲囪喘鎶ヨ〃-澧炲�肩◣鍥捐〃鏁版嵁", businessType = BusinessType.OTHER)
+ @GetMapping("/vatChart")
+ @Operation(summary = "澧炲�肩◣杩涢攢椤瑰姣斿浘琛ㄦ暟鎹�")
+ public R vatChart(String year) {
+ List<VatSummaryDto> list = purchaseReportService.vatSummary(year);
+ return R.ok(list);
+ }
+
+ @GetMapping("/listVatDetail")
+ @Operation(summary = "澧炲�肩◣鏄庣粏-鎸夊彂绁�/璁㈠崟灞曠ず")
+ public AjaxResult listVatDetail(Page page, String month) {
+ IPage<VatDto> result = purchaseReportService.listVatDetail(page, month);
+ return AjaxResult.success(result);
}
@GetMapping("/supplierTransactions")
@Log(title = "渚涘簲鍟嗗線鏉�", businessType = BusinessType.OTHER)
@Operation(summary = "渚涘簲鍟嗗線鏉�")
public R supplierTransactions(Page page, String supplierName) {
- return R.ok(supplierService.supplierTransactions(page,supplierName));
+ return R.ok(supplierService.supplierTransactions(page, supplierName));
}
@GetMapping("/supplierTransactionsDetails")
@Log(title = "渚涘簲鍟嗗線鏉ユ槑缁�", businessType = BusinessType.OTHER)
@Operation(summary = "渚涘簲鍟嗗線鏉ユ槑缁�")
public R supplierTransactionsDetails(Page page, Long supplierId) {
- return R.ok(supplierService.supplierTransactionsDetails(page,supplierId));
+ return R.ok(supplierService.supplierTransactionsDetails(page, supplierId));
}
}
diff --git a/src/main/java/com/ruoyi/purchase/dto/VatDto.java b/src/main/java/com/ruoyi/purchase/dto/VatDto.java
index 3564183..62ceff2 100644
--- a/src/main/java/com/ruoyi/purchase/dto/VatDto.java
+++ b/src/main/java/com/ruoyi/purchase/dto/VatDto.java
@@ -1,19 +1,59 @@
package com.ruoyi.purchase.dto;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.fasterxml.jackson.annotation.JsonFormat;
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 = "绠$悊椹鹃┒鑸�--澧炲�肩◣姣斿鍙傛暟")
+@Schema(name = "VatDto", description = "澧炲�肩◣姣斿鏄庣粏")
@ExcelIgnoreUnannotated
public class VatDto {
+ @Excel(name = "ID")
+ @Schema(description = "鍙戠エID")
+ private Long id;
+
+ @Excel(name = "鍙戠エ鍙风爜")
+ @Schema(description = "鍙戠エ鍙风爜")
+ private String invoiceNumber;
+
+ @Excel(name = "寮�绁ㄦ棩鏈�")
+ @Schema(description = "寮�绁ㄦ棩鏈�")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private LocalDate issueDate;
+
+ @Excel(name = "绫诲瀷")
+ @Schema(description = "绫诲瀷 sales-閿�椤� purchase-杩涢」")
+ private String type;
+
+ @Excel(name = "鍙戠エ绫诲瀷")
+ @Schema(description = "鍙戠エ绫诲瀷")
+ private String invoiceType;
+
+ @Excel(name = "绋庨")
+ @Schema(description = "绋庨")
+ private BigDecimal taxAmount;
+
+ @Excel(name = "浠风◣鍚堣")
+ @Schema(description = "浠风◣鍚堣")
+ private BigDecimal totalAmount;
+
+ @Excel(name = "瀹㈡埛鍚嶇О")
+ @Schema(description = "瀹㈡埛鍚嶇О")
+ private String customerName;
+
+ @Excel(name = "渚涘簲鍟嗗悕绉�")
+ @Schema(description = "渚涘簲鍟嗗悕绉�")
+ private String supplierName;
+
@Excel(name = "鏈堜唤")
@Schema(description = "鏈堜唤")
- private String month ;
+ private String month;
@Excel(name = "閿�椤圭◣棰�")
@Schema(description = "閿�椤圭◣棰�")
@@ -23,8 +63,27 @@
@Schema(description = "杩涢」绋庨")
private BigDecimal xTaxAmount;
- @Excel(name = "閿�-杩�")
- @Schema(description = "閿�-杩�")
- private BigDecimal taxAmount;
+ // ========== 鏄庣粏瑙嗗浘瀛楁 ==========
+
+ @Excel(name = "鍙戠エ鍙�")
+ @Schema(description = "鍙戠エ鍙�")
+ private String invoiceNo;
+
+ @Excel(name = "閿�鍞悎鍚屽彿")
+ @Schema(description = "閿�鍞悎鍚屽彿")
+ private String salesContractNo;
+
+ @Excel(name = "璁㈠崟绫诲瀷")
+ @Schema(description = "绫诲瀷 杩涢」/閿�椤�")
+ private String orderType;
+
+ @Excel(name = "寮�绁ㄦ棩鏈�")
+ @Schema(description = "寮�绁ㄦ棩鏈�")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private LocalDate invoiceDate;
+
+ @Excel(name = "绋庣巼")
+ @Schema(description = "绋庣巼")
+ private BigDecimal taxRate;
}
diff --git a/src/main/java/com/ruoyi/purchase/dto/VatSummaryDto.java b/src/main/java/com/ruoyi/purchase/dto/VatSummaryDto.java
new file mode 100644
index 0000000..5bbb6d4
--- /dev/null
+++ b/src/main/java/com/ruoyi/purchase/dto/VatSummaryDto.java
@@ -0,0 +1,23 @@
+package com.ruoyi.purchase.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+@Schema(description = "澧炲�肩◣杩涢攢椤规寜鏈堟眹鎬伙紙鍥捐〃鐢級")
+public class VatSummaryDto {
+
+ @Schema(description = "鏈堜唤")
+ private String month;
+
+ @Schema(description = "閿�椤圭◣棰濆悎璁�")
+ private BigDecimal jTaxAmount;
+
+ @Schema(description = "杩涢」绋庨鍚堣")
+ private BigDecimal xTaxAmount;
+
+ @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
index 4ec6522..3f7d263 100644
--- a/src/main/java/com/ruoyi/purchase/service/PurchaseReportService.java
+++ b/src/main/java/com/ruoyi/purchase/service/PurchaseReportService.java
@@ -1,14 +1,20 @@
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.dto.VatSummaryDto;
import com.ruoyi.purchase.vo.PurchaseReportVo;
+
+import java.util.List;
public interface PurchaseReportService {
IPage<PurchaseReportVo> list(Page page, String customerName);
- IPage<VatDto> listVat(Page page, String month);
+ IPage<VatDto> listVat(Page page, String month, String type);
+
+ List<VatSummaryDto> vatSummary(String year);
+
+ IPage<VatDto> listVatDetail(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
index 676cf46..9b88ce7 100644
--- a/src/main/java/com/ruoyi/purchase/service/impl/PurchaseReportServiceImpl.java
+++ b/src/main/java/com/ruoyi/purchase/service/impl/PurchaseReportServiceImpl.java
@@ -4,6 +4,7 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.account.mapper.AccountStatementMapper;
import com.ruoyi.purchase.dto.VatDto;
+import com.ruoyi.purchase.dto.VatSummaryDto;
import com.ruoyi.purchase.service.PurchaseReportService;
import com.ruoyi.purchase.vo.PurchaseReportVo;
import com.ruoyi.sales.mapper.SalesLedgerMapper;
@@ -11,6 +12,7 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
+import java.util.List;
@Service
@Slf4j
@@ -26,7 +28,17 @@
}
@Override
- public IPage<VatDto> listVat(Page page, String month) {
- return accountStatementMapper.selectVatDtoPage(page, month);
+ public IPage<VatDto> listVat(Page page, String month, String type) {
+ return accountStatementMapper.selectVatDtoPage(page, month, type);
+ }
+
+ @Override
+ public List<VatSummaryDto> vatSummary(String year) {
+ return accountStatementMapper.selectVatSummary(year);
+ }
+
+ @Override
+ public IPage<VatDto> listVatDetail(Page page, String month) {
+ return accountStatementMapper.listVatDetail(page, month);
}
}
diff --git a/src/main/java/com/ruoyi/sales/mapper/SalesLedgerMapper.java b/src/main/java/com/ruoyi/sales/mapper/SalesLedgerMapper.java
index 5518290..fb603ef 100644
--- a/src/main/java/com/ruoyi/sales/mapper/SalesLedgerMapper.java
+++ b/src/main/java/com/ruoyi/sales/mapper/SalesLedgerMapper.java
@@ -89,5 +89,4 @@
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/sales/mapper/SalesLedgerProductMapper.java b/src/main/java/com/ruoyi/sales/mapper/SalesLedgerProductMapper.java
index 2615d19..dd29a7e 100644
--- a/src/main/java/com/ruoyi/sales/mapper/SalesLedgerProductMapper.java
+++ b/src/main/java/com/ruoyi/sales/mapper/SalesLedgerProductMapper.java
@@ -32,8 +32,12 @@
List<Map<String, Object>> selectProductSalesAnalysis();
+ List<Map<String, Object>> selectProductSalesAnalysisByDate(@Param("startDate") String startDate, @Param("endDate") String endDate);
+
List<Map<String, Object>> selectRawMaterialPurchaseAnalysis();
+ List<Map<String, Object>> selectRawMaterialPurchaseAnalysisByDate(@Param("startDate") String startDate, @Param("endDate") String endDate);
+
int selectProductCountByTypeAndDate(@Param("type") Integer type, @Param("startDate") LocalDateTime startDate, @Param("endDate") LocalDateTime endDate);
BigDecimal selectRawMaterialExpense();
diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml
index e5e2f9a..f1a5bf9 100644
--- a/src/main/resources/application-dev.yml
+++ b/src/main/resources/application-dev.yml
@@ -74,7 +74,7 @@
druid:
# 涓诲簱鏁版嵁婧�
master:
- url: jdbc:mysql://localhost:3306/product-inventory-management-bdpro?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+ url: jdbc:mysql://localhost:3306/product-inventory-management-new-pro?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: 123456
# 浠庡簱鏁版嵁婧�
diff --git a/src/main/resources/mapper/account/AccountStatementMapper.xml b/src/main/resources/mapper/account/AccountStatementMapper.xml
index 32b1621..324d243 100644
--- a/src/main/resources/mapper/account/AccountStatementMapper.xml
+++ b/src/main/resources/mapper/account/AccountStatementMapper.xml
@@ -41,38 +41,129 @@
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 * FROM (
+ SELECT
+ asi.id,
+ asi.invoice_number AS invoiceNumber,
+ asi.issue_date AS issueDate,
+ 'sales' AS type,
+ asi.invoice_type AS invoiceType,
+ asi.tax_price AS taxAmount,
+ asi.tax_inclusive_price AS totalAmount,
+ c.customer_name AS customerName,
+ NULL AS supplierName,
+ DATE_FORMAT(asi.issue_date, '%Y-%m') AS month
+ FROM account_sales_invoice asi
+ LEFT JOIN customer c ON c.id = asi.customer_id
+ WHERE (asi.status IS NULL OR asi.status = 0)
+ UNION ALL
+ SELECT
+ api.id,
+ api.invoice_number AS invoiceNumber,
+ api.issue_date AS issueDate,
+ 'purchase' AS type,
+ api.invoice_type AS invoiceType,
+ api.tax_price AS taxAmount,
+ api.tax_inclusive_price AS totalAmount,
+ NULL AS customerName,
+ s.supplier_name AS supplierName,
+ DATE_FORMAT(api.issue_date, '%Y-%m') AS month
+ FROM account_purchase_invoice api
+ LEFT JOIN supplier_manage s ON s.id = api.supplier_id
+ WHERE (api.status IS NULL OR api.status = 0)
+ ) AS invoice_detail
+ <where>
+ <if test="month != null and month != ''">
+ AND month = #{month}
+ </if>
+ <if test="type != null and type != ''">
+ AND type = #{type}
+ </if>
+ </where>
+ ORDER BY issueDate DESC, type
+ </select>
+
+ <select id="selectVatSummary" resultType="com.ruoyi.purchase.dto.VatSummaryDto">
SELECT
month,
- SUM(IF(type = 'purchase', tax_price, 0)) AS xTaxAmount,
- SUM(IF(type = 'sales', tax_price, 0)) AS jTaxAmount
+ SUM(jTaxAmount) AS jTaxAmount,
+ SUM(xTaxAmount) AS xTaxAmount,
+ SUM(jTaxAmount) - SUM(xTaxAmount) AS taxAmount
FROM (
SELECT
DATE_FORMAT(issue_date, '%Y-%m') AS month,
- tax_price,
- 'sales' AS type
+ SUM(tax_price) AS jTaxAmount,
+ 0 AS xTaxAmount
FROM account_sales_invoice
- WHERE status != 1
+ WHERE (status IS NULL OR status = 0)
+ <if test="year != null and year != ''">
+ AND YEAR(issue_date) = #{year}
+ </if>
+ GROUP BY DATE_FORMAT(issue_date, '%Y-%m')
UNION ALL
SELECT
DATE_FORMAT(issue_date, '%Y-%m') AS month,
- tax_price,
- 'purchase' AS type
+ 0 AS jTaxAmount,
+ SUM(tax_price) AS xTaxAmount
FROM account_purchase_invoice
- WHERE status != 1
- ) AS all_data
- GROUP BY month
- ) AS TT
- <where>
- <if test="month != null">
- and TT.month = #{month}
+ WHERE (status IS NULL OR status = 0)
+ <if test="year != null and year != ''">
+ AND YEAR(issue_date) = #{year}
</if>
- </where>
- ORDER BY TT.month
+ GROUP BY DATE_FORMAT(issue_date, '%Y-%m')
+ ) t
+ GROUP BY month
+ ORDER BY month
+ </select>
+
+ <select id="listVatDetail" resultType="com.ruoyi.purchase.dto.VatDto">
+ SELECT *
+ FROM (
+ -- 杩涢」绋庢槑缁嗭紙閲囪喘璁㈠崟锛�
+ SELECT
+ pl.purchase_contract_number AS invoiceNo,
+ pl.sales_contract_no AS salesContractNo,
+ pl.supplier_name AS supplierName,
+ NULL AS customerName,
+ '杩涢」' AS orderType,
+ pl.entry_date AS invoiceDate,
+ slp.tax_rate AS taxRate,
+ ROUND(SUM(slp.tax_inclusive_total_price - slp.tax_exclusive_total_price), 2) AS jTaxAmount,
+ 0 AS xTaxAmount,
+ ROUND(SUM(slp.tax_inclusive_total_price - slp.tax_exclusive_total_price), 2) AS taxAmount
+ FROM sales_ledger_product slp
+ LEFT JOIN purchase_ledger pl ON pl.id = slp.sales_ledger_id
+ WHERE slp.type = 2
+ AND slp.tax_rate IS NOT NULL
+ AND slp.tax_rate > 0
+ GROUP BY pl.id
+
+ UNION ALL
+
+ -- 閿�椤圭◣鏄庣粏锛堥攢鍞鍗曪級
+ SELECT
+ sl.sales_contract_no AS invoiceNo,
+ sl.sales_contract_no AS salesContractNo,
+ NULL AS supplierName,
+ sl.customer_name AS customerName,
+ '閿�椤�' AS orderType,
+ sl.entry_date AS invoiceDate,
+ slp.tax_rate AS taxRate,
+ 0 AS jTaxAmount,
+ ROUND(SUM(slp.tax_inclusive_total_price - slp.tax_exclusive_total_price), 2) AS xTaxAmount,
+ ROUND(SUM(slp.tax_inclusive_total_price - slp.tax_exclusive_total_price), 2) AS taxAmount
+ FROM sales_ledger_product slp
+ LEFT JOIN sales_ledger sl ON sl.id = slp.sales_ledger_id
+ WHERE slp.type = 1
+ AND slp.tax_rate IS NOT NULL
+ AND slp.tax_rate > 0
+ GROUP BY sl.id
+ ) a
+ <where>
+ <if test="month != null and month != ''">
+ AND DATE_FORMAT(a.invoiceDate, '%Y-%m') = #{month}
+ </if>
+ </where>
+ ORDER BY a.invoiceDate DESC
</select>
</mapper>
diff --git a/src/main/resources/mapper/home/HomeMapper.xml b/src/main/resources/mapper/home/HomeMapper.xml
index 060099a..71a4df6 100644
--- a/src/main/resources/mapper/home/HomeMapper.xml
+++ b/src/main/resources/mapper/home/HomeMapper.xml
@@ -13,4 +13,28 @@
GROUP BY p.id, p.product_name
</select>
+ <select id="productTurnoverDaysByDate" resultType="com.ruoyi.dto.MapDto">
+ SELECT p.product_name AS name,
+ DATEDIFF(IFNULL(MAX(sor.create_time), NOW()), MAX(sir.create_time)) AS value
+ FROM product p
+ JOIN product_model pm ON p.id = pm.product_id
+ JOIN stock_in_record sir ON pm.id = sir.product_model_id
+ AND sir.create_time >= #{startDate}
+ AND sir.create_time <= #{endDate}
+ LEFT JOIN stock_out_record sor ON pm.id = sor.product_model_id
+ GROUP BY p.id, p.product_name
+ </select>
+
+ <select id="selectPurchaseCategoryDistribution" resultType="com.ruoyi.dto.MapDto">
+ SELECT p2.product_name AS name,
+ COUNT(DISTINCT slp.id) AS value
+ FROM sales_ledger_product slp
+ LEFT JOIN product p ON p.id = slp.product_category
+ LEFT JOIN product p2 ON p2.id = p.parent_id
+ WHERE slp.type = 2
+ AND p.parent_id IS NOT NULL
+ GROUP BY p2.product_name
+ ORDER BY value DESC
+ </select>
+
</mapper>
diff --git a/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml b/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
index ec5cca2..6059825 100644
--- a/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
+++ b/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
@@ -219,7 +219,29 @@
LIMIT 5
</select>
+ <select id="selectProductSalesAnalysisByDate" resultType="java.util.Map">
+ SELECT
+ product_category as name,
+ SUM( tax_inclusive_total_price ) AS value
+ FROM
+ sales_ledger_product
+ WHERE
+ type = 1
+ AND register_date >= #{startDate}
+ AND register_date <= #{endDate}
+ GROUP BY
+ product_category
+ ORDER BY
+ value DESC
+ LIMIT 5
+ </select>
+
<select id="selectRawMaterialPurchaseAnalysis" resultType="java.util.Map">
+ WITH RECURSIVE raw_material_tree AS (
+ SELECT id FROM product WHERE product_name = '鍘熸潗鏂�' AND parent_id IS NULL
+ UNION ALL
+ SELECT p.id FROM product p INNER JOIN raw_material_tree rmt ON p.parent_id = rmt.id
+ )
SELECT
pr.product_name AS name,
SUM( slp.tax_inclusive_total_price ) AS value
@@ -228,6 +250,26 @@
JOIN product pr ON slp.product_id = pr.id
WHERE
slp.type = 2
+ AND pr.id IN (SELECT id FROM raw_material_tree)
+ GROUP BY
+ pr.id,
+ pr.product_name
+ ORDER BY
+ value DESC
+ LIMIT 5
+ </select>
+
+ <select id="selectRawMaterialPurchaseAnalysisByDate" resultType="java.util.Map">
+ SELECT
+ pr.product_name AS name,
+ SUM( slp.tax_inclusive_total_price ) AS value
+ FROM
+ sales_ledger_product slp
+ JOIN product pr ON slp.product_id = pr.id
+ WHERE
+ slp.type = 2
+ AND slp.register_date >= #{startDate}
+ AND slp.register_date <= #{endDate}
AND pr.parent_id = ( SELECT id FROM product WHERE product_name = '鍘熸潗鏂�' )
GROUP BY
pr.id,
@@ -252,7 +294,7 @@
<select id="selectRawMaterialExpense" resultType="java.math.BigDecimal">
WITH RECURSIVE product_tree AS (SELECT id
FROM product
- WHERE product_name = '鍘熸潗鏂�'
+ WHERE product_name = '鍘熸潗鏂�' AND parent_id IS NULL
UNION ALL
--
Gitblit v1.9.3