From 6657d65777a1be6b97b745fe0c2be55a8b3ec11e Mon Sep 17 00:00:00 2001
From: maven <2163098428@qq.com>
Date: 星期六, 17 一月 2026 13:51:11 +0800
Subject: [PATCH] yys 财务报表,会计报表对接,设备增加字段

---
 src/main/java/com/ruoyi/device/pojo/DeviceLedger.java                   |   17 ++
 src/main/java/com/ruoyi/account/dto/DeviceTypeDetail.java               |   17 ++
 src/main/java/com/ruoyi/device/mapper/DeviceLedgerMapper.java           |    9 +
 src/main/java/com/ruoyi/device/dto/DeviceLedgerDto.java                 |   10 +
 src/main/java/com/ruoyi/account/service/impl/AccountingServiceImpl.java |  292 ++++++++++++++++++++++++++++++++++++
 src/main/java/com/ruoyi/account/controller/AccountingController.java    |   46 +++++
 src/main/resources/mapper/device/DeviceLedgerMapper.xml                 |   18 ++
 src/main/java/com/ruoyi/account/dto/DeviceTypeDistributionVO.java       |   28 +++
 8 files changed, 436 insertions(+), 1 deletions(-)

diff --git a/src/main/java/com/ruoyi/account/controller/AccountingController.java b/src/main/java/com/ruoyi/account/controller/AccountingController.java
new file mode 100644
index 0000000..332fc95
--- /dev/null
+++ b/src/main/java/com/ruoyi/account/controller/AccountingController.java
@@ -0,0 +1,46 @@
+package com.ruoyi.account.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.account.service.impl.AccountingServiceImpl;
+import com.ruoyi.framework.web.controller.BaseController;
+import com.ruoyi.framework.web.domain.AjaxResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author :yys
+ * @date : 2026/1/17 10:40
+ */
+@Api(tags = "浼氳鏍哥畻")
+@RestController
+@RequestMapping("/accounting")
+public class AccountingController extends BaseController {
+
+
+    @Autowired
+    private AccountingServiceImpl accountingService;
+
+    @ApiOperation("鎬昏")
+    @GetMapping("/total")
+    public AjaxResult total(@RequestParam Integer year) {
+        return accountingService.total(year);
+    }
+
+    @ApiOperation("璁惧绫诲瀷鍒嗗竷")
+    @GetMapping("/deviceTypeDistribution")
+    public AjaxResult deviceTypeDistribution(@RequestParam Integer year) {
+        return accountingService.deviceTypeDistribution(year);
+    }
+
+    @ApiOperation("璁惧鍒嗛〉鏌ヨ璁$畻鎶樻棫")
+    @GetMapping("/calculateDepreciation")
+    public AjaxResult calculateDepreciation(Page page, @RequestParam Integer year) {
+        return accountingService.calculateDepreciation(page,year);
+    }
+
+}
diff --git a/src/main/java/com/ruoyi/account/dto/DeviceTypeDetail.java b/src/main/java/com/ruoyi/account/dto/DeviceTypeDetail.java
new file mode 100644
index 0000000..ccbc897
--- /dev/null
+++ b/src/main/java/com/ruoyi/account/dto/DeviceTypeDetail.java
@@ -0,0 +1,17 @@
+package com.ruoyi.account.dto;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * @author :yys
+ * @date : 2026/1/17 13:42
+ */
+@Data
+public class DeviceTypeDetail {
+
+    private String type;       // 璁惧绫诲瀷
+    private BigDecimal count;  // 鏁伴噺
+    private BigDecimal amount; // 浠锋牸
+}
diff --git a/src/main/java/com/ruoyi/account/dto/DeviceTypeDistributionVO.java b/src/main/java/com/ruoyi/account/dto/DeviceTypeDistributionVO.java
new file mode 100644
index 0000000..f4c487b
--- /dev/null
+++ b/src/main/java/com/ruoyi/account/dto/DeviceTypeDistributionVO.java
@@ -0,0 +1,28 @@
+package com.ruoyi.account.dto;
+
+import com.mchange.v1.util.ListUtils;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author :yys
+ * @date : 2026/1/17 13:19
+ */
+@Data
+public class DeviceTypeDistributionVO {
+
+    private Integer totalCount = 0; // 璁惧绫诲瀷鎬绘暟
+
+    // 楗煎浘鍜屾姌绾垮浘鐨勫垎绫伙紙璁惧绫诲瀷锛�
+    private List<String> categories = new ArrayList<>();
+    // 鍚勭被鍨嬭澶囩殑鏁伴噺
+    private List<BigDecimal> countData = new ArrayList<>();
+    // 鍚勭被鍨嬭澶囩殑鎬婚噾棰�
+    private List<BigDecimal> amountData = new ArrayList<>();
+    // 鏄庣粏鍒楄〃锛屽寘鍚被鍨嬨�佹暟閲忋�侀噾棰�
+    private List<DeviceTypeDetail> details = new ArrayList<>();
+
+}
diff --git a/src/main/java/com/ruoyi/account/service/impl/AccountingServiceImpl.java b/src/main/java/com/ruoyi/account/service/impl/AccountingServiceImpl.java
new file mode 100644
index 0000000..e9a586f
--- /dev/null
+++ b/src/main/java/com/ruoyi/account/service/impl/AccountingServiceImpl.java
@@ -0,0 +1,292 @@
+package com.ruoyi.account.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.account.dto.DeviceTypeDetail;
+import com.ruoyi.account.dto.DeviceTypeDistributionVO;
+import com.ruoyi.account.mapper.BorrowInfoMapper;
+import com.ruoyi.account.pojo.BorrowInfo;
+import com.ruoyi.device.mapper.DeviceLedgerMapper;
+import com.ruoyi.device.pojo.DeviceLedger;
+import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.procurementrecord.mapper.CustomStorageMapper;
+import com.ruoyi.procurementrecord.mapper.ProcurementRecordMapper;
+import com.ruoyi.procurementrecord.mapper.ProcurementRecordOutMapper;
+import com.ruoyi.procurementrecord.pojo.CustomStorage;
+import com.ruoyi.procurementrecord.pojo.ProcurementRecordOut;
+import com.ruoyi.procurementrecord.pojo.ProcurementRecordStorage;
+import com.ruoyi.procurementrecord.service.impl.ProcurementRecordOutServiceImpl;
+import com.ruoyi.procurementrecord.service.impl.ProcurementRecordServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.time.Year;
+import java.time.temporal.ChronoUnit;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author :yys
+ * @date : 2026/1/17 10:41
+ */
+@Service
+@Slf4j
+public class AccountingServiceImpl {
+
+    @Autowired
+    private DeviceLedgerMapper deviceLedgerMapper;
+
+    @Autowired
+    private BorrowInfoMapper borrowInfoMapper;
+
+    @Autowired
+    private CustomStorageMapper customStorageMapper;
+
+    @Autowired
+    private ProcurementRecordMapper procurementRecordMapper;
+
+    @Autowired
+    private ProcurementRecordOutMapper procurementRecordOutMapper;
+
+    public AjaxResult total(Integer year) {
+        Map<String,Object> map = new HashMap<>();
+        map.put("deprAmount",0); // 鎶樻棫閲戦
+        map.put("deviceTotal",0); // 璁惧鎬绘暟
+        map.put("deviceAmount",0); // 璁惧璧勪骇鍘熷��
+        map.put("netValue",0); // 鍑�鍊�
+        map.put("debt",0); // 璐熷��
+        map.put("inventoryValue",0); // 搴撳瓨璧勪骇
+        LambdaQueryWrapper<DeviceLedger> deviceLedgerLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        deviceLedgerLambdaQueryWrapper.like(DeviceLedger::getCreateTime,year);
+        List<DeviceLedger> deviceLedgers = deviceLedgerMapper.selectList(deviceLedgerLambdaQueryWrapper);
+        if(CollectionUtils.isNotEmpty(deviceLedgers)){
+            map.put("deviceTotal",deviceLedgers.size());
+            BigDecimal reduce = deviceLedgers.stream()
+                    .map(DeviceLedger::getTaxIncludingPriceTotal)
+                    .filter(Objects::nonNull)
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
+            map.put("deviceAmount",reduce);
+            List<DeviceLedger> collect = deviceLedgers.stream().filter(deviceLedger -> deviceLedger.getIsDepr() != null && deviceLedger.getIsDepr() == 1).collect(Collectors.toList());
+            // 鏍规嵁褰撳墠骞翠唤鍜岃澶囧綍鍏ユ椂闂村勾浠芥瘮杈� * 姣忓勾鎶樻棫閲戦 = 璁惧鎶樻棫閲戦
+            BigDecimal total = new BigDecimal(0);
+            if(CollectionUtils.isNotEmpty(collect)){
+                for (DeviceLedger deviceLedger : collect) {
+                    BigDecimal totalDepreciation = calculatePreciseDepreciation(deviceLedger);
+                    total = total.add(totalDepreciation);
+                }
+                map.put("deprAmount",total);
+            }
+            // 鍑�鍊� = 璁惧璧勪骇鍘熷�� - 璁惧绱鎶樻棫閲戦
+            map.put("netValue",reduce.subtract(total));
+        }
+        // 璐熷��
+        LambdaQueryWrapper<BorrowInfo> borrowInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        borrowInfoLambdaQueryWrapper.like(BorrowInfo::getCreateTime,year)
+                .eq(BorrowInfo::getStatus,1);
+        List<BorrowInfo> borrowInfos = borrowInfoMapper.selectList(borrowInfoLambdaQueryWrapper);
+        if(CollectionUtils.isNotEmpty(borrowInfos)){
+            BigDecimal reduce = borrowInfos.stream()
+                    .map(BorrowInfo::getBorrowAmount)
+                    .filter(Objects::nonNull)
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
+            map.put("debt",reduce);
+        }
+        // 搴撳瓨璧勪骇
+        LambdaQueryWrapper<ProcurementRecordStorage> procurementRecordStorageLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        procurementRecordStorageLambdaQueryWrapper.like(ProcurementRecordStorage::getCreateTime,year);
+        List<ProcurementRecordStorage> procurementRecordStorages = procurementRecordMapper.selectList(procurementRecordStorageLambdaQueryWrapper);
+        BigDecimal procurementRecordTotal = new BigDecimal(0);
+        if(CollectionUtils.isNotEmpty(procurementRecordStorages)){
+            // 鑾峰彇鍑哄簱鏁版嵁
+            LambdaQueryWrapper<ProcurementRecordOut> procurementRecordOutLambdaQueryWrapper = new LambdaQueryWrapper<>();
+            procurementRecordOutLambdaQueryWrapper.like(ProcurementRecordOut::getCreateTime,year)
+                    .in(ProcurementRecordOut::getProcurementRecordStorageId, procurementRecordStorages
+                            .stream()
+                            .map(ProcurementRecordStorage::getId)
+                            .collect(Collectors.toList()))
+                    .in(ProcurementRecordOut::getType,Arrays.asList(1,2));
+            List<ProcurementRecordOut> procurementRecordOuts = procurementRecordOutMapper.selectList(procurementRecordOutLambdaQueryWrapper);
+            for (ProcurementRecordStorage procurementRecordStorage : procurementRecordStorages) {
+                // 閲囪喘锛岀敓浜у叆搴撴�讳环鍊�
+                procurementRecordTotal.add(procurementRecordStorage.getUnitPrice().multiply(procurementRecordStorage.getInboundNum()));
+                // 閫氳繃鍏ュ簱id锛岀被鍨嬭幏鍙栧嚭搴撴暟鎹�
+                List<ProcurementRecordOut> procurementRecordOutsByStorageId = procurementRecordOuts.stream()
+                        .filter(procurementRecordOut -> procurementRecordOut.getProcurementRecordStorageId().equals(procurementRecordStorage.getId())
+                        && procurementRecordOut.getType().equals(procurementRecordStorage.getType()))
+                        .collect(Collectors.toList());
+                if(CollectionUtils.isNotEmpty(procurementRecordOutsByStorageId)){
+                    for (ProcurementRecordOut procurementRecordOut : procurementRecordOutsByStorageId) {
+                        // 閲囪喘锛岀敓浜у嚭搴撴�讳环鍊�
+                        procurementRecordTotal.subtract(procurementRecordStorage.getUnitPrice().multiply(procurementRecordOut.getInboundNum()));
+                    }
+                }
+
+            }
+
+
+        }
+        LambdaQueryWrapper<CustomStorage> customStorageLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        customStorageLambdaQueryWrapper.like(CustomStorage::getInboundDate,year);
+        List<CustomStorage> customStorages = customStorageMapper.selectList(customStorageLambdaQueryWrapper);
+        BigDecimal customStorageTotal = new BigDecimal(0);
+        if(CollectionUtils.isNotEmpty(customStorages)){
+            // 鑾峰彇鍑哄簱鏁版嵁
+            LambdaQueryWrapper<ProcurementRecordOut> procurementRecordOutLambdaQueryWrapper = new LambdaQueryWrapper<>();
+            procurementRecordOutLambdaQueryWrapper.like(ProcurementRecordOut::getCreateTime,year)
+                    .in(ProcurementRecordOut::getProcurementRecordStorageId, customStorages
+                            .stream()
+                            .map(CustomStorage::getId)
+                            .collect(Collectors.toList()))
+                    .eq(ProcurementRecordOut::getType,3);
+            List<ProcurementRecordOut> procurementRecordOuts = procurementRecordOutMapper.selectList(procurementRecordOutLambdaQueryWrapper);
+            customStorages.forEach(customStorage -> {
+                // 鑷畾涔夊叆搴撴�讳环鍊�
+                customStorageTotal.add(customStorage.getTaxInclusiveUnitPrice().multiply(customStorage.getInboundNum()));
+                // 閫氳繃鍏ュ簱id锛岀被鍨嬭幏鍙栧嚭搴撴暟鎹�
+                List<ProcurementRecordOut> procurementRecordOutsByStorageId = procurementRecordOuts.stream()
+                        .filter(procurementRecordOut -> procurementRecordOut.getProcurementRecordStorageId().equals(customStorage.getId()))
+                        .collect(Collectors.toList());
+                if(CollectionUtils.isNotEmpty(procurementRecordOutsByStorageId)){
+                    for (ProcurementRecordOut procurementRecordOut : procurementRecordOutsByStorageId) {
+                        // 鑷畾涔夊嚭搴撴�讳环鍊�
+                        customStorageTotal.subtract(procurementRecordOut.getInboundNum().multiply(customStorage.getTaxInclusiveUnitPrice()));
+                    }
+                }
+            });
+        }
+        map.put("inventoryValue",procurementRecordTotal.add(customStorageTotal));
+        return AjaxResult.success( map);
+    }
+
+    /**
+     * 璁$畻璁惧绱鎶樻棫閲戦
+     * @param deviceLedger 璁惧鍙拌处瀹炰綋
+     * @return 绱鎶樻棫閲戦锛圔igDecimal锛屼繚鐣�2浣嶅皬鏁帮級
+     */
+    public static BigDecimal calculateTotalDepreciation(DeviceLedger deviceLedger) {
+        // 1. 绌哄�兼牎楠�
+        if (deviceLedger == null) {
+            return BigDecimal.ZERO;
+        }
+
+        // 2. 鍒ゆ柇鏄惁寮�鍚姌鏃э紝鏈紑鍚垯鎶樻棫閲戦涓�0
+        Integer isDepr = deviceLedger.getIsDepr();
+        if (isDepr == null || isDepr != 1) { // 1-鏄� 2-鍚�
+            return BigDecimal.ZERO;
+        }
+
+        // 3. 鑾峰彇姣忓勾鎶樻棫閲戦锛屼负绌哄垯杩斿洖0
+        BigDecimal annualDepreciation = deviceLedger.getAnnualDepreciationAmount();
+        if (annualDepreciation == null || annualDepreciation.compareTo(BigDecimal.ZERO) <= 0) {
+            return BigDecimal.ZERO;
+        }
+
+        // 4. 鑾峰彇璁惧褰曞叆鏃堕棿锛屼负绌哄垯杩斿洖0
+        LocalDateTime createTime = deviceLedger.getCreateTime();
+        if (createTime == null) {
+            return BigDecimal.ZERO;
+        }
+
+        // 5. 璁$畻骞翠唤宸��
+        int currentYear = Year.now().getValue(); // 褰撳墠骞翠唤
+        int createYear = createTime.getYear();    // 璁惧褰曞叆骞翠唤
+        int yearDiff = currentYear - createYear;
+
+        // 6. 澶勭悊骞翠唤宸�间负璐熸暟鐨勬儏鍐碉紙褰曞叆鏃堕棿鍦ㄦ湭鏉ワ級
+        if (yearDiff < 0) {
+            return BigDecimal.ZERO;
+        }
+
+        // 7. 璁$畻鎬绘姌鏃ч噾棰� = 骞翠唤宸�� * 姣忓勾鎶樻棫閲戦
+        BigDecimal totalDepreciation = annualDepreciation.multiply(BigDecimal.valueOf(yearDiff));
+
+        // 8. 杩斿洖淇濈暀2浣嶅皬鏁扮殑缁撴灉锛堥噾棰濊鑼冿級
+        return totalDepreciation.setScale(2, BigDecimal.ROUND_HALF_UP);
+    }
+
+    /**
+     * 銆愯繘闃剁増銆戞寜瀹為檯澶╂暟璁$畻鎶樻棫锛堟洿绮惧噯锛�
+     * @param deviceLedger 璁惧鍙拌处瀹炰綋
+     * @return 绱鎶樻棫閲戦
+     */
+    public static BigDecimal calculatePreciseDepreciation(DeviceLedger deviceLedger) {
+        if (deviceLedger == null) {
+            return BigDecimal.ZERO;
+        }
+
+        // 鍒ゆ柇鏄惁寮�鍚姌鏃�
+        Integer isDepr = deviceLedger.getIsDepr();
+        if (isDepr == null || isDepr != 1) {
+            return BigDecimal.ZERO;
+        }
+
+        // 鑾峰彇姣忓勾鎶樻棫閲戦
+        BigDecimal annualDepreciation = deviceLedger.getAnnualDepreciationAmount();
+        if (annualDepreciation == null || annualDepreciation.compareTo(BigDecimal.ZERO) <= 0) {
+            return BigDecimal.ZERO;
+        }
+
+        // 鑾峰彇璁惧褰曞叆鏃堕棿
+        LocalDateTime createTime = deviceLedger.getCreateTime();
+        if (createTime == null) {
+            return BigDecimal.ZERO;
+        }
+
+        // 褰撳墠鏃堕棿
+        LocalDateTime now = LocalDateTime.now();
+
+        // 濡傛灉褰曞叆鏃堕棿鍦ㄦ湭鏉ワ紝杩斿洖0
+        if (createTime.isAfter(now)) {
+            return BigDecimal.ZERO;
+        }
+
+        // 璁$畻鎬诲ぉ鏁�
+        long days = ChronoUnit.DAYS.between(createTime, now);
+
+        // 鎸夋瘡骞�365澶╄绠楁姌鏃ч噾棰�
+        BigDecimal dailyDepreciation = annualDepreciation.divide(BigDecimal.valueOf(365), 6, BigDecimal.ROUND_HALF_UP);
+        BigDecimal totalDepreciation = dailyDepreciation.multiply(BigDecimal.valueOf(days));
+
+        return totalDepreciation.setScale(2, BigDecimal.ROUND_HALF_UP);
+    }
+
+    public AjaxResult deviceTypeDistribution(Integer year) {
+        // 2. 缁勮杩斿洖VO
+       DeviceTypeDistributionVO vo = new DeviceTypeDistributionVO();
+       List<DeviceTypeDetail> details = deviceLedgerMapper.getDeviceTypeDistributionByYear( year);
+        vo.setDetails(details);
+       if(CollectionUtils.isNotEmpty(details)){
+           // 3. 鎻愬彇鍥捐〃鎵�闇�鐨勫垎绫诲拰鏁版嵁
+           vo.setCategories(details.stream()
+                   .map(DeviceTypeDetail::getType)
+                   .collect(Collectors.toList()));
+
+           vo.setCountData(details.stream()
+                   .map(DeviceTypeDetail::getCount)
+                   .collect(Collectors.toList()));
+
+           vo.setAmountData(details.stream()
+                   .map(DeviceTypeDetail::getAmount)
+                   .collect(Collectors.toList()));
+           vo.setTotalCount(vo.getCategories().size());
+       }
+        return AjaxResult.success(vo);
+    }
+
+    public AjaxResult calculateDepreciation(Page page, Integer year) {
+        LambdaQueryWrapper<DeviceLedger> deviceLedgerLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        deviceLedgerLambdaQueryWrapper.like(DeviceLedger::getCreateTime,year)
+                .eq(DeviceLedger::getIsDepr,1);
+        IPage<DeviceLedger> deviceLedgerIPage = deviceLedgerMapper.selectPage(page, deviceLedgerLambdaQueryWrapper);
+        for (DeviceLedger record : deviceLedgerIPage.getRecords()) {
+            record.setDeprAmount(calculatePreciseDepreciation(record));
+            record.setNetValue(record.getTaxIncludingPriceTotal().subtract(record.getDeprAmount()));
+        }
+        return AjaxResult.success(deviceLedgerIPage);
+    }
+}
diff --git a/src/main/java/com/ruoyi/device/dto/DeviceLedgerDto.java b/src/main/java/com/ruoyi/device/dto/DeviceLedgerDto.java
index 604001d..75d9250 100644
--- a/src/main/java/com/ruoyi/device/dto/DeviceLedgerDto.java
+++ b/src/main/java/com/ruoyi/device/dto/DeviceLedgerDto.java
@@ -135,4 +135,14 @@
 
     @ApiModelProperty("杩愯鏃堕暱")
     private String runtimeDuration;
