src/main/java/com/ruoyi/account/bean/dto/AccountDto.java
ÎļþÃû´Ó src/main/java/com/ruoyi/account/dto/AccountDto.java ÐÞ¸Ä @@ -1,22 +1,10 @@ package com.ruoyi.account.dto; package com.ruoyi.account.bean.dto; import com.baomidou.mybatisplus.annotation.*; import com.fasterxml.jackson.annotation.JsonFormat; import com.ruoyi.account.pojo.AccountExpense; import com.ruoyi.account.pojo.AccountIncome; import com.ruoyi.dto.DateQueryDto; import com.ruoyi.framework.aspectj.lang.annotation.Excel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; import javax.validation.constraints.NotBlank; import java.io.Serializable; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.Date; import java.util.List; import java.util.Map; /** * è´¢å¡ç®¡ç--è´¢å¡æ¥è¡¨ src/main/java/com/ruoyi/account/bean/dto/AccountDto2.java
ÎļþÃû´Ó src/main/java/com/ruoyi/account/dto/AccountDto2.java ÐÞ¸Ä @@ -1,12 +1,9 @@ package com.ruoyi.account.dto; package com.ruoyi.account.bean.dto; import com.ruoyi.account.pojo.AccountExpense; import com.ruoyi.account.pojo.AccountIncome; import lombok.Data; import java.io.Serializable; import java.math.BigDecimal; import java.util.List; /** * è´¢å¡ç®¡ç--è´¢å¡æ¥è¡¨(ç±»å) src/main/java/com/ruoyi/account/bean/dto/AccountDto3.java
ÎļþÃû´Ó src/main/java/com/ruoyi/account/dto/AccountDto3.java ÐÞ¸Ä @@ -1,4 +1,4 @@ package com.ruoyi.account.dto; package com.ruoyi.account.bean.dto; import lombok.Data; src/main/java/com/ruoyi/account/bean/dto/DeviceTypeDetail.java
ÎļþÃû´Ó src/main/java/com/ruoyi/account/dto/DeviceTypeDetail.java ÐÞ¸Ä @@ -1,4 +1,4 @@ package com.ruoyi.account.dto; package com.ruoyi.account.bean.dto; import lombok.Data; src/main/java/com/ruoyi/account/bean/dto/DeviceTypeDistributionVO.java
ÎļþÃû´Ó src/main/java/com/ruoyi/account/dto/DeviceTypeDistributionVO.java ÐÞ¸Ä @@ -1,6 +1,5 @@ package com.ruoyi.account.dto; package com.ruoyi.account.bean.dto; import com.mchange.v1.util.ListUtils; import lombok.Data; import java.math.BigDecimal; src/main/java/com/ruoyi/account/bean/dto/ReportDateDto.java
ÎļþÃû´Ó src/main/java/com/ruoyi/account/dto/ReportDateDto.java ÐÞ¸Ä @@ -1,11 +1,10 @@ package com.ruoyi.account.dto; package com.ruoyi.account.bean.dto; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDate; import java.util.Date; /** * @author :yys src/main/java/com/ruoyi/account/bean/dto/SalesReceiptReturnDto.java
ÎļþÃû´Ó src/main/java/com/ruoyi/account/dto/SalesReceiptReturnDto.java ÐÞ¸Ä @@ -1,4 +1,4 @@ package com.ruoyi.account.dto; package com.ruoyi.account.bean.dto; import com.ruoyi.account.pojo.SalesReceiptReturn; import lombok.Data; src/main/java/com/ruoyi/account/bean/dto/SalesRefundAmountOrderDto.java
ÎļþÃû´Ó src/main/java/com/ruoyi/account/dto/SalesRefundAmountOrderDto.java ÐÞ¸Ä @@ -1,7 +1,6 @@ package com.ruoyi.account.dto; package com.ruoyi.account.bean.dto; import com.ruoyi.account.pojo.SalesRefundAmountOrder; import io.swagger.annotations.Api; import io.swagger.annotations.ApiModelProperty; import lombok.Data; src/main/java/com/ruoyi/account/bean/dto/financial/AccountSubjectDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,10 @@ package com.ruoyi.account.bean.dto.financial; import com.ruoyi.account.pojo.financial.AccountSubject; import lombok.Data; import lombok.EqualsAndHashCode; @EqualsAndHashCode(callSuper = true) @Data public class AccountSubjectDto extends AccountSubject { } src/main/java/com/ruoyi/account/bean/dto/financial/AccountSubjectImportDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,36 @@ package com.ruoyi.account.bean.dto.financial; import com.ruoyi.framework.aspectj.lang.annotation.Excel; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @Data public class AccountSubjectImportDto { @Schema(description = "ç§ç®ç¼ç ") @Excel(name = "ç§ç®ç¼ç ") private String subjectCode; @Schema(description = "ç§ç®åç§°") @Excel(name = "ç§ç®åç§°") private String subjectName; @Schema(description = "ç§ç®ç±»å") @Excel(name = "ç§ç®ç±»å") private String subjectType; @Schema(description = "ä½é¢æ¹å") @Excel(name = "ä½é¢æ¹å") private String balanceDirection; /** * ç¶æ 0å¯ç¨ 1ç¦ç¨ */ @Schema(description = "ç¶æ") @Excel(name = "ç¶æ",readConverterExp = "0=å¯ç¨,1=ç¦ç¨") private Integer status; @Schema(description = "夿³¨") @Excel(name = "夿³¨") private String remark; } src/main/java/com/ruoyi/account/bean/dto/financial/FinDetailLedgerQueryDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,22 @@ package com.ruoyi.account.bean.dto.financial; import lombok.Data; import lombok.EqualsAndHashCode; /** * ç§ç®æç»è´¦æ¥è¯¢åæ°ï¼å«è¾ 婿 ¸ç®æ¡ä»¶ï¼ã */ @EqualsAndHashCode(callSuper = true) @Data public class FinDetailLedgerQueryDto extends FinLedgerQueryDto { /** * è¾ å©æ ¸ç®ç±»åï¼customer/supplier/department/employee/projectã */ private String auxiliaryType; /** * è¾ å©æ ¸ç®å¯¹è±¡IDã */ private String auxiliaryId; } src/main/java/com/ruoyi/account/bean/dto/financial/FinFixedAssetDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,13 @@ package com.ruoyi.account.bean.dto.financial; import com.ruoyi.account.pojo.financial.FinFixedAsset; import lombok.Data; import lombok.EqualsAndHashCode; /** * åºå®èµäº§æ¥è¯¢ä¸ä¿å DTOã */ @EqualsAndHashCode(callSuper = true) @Data public class FinFixedAssetDto extends FinFixedAsset { } src/main/java/com/ruoyi/account/bean/dto/financial/FinIdBatchDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,17 @@ package com.ruoyi.account.bean.dto.financial; import lombok.Data; import java.util.List; /** * æ¹éID请æ±åæ°ã */ @Data public class FinIdBatchDto { /** * IDéåã */ private List<Long> ids; } src/main/java/com/ruoyi/account/bean/dto/financial/FinIntangibleAssetDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,13 @@ package com.ruoyi.account.bean.dto.financial; import com.ruoyi.account.pojo.financial.FinIntangibleAsset; import lombok.Data; import lombok.EqualsAndHashCode; /** * æ å½¢èµäº§æ¥è¯¢ä¸ä¿å DTOã */ @EqualsAndHashCode(callSuper = true) @Data public class FinIntangibleAssetDto extends FinIntangibleAsset { } src/main/java/com/ruoyi/account/bean/dto/financial/FinLedgerQueryDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,25 @@ package com.ruoyi.account.bean.dto.financial; import lombok.Data; /** * ç§ç®è´¦æ¥è¯¢åæ°ã */ @Data public class FinLedgerQueryDto { /** * ç§ç®ç¼ç ï¼æ¯ææ«çº§ææå®ç§ç®ï¼ã */ private String subjectCode; /** * å¼å§æä»½ï¼æ ¼å¼ï¼YYYY-MMã */ private String startMonth; /** * ç»ææä»½ï¼æ ¼å¼ï¼YYYY-MMã */ private String endMonth; } src/main/java/com/ruoyi/account/bean/dto/financial/FinVoucherDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,27 @@ package com.ruoyi.account.bean.dto.financial; import com.ruoyi.account.pojo.financial.FinVoucher; import com.ruoyi.basic.dto.StorageBlobDTO; import com.ruoyi.sales.pojo.CommonFile; import lombok.Data; import lombok.EqualsAndHashCode; import java.util.List; /** * åè¯ä¿å DTOï¼ä¸»è¡¨ + åå½ï¼ã */ @EqualsAndHashCode(callSuper = true) @Data public class FinVoucherDto extends FinVoucher { /** * åè¯æç»åå½ã */ private List<FinVoucherEntryDto> entries; private List<StorageBlobDTO> storageBlobDTOs; private List<String> tempFileIds; } src/main/java/com/ruoyi/account/bean/dto/financial/FinVoucherEntryDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,13 @@ package com.ruoyi.account.bean.dto.financial; import com.ruoyi.account.pojo.financial.FinVoucherEntry; import lombok.Data; import lombok.EqualsAndHashCode; /** * åè¯åå½ DTOã */ @EqualsAndHashCode(callSuper = true) @Data public class FinVoucherEntryDto extends FinVoucherEntry { } src/main/java/com/ruoyi/account/bean/dto/financial/FinVoucherPageDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,37 @@ package com.ruoyi.account.bean.dto.financial; import lombok.Data; import java.time.LocalDate; /** * åè¯å页æ¥è¯¢åæ°ã */ @Data public class FinVoucherPageDto { /** * åè¯åå·ï¼æ¨¡ç³å¹é ï¼ã */ private String voucherNo; /** * å¶å人ã */ private String creator; /** * åè¯ç¶æã */ private String status; /** * å¼å§æ¥æï¼å«ï¼ã */ private LocalDate startDate; /** * ç»ææ¥æï¼å«ï¼ã */ private LocalDate endDate; } src/main/java/com/ruoyi/account/bean/dto/financial/FinVoucherStatusDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,15 @@ package com.ruoyi.account.bean.dto.financial; import lombok.Data; /** * åè¯ç¶æåæ´åæ°ã */ @Data public class FinVoucherStatusDto { /** * åè¯IDã */ private Long id; } src/main/java/com/ruoyi/account/bean/vo/financial/AccountSubjectVo.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,21 @@ package com.ruoyi.account.bean.vo.financial; import com.ruoyi.account.pojo.financial.AccountSubject; import lombok.Data; import java.util.ArrayList; import java.util.List; @Data public class AccountSubjectVo extends AccountSubject { /** * åç§ç®å表ï¼éå½ç»æï¼ã */ private List<AccountSubjectVo> children = new ArrayList<>(); /** * æ¯å¦å¶åèç¹ã */ private Boolean leaf; } src/main/java/com/ruoyi/account/bean/vo/financial/FinLedgerEntryRecordVo.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,43 @@ package com.ruoyi.account.bean.vo.financial; import lombok.Data; import java.math.BigDecimal; import java.time.LocalDate; /** * ç§ç®è´¦åºç¡å彿¥è¯¢å¯¹è±¡ï¼SQLæ å°ä½¿ç¨ï¼ã */ @Data public class FinLedgerEntryRecordVo { /** * åè¯æ¥æã */ private LocalDate voucherDate; /** * åè¯åå·ã */ private String voucherNo; /** * æè¦ã */ private String summary; /** * åæ¹éé¢ã */ private BigDecimal debit; /** * è´·æ¹éé¢ã */ private BigDecimal credit; /** * è¡å·ï¼æåºå段ï¼ã */ private Integer rowNo; } src/main/java/com/ruoyi/account/bean/vo/financial/FinLedgerRowVo.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,55 @@ package com.ruoyi.account.bean.vo.financial; import com.fasterxml.jackson.annotation.JsonInclude; import lombok.Data; import java.math.BigDecimal; import java.time.LocalDate; /** * ç§ç®è´¦è¡æ°æ®è¿å对象ã */ @Data @JsonInclude(JsonInclude.Include.NON_NULL) public class FinLedgerRowVo { /** * è¡ç±»åï¼opening/entry/monthly_total/yearly_totalã */ private String rowType; /** * æ¥æã */ private LocalDate date; /** * åè¯åå·ã */ private String voucherNo; /** * æè¦ã */ private String summary; /** * åæ¹éé¢ã */ private BigDecimal debit; /** * è´·æ¹éé¢ã */ private BigDecimal credit; /** * ä½é¢æ¹åï¼å/è´·ã */ private String direction; /** * ä½é¢ï¼åæ£è´·è´ï¼ã */ private BigDecimal balance; } src/main/java/com/ruoyi/account/bean/vo/financial/FinVoucherDetailVo.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,25 @@ package com.ruoyi.account.bean.vo.financial; import com.ruoyi.account.pojo.financial.FinVoucher; import com.ruoyi.account.pojo.financial.FinVoucherEntry; import com.ruoyi.sales.pojo.CommonFile; import lombok.Data; import lombok.EqualsAndHashCode; import java.util.List; /** * åè¯è¯¦æ è¿å对象ã */ @EqualsAndHashCode(callSuper = true) @Data public class FinVoucherDetailVo extends FinVoucher { /** * åè¯åå½å表ã */ private List<FinVoucherEntry> entries; // private List<StorageBlobVO> storageBlobVOList; private List<CommonFile> SalesLedgerFiles; } src/main/java/com/ruoyi/account/controller/AccountExpenseController.java
@@ -1,12 +1,9 @@ package com.ruoyi.account.controller; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.account.dto.ReportDateDto; import com.ruoyi.account.mapper.AccountIncomeMapper; import com.ruoyi.account.bean.dto.ReportDateDto; import com.ruoyi.account.pojo.AccountExpense; import com.ruoyi.account.pojo.AccountIncome; import com.ruoyi.account.service.AccountExpenseService; import com.ruoyi.account.service.AccountFileService; import com.ruoyi.account.service.AccountIncomeService; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.dto.DateQueryDto; src/main/java/com/ruoyi/account/controller/SalesReceiptReturnController.java
@@ -1,10 +1,8 @@ package com.ruoyi.account.controller; import com.baomidou.mybatisplus.core.metadata.IPage; import com.ruoyi.account.dto.SalesReceiptReturnDto; import com.ruoyi.account.pojo.SalesReceiptReturn; import com.ruoyi.account.bean.dto.SalesReceiptReturnDto; import com.ruoyi.account.service.SalesReceiptReturnService; import com.ruoyi.account.service.impl.SalesReceiptReturnServiceImpl; import com.ruoyi.framework.web.domain.R; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; src/main/java/com/ruoyi/account/controller/SalesRefundAmountOrderController.java
@@ -1,17 +1,12 @@ package com.ruoyi.account.controller; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.account.dto.SalesRefundAmountOrderDto; import com.ruoyi.account.pojo.SalesRefundAmountOrder; import com.ruoyi.account.bean.dto.SalesRefundAmountOrderDto; import com.ruoyi.account.service.SalesRefundAmountOrderService; import com.ruoyi.framework.web.domain.R; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; /** * <p> src/main/java/com/ruoyi/account/controller/financial/AccountSubjectController.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,70 @@ package com.ruoyi.account.controller.financial; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.account.bean.dto.financial.AccountSubjectDto; import com.ruoyi.account.bean.vo.financial.AccountSubjectVo; import com.ruoyi.account.service.financial.AccountSubjectService; import com.ruoyi.framework.aspectj.lang.annotation.Log; import com.ruoyi.framework.aspectj.lang.enums.BusinessType; import com.ruoyi.framework.web.domain.R; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletResponse; import java.util.Arrays; /** * <p> * æ»è´¦ç§ç®è¡¨ å端æ§å¶å¨ * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-05-07 04:45:30 */ @RestController @RequestMapping("/accountSubject") @RequiredArgsConstructor @Tag(name = "æ»è´¦ç§ç®") public class AccountSubjectController { private final AccountSubjectService accountSubjectService; @GetMapping("/list") @Log(title = "æ»è´¦ç§ç®æ°æ®éå", businessType = BusinessType.OTHER) @Operation(summary = "æ»è´¦ç§ç®æ å½¢æ¥è¯¢ï¼éå½ï¼") public R<IPage<AccountSubjectVo>> AccountSubjectDtoList(Page<AccountSubjectDto> page, AccountSubjectDto accountSubjectDto) { IPage<AccountSubjectVo> paramList = accountSubjectService.baseList(page, accountSubjectDto); return R.ok(paramList); } @PostMapping("/add") @Log(title = "æ°å¢æ»è´¦ç§ç®", businessType = BusinessType.INSERT) @Operation(summary = "æ°å¢æ»è´¦ç§ç®") public R AccountSubjectDtoAdd(@RequestBody AccountSubjectDto accountSubjectDto) { return R.ok(accountSubjectService.saveAccountSubject(accountSubjectDto)); } @PutMapping("/edit") @Log(title = "ä¿®æ¹æ»è´¦ç§ç®", businessType = BusinessType.UPDATE) @Operation(summary = "ä¿®æ¹æ»è´¦ç§ç®") public R AccountSubjectDtoEdit(@RequestBody AccountSubjectDto accountSubjectDto) { return R.ok(accountSubjectService.updateAccountSubject(accountSubjectDto)); } @DeleteMapping("/remove/{ids}") @Log(title = "å 餿»è´¦ç§ç®", businessType = BusinessType.DELETE) @Operation(summary = "å 餿»è´¦ç§ç®") public R AccountSubjectDtooRemove(@PathVariable Long[] ids) { return R.ok(accountSubjectService.removeAccountSubjectByIds(Arrays.asList(ids))); } @PostMapping("/export") @Operation(summary = "å¯¼åºæ»è´¦ç§ç®æä»¶") @Log(title = "å¯¼åºæ»è´¦ç§ç®æä»¶", businessType = BusinessType.EXPORT) public void exportAccountSubject(HttpServletResponse response) { accountSubjectService.exportAccountSubject(response); } } src/main/java/com/ruoyi/account/controller/financial/FinFixedAssetController.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,63 @@ package com.ruoyi.account.controller.financial; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.account.bean.dto.financial.FinFixedAssetDto; import com.ruoyi.account.bean.dto.financial.FinIdBatchDto; import com.ruoyi.account.pojo.financial.FinFixedAsset; import com.ruoyi.account.service.financial.FinFixedAssetService; import com.ruoyi.framework.aspectj.lang.annotation.Log; import com.ruoyi.framework.aspectj.lang.enums.BusinessType; import com.ruoyi.framework.web.domain.R; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; import java.util.Arrays; /** * åºå®èµäº§æ§å¶å¨ã */ @RestController @RequestMapping("/financial/fixedAsset") @RequiredArgsConstructor @Tag(name = "è´¢å¡ç®¡ç-åºå®èµäº§") public class FinFixedAssetController { private final FinFixedAssetService finFixedAssetService; @GetMapping("/page") @Operation(summary = "åºå®èµäº§å页æ¥è¯¢") public R<IPage<FinFixedAsset>> page(Page<FinFixedAsset> page, FinFixedAssetDto queryDto) { return R.ok(finFixedAssetService.pageList(page, queryDto)); } @PostMapping("/add") @Log(title = "åºå®èµäº§", businessType = BusinessType.INSERT) @Operation(summary = "æ°å¢åºå®èµäº§") public R<Boolean> add(@RequestBody FinFixedAssetDto dto) { return R.ok(finFixedAssetService.add(dto)); } @PutMapping("/update") @Log(title = "åºå®èµäº§", businessType = BusinessType.UPDATE) @Operation(summary = "ä¿®æ¹åºå®èµäº§") public R<Boolean> update(@RequestBody FinFixedAssetDto dto) { return R.ok(finFixedAssetService.update(dto)); } @DeleteMapping("/delete") @Log(title = "åºå®èµäº§", businessType = BusinessType.DELETE) @Operation(summary = "å é¤åºå®èµäº§") public R<Boolean> delete(@RequestParam("ids") Long[] ids) { return R.ok(finFixedAssetService.deleteByIds(Arrays.asList(ids))); } @PostMapping("/depreciate") @Log(title = "åºå®èµäº§ææ§è®¡æ", businessType = BusinessType.UPDATE) @Operation(summary = "åºå®èµäº§ææè®¡æææ§") public R depreciate(@RequestBody(required = false) FinIdBatchDto dto) { return R.ok(finFixedAssetService.depreciate(dto == null ? null : dto.getIds())); } } src/main/java/com/ruoyi/account/controller/financial/FinIntangibleAssetController.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,63 @@ package com.ruoyi.account.controller.financial; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.account.bean.dto.financial.FinIdBatchDto; import com.ruoyi.account.bean.dto.financial.FinIntangibleAssetDto; import com.ruoyi.account.pojo.financial.FinIntangibleAsset; import com.ruoyi.account.service.financial.FinIntangibleAssetService; import com.ruoyi.framework.aspectj.lang.annotation.Log; import com.ruoyi.framework.aspectj.lang.enums.BusinessType; import com.ruoyi.framework.web.domain.R; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; import java.util.Arrays; /** * æ å½¢èµäº§æ§å¶å¨ã */ @RestController @RequestMapping("/financial/intangibleAsset") @RequiredArgsConstructor @Tag(name = "è´¢å¡ç®¡ç-æ å½¢èµäº§") public class FinIntangibleAssetController { private final FinIntangibleAssetService finIntangibleAssetService; @GetMapping("/page") @Operation(summary = "æ å½¢èµäº§å页æ¥è¯¢") public R<IPage<FinIntangibleAsset>> page(Page<FinIntangibleAsset> page, FinIntangibleAssetDto queryDto) { return R.ok(finIntangibleAssetService.pageList(page, queryDto)); } @PostMapping("/add") @Log(title = "æ å½¢èµäº§", businessType = BusinessType.INSERT) @Operation(summary = "æ°å¢æ å½¢èµäº§") public R<Boolean> add(@RequestBody FinIntangibleAssetDto dto) { return R.ok(finIntangibleAssetService.add(dto)); } @PutMapping("/update") @Log(title = "æ å½¢èµäº§", businessType = BusinessType.UPDATE) @Operation(summary = "ä¿®æ¹æ å½¢èµäº§") public R<Boolean> update(@RequestBody FinIntangibleAssetDto dto) { return R.ok(finIntangibleAssetService.update(dto)); } @DeleteMapping("/delete") @Log(title = "æ å½¢èµäº§", businessType = BusinessType.DELETE) @Operation(summary = "å 餿 å½¢èµäº§") public R<Boolean> delete(@RequestParam("ids") Long[] ids) { return R.ok(finIntangibleAssetService.deleteByIds(Arrays.asList(ids))); } @PostMapping("/amortize") @Log(title = "æ å½¢èµäº§æé计æ", businessType = BusinessType.UPDATE) @Operation(summary = "æ å½¢èµäº§ææè®¡ææé") public R amortize(@RequestBody(required = false) FinIdBatchDto dto) { return R.ok(finIntangibleAssetService.amortize(dto == null ? null : dto.getIds())); } } src/main/java/com/ruoyi/account/controller/financial/FinLedgerController.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,39 @@ package com.ruoyi.account.controller.financial; import com.ruoyi.account.bean.dto.financial.FinDetailLedgerQueryDto; import com.ruoyi.account.bean.dto.financial.FinLedgerQueryDto; import com.ruoyi.account.bean.vo.financial.FinLedgerRowVo; import com.ruoyi.account.service.financial.FinLedgerService; import com.ruoyi.framework.web.domain.R; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; /** * ç§ç®æ»è´¦/æç»è´¦æ§å¶å¨ã */ @RestController @RequestMapping("/financial/ledger") @RequiredArgsConstructor @Tag(name = "è´¢å¡ç®¡ç-ç§ç®è´¦") public class FinLedgerController { private final FinLedgerService finLedgerService; @GetMapping("/general") @Operation(summary = "ç§ç®æ»è´¦æ¥è¯¢") public R<List<FinLedgerRowVo>> general(FinLedgerQueryDto queryDto) { return R.ok(finLedgerService.queryGeneralLedger(queryDto)); } @GetMapping("/detail") @Operation(summary = "ç§ç®æç»è´¦æ¥è¯¢") public R<List<FinLedgerRowVo>> detail(FinDetailLedgerQueryDto queryDto) { return R.ok(finLedgerService.queryDetailLedger(queryDto)); } } src/main/java/com/ruoyi/account/controller/financial/FinVoucherController.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,69 @@ package com.ruoyi.account.controller.financial; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.account.bean.dto.financial.FinVoucherDto; import com.ruoyi.account.bean.dto.financial.FinVoucherPageDto; import com.ruoyi.account.bean.dto.financial.FinVoucherStatusDto; import com.ruoyi.account.bean.vo.financial.FinVoucherDetailVo; import com.ruoyi.account.pojo.financial.FinVoucher; import com.ruoyi.account.service.financial.FinVoucherService; import com.ruoyi.framework.aspectj.lang.annotation.Log; import com.ruoyi.framework.aspectj.lang.enums.BusinessType; import com.ruoyi.framework.web.domain.R; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; /** * åè¯æ§å¶å¨ã */ @RestController @RequestMapping("/financial/voucher") @RequiredArgsConstructor @Tag(name = "è´¢å¡ç®¡ç-åè¯") public class FinVoucherController { private final FinVoucherService finVoucherService; @GetMapping("/page") @Operation(summary = "åè¯å页æ¥è¯¢") public R<IPage<FinVoucher>> page(Page<FinVoucher> page, FinVoucherPageDto queryDto) { return R.ok(finVoucherService.pageList(page, queryDto)); } @PostMapping("/add") @Log(title = "åè¯", businessType = BusinessType.INSERT) @Operation(summary = "æ°å¢åè¯") public R<Boolean> add(@RequestBody FinVoucherDto dto) { return R.ok(finVoucherService.addVoucher(dto)); } @PutMapping("/update") @Log(title = "åè¯", businessType = BusinessType.UPDATE) @Operation(summary = "ä¿®æ¹åè¯") public R<Boolean> update(@RequestBody FinVoucherDto dto) { return R.ok(finVoucherService.updateVoucher(dto)); } @PostMapping("/post") @Log(title = "åè¯è¿è´¦", businessType = BusinessType.UPDATE) @Operation(summary = "åè¯è¿è´¦") public R<Boolean> post(@RequestBody FinVoucherStatusDto dto) { return R.ok(finVoucherService.postVoucher(dto.getId())); } @PostMapping("/cancel") @Log(title = "åè¯ä½åº", businessType = BusinessType.UPDATE) @Operation(summary = "åè¯ä½åº") public R<Boolean> cancel(@RequestBody FinVoucherStatusDto dto) { return R.ok(finVoucherService.cancelVoucher(dto.getId())); } @GetMapping("/detail/{id}") @Operation(summary = "åè¯è¯¦æ ") public R<FinVoucherDetailVo> detail(@PathVariable("id") Long id) { return R.ok(finVoucherService.detail(id)); } } src/main/java/com/ruoyi/account/mapper/AccountExpenseMapper.java
@@ -3,10 +3,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.AccountDto; import com.ruoyi.account.dto.AccountDto2; import com.ruoyi.account.bean.dto.AccountDto2; import com.ruoyi.account.pojo.AccountExpense; import com.ruoyi.account.pojo.AccountIncome; import com.ruoyi.dto.DateQueryDto; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -14,7 +12,6 @@ import java.math.BigDecimal; import java.util.List; import java.util.Map; @Mapper public interface AccountExpenseMapper extends BaseMapper<AccountExpense> { src/main/java/com/ruoyi/account/mapper/AccountIncomeMapper.java
@@ -3,8 +3,7 @@ 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.AccountDto2; import com.ruoyi.account.pojo.AccountFile; import com.ruoyi.account.bean.dto.AccountDto2; import com.ruoyi.account.pojo.AccountIncome; import com.ruoyi.dto.DateQueryDto; import com.ruoyi.home.dto.IncomeExpenseAnalysisDto; @@ -13,7 +12,6 @@ import java.math.BigDecimal; import java.util.List; import java.util.Map; @Mapper public interface AccountIncomeMapper extends BaseMapper<AccountIncome> { src/main/java/com/ruoyi/account/mapper/SalesRefundAmountOrderMapper.java
@@ -2,7 +2,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.account.dto.SalesRefundAmountOrderDto; import com.ruoyi.account.bean.dto.SalesRefundAmountOrderDto; import com.ruoyi.account.pojo.SalesRefundAmountOrder; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; src/main/java/com/ruoyi/account/mapper/financial/AccountSubjectMapper.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,23 @@ package com.ruoyi.account.mapper.financial; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.account.pojo.financial.AccountSubject; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import java.util.List; /** * <p> * æ»è´¦ç§ç®è¡¨ Mapper æ¥å£ * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-05-07 04:45:30 */ @Mapper public interface AccountSubjectMapper extends BaseMapper<AccountSubject> { Long countReferencedBySubjectCodes(@Param("subjectCodes") List<String> subjectCodes); } src/main/java/com/ruoyi/account/mapper/financial/FinFixedAssetMapper.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,12 @@ package com.ruoyi.account.mapper.financial; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.account.pojo.financial.FinFixedAsset; import org.apache.ibatis.annotations.Mapper; /** * åºå®èµäº§ Mapperã */ @Mapper public interface FinFixedAssetMapper extends BaseMapper<FinFixedAsset> { } src/main/java/com/ruoyi/account/mapper/financial/FinIntangibleAssetMapper.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,12 @@ package com.ruoyi.account.mapper.financial; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.account.pojo.financial.FinIntangibleAsset; import org.apache.ibatis.annotations.Mapper; /** * æ å½¢èµäº§ Mapperã */ @Mapper public interface FinIntangibleAssetMapper extends BaseMapper<FinIntangibleAsset> { } src/main/java/com/ruoyi/account/mapper/financial/FinVoucherEntryMapper.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,28 @@ package com.ruoyi.account.mapper.financial; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.account.bean.vo.financial.FinLedgerEntryRecordVo; import com.ruoyi.account.pojo.financial.FinVoucherEntry; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import java.time.LocalDate; import java.util.List; /** * åè¯åå½ Mapperã */ @Mapper public interface FinVoucherEntryMapper extends BaseMapper<FinVoucherEntry> { List<FinLedgerEntryRecordVo> listPostedEntries(@Param("subjectCode") String subjectCode, @Param("startDate") LocalDate startDate, @Param("endDate") LocalDate endDate, @Param("auxiliaryType") String auxiliaryType, @Param("auxiliaryId") String auxiliaryId); List<FinLedgerEntryRecordVo> listPostedEntriesBefore(@Param("subjectCode") String subjectCode, @Param("beforeDate") LocalDate beforeDate, @Param("auxiliaryType") String auxiliaryType, @Param("auxiliaryId") String auxiliaryId); } src/main/java/com/ruoyi/account/mapper/financial/FinVoucherMapper.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,12 @@ package com.ruoyi.account.mapper.financial; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.account.pojo.financial.FinVoucher; import org.apache.ibatis.annotations.Mapper; /** * åè¯ä¸»è¡¨ Mapperã */ @Mapper public interface FinVoucherMapper extends BaseMapper<FinVoucher> { } src/main/java/com/ruoyi/account/pojo/financial/AccountSubject.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,113 @@ package com.ruoyi.account.pojo.financial; import com.baomidou.mybatisplus.annotation.*; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Getter; import lombok.Setter; import lombok.ToString; import java.io.Serializable; import java.time.LocalDateTime; /** * <p> * æ»è´¦ç§ç®è¡¨ * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-05-07 04:45:30 */ @Getter @Setter @ToString @TableName("account_subject") @ApiModel(value = "AccountSubject对象", description = "æ»è´¦ç§ç®è¡¨") public class AccountSubject implements Serializable { private static final long serialVersionUID = 1L; /** * 主é®ID */ @ApiModelProperty("主é®ID") @TableId(value = "id", type = IdType.AUTO) private Long id; /** * ç¶ç§ç®IDï¼ä¸ºç©ºè¡¨ç¤ºæ ¹èç¹ï¼ */ @ApiModelProperty("ç¶ç§ç®IDï¼ä¸ºç©ºè¡¨ç¤ºæ ¹èç¹ï¼") private Long parentId; /** * ç§ç®ç¼ç (å¯ä¸æ è¯) */ @ApiModelProperty("ç§ç®ç¼ç (å¯ä¸æ è¯)") private String subjectCode; /** * ç§ç®åç§° */ @ApiModelProperty("ç§ç®åç§°") private String subjectName; /** * ç§ç®ç±»å */ @ApiModelProperty("ç§ç®ç±»å") private String subjectType; /** * ä½é¢æ¹å */ @ApiModelProperty("ä½é¢æ¹å") private String balanceDirection; /** * ç¶æ 0å¯ç¨ 1ç¦ç¨ */ @ApiModelProperty("ç¶æ 0å¯ç¨ 1ç¦ç¨") private Integer status; /** * 夿³¨ */ @ApiModelProperty("夿³¨") private String remark; /** * å建人 */ @ApiModelProperty("å建人") @TableField(fill = FieldFill.INSERT) private Integer createUser; /** * å建æ¶é´ */ @ApiModelProperty("å建æ¶é´") @TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; /** * ä¿®æ¹äºº */ @ApiModelProperty("ä¿®æ¹äºº") @TableField(fill = FieldFill.INSERT_UPDATE) private Integer updateUser; /** * ä¿®æ¹æ¶é´ */ @ApiModelProperty("ä¿®æ¹æ¶é´") @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; /** * é¨é¨ID */ @ApiModelProperty("é¨é¨ID") @TableField(fill = FieldFill.INSERT) private Long deptId; } src/main/java/com/ruoyi/account/pojo/financial/FinFixedAsset.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,96 @@ package com.ruoyi.account.pojo.financial; import com.baomidou.mybatisplus.annotation.*; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Getter; import lombok.Setter; import lombok.ToString; import java.io.Serializable; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; /** * åºå®èµäº§å®ä½ã */ @Getter @Setter @ToString @TableName("fin_fixed_asset") @ApiModel(value = "FinFixedAsset对象", description = "åºå®èµäº§") public class FinFixedAsset implements Serializable { private static final long serialVersionUID = 1L; @ApiModelProperty("主é®ID") @TableId(value = "id", type = IdType.AUTO) private Long id; @ApiModelProperty("èµäº§ç¼å·") private String assetCode; @ApiModelProperty("èµäº§åç§°") private String assetName; @ApiModelProperty("èµäº§ç±»å«") private String category; @ApiModelProperty("è§æ ¼åå·") private String specification; @ApiModelProperty("è´ç½®æ¥æ") private LocalDate purchaseDate; @ApiModelProperty("èµäº§åå¼") private BigDecimal originalValue; @ApiModelProperty("使ç¨å¹´é(å¹´)") private Integer usefulLife; @ApiModelProperty("æ®å¼ç(%)") private BigDecimal residualRate; @ApiModelProperty("ç´¯è®¡ææ§") private BigDecimal accumulatedDepreciation; @ApiModelProperty("åå¼") private BigDecimal netValue; @ApiModelProperty("åæ¾å°ç¹") private String location; @ApiModelProperty("使ç¨é¨é¨") private String department; @ApiModelProperty("ä¿ç®¡äºº") private String keeper; @ApiModelProperty("ç¶æ") private String status; @ApiModelProperty("夿³¨") private String remark; @ApiModelProperty("å建人") @TableField(fill = FieldFill.INSERT) private String createUser; @ApiModelProperty("å建æ¶é´") @TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; @ApiModelProperty("ä¿®æ¹äºº") @TableField(fill = FieldFill.INSERT_UPDATE) private String updateUser; @ApiModelProperty("ä¿®æ¹æ¶é´") @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; @ApiModelProperty("é¨é¨ID") @TableField(fill = FieldFill.INSERT) private Long deptId; } src/main/java/com/ruoyi/account/pojo/financial/FinIntangibleAsset.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,92 @@ package com.ruoyi.account.pojo.financial; import com.baomidou.mybatisplus.annotation.*; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Getter; import lombok.Setter; import lombok.ToString; import java.io.Serializable; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; /** * æ å½¢èµäº§å®ä½ã */ @Getter @Setter @ToString @TableName("fin_intangible_asset") @ApiModel(value = "FinIntangibleAsset对象", description = "æ å½¢èµäº§") public class FinIntangibleAsset implements Serializable { private static final long serialVersionUID = 1L; @ApiModelProperty("主é®ID") @TableId(value = "id", type = IdType.AUTO) private Long id; @ApiModelProperty("èµäº§ç¼å·") private String assetCode; @ApiModelProperty("èµäº§åç§°") private String assetName; @ApiModelProperty("èµäº§ç±»å«") private String category; @ApiModelProperty("è¯ä¹¦ç¼å·") private String certificateNo; @ApiModelProperty("å徿¥æ") private LocalDate acquisitionDate; @ApiModelProperty("èµäº§åå¼") private BigDecimal originalValue; @ApiModelProperty("æéå¹´é(å¹´)") private Integer amortizationPeriod; @ApiModelProperty("æ®å¼ç(%)") private BigDecimal residualRate; @ApiModelProperty("累计æé") private BigDecimal accumulatedAmortization; @ApiModelProperty("åå¼") private BigDecimal netValue; @ApiModelProperty("æææè³") private LocalDate validityDate; @ApiModelProperty("ç¶æ") private String status; @ApiModelProperty("èµäº§æè¿°") private String description; @ApiModelProperty("夿³¨") private String remark; @ApiModelProperty("å建人") @TableField(fill = FieldFill.INSERT) private String createUser; @ApiModelProperty("å建æ¶é´") @TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; @ApiModelProperty("ä¿®æ¹äºº") @TableField(fill = FieldFill.INSERT_UPDATE) private String updateUser; @ApiModelProperty("ä¿®æ¹æ¶é´") @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; @ApiModelProperty("é¨é¨ID") @TableField(fill = FieldFill.INSERT) private Long deptId; } src/main/java/com/ruoyi/account/pojo/financial/FinVoucher.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,77 @@ package com.ruoyi.account.pojo.financial; import com.baomidou.mybatisplus.annotation.*; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Getter; import lombok.Setter; import lombok.ToString; import java.io.Serializable; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; /** * åè¯ä¸»è¡¨å®ä½ã */ @Getter @Setter @ToString @TableName("fin_voucher") @ApiModel(value = "FinVoucher对象", description = "åè¯ä¸»è¡¨") public class FinVoucher implements Serializable { private static final long serialVersionUID = 1L; @ApiModelProperty("主é®ID") @TableId(value = "id", type = IdType.AUTO) private Long id; @ApiModelProperty("åè¯åå·") private String voucherNo; @ApiModelProperty("åè¯æ¥æ") private LocalDate voucherDate; @ApiModelProperty("æè¦") private String summary; @ApiModelProperty("åæ¹å计") private BigDecimal debit; @ApiModelProperty("è´·æ¹å计") private BigDecimal credit; @ApiModelProperty("å¶å人") private String creator; @ApiModelProperty("ç¶æ: unposted/posted/cancelled") private String status; @ApiModelProperty("éä»¶æ°é") private Integer attachmentCount; @ApiModelProperty("夿³¨") private String remark; @ApiModelProperty("å建人") @TableField(fill = FieldFill.INSERT) private String createUser; @ApiModelProperty("å建æ¶é´") @TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; @ApiModelProperty("ä¿®æ¹äºº") @TableField(fill = FieldFill.INSERT_UPDATE) private String updateUser; @ApiModelProperty("ä¿®æ¹æ¶é´") @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; @ApiModelProperty("é¨é¨ID") @TableField(fill = FieldFill.INSERT) private Long deptId; } src/main/java/com/ruoyi/account/pojo/financial/FinVoucherEntry.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,79 @@ package com.ruoyi.account.pojo.financial; import com.baomidou.mybatisplus.annotation.*; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Getter; import lombok.Setter; import lombok.ToString; import java.io.Serializable; import java.math.BigDecimal; import java.time.LocalDateTime; /** * åè¯åå½å®ä½ã */ @Getter @Setter @ToString @TableName("fin_voucher_entry") @ApiModel(value = "FinVoucherEntry对象", description = "åè¯åå½") public class FinVoucherEntry implements Serializable { private static final long serialVersionUID = 1L; @ApiModelProperty("主é®ID") @TableId(value = "id", type = IdType.AUTO) private Long id; @ApiModelProperty("åè¯ID") private Long voucherId; @ApiModelProperty("è¡å·") private Integer rowNo; @ApiModelProperty("ç§ç®ç¼ç ") private String subjectCode; @ApiModelProperty("ç§ç®åç§°") private String subjectName; @ApiModelProperty("æè¦") private String summary; @ApiModelProperty("åæ¹éé¢") private BigDecimal debit; @ApiModelProperty("è´·æ¹éé¢") private BigDecimal credit; @ApiModelProperty("è¾ å©æ ¸ç®ç±»å") private String auxiliaryType; @ApiModelProperty("è¾ å©æ ¸ç®å¯¹è±¡ID") private String auxiliaryId; @ApiModelProperty("è¾ å©æ ¸ç®å¯¹è±¡åç§°") private String auxiliaryName; @ApiModelProperty("å建人") @TableField(fill = FieldFill.INSERT) private String createUser; @ApiModelProperty("å建æ¶é´") @TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; @ApiModelProperty("ä¿®æ¹äºº") @TableField(fill = FieldFill.INSERT_UPDATE) private String updateUser; @ApiModelProperty("ä¿®æ¹æ¶é´") @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; @ApiModelProperty("é¨é¨ID") @TableField(fill = FieldFill.INSERT) private Long deptId; } src/main/java/com/ruoyi/account/service/AccountExpenseService.java
@@ -3,12 +3,10 @@ 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.account.dto.AccountDto; import com.ruoyi.account.dto.AccountDto2; import com.ruoyi.account.dto.AccountDto3; import com.ruoyi.account.dto.ReportDateDto; import com.ruoyi.account.bean.dto.AccountDto; import com.ruoyi.account.bean.dto.AccountDto3; import com.ruoyi.account.bean.dto.ReportDateDto; import com.ruoyi.account.pojo.AccountExpense; import com.ruoyi.account.pojo.AccountIncome; import com.ruoyi.dto.DateQueryDto; import javax.servlet.http.HttpServletResponse; src/main/java/com/ruoyi/account/service/AccountIncomeService.java
@@ -3,9 +3,8 @@ 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.account.dto.AccountDto2; import com.ruoyi.account.dto.AccountDto3; import com.ruoyi.account.dto.ReportDateDto; import com.ruoyi.account.bean.dto.AccountDto3; import com.ruoyi.account.bean.dto.ReportDateDto; import com.ruoyi.account.pojo.AccountIncome; import javax.servlet.http.HttpServletResponse; src/main/java/com/ruoyi/account/service/SalesReceiptReturnService.java
@@ -1,7 +1,7 @@ package com.ruoyi.account.service; import com.baomidou.mybatisplus.core.metadata.IPage; import com.ruoyi.account.dto.SalesReceiptReturnDto; import com.ruoyi.account.bean.dto.SalesReceiptReturnDto; import com.ruoyi.account.pojo.SalesReceiptReturn; import com.baomidou.mybatisplus.extension.service.IService; src/main/java/com/ruoyi/account/service/SalesRefundAmountOrderService.java
@@ -2,7 +2,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.account.dto.SalesRefundAmountOrderDto; import com.ruoyi.account.bean.dto.SalesRefundAmountOrderDto; import com.ruoyi.account.pojo.SalesRefundAmountOrder; import com.baomidou.mybatisplus.extension.service.IService; src/main/java/com/ruoyi/account/service/financial/AccountSubjectService.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,32 @@ package com.ruoyi.account.service.financial; 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.account.bean.dto.financial.AccountSubjectDto; import com.ruoyi.account.bean.vo.financial.AccountSubjectVo; import com.ruoyi.account.pojo.financial.AccountSubject; import javax.servlet.http.HttpServletResponse; import java.util.List; /** * <p> * æ»è´¦ç§ç®è¡¨ æå¡ç±» * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-05-07 04:45:30 */ public interface AccountSubjectService extends IService<AccountSubject> { IPage<AccountSubjectVo> baseList(Page<AccountSubjectDto> page, AccountSubjectDto accountSubjectDto); Boolean saveAccountSubject(AccountSubjectDto accountSubjectDto); Boolean updateAccountSubject(AccountSubjectDto accountSubjectDto); Boolean removeAccountSubjectByIds(List<Long> ids); void exportAccountSubject(HttpServletResponse response); } src/main/java/com/ruoyi/account/service/financial/FinFixedAssetService.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,26 @@ package com.ruoyi.account.service.financial; 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.account.bean.dto.financial.FinFixedAssetDto; import com.ruoyi.account.pojo.financial.FinFixedAsset; import java.util.List; import java.util.Map; /** * åºå®èµäº§æå¡ã */ public interface FinFixedAssetService extends IService<FinFixedAsset> { IPage<FinFixedAsset> pageList(Page<FinFixedAsset> page, FinFixedAssetDto queryDto); Boolean add(FinFixedAssetDto dto); Boolean update(FinFixedAssetDto dto); Boolean deleteByIds(List<Long> ids); Map<String, Object> depreciate(List<Long> ids); } src/main/java/com/ruoyi/account/service/financial/FinIntangibleAssetService.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,26 @@ package com.ruoyi.account.service.financial; 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.account.bean.dto.financial.FinIntangibleAssetDto; import com.ruoyi.account.pojo.financial.FinIntangibleAsset; import java.util.List; import java.util.Map; /** * æ å½¢èµäº§æå¡ã */ public interface FinIntangibleAssetService extends IService<FinIntangibleAsset> { IPage<FinIntangibleAsset> pageList(Page<FinIntangibleAsset> page, FinIntangibleAssetDto queryDto); Boolean add(FinIntangibleAssetDto dto); Boolean update(FinIntangibleAssetDto dto); Boolean deleteByIds(List<Long> ids); Map<String, Object> amortize(List<Long> ids); } src/main/java/com/ruoyi/account/service/financial/FinLedgerService.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,17 @@ package com.ruoyi.account.service.financial; import com.ruoyi.account.bean.dto.financial.FinDetailLedgerQueryDto; import com.ruoyi.account.bean.dto.financial.FinLedgerQueryDto; import com.ruoyi.account.bean.vo.financial.FinLedgerRowVo; import java.util.List; /** * ç§ç®è´¦æå¡ã */ public interface FinLedgerService { List<FinLedgerRowVo> queryGeneralLedger(FinLedgerQueryDto queryDto); List<FinLedgerRowVo> queryDetailLedger(FinDetailLedgerQueryDto queryDto); } src/main/java/com/ruoyi/account/service/financial/FinVoucherService.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,27 @@ package com.ruoyi.account.service.financial; 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.account.bean.dto.financial.FinVoucherDto; import com.ruoyi.account.bean.dto.financial.FinVoucherPageDto; import com.ruoyi.account.bean.vo.financial.FinVoucherDetailVo; import com.ruoyi.account.pojo.financial.FinVoucher; /** * åè¯æå¡ã */ public interface FinVoucherService extends IService<FinVoucher> { IPage<FinVoucher> pageList(Page<FinVoucher> page, FinVoucherPageDto queryDto); Boolean addVoucher(FinVoucherDto dto); Boolean updateVoucher(FinVoucherDto dto); Boolean postVoucher(Long id); Boolean cancelVoucher(Long id); FinVoucherDetailVo detail(Long id); } src/main/java/com/ruoyi/account/service/impl/AccountExpenseServiceImpl.java
@@ -5,10 +5,10 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.account.dto.AccountDto; import com.ruoyi.account.dto.AccountDto2; import com.ruoyi.account.dto.AccountDto3; import com.ruoyi.account.dto.ReportDateDto; import com.ruoyi.account.bean.dto.AccountDto; import com.ruoyi.account.bean.dto.AccountDto2; import com.ruoyi.account.bean.dto.AccountDto3; import com.ruoyi.account.bean.dto.ReportDateDto; import com.ruoyi.account.mapper.AccountExpenseMapper; import com.ruoyi.account.mapper.AccountIncomeMapper; import com.ruoyi.account.pojo.AccountExpense; @@ -23,7 +23,6 @@ import javax.servlet.http.HttpServletResponse; import java.math.BigDecimal; import java.time.DayOfWeek; import java.time.LocalDate; import java.time.ZoneId; import java.time.format.DateTimeFormatter; src/main/java/com/ruoyi/account/service/impl/AccountIncomeServiceImpl.java
@@ -5,13 +5,11 @@ 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.account.dto.AccountDto2; import com.ruoyi.account.dto.AccountDto3; import com.ruoyi.account.dto.ReportDateDto; import com.ruoyi.account.bean.dto.AccountDto3; import com.ruoyi.account.bean.dto.ReportDateDto; import com.ruoyi.account.mapper.AccountIncomeMapper; import com.ruoyi.account.pojo.AccountIncome; import com.ruoyi.account.service.AccountIncomeService; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.dto.DateQueryDto; import com.ruoyi.project.system.domain.SysDictData; @@ -24,9 +22,7 @@ import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @AllArgsConstructor @Service src/main/java/com/ruoyi/account/service/impl/AccountingServiceImpl.java
@@ -4,8 +4,8 @@ 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.bean.dto.DeviceTypeDetail; import com.ruoyi.account.bean.dto.DeviceTypeDistributionVO; import com.ruoyi.account.mapper.BorrowInfoMapper; import com.ruoyi.account.pojo.BorrowInfo; import com.ruoyi.device.mapper.DeviceLedgerMapper; @@ -17,8 +17,6 @@ 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; src/main/java/com/ruoyi/account/service/impl/SalesReceiptReturnServiceImpl.java
@@ -1,7 +1,7 @@ package com.ruoyi.account.service.impl; import com.baomidou.mybatisplus.core.metadata.IPage; import com.ruoyi.account.dto.SalesReceiptReturnDto; import com.ruoyi.account.bean.dto.SalesReceiptReturnDto; import com.ruoyi.account.pojo.SalesReceiptReturn; import com.ruoyi.account.mapper.SalesReceiptReturnMapper; import com.ruoyi.account.service.SalesReceiptReturnService; src/main/java/com/ruoyi/account/service/impl/SalesRefundAmountOrderServiceImpl.java
@@ -2,7 +2,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.account.dto.SalesRefundAmountOrderDto; import com.ruoyi.account.bean.dto.SalesRefundAmountOrderDto; import com.ruoyi.account.pojo.SalesRefundAmountOrder; import com.ruoyi.account.mapper.SalesRefundAmountOrderMapper; import com.ruoyi.account.service.SalesRefundAmountOrderService; src/main/java/com/ruoyi/account/service/impl/financial/AccountSubjectServiceImpl.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,387 @@ package com.ruoyi.account.service.impl.financial; 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.account.bean.dto.financial.AccountSubjectDto; import com.ruoyi.account.bean.dto.financial.AccountSubjectImportDto; import com.ruoyi.account.bean.vo.financial.AccountSubjectVo; import com.ruoyi.account.mapper.financial.AccountSubjectMapper; import com.ruoyi.account.pojo.financial.AccountSubject; import com.ruoyi.account.service.financial.AccountSubjectService; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.poi.ExcelUtil; import lombok.RequiredArgsConstructor; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletResponse; import java.util.*; import java.util.stream.Collectors; /** * <p> * æ»è´¦ç§ç®è¡¨ æå¡å®ç°ç±» * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-05-07 04:45:30 */ @Service @RequiredArgsConstructor public class AccountSubjectServiceImpl extends ServiceImpl<AccountSubjectMapper, AccountSubject> implements AccountSubjectService { private final AccountSubjectMapper accountSubjectMapper; @Override public IPage<AccountSubjectVo> baseList(Page<AccountSubjectDto> page, AccountSubjectDto accountSubjectDto) { Page<AccountSubjectDto> requestPage = page == null ? new Page<>(1, 10) : page; List<AccountSubject> allSubjects = list(loadBaseQueryWrapper(accountSubjectDto)); List<AccountSubject> filteredSubjects = applyTreeFilter(allSubjects, accountSubjectDto); List<AccountSubjectVo> fullTree = buildTree(filteredSubjects); long current = requestPage.getCurrent() <= 0 ? 1 : requestPage.getCurrent(); long size = requestPage.getSize() <= 0 ? 10 : requestPage.getSize(); int fromIndex = (int) Math.min((current - 1) * size, fullTree.size()); int toIndex = (int) Math.min(fromIndex + size, fullTree.size()); List<AccountSubjectVo> pagedRoots = fromIndex >= toIndex ? Collections.emptyList() : fullTree.subList(fromIndex, toIndex); Page<AccountSubjectVo> resultPage = new Page<>(current, size, fullTree.size()); resultPage.setRecords(pagedRoots); return resultPage; } @Override public Boolean saveAccountSubject(AccountSubjectDto accountSubjectDto) { validateSubjectRequiredFields(accountSubjectDto); validateSubjectCodeUnique(accountSubjectDto, false); validateParent(accountSubjectDto.getParentId(), null); if (accountSubjectDto.getStatus() == null) { accountSubjectDto.setStatus(0); } return save(accountSubjectDto); } @Override public Boolean updateAccountSubject(AccountSubjectDto accountSubjectDto) { if (accountSubjectDto == null || accountSubjectDto.getId() == null) { throw new ServiceException("ä¿®æ¹å¤±è´¥ï¼ç§ç®IDä¸è½ä¸ºç©º"); } if (getById(accountSubjectDto.getId()) == null) { throw new ServiceException("ä¿®æ¹å¤±è´¥ï¼æªæ¾å°å¯¹åºç§ç®"); } validateParent(accountSubjectDto.getParentId(), accountSubjectDto.getId()); validateSubjectRequiredFields(accountSubjectDto); validateSubjectCodeUnique(accountSubjectDto, true); return updateById(accountSubjectDto); } @Override public Boolean removeAccountSubjectByIds(List<Long> ids) { if (ids == null || ids.isEmpty()) { return true; } List<AccountSubject> allSubjects = list(); if (allSubjects == null || allSubjects.isEmpty()) { return true; } Map<Long, List<Long>> childrenIdMap = buildChildrenIdMap(allSubjects); Set<Long> removeIds = new LinkedHashSet<>(); for (Long id : ids) { collectDescendantIds(id, childrenIdMap, removeIds); } if (removeIds.isEmpty()) { return true; } List<String> subjectCodes = allSubjects.stream() .filter(subject -> removeIds.contains(subject.getId())) .map(AccountSubject::getSubjectCode) .filter(StringUtils::isNotEmpty) .collect(Collectors.toList()); if (!subjectCodes.isEmpty()) { Long referencedCount = accountSubjectMapper.countReferencedBySubjectCodes(subjectCodes); if (referencedCount != null && referencedCount > 0) { throw new ServiceException("å é¤å¤±è´¥ï¼ç§ç®å·²è¢«åè¯åå½å¼ç¨"); } } return removeByIds(removeIds); } @Override public void exportAccountSubject(HttpServletResponse response) { List<AccountSubject> list = accountSubjectMapper.selectList(null); List<AccountSubjectImportDto> importDtos = list.stream().map(accountSubject -> { AccountSubjectImportDto accountSubjectImportDto = new AccountSubjectImportDto(); BeanUtils.copyProperties(accountSubject, accountSubjectImportDto); return accountSubjectImportDto; }).collect(Collectors.toList()); ExcelUtil<AccountSubjectImportDto> util = new ExcelUtil<>(AccountSubjectImportDto.class); util.exportExcel(response, importDtos , "æ»è´¦ç§ç®"); } /** * æ ¡éªç§ç®å¿ å¡«åæ®µï¼é¿å èæ°æ®åå ¥ã */ private void validateSubjectRequiredFields(AccountSubjectDto accountSubjectDto) { if (accountSubjectDto == null) { throw new ServiceException("æ»è´¦ç§ç®æ°æ®ä¸è½ä¸ºç©º"); } if (StringUtils.isEmpty(accountSubjectDto.getSubjectCode())) { throw new ServiceException("ç§ç®ç¼ç ä¸è½ä¸ºç©º"); } if (StringUtils.isEmpty(accountSubjectDto.getSubjectName())) { throw new ServiceException("ç§ç®åç§°ä¸è½ä¸ºç©º"); } if (StringUtils.isEmpty(accountSubjectDto.getSubjectType())) { throw new ServiceException("ç§ç®ç±»åä¸è½ä¸ºç©º"); } } /** * æ ¡éªç§ç®ç¼ç å¯ä¸ï¼æ°å¢åä¿®æ¹é½è¦æ§è¡ã */ private void validateSubjectCodeUnique(AccountSubjectDto accountSubjectDto, boolean isUpdate) { LambdaQueryWrapper<AccountSubject> codeQueryWrapper = new LambdaQueryWrapper<>(); codeQueryWrapper.eq(AccountSubject::getSubjectCode, accountSubjectDto.getSubjectCode()); if (isUpdate) { codeQueryWrapper.ne(AccountSubject::getId, accountSubjectDto.getId()); } AccountSubject exists = getOne(codeQueryWrapper, false); if (Objects.nonNull(exists)) { throw new ServiceException("ç§ç®ç¼ç å·²åå¨ï¼è¯·å¿éå¤æäº¤"); } } /** * ä» æéç¨è¿æ»¤æ¡ä»¶æ¥è¯¢åºç¡æ°æ®ï¼æ å½¢è¿æ»¤åç»ååï¼ã */ private LambdaQueryWrapper<AccountSubject> loadBaseQueryWrapper(AccountSubjectDto accountSubjectDto) { LambdaQueryWrapper<AccountSubject> queryWrapper = new LambdaQueryWrapper<>(); if (accountSubjectDto != null && accountSubjectDto.getStatus() != null) { queryWrapper.eq(AccountSubject::getStatus, accountSubjectDto.getStatus()); } queryWrapper.orderByAsc(AccountSubject::getSubjectCode).orderByAsc(AccountSubject::getId); return queryWrapper; } /** * æ å½¢è¿æ»¤ï¼å½ä¸èç¹åä¿çå ¶ç¶é¾ä¸åæ ï¼ä¿è¯éå½ç»æå®æ´ã */ private List<AccountSubject> applyTreeFilter(List<AccountSubject> allSubjects, AccountSubjectDto queryDto) { if (allSubjects == null || allSubjects.isEmpty()) { return Collections.emptyList(); } boolean hasFilter = queryDto != null && ( StringUtils.isNotEmpty(queryDto.getSubjectCode()) || StringUtils.isNotEmpty(queryDto.getSubjectName()) || StringUtils.isNotEmpty(queryDto.getSubjectType()) ); if (!hasFilter) { return allSubjects; } Map<Long, AccountSubject> subjectMap = allSubjects.stream() .filter(item -> item.getId() != null) .collect(Collectors.toMap(AccountSubject::getId, item -> item, (a, b) -> a, LinkedHashMap::new)); Map<Long, List<AccountSubject>> childrenMap = buildChildrenMap(allSubjects); Set<Long> matchedIds = new LinkedHashSet<>(); for (AccountSubject subject : allSubjects) { if (subject.getId() == null) { continue; } if (matchesFilter(subject, queryDto)) { matchedIds.add(subject.getId()); } } if (matchedIds.isEmpty()) { return Collections.emptyList(); } Set<Long> resultIds = new LinkedHashSet<>(matchedIds); for (Long matchedId : matchedIds) { addAncestors(matchedId, subjectMap, resultIds); addDescendants(matchedId, childrenMap, resultIds); } return allSubjects.stream() .filter(item -> item.getId() != null && resultIds.contains(item.getId())) .collect(Collectors.toList()); } private boolean matchesFilter(AccountSubject subject, AccountSubjectDto queryDto) { if (queryDto == null) { return true; } if (StringUtils.isNotEmpty(queryDto.getSubjectCode()) && (subject.getSubjectCode() == null || !subject.getSubjectCode().contains(queryDto.getSubjectCode()))) { return false; } if (StringUtils.isNotEmpty(queryDto.getSubjectName()) && (subject.getSubjectName() == null || !subject.getSubjectName().contains(queryDto.getSubjectName()))) { return false; } if (StringUtils.isNotEmpty(queryDto.getSubjectType()) && !queryDto.getSubjectType().equals(subject.getSubjectType())) { return false; } return true; } private void addAncestors(Long subjectId, Map<Long, AccountSubject> subjectMap, Set<Long> resultIds) { AccountSubject current = subjectMap.get(subjectId); if (current == null) { return; } Long parentId = current.getParentId(); while (parentId != null && parentId > 0) { AccountSubject parent = subjectMap.get(parentId); if (parent == null) { break; } if (!resultIds.add(parent.getId())) { break; } parentId = parent.getParentId(); } } private void addDescendants(Long subjectId, Map<Long, List<AccountSubject>> childrenMap, Set<Long> resultIds) { List<AccountSubject> children = childrenMap.getOrDefault(subjectId, Collections.emptyList()); for (AccountSubject child : children) { if (child.getId() == null) { continue; } if (resultIds.add(child.getId())) { addDescendants(child.getId(), childrenMap, resultIds); } } } private Map<Long, List<AccountSubject>> buildChildrenMap(List<AccountSubject> subjects) { Map<Long, List<AccountSubject>> childrenMap = new HashMap<>(); for (AccountSubject subject : subjects) { if (subject.getId() == null) { continue; } Long parentId = subject.getParentId(); if (parentId == null || parentId <= 0) { continue; } childrenMap.computeIfAbsent(parentId, key -> new ArrayList<>()).add(subject); } return childrenMap; } /** * åºäº parentId éå½æå»ºç§ç®æ ã */ private List<AccountSubjectVo> buildTree(List<AccountSubject> subjects) { if (subjects == null || subjects.isEmpty()) { return Collections.emptyList(); } List<AccountSubject> sortedSubjects = new ArrayList<>(subjects); sortedSubjects.sort(Comparator .comparing(AccountSubject::getSubjectCode, Comparator.nullsLast(String::compareTo)) .thenComparing(AccountSubject::getId, Comparator.nullsLast(Long::compareTo))); Map<Long, AccountSubjectVo> subjectVoMap = new LinkedHashMap<>(); for (AccountSubject subject : sortedSubjects) { if (subject.getId() == null) { continue; } AccountSubjectVo vo = new AccountSubjectVo(); BeanUtils.copyProperties(subject, vo); subjectVoMap.put(subject.getId(), vo); } List<AccountSubjectVo> roots = new ArrayList<>(); for (AccountSubject subject : sortedSubjects) { if (subject.getId() == null) { continue; } AccountSubjectVo current = subjectVoMap.get(subject.getId()); Long parentId = subject.getParentId(); if (parentId != null && parentId > 0 && subjectVoMap.containsKey(parentId)) { subjectVoMap.get(parentId).getChildren().add(current); } else { roots.add(current); } } markLeafRecursively(roots); return roots; } private void markLeafRecursively(List<AccountSubjectVo> nodes) { for (AccountSubjectVo node : nodes) { List<AccountSubjectVo> children = node.getChildren(); node.setLeaf(children == null || children.isEmpty()); if (children != null && !children.isEmpty()) { markLeafRecursively(children); } } } /** * æ ¡éªç¶åå ³ç³»ï¼ç¶èç¹å¿ é¡»åå¨ï¼ä¸ä¸è½å½¢æå¾ªç¯å¼ç¨ã */ private void validateParent(Long parentId, Long currentId) { if (parentId == null || parentId <= 0) { return; } if (currentId != null && parentId.equals(currentId)) { throw new ServiceException("ç¶ç§ç®ä¸è½éæ©èªèº«"); } AccountSubject parent = getById(parentId); if (parent == null) { throw new ServiceException("ç¶ç§ç®ä¸åå¨ï¼è¯·éæ°éæ©"); } // 鲿¢å½¢æç¯ï¼æ´æ°æ¶ï¼ç¶èç¹ä¸è½æ¯å½åèç¹çä»»æååèç¹ã if (currentId != null) { Set<Long> visited = new HashSet<>(); Long traceParentId = parentId; while (traceParentId != null && traceParentId > 0) { if (!visited.add(traceParentId)) { throw new ServiceException("ç§ç®å±çº§åå¨å¾ªç¯å¼ç¨ï¼è¯·æ£æ¥ç¶ç§ç®è®¾ç½®"); } if (traceParentId.equals(currentId)) { throw new ServiceException("ç¶ç§ç®ä¸è½æ¯å½åç§ç®æå ¶åç§ç®"); } AccountSubject traceNode = getById(traceParentId); if (traceNode == null) { break; } traceParentId = traceNode.getParentId(); } } } private Map<Long, List<Long>> buildChildrenIdMap(List<AccountSubject> subjects) { Map<Long, List<Long>> map = new HashMap<>(); for (AccountSubject subject : subjects) { if (subject.getId() == null || subject.getParentId() == null || subject.getParentId() <= 0) { continue; } map.computeIfAbsent(subject.getParentId(), key -> new ArrayList<>()).add(subject.getId()); } return map; } /** * æ¶éå¾ å é¤èç¹åå ¶ææååèç¹ã */ private void collectDescendantIds(Long id, Map<Long, List<Long>> childrenIdMap, Set<Long> result) { if (id == null || !result.add(id)) { return; } List<Long> children = childrenIdMap.getOrDefault(id, Collections.emptyList()); for (Long childId : children) { collectDescendantIds(childId, childrenIdMap, result); } } } src/main/java/com/ruoyi/account/service/impl/financial/FinFixedAssetServiceImpl.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,234 @@ package com.ruoyi.account.service.impl.financial; 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.account.bean.dto.financial.FinFixedAssetDto; import com.ruoyi.account.mapper.financial.FinFixedAssetMapper; import com.ruoyi.account.pojo.financial.FinFixedAsset; import com.ruoyi.account.service.financial.FinFixedAssetService; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.StringUtils; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; /** * åºå®èµäº§æå¡å®ç°ã */ @Service @RequiredArgsConstructor public class FinFixedAssetServiceImpl extends ServiceImpl<FinFixedAssetMapper, FinFixedAsset> implements FinFixedAssetService { private static final BigDecimal ONE_HUNDRED = new BigDecimal("100"); private static final BigDecimal ZERO = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP); private static final DateTimeFormatter CODE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); @Override public IPage<FinFixedAsset> pageList(Page<FinFixedAsset> page, FinFixedAssetDto queryDto) { LambdaQueryWrapper<FinFixedAsset> wrapper = new LambdaQueryWrapper<>(); if (queryDto != null && StringUtils.isNotEmpty(queryDto.getAssetCode())) { wrapper.like(FinFixedAsset::getAssetCode, queryDto.getAssetCode()); } if (queryDto != null && StringUtils.isNotEmpty(queryDto.getAssetName())) { wrapper.like(FinFixedAsset::getAssetName, queryDto.getAssetName()); } if (queryDto != null && StringUtils.isNotEmpty(queryDto.getCategory())) { wrapper.eq(FinFixedAsset::getCategory, queryDto.getCategory()); } if (queryDto != null && StringUtils.isNotEmpty(queryDto.getStatus())) { wrapper.eq(FinFixedAsset::getStatus, queryDto.getStatus()); } wrapper.orderByDesc(FinFixedAsset::getId); return page(page, wrapper); } @Override @Transactional(rollbackFor = Exception.class) public Boolean add(FinFixedAssetDto dto) { validateForSave(dto, false); if (StringUtils.isEmpty(dto.getAssetCode())) { dto.setAssetCode(generateAssetCode()); } BigDecimal residualRate = normalizeResidualRate(dto.getResidualRate()); dto.setResidualRate(residualRate); BigDecimal accumulatedDepreciation = defaultMoney(dto.getAccumulatedDepreciation()); dto.setAccumulatedDepreciation(accumulatedDepreciation); dto.setNetValue(calculateNetValue(dto.getOriginalValue(), accumulatedDepreciation)); if (StringUtils.isEmpty(dto.getStatus())) { dto.setStatus("in_use"); } return save(dto); } @Override @Transactional(rollbackFor = Exception.class) public Boolean update(FinFixedAssetDto dto) { if (dto == null || dto.getId() == null) { throw new ServiceException("ä¿®æ¹å¤±è´¥ï¼èµäº§IDä¸è½ä¸ºç©º"); } FinFixedAsset existed = getById(dto.getId()); if (existed == null) { throw new ServiceException("ä¿®æ¹å¤±è´¥ï¼åºå®èµäº§ä¸åå¨"); } if (StringUtils.isEmpty(dto.getAssetCode())) { dto.setAssetCode(existed.getAssetCode()); } if (StringUtils.isEmpty(dto.getStatus())) { dto.setStatus(existed.getStatus()); } validateForSave(dto, true); BigDecimal residualRate = normalizeResidualRate(dto.getResidualRate()); dto.setResidualRate(residualRate); if (dto.getAccumulatedDepreciation() == null) { dto.setAccumulatedDepreciation(defaultMoney(existed.getAccumulatedDepreciation())); } dto.setNetValue(calculateNetValue(dto.getOriginalValue(), dto.getAccumulatedDepreciation())); return updateById(dto); } @Override @Transactional(rollbackFor = Exception.class) public Boolean deleteByIds(List<Long> ids) { if (ids == null || ids.isEmpty()) { throw new ServiceException("å é¤å¤±è´¥ï¼è¯·éæ©è¦å é¤çæ°æ®"); } return removeByIds(ids); } @Override @Transactional(rollbackFor = Exception.class) public Map<String, Object> depreciate(List<Long> ids) { LambdaQueryWrapper<FinFixedAsset> wrapper = new LambdaQueryWrapper<>(); if (ids != null && !ids.isEmpty()) { wrapper.in(FinFixedAsset::getId, ids); } else { wrapper.eq(FinFixedAsset::getStatus, "in_use"); } List<FinFixedAsset> assets = list(wrapper); BigDecimal totalMonthlyDepreciation = ZERO; int processedCount = 0; for (FinFixedAsset asset : assets) { if (!"in_use".equals(asset.getStatus())) { continue; } BigDecimal monthlyDepreciation = calculateMonthlyDepreciation( asset.getOriginalValue(), asset.getResidualRate(), asset.getUsefulLife() ); BigDecimal accumulatedDepreciation = defaultMoney(asset.getAccumulatedDepreciation()).add(monthlyDepreciation); if (accumulatedDepreciation.compareTo(defaultMoney(asset.getOriginalValue())) > 0) { accumulatedDepreciation = defaultMoney(asset.getOriginalValue()); } asset.setAccumulatedDepreciation(roundMoney(accumulatedDepreciation)); asset.setNetValue(calculateNetValue(asset.getOriginalValue(), asset.getAccumulatedDepreciation())); updateById(asset); processedCount++; totalMonthlyDepreciation = totalMonthlyDepreciation.add(monthlyDepreciation); } Map<String, Object> result = new HashMap<>(4); result.put("processedCount", processedCount); result.put("totalMonthlyDepreciation", roundMoney(totalMonthlyDepreciation)); result.put("executionTime", LocalDateTime.now()); return result; } /** * æææ¡£è§åæ ¡éªåºå®èµäº§æ°æ®ã */ private void validateForSave(FinFixedAssetDto dto, boolean isUpdate) { if (dto == null) { throw new ServiceException("åºå®èµäº§æ°æ®ä¸è½ä¸ºç©º"); } if (isUpdate && dto.getId() == null) { throw new ServiceException("ä¿®æ¹å¤±è´¥ï¼èµäº§IDä¸è½ä¸ºç©º"); } if (StringUtils.isEmpty(dto.getAssetName())) { throw new ServiceException("èµäº§åç§°ä¸è½ä¸ºç©º"); } if (StringUtils.isEmpty(dto.getCategory())) { throw new ServiceException("èµäº§ç±»å«ä¸è½ä¸ºç©º"); } if (dto.getPurchaseDate() == null) { throw new ServiceException("è´ç½®æ¥æä¸è½ä¸ºç©º"); } if (dto.getOriginalValue() == null || dto.getOriginalValue().compareTo(BigDecimal.ZERO) < 0) { throw new ServiceException("èµäº§åå¼ä¸è½ä¸ºç©ºä¸ä¸è½å°äº0"); } if (dto.getUsefulLife() == null || dto.getUsefulLife() <= 0) { throw new ServiceException("使ç¨å¹´éå¿ é¡»å¤§äº0"); } if (dto.getResidualRate() != null && dto.getResidualRate().compareTo(BigDecimal.ZERO) < 0) { throw new ServiceException("æ®å¼çä¸è½å°äº0"); } if (dto.getResidualRate() != null && dto.getResidualRate().compareTo(ONE_HUNDRED) > 0) { throw new ServiceException("æ®å¼çä¸è½å¤§äº100%"); } if (StringUtils.isNotEmpty(dto.getAssetCode())) { LambdaQueryWrapper<FinFixedAsset> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(FinFixedAsset::getAssetCode, dto.getAssetCode()); if (isUpdate) { wrapper.ne(FinFixedAsset::getId, dto.getId()); } if (count(wrapper) > 0) { throw new ServiceException("èµäº§ç¼å·å·²åå¨ï¼è¯·å¿éå¤æäº¤"); } } } /** * åºå®èµäº§ææ§å ¬å¼ï¼ * monthlyDepreciation = originalValue * (1 - residualRate/100) / (usefulLife*12) */ private BigDecimal calculateMonthlyDepreciation(BigDecimal originalValue, BigDecimal residualRate, Integer usefulLife) { BigDecimal normalizedOriginalValue = defaultMoney(originalValue); BigDecimal normalizedResidualRate = normalizeResidualRate(residualRate); BigDecimal depreciableRatio = BigDecimal.ONE.subtract(normalizedResidualRate.divide(ONE_HUNDRED, 8, RoundingMode.HALF_UP)); BigDecimal months = BigDecimal.valueOf((long) usefulLife * 12L); if (months.compareTo(BigDecimal.ZERO) <= 0) { throw new ServiceException("使ç¨å¹´éæ æï¼æ æ³è®¡æææ§"); } return roundMoney(normalizedOriginalValue.multiply(depreciableRatio).divide(months, 8, RoundingMode.HALF_UP)); } /** * åå¼ = åå¼ - ç´¯è®¡ææ§ã */ private BigDecimal calculateNetValue(BigDecimal originalValue, BigDecimal accumulatedDepreciation) { BigDecimal value = defaultMoney(originalValue).subtract(defaultMoney(accumulatedDepreciation)); if (value.compareTo(BigDecimal.ZERO) < 0) { value = BigDecimal.ZERO; } return roundMoney(value); } private BigDecimal normalizeResidualRate(BigDecimal residualRate) { return residualRate == null ? BigDecimal.ZERO : residualRate; } private BigDecimal defaultMoney(BigDecimal value) { return value == null ? ZERO : roundMoney(value); } private BigDecimal roundMoney(BigDecimal value) { if (value == null) { return ZERO; } return value.setScale(2, RoundingMode.HALF_UP); } private String generateAssetCode() { return "GD" + LocalDateTime.now().format(CODE_TIME_FORMATTER) + new Random().nextInt(10); } } src/main/java/com/ruoyi/account/service/impl/financial/FinIntangibleAssetServiceImpl.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,253 @@ package com.ruoyi.account.service.impl.financial; 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.account.bean.dto.financial.FinIntangibleAssetDto; import com.ruoyi.account.mapper.financial.FinIntangibleAssetMapper; import com.ruoyi.account.pojo.financial.FinIntangibleAsset; import com.ruoyi.account.service.financial.FinIntangibleAssetService; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.StringUtils; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; /** * æ å½¢èµäº§æå¡å®ç°ã */ @Service @RequiredArgsConstructor public class FinIntangibleAssetServiceImpl extends ServiceImpl<FinIntangibleAssetMapper, FinIntangibleAsset> implements FinIntangibleAssetService { private static final BigDecimal ONE_HUNDRED = new BigDecimal("100"); private static final BigDecimal ZERO = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP); private static final DateTimeFormatter CODE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); @Override public IPage<FinIntangibleAsset> pageList(Page<FinIntangibleAsset> page, FinIntangibleAssetDto queryDto) { LambdaQueryWrapper<FinIntangibleAsset> wrapper = new LambdaQueryWrapper<>(); if (queryDto != null && StringUtils.isNotEmpty(queryDto.getAssetCode())) { wrapper.like(FinIntangibleAsset::getAssetCode, queryDto.getAssetCode()); } if (queryDto != null && StringUtils.isNotEmpty(queryDto.getAssetName())) { wrapper.like(FinIntangibleAsset::getAssetName, queryDto.getAssetName()); } if (queryDto != null && StringUtils.isNotEmpty(queryDto.getCategory())) { wrapper.eq(FinIntangibleAsset::getCategory, queryDto.getCategory()); } if (queryDto != null && StringUtils.isNotEmpty(queryDto.getStatus())) { wrapper.eq(FinIntangibleAsset::getStatus, queryDto.getStatus()); } wrapper.orderByDesc(FinIntangibleAsset::getId); return page(page, wrapper); } @Override @Transactional(rollbackFor = Exception.class) public Boolean add(FinIntangibleAssetDto dto) { validateForSave(dto, false); if (StringUtils.isEmpty(dto.getAssetCode())) { dto.setAssetCode(generateAssetCode()); } BigDecimal residualRate = normalizeResidualRate(dto.getResidualRate()); dto.setResidualRate(residualRate); BigDecimal accumulatedAmortization = defaultMoney(dto.getAccumulatedAmortization()); dto.setAccumulatedAmortization(accumulatedAmortization); dto.setNetValue(calculateNetValue(dto.getOriginalValue(), accumulatedAmortization)); if (StringUtils.isEmpty(dto.getStatus())) { dto.setStatus("in_use"); } return save(dto); } @Override @Transactional(rollbackFor = Exception.class) public Boolean update(FinIntangibleAssetDto dto) { if (dto == null || dto.getId() == null) { throw new ServiceException("ä¿®æ¹å¤±è´¥ï¼èµäº§IDä¸è½ä¸ºç©º"); } FinIntangibleAsset existed = getById(dto.getId()); if (existed == null) { throw new ServiceException("ä¿®æ¹å¤±è´¥ï¼æ å½¢èµäº§ä¸åå¨"); } if (StringUtils.isEmpty(dto.getAssetCode())) { dto.setAssetCode(existed.getAssetCode()); } if (StringUtils.isEmpty(dto.getStatus())) { dto.setStatus(existed.getStatus()); } validateForSave(dto, true); BigDecimal residualRate = normalizeResidualRate(dto.getResidualRate()); dto.setResidualRate(residualRate); if (dto.getAccumulatedAmortization() == null) { dto.setAccumulatedAmortization(defaultMoney(existed.getAccumulatedAmortization())); } dto.setNetValue(calculateNetValue(dto.getOriginalValue(), dto.getAccumulatedAmortization())); if (dto.getNetValue().compareTo(BigDecimal.ZERO) <= 0) { dto.setStatus("amortized"); } else if ("amortized".equals(dto.getStatus())) { dto.setStatus("in_use"); } if (dto.getValidityDate() != null && dto.getValidityDate().isBefore(LocalDate.now()) && !"amortized".equals(dto.getStatus())) { dto.setStatus("expired"); } return updateById(dto); } @Override @Transactional(rollbackFor = Exception.class) public Boolean deleteByIds(List<Long> ids) { if (ids == null || ids.isEmpty()) { throw new ServiceException("å é¤å¤±è´¥ï¼è¯·éæ©è¦å é¤çæ°æ®"); } return removeByIds(ids); } @Override @Transactional(rollbackFor = Exception.class) public Map<String, Object> amortize(List<Long> ids) { LambdaQueryWrapper<FinIntangibleAsset> wrapper = new LambdaQueryWrapper<>(); if (ids != null && !ids.isEmpty()) { wrapper.in(FinIntangibleAsset::getId, ids); } else { wrapper.eq(FinIntangibleAsset::getStatus, "in_use"); } List<FinIntangibleAsset> assets = list(wrapper); BigDecimal totalMonthlyAmortization = ZERO; int processedCount = 0; for (FinIntangibleAsset asset : assets) { if (!"in_use".equals(asset.getStatus())) { continue; } BigDecimal monthlyAmortization = calculateMonthlyAmortization( asset.getOriginalValue(), asset.getResidualRate(), asset.getAmortizationPeriod() ); BigDecimal accumulatedAmortization = defaultMoney(asset.getAccumulatedAmortization()).add(monthlyAmortization); if (accumulatedAmortization.compareTo(defaultMoney(asset.getOriginalValue())) > 0) { accumulatedAmortization = defaultMoney(asset.getOriginalValue()); } asset.setAccumulatedAmortization(roundMoney(accumulatedAmortization)); asset.setNetValue(calculateNetValue(asset.getOriginalValue(), asset.getAccumulatedAmortization())); // è§åï¼å½åå¼ <= 0 æ¶ï¼åå¼å½é¶å¹¶æ 记为已æéå®ã if (asset.getNetValue().compareTo(BigDecimal.ZERO) <= 0) { asset.setNetValue(BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP)); asset.setStatus("amortized"); } else if (asset.getValidityDate() != null && asset.getValidityDate().isBefore(LocalDate.now())) { asset.setStatus("expired"); } updateById(asset); processedCount++; totalMonthlyAmortization = totalMonthlyAmortization.add(monthlyAmortization); } Map<String, Object> result = new HashMap<>(4); result.put("processedCount", processedCount); result.put("totalMonthlyAmortization", roundMoney(totalMonthlyAmortization)); result.put("executionTime", LocalDateTime.now()); return result; } /** * æææ¡£è§åæ ¡éªæ å½¢èµäº§æ°æ®ã */ private void validateForSave(FinIntangibleAssetDto dto, boolean isUpdate) { if (dto == null) { throw new ServiceException("æ å½¢èµäº§æ°æ®ä¸è½ä¸ºç©º"); } if (isUpdate && dto.getId() == null) { throw new ServiceException("ä¿®æ¹å¤±è´¥ï¼èµäº§IDä¸è½ä¸ºç©º"); } if (StringUtils.isEmpty(dto.getAssetName())) { throw new ServiceException("èµäº§åç§°ä¸è½ä¸ºç©º"); } if (StringUtils.isEmpty(dto.getCategory())) { throw new ServiceException("èµäº§ç±»å«ä¸è½ä¸ºç©º"); } if (dto.getAcquisitionDate() == null) { throw new ServiceException("å徿¥æä¸è½ä¸ºç©º"); } if (dto.getOriginalValue() == null || dto.getOriginalValue().compareTo(BigDecimal.ZERO) < 0) { throw new ServiceException("èµäº§åå¼ä¸è½ä¸ºç©ºä¸ä¸è½å°äº0"); } if (dto.getAmortizationPeriod() == null || dto.getAmortizationPeriod() <= 0) { throw new ServiceException("æéå¹´éå¿ é¡»å¤§äº0"); } if (dto.getResidualRate() != null && dto.getResidualRate().compareTo(BigDecimal.ZERO) < 0) { throw new ServiceException("æ®å¼çä¸è½å°äº0"); } if (dto.getResidualRate() != null && dto.getResidualRate().compareTo(ONE_HUNDRED) > 0) { throw new ServiceException("æ®å¼çä¸è½å¤§äº100%"); } if (StringUtils.isNotEmpty(dto.getAssetCode())) { LambdaQueryWrapper<FinIntangibleAsset> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(FinIntangibleAsset::getAssetCode, dto.getAssetCode()); if (isUpdate) { wrapper.ne(FinIntangibleAsset::getId, dto.getId()); } if (count(wrapper) > 0) { throw new ServiceException("èµäº§ç¼å·å·²åå¨ï¼è¯·å¿éå¤æäº¤"); } } } /** * æ å½¢èµäº§æéå ¬å¼ï¼ * monthlyAmortization = originalValue * (1 - residualRate/100) / (amortizationPeriod*12) */ private BigDecimal calculateMonthlyAmortization(BigDecimal originalValue, BigDecimal residualRate, Integer amortizationPeriod) { BigDecimal normalizedOriginalValue = defaultMoney(originalValue); BigDecimal normalizedResidualRate = normalizeResidualRate(residualRate); BigDecimal amortizableRatio = BigDecimal.ONE.subtract(normalizedResidualRate.divide(ONE_HUNDRED, 8, RoundingMode.HALF_UP)); BigDecimal months = BigDecimal.valueOf((long) amortizationPeriod * 12L); if (months.compareTo(BigDecimal.ZERO) <= 0) { throw new ServiceException("æéå¹´éæ æï¼æ æ³è®¡ææé"); } return roundMoney(normalizedOriginalValue.multiply(amortizableRatio).divide(months, 8, RoundingMode.HALF_UP)); } /** * åå¼ = åå¼ - 累计æéã */ private BigDecimal calculateNetValue(BigDecimal originalValue, BigDecimal accumulatedAmortization) { BigDecimal value = defaultMoney(originalValue).subtract(defaultMoney(accumulatedAmortization)); if (value.compareTo(BigDecimal.ZERO) < 0) { value = BigDecimal.ZERO; } return roundMoney(value); } private BigDecimal normalizeResidualRate(BigDecimal residualRate) { return residualRate == null ? BigDecimal.ZERO : residualRate; } private BigDecimal defaultMoney(BigDecimal value) { return value == null ? ZERO : roundMoney(value); } private BigDecimal roundMoney(BigDecimal value) { if (value == null) { return ZERO; } return value.setScale(2, RoundingMode.HALF_UP); } private String generateAssetCode() { return "WX" + LocalDateTime.now().format(CODE_TIME_FORMATTER) + new Random().nextInt(10); } } src/main/java/com/ruoyi/account/service/impl/financial/FinLedgerServiceImpl.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,237 @@ package com.ruoyi.account.service.impl.financial; import com.ruoyi.account.bean.dto.financial.FinDetailLedgerQueryDto; import com.ruoyi.account.bean.dto.financial.FinLedgerQueryDto; import com.ruoyi.account.bean.vo.financial.FinLedgerEntryRecordVo; import com.ruoyi.account.bean.vo.financial.FinLedgerRowVo; import com.ruoyi.account.mapper.financial.FinVoucherEntryMapper; import com.ruoyi.account.service.financial.FinLedgerService; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.StringUtils; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDate; import java.time.YearMonth; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.util.*; /** * ç§ç®æ»è´¦/æç»è´¦æå¡å®ç°ã */ @Service @RequiredArgsConstructor public class FinLedgerServiceImpl implements FinLedgerService { private static final DateTimeFormatter MONTH_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM"); private static final BigDecimal ZERO = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP); private final FinVoucherEntryMapper finVoucherEntryMapper; @Override public List<FinLedgerRowVo> queryGeneralLedger(FinLedgerQueryDto queryDto) { if (queryDto == null || StringUtils.isEmpty(queryDto.getSubjectCode())) { return Collections.emptyList(); } YearMonth startMonth = parseMonth(queryDto.getStartMonth(), "å¼å§æä»½"); YearMonth endMonth = parseMonth(queryDto.getEndMonth(), "ç»ææä»½"); if (startMonth.isAfter(endMonth)) { throw new ServiceException("å¼å§æä»½ä¸è½å¤§äºç»ææä»½"); } return Collections.singletonList(buildGeneralLedgerTotalRow(queryDto.getSubjectCode(), startMonth, endMonth)); } @Override public List<FinLedgerRowVo> queryDetailLedger(FinDetailLedgerQueryDto queryDto) { if (queryDto == null || StringUtils.isEmpty(queryDto.getSubjectCode())) { return Collections.emptyList(); } YearMonth startMonth = parseMonth(queryDto.getStartMonth(), "å¼å§æä»½"); YearMonth endMonth = parseMonth(queryDto.getEndMonth(), "ç»ææä»½"); if (startMonth.isAfter(endMonth)) { throw new ServiceException("å¼å§æä»½ä¸è½å¤§äºç»ææä»½"); } return buildLedgerRows(queryDto.getSubjectCode(), startMonth, endMonth, queryDto.getAuxiliaryType(), queryDto.getAuxiliaryId()); } /** * æå»ºè´¦ç°¿è¡æ°æ®ï¼è¾åºæåãåå½ãæ¬æåè®¡ãæ¬å¹´ç´¯è®¡ã */ private List<FinLedgerRowVo> buildLedgerRows(String subjectCode, YearMonth startMonth, YearMonth endMonth, String auxiliaryType, String auxiliaryId) { LocalDate startDate = startMonth.atDay(1); LocalDate endDate = endMonth.atEndOfMonth(); List<FinLedgerEntryRecordVo> openingEntries = finVoucherEntryMapper.listPostedEntriesBefore( subjectCode, startDate, auxiliaryType, auxiliaryId ); BigDecimal openingBalance = calculateBalance(openingEntries); List<FinLedgerEntryRecordVo> currentPeriodEntries = finVoucherEntryMapper.listPostedEntries( subjectCode, startDate, endDate, auxiliaryType, auxiliaryId ); Map<YearMonth, List<FinLedgerEntryRecordVo>> monthEntriesMap = groupEntriesByMonth(currentPeriodEntries); List<FinLedgerRowVo> rows = new ArrayList<>(); BigDecimal runningBalance = openingBalance; BigDecimal yearDebit = ZERO; BigDecimal yearCredit = ZERO; for (YearMonth month = startMonth; !month.isAfter(endMonth); month = month.plusMonths(1)) { rows.add(buildOpeningRow(month.atDay(1), runningBalance)); List<FinLedgerEntryRecordVo> monthEntries = monthEntriesMap.getOrDefault(month, Collections.emptyList()); BigDecimal monthDebit = ZERO; BigDecimal monthCredit = ZERO; for (FinLedgerEntryRecordVo entry : monthEntries) { BigDecimal debit = money(entry.getDebit()); BigDecimal credit = money(entry.getCredit()); runningBalance = runningBalance.add(debit).subtract(credit); monthDebit = monthDebit.add(debit); monthCredit = monthCredit.add(credit); FinLedgerRowVo row = new FinLedgerRowVo(); row.setRowType("entry"); row.setDate(entry.getVoucherDate()); row.setVoucherNo(entry.getVoucherNo()); row.setSummary(StringUtils.isNotEmpty(entry.getSummary()) ? entry.getSummary() : ""); row.setDebit(debit); row.setCredit(credit); row.setBalance(money(runningBalance)); row.setDirection(resolveDirection(runningBalance)); rows.add(row); } rows.add(buildMonthlyTotalRow(month.atEndOfMonth(), monthDebit, monthCredit, runningBalance)); yearDebit = yearDebit.add(monthDebit); yearCredit = yearCredit.add(monthCredit); } rows.add(buildYearlyTotalRow(endMonth.atEndOfMonth(), yearDebit, yearCredit, runningBalance)); return rows; } private FinLedgerRowVo buildGeneralLedgerTotalRow(String subjectCode, YearMonth startMonth, YearMonth endMonth) { LocalDate startDate = startMonth.atDay(1); LocalDate endDate = endMonth.atEndOfMonth(); List<FinLedgerEntryRecordVo> openingEntries = finVoucherEntryMapper.listPostedEntriesBefore( subjectCode, startDate, null, null ); BigDecimal openingBalance = calculateBalance(openingEntries); List<FinLedgerEntryRecordVo> currentPeriodEntries = finVoucherEntryMapper.listPostedEntries( subjectCode, startDate, endDate, null, null ); BigDecimal totalDebit = ZERO; BigDecimal totalCredit = ZERO; for (FinLedgerEntryRecordVo entry : currentPeriodEntries) { totalDebit = totalDebit.add(money(entry.getDebit())); totalCredit = totalCredit.add(money(entry.getCredit())); } BigDecimal endingBalance = openingBalance.add(totalDebit).subtract(totalCredit); FinLedgerRowVo totalRow = new FinLedgerRowVo(); totalRow.setRowType("yearly_total"); totalRow.setDate(endDate); totalRow.setDebit(money(totalDebit)); totalRow.setCredit(money(totalCredit)); totalRow.setBalance(money(endingBalance)); totalRow.setDirection(resolveDirection(endingBalance)); return totalRow; } private Map<YearMonth, List<FinLedgerEntryRecordVo>> groupEntriesByMonth(List<FinLedgerEntryRecordVo> entries) { Map<YearMonth, List<FinLedgerEntryRecordVo>> map = new LinkedHashMap<>(); for (FinLedgerEntryRecordVo entry : entries) { if (entry.getVoucherDate() == null) { continue; } YearMonth month = YearMonth.from(entry.getVoucherDate()); map.computeIfAbsent(month, key -> new ArrayList<>()).add(entry); } return map; } private FinLedgerRowVo buildOpeningRow(LocalDate date, BigDecimal openingBalance) { FinLedgerRowVo row = new FinLedgerRowVo(); row.setRowType("opening"); row.setDate(date); row.setVoucherNo("-"); row.setSummary("æåä½é¢"); row.setDebit(ZERO); row.setCredit(ZERO); row.setBalance(money(openingBalance)); row.setDirection(resolveDirection(openingBalance)); return row; } private FinLedgerRowVo buildMonthlyTotalRow(LocalDate date, BigDecimal monthDebit, BigDecimal monthCredit, BigDecimal monthBalance) { FinLedgerRowVo row = new FinLedgerRowVo(); row.setRowType("monthly_total"); row.setDate(date); row.setVoucherNo("-"); row.setSummary("æ¬æå计"); row.setDebit(money(monthDebit)); row.setCredit(money(monthCredit)); row.setBalance(money(monthBalance)); row.setDirection(resolveDirection(monthBalance)); return row; } private FinLedgerRowVo buildYearlyTotalRow(LocalDate date, BigDecimal yearDebit, BigDecimal yearCredit, BigDecimal yearBalance) { FinLedgerRowVo row = new FinLedgerRowVo(); row.setRowType("yearly_total"); row.setDate(date); row.setVoucherNo("-"); row.setSummary("å计"); row.setDebit(money(yearDebit)); row.setCredit(money(yearCredit)); row.setBalance(money(yearBalance)); row.setDirection(resolveDirection(yearBalance)); return row; } private BigDecimal calculateBalance(List<FinLedgerEntryRecordVo> entries) { BigDecimal balance = ZERO; for (FinLedgerEntryRecordVo entry : entries) { balance = balance.add(money(entry.getDebit())).subtract(money(entry.getCredit())); } return money(balance); } private String resolveDirection(BigDecimal balance) { return money(balance).compareTo(BigDecimal.ZERO) >= 0 ? "å" : "è´·"; } private YearMonth parseMonth(String value, String fieldLabel) { if (StringUtils.isEmpty(value)) { throw new ServiceException(fieldLabel + "ä¸è½ä¸ºç©ºï¼æ ¼å¼åºä¸ºYYYY-MM"); } try { return YearMonth.parse(value, MONTH_FORMATTER); } catch (DateTimeParseException ex) { throw new ServiceException(fieldLabel + "æ ¼å¼éè¯¯ï¼æ ¼å¼åºä¸ºYYYY-MM"); } } private BigDecimal money(BigDecimal value) { if (value == null) { return ZERO; } return value.setScale(2, RoundingMode.HALF_UP); } } src/main/java/com/ruoyi/account/service/impl/financial/FinVoucherServiceImpl.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,324 @@ package com.ruoyi.account.service.impl.financial; 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.account.bean.dto.financial.FinVoucherDto; import com.ruoyi.account.bean.dto.financial.FinVoucherEntryDto; import com.ruoyi.account.bean.dto.financial.FinVoucherPageDto; import com.ruoyi.account.bean.vo.financial.FinVoucherDetailVo; import com.ruoyi.account.mapper.financial.AccountSubjectMapper; import com.ruoyi.account.mapper.financial.FinVoucherEntryMapper; import com.ruoyi.account.mapper.financial.FinVoucherMapper; import com.ruoyi.account.pojo.financial.AccountSubject; import com.ruoyi.account.pojo.financial.FinVoucher; import com.ruoyi.account.pojo.financial.FinVoucherEntry; import com.ruoyi.account.service.financial.FinVoucherService; import com.ruoyi.common.enums.FileNameType; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.other.service.impl.TempFileServiceImpl; import com.ruoyi.sales.service.impl.CommonFileServiceImpl; import lombok.RequiredArgsConstructor; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; /** * åè¯æå¡å®ç°ã */ @Service @RequiredArgsConstructor public class FinVoucherServiceImpl extends ServiceImpl<FinVoucherMapper, FinVoucher> implements FinVoucherService { private static final BigDecimal ZERO = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP); private final FinVoucherEntryMapper finVoucherEntryMapper; private final AccountSubjectMapper accountSubjectMapper; private final CommonFileServiceImpl commonFileService; @Override public IPage<FinVoucher> pageList(Page<FinVoucher> page, FinVoucherPageDto queryDto) { LambdaQueryWrapper<FinVoucher> wrapper = new LambdaQueryWrapper<>(); if (queryDto != null && StringUtils.isNotEmpty(queryDto.getVoucherNo())) { wrapper.like(FinVoucher::getVoucherNo, queryDto.getVoucherNo()); } if (queryDto != null && StringUtils.isNotEmpty(queryDto.getCreator())) { wrapper.eq(FinVoucher::getCreator, queryDto.getCreator()); } if (queryDto != null && StringUtils.isNotEmpty(queryDto.getStatus())) { wrapper.eq(FinVoucher::getStatus, queryDto.getStatus()); } if (queryDto != null && queryDto.getStartDate() != null) { wrapper.ge(FinVoucher::getVoucherDate, queryDto.getStartDate()); } if (queryDto != null && queryDto.getEndDate() != null) { wrapper.le(FinVoucher::getVoucherDate, queryDto.getEndDate()); } wrapper.orderByDesc(FinVoucher::getVoucherDate).orderByDesc(FinVoucher::getId); return page(page, wrapper); } @Override @Transactional(rollbackFor = Exception.class) public Boolean addVoucher(FinVoucherDto dto) { validateVoucherBasicInfo(dto, false); List<FinVoucherEntry> validEntries = buildAndValidateEntries(dto); FinVoucher voucher = new FinVoucher(); BeanUtils.copyProperties(dto, voucher); voucher.setStatus("unposted"); voucher.setAttachmentCount(voucher.getAttachmentCount() == null ? 0 : voucher.getAttachmentCount()); BigDecimal totalDebit = calculateTotalDebit(validEntries); BigDecimal totalCredit = calculateTotalCredit(validEntries); voucher.setDebit(totalDebit); voucher.setCredit(totalCredit); if (StringUtils.isEmpty(voucher.getSummary())) { voucher.setSummary(findDefaultSummary(validEntries)); } save(voucher); saveEntries(voucher.getId(), validEntries); // 5. ä¿åéä»¶ try { if(!CollectionUtils.isEmpty(dto.getTempFileIds())){ commonFileService.migrateTempFilesToFormal(voucher.getId(),dto.getTempFileIds()); } }catch (Exception e){ throw new ServiceException("ä¿åé件失败"); } return true; } @Override @Transactional(rollbackFor = Exception.class) public Boolean updateVoucher(FinVoucherDto dto) { validateVoucherBasicInfo(dto, true); FinVoucher existed = getById(dto.getId()); if (existed == null) { throw new ServiceException("ä¿®æ¹å¤±è´¥ï¼åè¯ä¸åå¨"); } if (!"unposted".equals(existed.getStatus())) { throw new ServiceException("ä» æªè¿è´¦åè¯å 许修æ¹"); } List<FinVoucherEntry> validEntries = buildAndValidateEntries(dto); FinVoucher voucher = new FinVoucher(); BeanUtils.copyProperties(dto, voucher); voucher.setStatus(existed.getStatus()); voucher.setAttachmentCount(voucher.getAttachmentCount() == null ? 0 : voucher.getAttachmentCount()); BigDecimal totalDebit = calculateTotalDebit(validEntries); BigDecimal totalCredit = calculateTotalCredit(validEntries); voucher.setDebit(totalDebit); voucher.setCredit(totalCredit); if (StringUtils.isEmpty(voucher.getSummary())) { voucher.setSummary(findDefaultSummary(validEntries)); } updateById(voucher); LambdaQueryWrapper<FinVoucherEntry> deleteWrapper = new LambdaQueryWrapper<>(); deleteWrapper.eq(FinVoucherEntry::getVoucherId, voucher.getId()); finVoucherEntryMapper.delete(deleteWrapper); saveEntries(voucher.getId(), validEntries); // 5. ä¿åéä»¶ try { if(!CollectionUtils.isEmpty(dto.getTempFileIds())){ commonFileService.migrateTempFilesToFormal(voucher.getId(),dto.getTempFileIds()); } }catch (Exception e){ throw new ServiceException("ä¿åé件失败"); } return true; } @Override @Transactional(rollbackFor = Exception.class) public Boolean postVoucher(Long id) { FinVoucher voucher = getById(id); if (voucher == null) { throw new ServiceException("è¿è´¦å¤±è´¥ï¼åè¯ä¸åå¨"); } if (!"unposted".equals(voucher.getStatus())) { throw new ServiceException("ä» æªè¿è´¦åè¯å 许è¿è´¦"); } voucher.setStatus("posted"); return updateById(voucher); } @Override @Transactional(rollbackFor = Exception.class) public Boolean cancelVoucher(Long id) { FinVoucher voucher = getById(id); if (voucher == null) { throw new ServiceException("ä½åºå¤±è´¥ï¼åè¯ä¸åå¨"); } if (!"unposted".equals(voucher.getStatus())) { throw new ServiceException("ä» æªè¿è´¦åè¯å 许ä½åº"); } voucher.setStatus("cancelled"); return updateById(voucher); } @Override public FinVoucherDetailVo detail(Long id) { FinVoucher voucher = getById(id); if (voucher == null) { throw new ServiceException("æ¥è¯¢å¤±è´¥ï¼åè¯ä¸åå¨"); } LambdaQueryWrapper<FinVoucherEntry> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(FinVoucherEntry::getVoucherId, id) .orderByAsc(FinVoucherEntry::getRowNo) .orderByAsc(FinVoucherEntry::getId); List<FinVoucherEntry> entries = finVoucherEntryMapper.selectList(wrapper); FinVoucherDetailVo vo = new FinVoucherDetailVo(); BeanUtils.copyProperties(voucher, vo); vo.setEntries(entries); vo.setSalesLedgerFiles(commonFileService.getFileListByBusinessId(id, FileNameType.FIN_VOUCHER.getValue())); return vo; } /** * æ ¡éªåè¯ä¸»è¡¨å段ãç¶æåæ®µä¸å¯ä¸æ§ã */ private void validateVoucherBasicInfo(FinVoucherDto dto, boolean isUpdate) { if (dto == null) { throw new ServiceException("åè¯æ°æ®ä¸è½ä¸ºç©º"); } if (isUpdate && dto.getId() == null) { throw new ServiceException("ä¿®æ¹å¤±è´¥ï¼åè¯IDä¸è½ä¸ºç©º"); } if (StringUtils.isEmpty(dto.getVoucherNo())) { throw new ServiceException("åè¯åå·ä¸è½ä¸ºç©º"); } if (dto.getVoucherDate() == null) { throw new ServiceException("åè¯æ¥æä¸è½ä¸ºç©º"); } LambdaQueryWrapper<FinVoucher> uniqueWrapper = new LambdaQueryWrapper<>(); uniqueWrapper.eq(FinVoucher::getVoucherNo, dto.getVoucherNo()); if (isUpdate) { uniqueWrapper.ne(FinVoucher::getId, dto.getId()); } if (count(uniqueWrapper) > 0) { throw new ServiceException("åè¯åå·å·²åå¨ï¼è¯·å¿éå¤æäº¤"); } } /** * è¿æ»¤ææåå½å¹¶æ§è¡åè´·å¹³è¡¡æ ¡éªã */ private List<FinVoucherEntry> buildAndValidateEntries(FinVoucherDto dto) { List<FinVoucherEntryDto> rawEntries = dto.getEntries(); if (rawEntries == null || rawEntries.isEmpty()) { throw new ServiceException("åå½ä¸è½ä¸ºç©ºï¼è³å°éè¦ä¸æ¡ææåå½"); } List<FinVoucherEntry> validEntries = new ArrayList<>(); int rowNo = 1; for (FinVoucherEntryDto entryDto : rawEntries) { if (entryDto == null || StringUtils.isEmpty(entryDto.getSubjectCode())) { continue; } BigDecimal debit = defaultMoney(entryDto.getDebit()); BigDecimal credit = defaultMoney(entryDto.getCredit()); if (debit.compareTo(BigDecimal.ZERO) <= 0 && credit.compareTo(BigDecimal.ZERO) <= 0) { continue; } if (debit.compareTo(BigDecimal.ZERO) > 0 && credit.compareTo(BigDecimal.ZERO) > 0) { throw new ServiceException("åå½åæ¹åè´·æ¹ä¸è½åæ¶å¤§äº0"); } FinVoucherEntry entry = new FinVoucherEntry(); BeanUtils.copyProperties(entryDto, entry); entry.setDebit(debit); entry.setCredit(credit); entry.setRowNo(rowNo++); validEntries.add(entry); } if (validEntries.isEmpty()) { throw new ServiceException("åå½è³å°éè¦ä¸æ¡ææè¡ï¼ç§ç®ä¸ç©ºï¼ä¸åæ¹æè´·æ¹å¤§äº0ï¼"); } // åå½ç§ç®å¿ é¡»åå¨ï¼é¿å èç§ç®ç¼ç å ¥è´¦ã Set<String> subjectCodes = validEntries.stream() .map(FinVoucherEntry::getSubjectCode) .filter(StringUtils::isNotEmpty) .collect(Collectors.toSet()); if (subjectCodes.isEmpty()) { throw new ServiceException("åå½ç§ç®ä¸è½ä¸ºç©º"); } LambdaQueryWrapper<AccountSubject> subjectWrapper = new LambdaQueryWrapper<>(); subjectWrapper.in(AccountSubject::getSubjectCode, subjectCodes); List<AccountSubject> subjects = accountSubjectMapper.selectList(subjectWrapper); Map<String, AccountSubject> subjectMap = subjects.stream() .collect(Collectors.toMap(AccountSubject::getSubjectCode, it -> it, (a, b) -> a)); for (FinVoucherEntry entry : validEntries) { AccountSubject accountSubject = subjectMap.get(entry.getSubjectCode()); if (accountSubject == null) { throw new ServiceException("ç§ç®ç¼ç ä¸åå¨ï¼" + entry.getSubjectCode()); } if (StringUtils.isEmpty(entry.getSubjectName())) { entry.setSubjectName(accountSubject.getSubjectName()); } } BigDecimal totalDebit = calculateTotalDebit(validEntries); BigDecimal totalCredit = calculateTotalCredit(validEntries); if (totalDebit.compareTo(BigDecimal.ZERO) <= 0 || totalCredit.compareTo(BigDecimal.ZERO) <= 0) { throw new ServiceException("åè´·éé¢å¿ 须大äº0"); } if (totalDebit.compareTo(totalCredit) != 0) { throw new ServiceException("åè´·ä¸å¹³è¡¡ï¼ç¦æ¢ä¿å"); } return validEntries; } private void saveEntries(Long voucherId, List<FinVoucherEntry> entries) { if (voucherId == null) { throw new ServiceException("åè¯IDä¸è½ä¸ºç©º"); } for (FinVoucherEntry entry : entries) { entry.setVoucherId(voucherId); finVoucherEntryMapper.insert(entry); } } private String findDefaultSummary(List<FinVoucherEntry> entries) { for (FinVoucherEntry entry : entries) { if (StringUtils.isNotEmpty(entry.getSummary())) { return entry.getSummary(); } } return ""; } private BigDecimal calculateTotalDebit(List<FinVoucherEntry> entries) { BigDecimal total = BigDecimal.ZERO; for (FinVoucherEntry entry : entries) { total = total.add(defaultMoney(entry.getDebit())); } return total.setScale(2, RoundingMode.HALF_UP); } private BigDecimal calculateTotalCredit(List<FinVoucherEntry> entries) { BigDecimal total = BigDecimal.ZERO; for (FinVoucherEntry entry : entries) { total = total.add(defaultMoney(entry.getCredit())); } return total.setScale(2, RoundingMode.HALF_UP); } private BigDecimal defaultMoney(BigDecimal value) { if (value == null) { return ZERO; } return value.setScale(2, RoundingMode.HALF_UP); } } src/main/java/com/ruoyi/common/enums/FileNameType.java
@@ -17,7 +17,8 @@ INSPECTION_PRODUCTION_BEFORE(10), INSPECTION_PRODUCTION_AFTER(11), INSPECTION(12),//å·¡æ£ ç产å APP(13); APP(13), FIN_VOUCHER(14); private final int value; src/main/java/com/ruoyi/device/mapper/DeviceLedgerMapper.java
@@ -4,8 +4,7 @@ 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.account.bean.dto.DeviceTypeDetail; import com.ruoyi.device.dto.DeviceLedgerDto; import com.ruoyi.device.execl.DeviceLedgerExeclDto; import com.ruoyi.device.pojo.DeviceLedger; src/main/java/com/ruoyi/procurementrecord/service/impl/ReturnManagementServiceImpl.java
@@ -1,13 +1,11 @@ package com.ruoyi.procurementrecord.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 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.account.dto.SalesRefundAmountOrderDto; import com.ruoyi.account.bean.dto.SalesRefundAmountOrderDto; import com.ruoyi.account.mapper.AccountExpenseMapper; import com.ruoyi.account.pojo.AccountExpense; import com.ruoyi.account.pojo.SalesRefundAmountOrder; import com.ruoyi.account.service.SalesRefundAmountOrderService; import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum; import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum; src/main/resources/application-dev.yml
@@ -74,7 +74,7 @@ druid: # ä¸»åºæ°æ®æº master: url: jdbc:mysql://localhost:3306/product-inventory-management-new?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 url: jdbc:mysql://localhost:3306/product-inventory-management-fbdzsw?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 username: root password: 123456 # ä»åºæ°æ®æº src/main/resources/mapper/account/AccountExpenseMapper.xml
@@ -45,7 +45,7 @@ AND expense_method = #{accountExpense.expenseMethod} </if> </select> <select id="report" resultType="com.ruoyi.account.dto.AccountDto2"> <select id="report" resultType="com.ruoyi.account.bean.dto.AccountDto2"> SELECT sdd.dict_label typeName, sum(expense_money) account src/main/resources/mapper/account/AccountIncomeMapper.xml
@@ -47,7 +47,7 @@ AND income_method = #{accountIncome.incomeMethod} </if> </select> <select id="report" resultType="com.ruoyi.account.dto.AccountDto2"> <select id="report" resultType="com.ruoyi.account.bean.dto.AccountDto2"> SELECT sdd.dict_label typeName, ifnull(sum(income_money),0) account src/main/resources/mapper/account/SalesRefundAmountOrderMapper.xml
@@ -15,7 +15,7 @@ <result column="create_user_id" property="createUserId" /> <result column="update_user_id" property="updateUserId" /> </resultMap> <select id="pageSalesRefundAmountOrderDto" resultType="com.ruoyi.account.dto.SalesRefundAmountOrderDto"> <select id="pageSalesRefundAmountOrderDto" resultType="com.ruoyi.account.bean.dto.SalesRefundAmountOrderDto"> select sl.sales_contract_no, sl.customer_contract_no, slp.specification_model, src/main/resources/mapper/account/financial/AccountSubjectMapper.xml
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,31 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.ruoyi.account.mapper.financial.AccountSubjectMapper"> <!-- éç¨æ¥è¯¢æ å°ç»æ --> <resultMap id="BaseResultMap" type="com.ruoyi.account.pojo.financial.AccountSubject"> <id column="id" property="id" /> <result column="parent_id" property="parentId" /> <result column="subject_code" property="subjectCode" /> <result column="subject_name" property="subjectName" /> <result column="subject_type" property="subjectType" /> <result column="balance_direction" property="balanceDirection" /> <result column="status" property="status" /> <result column="remark" property="remark" /> <result column="create_user" property="createUser" /> <result column="create_time" property="createTime" /> <result column="update_user" property="updateUser" /> <result column="update_time" property="updateTime" /> <result column="dept_id" property="deptId" /> </resultMap> <select id="countReferencedBySubjectCodes" resultType="java.lang.Long"> SELECT COUNT(1) FROM fin_voucher_entry WHERE subject_code IN <foreach collection="subjectCodes" item="item" open="(" separator="," close=")"> #{item} </foreach> </select> </mapper> src/main/resources/mapper/account/financial/FinVoucherEntryMapper.xml
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,74 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.ruoyi.account.mapper.financial.FinVoucherEntryMapper"> <resultMap id="BaseResultMap" type="com.ruoyi.account.pojo.financial.FinVoucherEntry"> <id column="id" property="id"/> <result column="voucher_id" property="voucherId"/> <result column="row_no" property="rowNo"/> <result column="subject_code" property="subjectCode"/> <result column="subject_name" property="subjectName"/> <result column="summary" property="summary"/> <result column="debit" property="debit"/> <result column="credit" property="credit"/> <result column="auxiliary_type" property="auxiliaryType"/> <result column="auxiliary_id" property="auxiliaryId"/> <result column="auxiliary_name" property="auxiliaryName"/> <result column="create_user" property="createUser"/> <result column="create_time" property="createTime"/> <result column="update_user" property="updateUser"/> <result column="update_time" property="updateTime"/> <result column="dept_id" property="deptId"/> </resultMap> <select id="listPostedEntries" resultType="com.ruoyi.account.bean.vo.financial.FinLedgerEntryRecordVo"> SELECT v.voucher_date AS voucherDate, v.voucher_no AS voucherNo, CASE WHEN e.summary IS NOT NULL AND e.summary != '' THEN e.summary ELSE v.summary END AS summary, e.debit AS debit, e.credit AS credit, e.row_no AS rowNo FROM fin_voucher_entry e INNER JOIN fin_voucher v ON e.voucher_id = v.id WHERE v.status = 'posted' AND (e.subject_code = #{subjectCode} OR e.subject_code LIKE CONCAT(#{subjectCode}, '%')) AND v.voucher_date <![CDATA[>=]]> #{startDate} AND v.voucher_date <![CDATA[<=]]> #{endDate} <if test="auxiliaryType != null and auxiliaryType != ''"> AND e.auxiliary_type = #{auxiliaryType} </if> <if test="auxiliaryId != null and auxiliaryId != ''"> AND e.auxiliary_id = #{auxiliaryId} </if> ORDER BY v.voucher_date ASC, v.id ASC, e.row_no ASC, e.id ASC </select> <select id="listPostedEntriesBefore" resultType="com.ruoyi.account.bean.vo.financial.FinLedgerEntryRecordVo"> SELECT v.voucher_date AS voucherDate, v.voucher_no AS voucherNo, CASE WHEN e.summary IS NOT NULL AND e.summary != '' THEN e.summary ELSE v.summary END AS summary, e.debit AS debit, e.credit AS credit, e.row_no AS rowNo FROM fin_voucher_entry e INNER JOIN fin_voucher v ON e.voucher_id = v.id WHERE v.status = 'posted' AND (e.subject_code = #{subjectCode} OR e.subject_code LIKE CONCAT(#{subjectCode}, '%')) AND v.voucher_date <![CDATA[<]]> #{beforeDate} <if test="auxiliaryType != null and auxiliaryType != ''"> AND e.auxiliary_type = #{auxiliaryType} </if> <if test="auxiliaryId != null and auxiliaryId != ''"> AND e.auxiliary_id = #{auxiliaryId} </if> </select> </mapper> src/main/resources/mapper/device/DeviceLedgerMapper.xml
@@ -88,7 +88,7 @@ where id = #{id} </select> <select id="getDeviceTypeDistributionByYear" resultType="com.ruoyi.account.dto.DeviceTypeDetail" resultType="com.ruoyi.account.bean.dto.DeviceTypeDetail" parameterType="java.lang.Integer"> SELECT `type`,