+
+
+    @ApiModelProperty("鏄惁鎶樻棫 1-鏄� 2-鍚�")
+    private Integer isDepr;
+
+    @ApiModelProperty("姣忓勾鎶樻棫閲戦")
+    private BigDecimal annualDepreciationAmount;
+
+    @ApiModelProperty("璁惧绫诲瀷")
+    private String type;
 }
diff --git a/src/main/java/com/ruoyi/device/mapper/DeviceLedgerMapper.java b/src/main/java/com/ruoyi/device/mapper/DeviceLedgerMapper.java
index 17683d4..a7d1a37 100644
--- a/src/main/java/com/ruoyi/device/mapper/DeviceLedgerMapper.java
+++ b/src/main/java/com/ruoyi/device/mapper/DeviceLedgerMapper.java
@@ -4,6 +4,8 @@
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.account.dto.DeviceTypeDetail;
+import com.ruoyi.account.dto.DeviceTypeDistributionVO;
 import com.ruoyi.device.dto.DeviceLedgerDto;
 import com.ruoyi.device.execl.DeviceLedgerExeclDto;
 import com.ruoyi.device.pojo.DeviceLedger;
@@ -21,4 +23,11 @@
 
     @InterceptorIgnore(tenantLine = "true")
     DeviceLedger selectById1(Long id);
+
+    /**
+     * 鎸夊勾浠界粺璁¤澶囩被鍨嬪垎甯�
+     * @param year 浼犲叆鐨勫勾浠斤紙濡�2026锛�
+     * @return 鍚勭被鍨嬬殑鏁伴噺鍜岄噾棰�
+     */
+    List<DeviceTypeDetail> getDeviceTypeDistributionByYear(@Param("year") Integer year);
 }
diff --git a/src/main/java/com/ruoyi/device/pojo/DeviceLedger.java b/src/main/java/com/ruoyi/device/pojo/DeviceLedger.java
index ca59a12..f8c9e53 100644
--- a/src/main/java/com/ruoyi/device/pojo/DeviceLedger.java
+++ b/src/main/java/com/ruoyi/device/pojo/DeviceLedger.java
@@ -142,4 +142,21 @@
 
     @ApiModelProperty("杩愯鏃堕暱")
     private String runtimeDuration;
+
+    @ApiModelProperty("鏄惁鎶樻棫 1-鏄� 2-鍚�")
+    private Integer isDepr;
+
+    @ApiModelProperty("姣忓勾鎶樻棫閲戦")
+    private BigDecimal annualDepreciationAmount;
+
+    @TableField(exist = false)
+    @ApiModelProperty("绱鎶樻棫")
+    private BigDecimal deprAmount;
+
+    @TableField(exist = false)
+    @ApiModelProperty("鍑�鍊�")
+    private BigDecimal netValue;
+
+    @ApiModelProperty("璁惧绫诲瀷")
+    private String type;
 }
diff --git a/src/main/resources/mapper/device/DeviceLedgerMapper.xml b/src/main/resources/mapper/device/DeviceLedgerMapper.xml
index 2b14b90..c980120 100644
--- a/src/main/resources/mapper/device/DeviceLedgerMapper.xml
+++ b/src/main/resources/mapper/device/DeviceLedgerMapper.xml
@@ -28,7 +28,10 @@
         dl.update_time ,
         su.nick_name AS createUser,
         dl.update_user,
-        dl.tenant_id
+        dl.tenant_id,
+        dl.is_depr,
+        dl.annual_depreciation_amount,
+        dl.type
         FROM device_ledger dl
         left join sys_user su on dl.create_user = su.user_id
         <where>
@@ -84,5 +87,18 @@
         from device_ledger
         where id = #{id}
     </select>
+    <select id="getDeviceTypeDistributionByYear"
+            resultType="com.ruoyi.account.dto.DeviceTypeDetail"
+            parameterType="java.lang.Integer">
+        SELECT
+            `type`,
+            SUM(`number`) AS `count`,
+            SUM(tax_including_price_unit) AS amount
+        FROM device_ledger
+        WHERE YEAR(create_time) = #{year}
+          AND type IS NOT NULL
+        GROUP BY type
+    </select>
+
 
 </mapper>

--
Gitblit v1.9.3