yaowanxin
2025-08-11 1b5604f8a88000e2f51d4c989fd179989468ee67
Merge remote-tracking branch 'origin/pim_yys' into pim_ywx
已修改28个文件
已添加24个文件
2549 ■■■■■ 文件已修改
pom.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/controller/AccountExpenseController.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/dto/AccountDto2.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/dto/AccountDto3.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/mapper/AccountExpenseMapper.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/mapper/AccountIncomeMapper.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/service/AccountExpenseService.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/service/AccountIncomeService.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/service/impl/AccountExpenseServiceImpl.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/service/impl/AccountIncomeServiceImpl.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/controller/ApproveNodeController.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/pojo/ApproveNode.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/service/IApproveNodeService.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/common/enums/FileNameType.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/common/utils/HackLoopTableRenderPolicy.java 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/compensationperformance/controller/CompensationPerformanceController.java 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/compensationperformance/mapper/CompensationPerformanceMapper.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/compensationperformance/pojo/CompensationPerformance.java 230 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/compensationperformance/service/CompensationPerformanceService.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/compensationperformance/service/impl/CompensationPerformanceServiceImpl.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/framework/config/MybatisPlusConfig.java 42 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/measuringinstrumentledger/controller/MeasuringInstrumentLedgerController.java 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/measuringinstrumentledger/controller/MeasuringInstrumentLedgerRecordController.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/measuringinstrumentledger/dto/MeasuringInstrumentLedgerDto.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/measuringinstrumentledger/mapper/MeasuringInstrumentLedgerMapper.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/measuringinstrumentledger/mapper/MeasuringInstrumentLedgerRecordMapper.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/measuringinstrumentledger/pojo/MeasuringInstrumentLedger.java 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/measuringinstrumentledger/pojo/MeasuringInstrumentLedgerRecord.java 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/measuringinstrumentledger/service/MeasuringInstrumentLedgerRecordService.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/measuringinstrumentledger/service/MeasuringInstrumentLedgerService.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/measuringinstrumentledger/service/impl/MeasuringInstrumentLedgerRecordServiceImpl.java 175 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/measuringinstrumentledger/service/impl/MeasuringInstrumentLedgerServiceImpl.java 220 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/other/service/impl/TempFileServiceImpl.java 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/controller/SysLoginController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/pojo/TicketRegistration.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/service/impl/TicketRegistrationServiceImpl.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/controller/QualityInspectController.java 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/controller/QualityTestStandardController.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/dto/QualityInspectDto.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/pojo/QualityInspect.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/pojo/QualityInspectParam.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/service/IQualityInspectService.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java 142 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-demo.yml 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/account/AccountExpenseMapper.xml 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/account/AccountIncomeMapper.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/approve/ApproveProcessMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/compensationperformance/CompensationPerformanceMapper.xml 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/measuringinstrumentledger/MeasuringInstrumentLedgerMapper.xml 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/measuringinstrumentledger/MeasuringInstrumentLedgerRecordMapper.xml 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/report-template.docx 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml
@@ -224,6 +224,7 @@
            <version>${poi.version}</version>
        </dependency>
        <!-- velocity代码生成使用模板 -->
        <dependency>
            <groupId>org.apache.velocity</groupId>
@@ -282,6 +283,12 @@
            <version>${okhttp.version}</version>
        </dependency>
        <dependency>
            <groupId>com.deepoove</groupId>
            <artifactId>poi-tl</artifactId>
            <version>1.12.2</version>
        </dependency>
    </dependencies>
    <build>
src/main/java/com/ruoyi/account/controller/AccountExpenseController.java
@@ -1,6 +1,7 @@
package com.ruoyi.account.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.account.mapper.AccountIncomeMapper;
import com.ruoyi.account.pojo.AccountExpense;
import com.ruoyi.account.pojo.AccountIncome;
import com.ruoyi.account.service.AccountExpenseService;
@@ -27,6 +28,9 @@
    @Resource
    private AccountExpenseService accountExpenseService;
    @Resource
    private AccountIncomeService accountIncomeService;
    /**
@@ -107,5 +111,25 @@
        return AjaxResult.success(accountExpenseService.report(dateQueryDto));
    }
    /**
     * è´¢åŠ¡æŠ¥è¡¨å›¾è¡¨æ”¶å…¥å¹´åº¦æŸ¥è¯¢
     * @param
     * @return
     */
    @GetMapping("/report/income")
    public AjaxResult reportIncome() {
        return AjaxResult.success(accountIncomeService.reportIncome());
    }
    /**
     * è´¢åŠ¡æŠ¥è¡¨å›¾è¡¨æ”¯å‡ºå¹´åº¦æŸ¥è¯¢
     * @param
     * @return
     */
    @GetMapping("/report/expense")
    public AjaxResult reportExpense() {
        return AjaxResult.success(accountExpenseService.reportExpense());
    }
}
src/main/java/com/ruoyi/account/dto/AccountDto2.java
@@ -22,6 +22,12 @@
    private String typeName;
    /**
     * ç™¾åˆ†å æ¯”
     */
    private BigDecimal proportion;
    /**
     * é‡‘额
src/main/java/com/ruoyi/account/dto/AccountDto3.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,39 @@
package com.ruoyi.account.dto;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
/**
 * è´¢åŠ¡ç®¡ç†--财务报表(类型)
 */
@Data
public class AccountDto3 implements Serializable {
    /**
     * ç±»åž‹
     */
    private String typeName;
    /**
     * ç™¾åˆ†å æ¯”
     */
    private BigDecimal proportion;
    /**
     * é‡‘额
     */
    private List<BigDecimal> account;
}
src/main/java/com/ruoyi/account/mapper/AccountExpenseMapper.java
@@ -23,4 +23,5 @@
    List<AccountDto2> report(@Param("dateQueryDto") DateQueryDto dateQueryDto);
    BigDecimal report1(@Param("dateQueryDto") DateQueryDto dateQueryDto, @Param("dictValue") String dictValue);
}
src/main/java/com/ruoyi/account/mapper/AccountIncomeMapper.java
@@ -22,4 +22,5 @@
    List<AccountIncome> accountIncomeExport(@Param("accountIncome") AccountIncome accountIncome);
    List<AccountDto2> report(@Param("dateQueryDto") DateQueryDto dateQueryDto);
    BigDecimal report1(@Param("dateQueryDto") DateQueryDto dateQueryDto, @Param("dictValue") String dictValue);
}
src/main/java/com/ruoyi/account/service/AccountExpenseService.java
@@ -4,11 +4,13 @@
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.pojo.AccountExpense;
import com.ruoyi.account.pojo.AccountIncome;
import com.ruoyi.dto.DateQueryDto;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
public interface AccountExpenseService extends IService<AccountExpense> {
@@ -17,4 +19,6 @@
    void accountExpenseExport(HttpServletResponse response, AccountExpense accountExpense);
    AccountDto report(DateQueryDto dateQueryDto);
    List<AccountDto3> reportExpense();
}
src/main/java/com/ruoyi/account/service/AccountIncomeService.java
@@ -3,10 +3,12 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.account.pojo.AccountFile;
import com.ruoyi.account.dto.AccountDto2;
import com.ruoyi.account.dto.AccountDto3;
import com.ruoyi.account.pojo.AccountIncome;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
public interface AccountIncomeService extends IService<AccountIncome> {
@@ -14,4 +16,6 @@
    IPage<AccountIncome> accountIncomeListPage(Page page, AccountIncome accountIncome);
    void accountIncomeExport(HttpServletResponse response, AccountIncome accountIncome);
    List<AccountDto3> reportIncome();
}
src/main/java/com/ruoyi/account/service/impl/AccountExpenseServiceImpl.java
@@ -7,20 +7,25 @@
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.mapper.AccountExpenseMapper;
import com.ruoyi.account.mapper.AccountFileMapper;
import com.ruoyi.account.mapper.AccountIncomeMapper;
import com.ruoyi.account.pojo.AccountExpense;
import com.ruoyi.account.pojo.AccountIncome;
import com.ruoyi.account.service.AccountExpenseService;
import com.ruoyi.account.service.AccountIncomeService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.dto.DateQueryDto;
import com.ruoyi.project.system.domain.SysDictData;
import com.ruoyi.project.system.mapper.SysDictDataMapper;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
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;
@@ -31,6 +36,8 @@
    private AccountExpenseMapper accountExpenseMapper;
    private AccountIncomeMapper accountIncomeMapper;
    private SysDictDataMapper sysDictDataMapper;
    //分页查询
@@ -53,12 +60,16 @@
        AccountDto accountDto = new AccountDto();
        //获取该段时间内的所有收入
        List<AccountDto2> accountIncomes =accountIncomeMapper.report(dateQueryDto);
        accountDto.setIncomeType(accountIncomes);
        Long incomeNumber = accountIncomeMapper.selectCount(Wrappers.<AccountIncome>lambdaQuery()
                .between(AccountIncome::getIncomeDate, dateQueryDto.getEntryDateStart(), dateQueryDto.getEntryDateEnd()));
        accountDto.setIncomeNumber(incomeNumber);
        BigDecimal totalIncome = accountIncomes.stream().map(AccountDto2::getAccount).reduce(BigDecimal.ZERO, BigDecimal::add);
        accountDto.setTotalIncome(totalIncome);
        accountIncomes.stream().forEach(accountDto2 -> {
            accountDto2.setProportion(accountDto2.getAccount().divide(totalIncome,2,BigDecimal.ROUND_HALF_UP));
        });
        accountDto.setIncomeType(accountIncomes);
        //获取该段时间内的所有支出
        List<AccountDto2> accountExpenses =accountExpenseMapper.report(dateQueryDto);
        accountDto.setExpenseType(accountExpenses);
@@ -67,11 +78,42 @@
        accountDto.setExpenseNumber(expenseNumber);
        BigDecimal totalExpense = accountExpenses.stream().map(AccountDto2::getAccount).reduce(BigDecimal.ZERO, BigDecimal::add);
        accountDto.setTotalExpense(totalExpense);
        accountExpenses.stream().forEach(accountDto2 -> {
            accountDto2.setProportion(accountDto2.getAccount().divide(totalExpense,2,BigDecimal.ROUND_HALF_UP));
        });
        accountDto.setExpenseType(accountExpenses);
        //净收入
        BigDecimal netRevenue = totalIncome.subtract(totalExpense);
        accountDto.setNetRevenue(netRevenue);
        return accountDto;
    }
    //财务报表年查询
    @Override
    public  List<AccountDto3> reportExpense() {
        List<AccountDto3> accountDto3s = new ArrayList<>();
        //先查询收入类型有哪些
        List<SysDictData> incomeTypes = sysDictDataMapper.selectDictDataByType("expense_types");
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        int currentYear = LocalDate.now().getYear(); // èŽ·å–å½“å‰å¹´ä»½ï¼ˆå¦‚2025)
        for (SysDictData incomeType : incomeTypes) {
            AccountDto3 accountDto3 = new AccountDto3();
            accountDto3.setTypeName(incomeType.getDictLabel());//类型
            List<BigDecimal> account=new ArrayList<>();
            for (int i = 1; i <= 12; i++) {
                // å½“月第一天:年份为当前年,月份为i,日期为1
                LocalDate firstDay = LocalDate.of(currentYear, i, 1);
                DateQueryDto dateQueryDto = new DateQueryDto();
                dateQueryDto.setEntryDateStart(firstDay.format(formatter));
                // å½“月最后一天:第一天的月份的最后一天
                dateQueryDto.setEntryDateEnd(firstDay.plusMonths(1).minusDays(1).format(formatter));
                account.add(accountExpenseMapper.report1(dateQueryDto,incomeType.getDictValue()));
            }
            accountDto3.setAccount(account);//类型
            accountDto3s.add(accountDto3);
        }
        return accountDto3s;
    }
}
src/main/java/com/ruoyi/account/service/impl/AccountIncomeServiceImpl.java
@@ -4,25 +4,34 @@
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.mapper.AccountFileMapper;
import com.ruoyi.account.dto.AccountDto2;
import com.ruoyi.account.dto.AccountDto3;
import com.ruoyi.account.mapper.AccountIncomeMapper;
import com.ruoyi.account.pojo.AccountFile;
import com.ruoyi.account.pojo.AccountIncome;
import com.ruoyi.account.service.AccountFileService;
import com.ruoyi.account.service.AccountIncomeService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.quality.pojo.QualityInspect;
import com.ruoyi.dto.DateQueryDto;
import com.ruoyi.project.system.domain.SysDictData;
import com.ruoyi.project.system.mapper.SysDictDataMapper;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
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
public class AccountIncomeServiceImpl extends ServiceImpl<AccountIncomeMapper, AccountIncome> implements AccountIncomeService {
    private AccountIncomeMapper accountIncomeMapper;
    private SysDictDataMapper sysDictDataMapper;
    //分页查询
@@ -38,4 +47,31 @@
        ExcelUtil<AccountIncome> util = new ExcelUtil<AccountIncome>(AccountIncome.class);
        util.exportExcel(response, accountIncomes, "收入管理导出");
    }
    //财务报表年查询
    @Override
    public List<AccountDto3> reportIncome() {
        List<AccountDto3> accountDto3s = new ArrayList<>();
        //先查询收入类型有哪些
        List<SysDictData> incomeTypes = sysDictDataMapper.selectDictDataByType("income_types");
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        int currentYear = LocalDate.now().getYear(); // èŽ·å–å½“å‰å¹´ä»½ï¼ˆå¦‚2025)
        for (SysDictData incomeType : incomeTypes) {
            AccountDto3 accountDto3 = new AccountDto3();
            accountDto3.setTypeName(incomeType.getDictLabel());//类型
            List<BigDecimal> account=new ArrayList<>();
            for (int i = 1; i <= 12; i++) {
                // å½“月第一天:年份为当前年,月份为i,日期为1
                LocalDate firstDay = LocalDate.of(currentYear, i, 1);
                DateQueryDto dateQueryDto = new DateQueryDto();
                dateQueryDto.setEntryDateStart(firstDay.format(formatter));
                // å½“月最后一天:第一天的月份的最后一天
                dateQueryDto.setEntryDateEnd(firstDay.plusMonths(1).minusDays(1).format(formatter));
                account.add(accountIncomeMapper.report1(dateQueryDto,incomeType.getDictValue()));
            }
            accountDto3.setAccount(account);//类型
            accountDto3s.add(accountDto3);
        }
        return accountDto3s;
    }
}
src/main/java/com/ruoyi/approve/controller/ApproveNodeController.java
@@ -3,9 +3,15 @@
import com.ruoyi.approve.pojo.ApproveNode;
import com.ruoyi.approve.service.IApproveNodeService;
import com.ruoyi.framework.web.domain.AjaxResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
@Api(tags = "审批记录")
@RestController
@RequestMapping("/approveNode")
public class ApproveNodeController {
@@ -18,6 +24,7 @@
     * @return
     */
    @GetMapping("/details/{id}")
    @ApiOperation(value = "流程状态详情")
    public AjaxResult details(@PathVariable String id) {
        return AjaxResult.success(approveNodeService.details(id));
    }
@@ -28,7 +35,9 @@
     * @return
     */
    @PostMapping("/updateApproveNode")
    public AjaxResult updateApproveNode(@RequestBody ApproveNode approveNode) {
    @Transactional(rollbackFor = Exception.class)
    @ApiOperation(value = "审批节点")
    public AjaxResult updateApproveNode(@RequestBody ApproveNode approveNode) throws IOException {
        approveNodeService.updateApproveNode(approveNode);
        return AjaxResult.success();
    }
src/main/java/com/ruoyi/approve/pojo/ApproveNode.java
@@ -3,11 +3,15 @@
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.sales.pojo.CommonFile;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
@@ -16,7 +20,18 @@
 */
@Data
@TableName("approve_node")
@ApiModel
public class ApproveNode{
    @ApiModelProperty("附件id")
    @TableField(exist = false)
    private List<String> tempFileIds;
    @TableField(exist = false)
    @ApiModelProperty("附件列表")
    private String url;
    /**
     * 
     */
src/main/java/com/ruoyi/approve/service/IApproveNodeService.java
@@ -3,6 +3,7 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.approve.pojo.ApproveNode;
import java.io.IOException;
import java.util.List;
public interface IApproveNodeService extends IService<ApproveNode> {
@@ -14,7 +15,7 @@
     */
    List<ApproveNode> details(String id);
    void updateApproveNode(ApproveNode approveNode);
    void updateApproveNode(ApproveNode approveNode) throws IOException;
    void delApproveNodeByApproveId(Long id);
}
src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java
@@ -8,13 +8,20 @@
import com.ruoyi.approve.pojo.ApproveNode;
import com.ruoyi.approve.pojo.ApproveProcess;
import com.ruoyi.approve.service.IApproveNodeService;
import com.ruoyi.common.enums.FileNameType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.other.service.impl.TempFileServiceImpl;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.sales.mapper.CommonFileMapper;
import com.ruoyi.sales.pojo.CommonFile;
import com.ruoyi.sales.service.impl.CommonFileServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.Date;
@@ -30,6 +37,12 @@
    private ApproveProcessMapper approveProcessMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private TempFileServiceImpl tempFileService;
    @Autowired
    private CommonFileMapper fileMapper;
    public ApproveProcess getApproveById(String id) {
@@ -87,6 +100,12 @@
            return list;
        }
        for (ApproveNode approveNode : list) {
            List<CommonFile> commonFiles = fileMapper.selectList(new LambdaQueryWrapper<CommonFile>()
                    .eq(CommonFile::getCommonId, approveNode.getId())
                    .eq(CommonFile::getType, FileNameType.ApproveNode.getValue()));
            if(!CollectionUtils.isEmpty(commonFiles)){
                approveNode.setUrl(commonFiles.get(0).getUrl());
            }
            if(approveNode.getApproveNodeStatus() == 1){
                continue;
            }
@@ -96,7 +115,7 @@
        return list;
    }
    public void updateApproveProcessStatus(ApproveNode approveNode,Integer status) {
    public void updateApproveProcessStatus(ApproveNode approveNode,Integer status) throws IOException {
        LambdaQueryWrapper<ApproveProcess> approveProcessLambdaQueryWrapper = new LambdaQueryWrapper<>();
        approveProcessLambdaQueryWrapper.eq(ApproveProcess::getApproveId, approveNode.getApproveProcessId())
                .eq(ApproveProcess::getApproveDelete, 0)
@@ -117,10 +136,15 @@
            approveProcess.setApproveUserCurrentName(approveNode1.getApproveNodeUser());
        }
        approveProcessMapper.updateById(approveProcess);
        // ç»‘定附件
        if(!CollectionUtils.isEmpty(approveNode.getTempFileIds()) && approveNode.getApproveNodeStatus() == 1){
            tempFileService.migrateTempFilesToFormal(approveNode.getId(), approveNode.getTempFileIds(), FileNameType.ApproveNode.getValue());
        }
    }
    @Override
    public void updateApproveNode(ApproveNode approveNode) {
    public void updateApproveNode(ApproveNode approveNode) throws IOException {
        // å®¡æ‰¹èŠ‚ç‚¹çŠ¶æ€:1同意,2拒绝,0尚未审核
        switch (approveNode.getApproveNodeStatus()){
            case 1:
src/main/java/com/ruoyi/common/enums/FileNameType.java
@@ -5,7 +5,10 @@
    SALE(1),      // é”€å”®
    PURCHASE(2),  // é‡‡è´­
    INVOICE(3),     //发票
    PURCHASELEDGER(4);  //
    PURCHASELEDGER(4),
    MEASURING(5),  //计量器具台账
    MEASURINGRecord(6),//计量器具台账记录
    ApproveNode(7);  //协同审批审核
    private final int value;
src/main/java/com/ruoyi/common/utils/HackLoopTableRenderPolicy.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,154 @@
/*
 * Copyright 2014-2020 Sayi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.ruoyi.common.utils;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.exception.RenderException;
import com.deepoove.poi.policy.RenderPolicy;
import com.deepoove.poi.render.compute.RenderDataCompute;
import com.deepoove.poi.render.processor.DocumentProcessor;
import com.deepoove.poi.resolver.TemplateResolver;
import com.deepoove.poi.template.ElementTemplate;
import com.deepoove.poi.template.MetaTemplate;
import com.deepoove.poi.template.run.RunTemplate;
import com.deepoove.poi.util.ReflectionUtils;
import com.deepoove.poi.util.TableTools;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;
import java.util.Iterator;
import java.util.List;
/**
 * Hack for loop table row
 *
 * @author
 *
 */
public class HackLoopTableRenderPolicy implements RenderPolicy {
    private String prefix;
    private String suffix;
    private boolean onSameLine;
    public HackLoopTableRenderPolicy() {
        this(false);
    }
    public HackLoopTableRenderPolicy(boolean onSameLine) {
        this("[", "]", onSameLine);
    }
    public HackLoopTableRenderPolicy(String prefix, String suffix) {
        this(prefix, suffix, false);
    }
    public HackLoopTableRenderPolicy(String prefix, String suffix, boolean onSameLine) {
        this.prefix = prefix;
        this.suffix = suffix;
        this.onSameLine = onSameLine;
    }
    @Override
    public void render(ElementTemplate eleTemplate, Object data, XWPFTemplate template) {
        RunTemplate runTemplate = (RunTemplate) eleTemplate;
        XWPFRun run = runTemplate.getRun();
        try {
            if (!TableTools.isInsideTable(run)) {
                throw new IllegalStateException(
                        "The template tag " + runTemplate.getSource() + " must be inside a table");
            }
            XWPFTableCell tagCell = (XWPFTableCell) ((XWPFParagraph) run.getParent()).getBody();
            XWPFTable table = tagCell.getTableRow().getTable();
            run.setText("", 0);
            int templateRowIndex = getTemplateRowIndex(tagCell);
            if (null != data && data instanceof Iterable) {
                Iterator<?> iterator = ((Iterable<?>) data).iterator();
                XWPFTableRow templateRow = table.getRow(templateRowIndex);
                int insertPosition = templateRowIndex;
                TemplateResolver resolver = new TemplateResolver(template.getConfig().copy(prefix, suffix));
                boolean firstFlag = true;
                while (iterator.hasNext()) {
                    insertPosition = templateRowIndex++;
                    XWPFTableRow nextRow = table.insertNewTableRow(insertPosition);
                    setTableRow(table, templateRow, insertPosition);
                    // double set row
                    XmlCursor newCursor = templateRow.getCtRow().newCursor();
                    newCursor.toPrevSibling();
                    XmlObject object = newCursor.getObject();
                    nextRow = new XWPFTableRow((CTRow) object, table);
                    if (!firstFlag) {
                        // update VMerge cells for non-first row
                        List<XWPFTableCell> tableCells = nextRow.getTableCells();
                        for (XWPFTableCell cell : tableCells) {
                            CTTcPr tcPr = TableTools.getTcPr(cell);
                            CTVMerge vMerge = tcPr.getVMerge();
                            if (null == vMerge) continue;
                            if (STMerge.RESTART == vMerge.getVal()) {
                                vMerge.setVal(STMerge.CONTINUE);
                            }
                        }
                    } else {
                        firstFlag = false;
                    }
                    setTableRow(table, nextRow, insertPosition);
                    RenderDataCompute dataCompute = template.getConfig().getRenderDataComputeFactory()
                            .newCompute(iterator.next());
                    List<XWPFTableCell> cells = nextRow.getTableCells();
                    cells.forEach(cell -> {
                        List<MetaTemplate> templates = resolver.resolveBodyElements(cell.getBodyElements());
                        new DocumentProcessor(template, resolver, dataCompute).process(templates);
                    });
                }
            }
            table.removeRow(templateRowIndex);
            afterloop(table, data);
        } catch (Exception e) {
            throw new RenderException("HackLoopTable for " + eleTemplate + "error: " + e.getMessage(), e);
        }
    }
    private int getTemplateRowIndex(XWPFTableCell tagCell) {
        XWPFTableRow tagRow = tagCell.getTableRow();
        return onSameLine ? getRowIndex(tagRow) : (getRowIndex(tagRow) + 1);
    }
    protected void afterloop(XWPFTable table, Object data) {
    }
    @SuppressWarnings("unchecked")
    private void setTableRow(XWPFTable table, XWPFTableRow templateRow, int pos) {
        List<XWPFTableRow> rows = (List<XWPFTableRow>) ReflectionUtils.getValue("tableRows", table);
        rows.set(pos, templateRow);
        table.getCTTbl().setTrArray(pos, templateRow.getCtRow());
    }
    private int getRowIndex(XWPFTableRow row) {
        List<XWPFTableRow> rows = row.getTable().getRows();
        return rows.indexOf(row);
    }
}
src/main/java/com/ruoyi/compensationperformance/controller/CompensationPerformanceController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,69 @@
package com.ruoyi.compensationperformance.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.compensationperformance.pojo.CompensationPerformance;
import com.ruoyi.compensationperformance.service.CompensationPerformanceService;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
 * @author :yys
 * @date : 2025/8/8 9:56
 */
@RestController
@Api(tags = "薪酬绩效")
@RequestMapping("/compensationPerformance")
public class CompensationPerformanceController extends BaseController {
    @Autowired
    private CompensationPerformanceService compensationPerformanceService;
    @GetMapping("/listPage")
    @Log(title = "薪酬绩效-分页查询", businessType = BusinessType.OTHER)
    @ApiOperation("薪酬绩效-分页查询")
    public AjaxResult listPage(Page page, CompensationPerformance compensationPerformance){
        IPage<CompensationPerformance> listPage = compensationPerformanceService.listPage(page, compensationPerformance);
        return AjaxResult.success(listPage);
    }
    @PostMapping("/add")
    @Log(title = "薪酬绩效-添加", businessType = BusinessType.INSERT)
    @ApiOperation("薪酬绩效-添加")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult add(@RequestBody CompensationPerformance compensationPerformance){
        boolean save = compensationPerformanceService.save(compensationPerformance);
        return save ? AjaxResult.success("添加成功") : AjaxResult.error("添加失败");
    }
    @PostMapping("/update")
    @Log(title = "薪酬绩效-修改", businessType = BusinessType.UPDATE)
    @ApiOperation("薪酬绩效-修改")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult update(@RequestBody CompensationPerformance compensationPerformance){
        boolean update = compensationPerformanceService.updateById(compensationPerformance);
        return update ? AjaxResult.success("修改成功") : AjaxResult.error("修改失败");
    }
    @DeleteMapping("/delete")
    @Log(title = "薪酬绩效-删除", businessType = BusinessType.DELETE)
    @ApiOperation("薪酬绩效-删除")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult delete(@RequestBody List<Long> ids){
        if(CollectionUtils.isEmpty(ids)) return AjaxResult.error("请传入要删除的ID");
        boolean delete = compensationPerformanceService.removeBatchByIds(ids);
        return delete ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
    }
}
src/main/java/com/ruoyi/compensationperformance/mapper/CompensationPerformanceMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
package com.ruoyi.compensationperformance.mapper;
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.compensationperformance.pojo.CompensationPerformance;
import org.apache.ibatis.annotations.Param;
/**
 * @author :yys
 * @date : 2025/8/8 9:54
 */
public interface CompensationPerformanceMapper extends BaseMapper<CompensationPerformance> {
    /**
     * åˆ†é¡µæŸ¥è¯¢
     *
     * @param page
     * @param compensationPerformance
     * @return
     */
    IPage<CompensationPerformance> listPage(Page page,@Param("req") CompensationPerformance compensationPerformance);
}
src/main/java/com/ruoyi/compensationperformance/pojo/CompensationPerformance.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,230 @@
package com.ruoyi.compensationperformance.pojo;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
/**
 * @author :yys
 * @date : 2025/8/8 9:40
 */
@Data
@TableName("compensation_performance")
@ApiModel
public class CompensationPerformance {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * å‘˜å·¥id
     */
    @ApiModelProperty("员工id")
    @Excel(name = "员工id")
    private Long staffId;
    /**
     * å§“名
     */
    @ApiModelProperty("姓名")
    @Excel(name = "姓名")
    private String name;
    /**
     * è–ªèµ„月份(查询)
     */
    @ApiModelProperty("薪资月份(查询)")
    @TableField(exist = false)
    private String payDateStr;
    /**
     * è–ªèµ„月份
     */
    @ApiModelProperty("薪资月份")
    @Excel(name = "薪资月份", dateFormat = "yyyy-MM", width = 30)
    @JsonFormat(pattern = "yyyy-MM", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM")
    private Date payDate;
    /**
     * åº”出勤天数
     */
    @ApiModelProperty("应出勤天数")
    @Excel(name = "应出勤天数")
    private BigDecimal shouldAttendedNum;
    /**
     * å®žé™…出勤天数
     */
    @ApiModelProperty("实际出勤天数")
    @Excel(name = "实际出勤天数")
    private BigDecimal actualAttendedNum;
    /**
     * åŸºæœ¬å·¥èµ„
     */
    @ApiModelProperty("基本工资")
    @Excel(name = "基本工资")
    private BigDecimal basicSalary;
    /**
     * å²—位工资
     */
    @ApiModelProperty("岗位工资")
    @Excel(name = "岗位工资")
    private BigDecimal postSalary;
    /**
     * å…¥ç¦»èŒç¼ºå‹¤æ‰£æ¬¾
     */
    @ApiModelProperty("入离职缺勤扣款")
    @Excel(name = "入离职缺勤扣款")
    private BigDecimal deductionAbsenteeism;
    /**
     * ç—…假扣款
     */
    @ApiModelProperty("病假扣款")
    @Excel(name = "病假扣款")
    private BigDecimal sickLeaveDeductions;
    /**
     * äº‹å‡æ‰£æ¬¾
     */
    @ApiModelProperty("事假扣款")
    @Excel(name = "事假扣款")
    private BigDecimal deductionPersonalLeave;
    /**
     * å¿˜è®°æ‰“卡扣款
     */
    @ApiModelProperty("忘记打卡扣款")
    @Excel(name = "忘记打卡扣款")
    private BigDecimal forgetClockDeduct;
    /**
     * ç»©æ•ˆå¾—分
     */
    @ApiModelProperty("绩效得分")
    @Excel(name = "绩效得分")
    private BigDecimal performanceScore;
    /**
     * ç»©æ•ˆå·¥èµ„
     */
    @ApiModelProperty("绩效工资")
    @Excel(name = "绩效工资")
    private BigDecimal performancePay;
    /**
     * åº”发合计
     */
    @ApiModelProperty("应发合计")
    @Excel(name = "应发合计")
    private BigDecimal payableWages;
    /**
     * ç¤¾ä¿ä¸ªäºº
     */
    @ApiModelProperty("社保个人")
    @Excel(name = "社保个人")
    private BigDecimal socialSecurityIndividuals;
    /**
     * ç¤¾ä¿å…¬å¸
     */
    @ApiModelProperty("社保公司")
    @Excel(name = "社保公司")
    private BigDecimal socialSecurityCompanies;
    /**
     * ç¤¾ä¿åˆè®¡
     */
    @ApiModelProperty("社保合计")
    @Excel(name = "社保合计")
    private BigDecimal socialSecurityTotal;
    /**
     * å…¬ç§¯é‡‘合计
     */
    @ApiModelProperty("公积金合计")
    @Excel(name = "公积金合计")
    private BigDecimal providentFundTotal;
    /**
     * å…¬ç§¯é‡‘公司
     */
    @ApiModelProperty("公积金公司")
    @Excel(name = "公积金公司")
    private BigDecimal providentFundCompany;
    /**
     * å…¬ç§¯é‡‘个人
     */
    @ApiModelProperty("公积金个人")
    @Excel(name = "公积金个人")
    private BigDecimal providentFundIndividuals;
    /**
     * åº”税工资
     */
    @ApiModelProperty("应税工资")
    @Excel(name = "应税工资")
    private BigDecimal taxableWaget;
    /**
     * ä¸ªäººæ‰€å¾—税
     */
    @ApiModelProperty("个人所得税")
    @Excel(name = "个人所得税")
    private BigDecimal personalIncomeTax;
    /**
     * å®žå‘工资
     */
    @ApiModelProperty("实发工资")
    @Excel(name = "实发工资")
    private BigDecimal actualWages;
    /**
     * åˆ›å»ºè€…
     */
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    /**
     * åˆ›å»ºæ—¶é—´
     */
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    /**
     * ä¿®æ”¹è€…
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    /**
     * ä¿®æ”¹æ—¶é—´
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    /**
     * ç§Ÿæˆ·ID
     */
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
}
src/main/java/com/ruoyi/compensationperformance/service/CompensationPerformanceService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.ruoyi.compensationperformance.service;
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.compensationperformance.pojo.CompensationPerformance;
/**
 * @author :yys
 * @date : 2025/8/8 9:55
 */
public interface CompensationPerformanceService extends IService<CompensationPerformance> {
    /**
     * åˆ†é¡µæŸ¥è¯¢
     *
     * @param page
     * @param compensationPerformance
     * @return
     */
    IPage<CompensationPerformance> listPage(Page page, CompensationPerformance compensationPerformance);
}
src/main/java/com/ruoyi/compensationperformance/service/impl/CompensationPerformanceServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,30 @@
package com.ruoyi.compensationperformance.service.impl;
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.compensationperformance.mapper.CompensationPerformanceMapper;
import com.ruoyi.compensationperformance.pojo.CompensationPerformance;
import com.ruoyi.compensationperformance.service.CompensationPerformanceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
 * @author :yys
 * @date : 2025/8/8 9:55
 */
@Service
@Slf4j
public class CompensationPerformanceServiceImpl extends ServiceImpl<CompensationPerformanceMapper, CompensationPerformance> implements CompensationPerformanceService {
    @Autowired
    private CompensationPerformanceMapper compensationPerformanceMapper;
    @Override
    public IPage<CompensationPerformance> listPage(Page page, CompensationPerformance compensationPerformance) {
        IPage<CompensationPerformance> compensationPerformanceIPage = compensationPerformanceMapper.listPage(page, compensationPerformance);
        return compensationPerformanceIPage;
    }
}
src/main/java/com/ruoyi/framework/config/MybatisPlusConfig.java
@@ -1,15 +1,24 @@
package com.ruoyi.framework.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ParameterUtils;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import com.ruoyi.common.handler.CustomTenantLineHandler;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import java.sql.SQLException;
/**
 * Mybatis Plus é…ç½®
@@ -39,14 +48,31 @@
    /**
     * åˆ†é¡µæ’件,自动识别数据库类型 https://baomidou.com/guide/interceptor-pagination.html
     */
    public PaginationInnerInterceptor paginationInnerInterceptor()
    {
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
        // è®¾ç½®æ•°æ®åº“类型为mysql
        paginationInnerInterceptor.setDbType(DbType.MYSQL);
        // è®¾ç½®æœ€å¤§å•页限制数量,默认 500 æ¡ï¼Œ-1 ä¸å—限制
        paginationInnerInterceptor.setMaxLimit(-1L);
        return paginationInnerInterceptor;
//    public PaginationInnerInterceptor paginationInnerInterceptor()
//    {
//        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
//        // è®¾ç½®æ•°æ®åº“类型为mysql
//        paginationInnerInterceptor.setDbType(DbType.MYSQL);
//        // è®¾ç½®æœ€å¤§å•页限制数量,默认 500 æ¡ï¼Œ-1 ä¸å—限制
//        paginationInnerInterceptor.setMaxLimit(-1L);
//        return paginationInnerInterceptor;
//    }
    public PaginationInnerInterceptor paginationInnerInterceptor() {
        PaginationInnerInterceptor interceptor = new PaginationInnerInterceptor(DbType.MYSQL) {
            @Override
            public void beforeQuery(Executor executor, MappedStatement ms, Object parameter,
                                    RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
                IPage<?> page = ParameterUtils.findPage(parameter).orElse(null);
                if (page != null && page.getSize() <= 0) {
                    // å½“size<=0时,不进行分页
                    return;
                }
                super.beforeQuery(executor, ms, parameter, rowBounds, resultHandler, boundSql);
            }
        };
        interceptor.setMaxLimit(1000L); // å»ºè®®è®¾ç½®åˆç†çš„æœ€å¤§å€¼
        return interceptor;
    }
    /**
src/main/java/com/ruoyi/measuringinstrumentledger/controller/MeasuringInstrumentLedgerController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,129 @@
package com.ruoyi.measuringinstrumentledger.controller;
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.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.equipmentenergyconsumption.pojo.EquipmentEnergyConsumption;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.measuringinstrumentledger.dto.MeasuringInstrumentLedgerDto;
import com.ruoyi.measuringinstrumentledger.mapper.MeasuringInstrumentLedgerRecordMapper;
import com.ruoyi.measuringinstrumentledger.pojo.MeasuringInstrumentLedger;
import com.ruoyi.measuringinstrumentledger.pojo.MeasuringInstrumentLedgerRecord;
import com.ruoyi.measuringinstrumentledger.service.MeasuringInstrumentLedgerService;
import com.ruoyi.measuringinstrumentledger.service.impl.MeasuringInstrumentLedgerServiceImpl;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysUserMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
/**
 * @author :yys
 * @date : 2025/8/5 9:27
 */
@RestController
@Api(tags = "计量器具台账")
@RequestMapping("/measuringInstrumentLedger")
public class MeasuringInstrumentLedgerController extends BaseController {
    @Autowired
    private MeasuringInstrumentLedgerService measuringInstrumentLedgerService;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private MeasuringInstrumentLedgerRecordMapper measuringInstrumentLedgerRecordMapper;
    @GetMapping("/listPage")
    @ApiOperation("计量器具台账-分页查询")
    @Log(title = "计量器具台账-分页查询", businessType = BusinessType.OTHER)
    public AjaxResult listPage(Page page, MeasuringInstrumentLedger measuringInstrumentLedger) {
        IPage<MeasuringInstrumentLedger> listPage = measuringInstrumentLedgerService.listPage(page, measuringInstrumentLedger);
        return AjaxResult.success(listPage);
    }
    @PostMapping("/add")
    @ApiOperation("计量器具台账-新增")
    @Log(title = "计量器具台账-新增", businessType = BusinessType.INSERT)
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult add(@RequestBody MeasuringInstrumentLedger measuringInstrumentLedger) throws IOException {
        boolean save = measuringInstrumentLedgerService.add(measuringInstrumentLedger);
        if (save) {
            return AjaxResult.success();
        }
        return AjaxResult.error();
    }
    @PostMapping("/update")
    @ApiOperation("计量器具台账-修改")
    @Log(title = "计量器具台账-修改", businessType = BusinessType.UPDATE)
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult update(@RequestBody MeasuringInstrumentLedger measuringInstrumentLedger) {
        SysUser sysUser = sysUserMapper.selectUserById(measuringInstrumentLedger.getUserId());
        if (sysUser == null) {
            return AjaxResult.error("用户不存在");
        }
        measuringInstrumentLedger.setUserName(sysUser.getUserName());
        boolean update = measuringInstrumentLedgerService.updateById(measuringInstrumentLedger);
        if (update) {
            return AjaxResult.success();
        }
        return AjaxResult.error();
    }
    @DeleteMapping("/delete")
    @ApiOperation("计量器具台账-删除")
    @Log(title = "计量器具台账-删除", businessType = BusinessType.DELETE)
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult delete(@RequestBody List<Long> ids) {
        if(CollectionUtils.isEmpty(ids)) return AjaxResult.error("请选择至少一条数据");
        for (Long id : ids) {
            LambdaQueryWrapper<MeasuringInstrumentLedgerRecord> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(MeasuringInstrumentLedgerRecord::getMeasuringInstrumentLedgerId,id);
            List<MeasuringInstrumentLedgerRecord> measuringInstrumentLedgerRecords = measuringInstrumentLedgerRecordMapper.selectList(queryWrapper);
            if(!CollectionUtils.isEmpty(measuringInstrumentLedgerRecords)){
                return AjaxResult.error("请先删除选中计量器具台账下的所有检定记录");
            }
        }
        boolean delete = measuringInstrumentLedgerService.removeBatchByIds(ids);
        if (delete) {
            return AjaxResult.success();
        }
        return AjaxResult.error();
    }
    @PostMapping("/verifying")
    @ApiOperation("计量器具台账-检定")
    @Log(title = "计量器具台账-检定", businessType = BusinessType.UPDATE)
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult verifying(@RequestBody MeasuringInstrumentLedgerDto measuringInstrumentLedger) throws IOException {
        boolean update = measuringInstrumentLedgerService.verifying(measuringInstrumentLedger);
        return update ? AjaxResult.success("检定成功") : AjaxResult.error("检定失败");
    }
    /**
     * å¯¼å‡ºè®¡é‡å™¨å…·å°è´¦
     */
    @Log(title = "导出计量器具台账", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ApiOperation("导出计量器具台账")
    public void export(HttpServletResponse response) {
        measuringInstrumentLedgerService.export( response);
    }
}
src/main/java/com/ruoyi/measuringinstrumentledger/controller/MeasuringInstrumentLedgerRecordController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,63 @@
package com.ruoyi.measuringinstrumentledger.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.measuringinstrumentledger.pojo.MeasuringInstrumentLedgerRecord;
import com.ruoyi.measuringinstrumentledger.service.MeasuringInstrumentLedgerRecordService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
 * @author :yys
 * @date : 2025/8/5 9:28
 */
@RestController
@Api(tags = "计量器具台账记录")
@RequestMapping("/measuringInstrumentLedgerRecord")
public class MeasuringInstrumentLedgerRecordController extends BaseController {
    @Autowired
    private MeasuringInstrumentLedgerRecordService measuringInstrumentLedgerRecordService;
    @GetMapping("/listPage")
    @ApiOperation("计量器具台账记录-分页查询")
    @Log(title = "计量器具台账记录-分页查询", businessType = BusinessType.OTHER)
    public AjaxResult listPage(Page page, MeasuringInstrumentLedgerRecord measuringInstrumentLedgerRecord){
        IPage<MeasuringInstrumentLedgerRecord> listPage = measuringInstrumentLedgerRecordService.listPage(page, measuringInstrumentLedgerRecord);
        return AjaxResult.success(listPage);
    }
    @PostMapping("/update")
    @ApiOperation("计量器具台账记录-修改")
    @Log(title = "计量器具台账记录-修改", businessType = BusinessType.UPDATE)
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult update(@RequestBody MeasuringInstrumentLedgerRecord measuringInstrumentLedgerRecord) throws IOException {
        boolean update = measuringInstrumentLedgerRecordService.updateMeasuringInstrumentLedgerRecord(measuringInstrumentLedgerRecord);
        if (update) {
            return AjaxResult.success();
        }
        return AjaxResult.error();
    }
    /**
     * å¯¼å‡ºè®¡é‡å™¨å…·å°è´¦
     */
    @ApiOperation("计量器具台账记录-导出")
    @Log(title = "计量器具台账记录-导出", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response) {
        measuringInstrumentLedgerRecordService.export( response);
    }
}
src/main/java/com/ruoyi/measuringinstrumentledger/dto/MeasuringInstrumentLedgerDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,46 @@
package com.ruoyi.measuringinstrumentledger.dto;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import java.util.List;
/**
 * @author :yys
 * @date : 2025/8/5 9:50
 */
@Data
@ApiModel
public class MeasuringInstrumentLedgerDto {
    @ApiModelProperty("ID")
    private Long id;
    @ApiModelProperty("附件id")
    private List<String> tempFileIds;
    @ApiModelProperty("检定日期")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd", iso = DateTimeFormat.ISO.DATE)
    private Date recordDate;
    @ApiModelProperty("录入日期")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd", iso = DateTimeFormat.ISO.DATE)
    private Date entryDate;
    @ApiModelProperty("有效期")
    private Integer valid;
    @ApiModelProperty("检定人")
    private Long userId;
}
src/main/java/com/ruoyi/measuringinstrumentledger/mapper/MeasuringInstrumentLedgerMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,27 @@
package com.ruoyi.measuringinstrumentledger.mapper;
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.measuringinstrumentledger.pojo.MeasuringInstrumentLedger;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * @author :yys
 * @date : 2025/8/5 9:20
 */
public interface MeasuringInstrumentLedgerMapper extends BaseMapper<MeasuringInstrumentLedger> {
    /**
     * åˆ†é¡µæŸ¥è¯¢
     *
     * @param page
     * @param measuringInstrumentLedger
     * @return
     */
    IPage<MeasuringInstrumentLedger> listPage(Page page,@Param("req") MeasuringInstrumentLedger measuringInstrumentLedger);
    List<MeasuringInstrumentLedger> listPage(@Param("req") MeasuringInstrumentLedger measuringInstrumentLedger);
}
src/main/java/com/ruoyi/measuringinstrumentledger/mapper/MeasuringInstrumentLedgerRecordMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.ruoyi.measuringinstrumentledger.mapper;
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.measuringinstrumentledger.pojo.MeasuringInstrumentLedgerRecord;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * @author :yys
 * @date : 2025/8/5 9:19
 */
public interface MeasuringInstrumentLedgerRecordMapper extends BaseMapper<MeasuringInstrumentLedgerRecord> {
    IPage<MeasuringInstrumentLedgerRecord> listPage(Page page,@Param("req") MeasuringInstrumentLedgerRecord measuringInstrumentLedgerRecord);
    List<MeasuringInstrumentLedgerRecord> list(@Param("req") MeasuringInstrumentLedgerRecord measuringInstrumentLedgerRecord);
}
src/main/java/com/ruoyi/measuringinstrumentledger/pojo/MeasuringInstrumentLedger.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,140 @@
package com.ruoyi.measuringinstrumentledger.pojo;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import com.ruoyi.sales.pojo.CommonFile;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
/**
 * @author :yys
 * @date : 2025/8/5 9:12
 */
@Data
@TableName("measuring_instrument_ledger")
@ApiModel
public class MeasuringInstrumentLedger {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty("附件id")
    @TableField(exist = false)
    private List<String> tempFileIds;
    @TableField(exist = false)
    @ApiModelProperty("附件列表")
    private List<CommonFile> commonFiles;
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty("录入人id")
    private Long userId;
    @ApiModelProperty("录入人名称")
    @Excel(name = "录入人名称")
    private String userName;
    /**
     * è®¡é‡å™¨å…·ç¼–号
     */
    @ApiModelProperty("计量器具编号")
    @Excel(name = "计量器具编号")
    private String code;
    /**
     * è®¡é‡å™¨å…·åç§°
     */
    @ApiModelProperty("计量器具名称")
    @Excel(name = "计量器具名称")
    private String name;
    /**
     * è§„格型号
     */
    @ApiModelProperty("规格型号")
    @Excel(name = "规格型号")
    private String model;
    /**
     * æœ€è¿‘一次检定日期
     */
    @ApiModelProperty("最近一次检定日期")
    @Excel(name = "最近一次检定日期", width = 30, dateFormat = "yyyy-MM-dd")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date mostDate;
    /**
     * æ£€å®šæœ‰æ•ˆæœŸ
     */
    @ApiModelProperty("检定有效期")
    @Excel(name = "检定有效期")
    private Integer valid;
    /**
     * é¢„计下次检定日期
     */
    @ApiModelProperty("预计下次检定日期")
    @Excel(name = "预计下次检定日期" , width = 30, dateFormat = "yyyy-MM-dd")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date nextDate;
    /**
     * å½•入日期
     */
    @ApiModelProperty("录入日期")
    @Excel(name = "录入日期" , width = 30, dateFormat = "yyyy-MM-dd")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date recordDate;
    /**
     * çŠ¶æ€ï¼ˆ1-有效 2-逾期)
     */
    @ApiModelProperty("状态(1-有效 2-逾期)")
    @Excel(name = "状态", readConverterExp = "1=有效,2=逾期")
    private Integer status;
    /**
     * åˆ›å»ºè€…
     */
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    /**
     * åˆ›å»ºæ—¶é—´
     */
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    /**
     * ä¿®æ”¹è€…
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    /**
     * ä¿®æ”¹æ—¶é—´
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    /**
     * ç§Ÿæˆ·ID
     */
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
}
src/main/java/com/ruoyi/measuringinstrumentledger/pojo/MeasuringInstrumentLedgerRecord.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,122 @@
package com.ruoyi.measuringinstrumentledger.pojo;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import com.ruoyi.sales.pojo.CommonFile;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
/**
 * @author :yys
 * @date : 2025/8/5 9:12
 */
@Data
@TableName("measuring_instrument_ledger_record")
@ApiModel
public class MeasuringInstrumentLedgerRecord {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty("计量器具编号")
    @TableField(exist = false)
    @Excel(name = "计量器具编号")
    private String code;
    @ApiModelProperty("名称")
    @TableField(exist = false)
    @Excel(name = "名称")
    private String name;
    @ApiModelProperty("计量器具名称")
    @TableField(exist = false)
    @Excel(name = "计量器具名称")
    private String model;
    @ApiModelProperty("附件id")
    @TableField(exist = false)
    private List<String> tempFileIds;
    @TableField(exist = false)
    @ApiModelProperty("附件列表")
    private List<CommonFile> commonFiles;
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty("计量器具台账id")
    private Long measuringInstrumentLedgerId;
    @ApiModelProperty("检定人id")
    private Long userId;
    @ApiModelProperty("检定人名称")
    @Excel(name = "检定人名称")
    private String userName;
    /**
     * æ£€å®šæ—¥æœŸ
     */
    @ApiModelProperty("检定日期")
    @Excel(name = "检定日期" , width = 30, dateFormat = "yyyy-MM-dd")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date recordDate;
    @ApiModelProperty("录入日期")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @Excel(name = "录入日期" , width = 30, dateFormat = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd", iso = DateTimeFormat.ISO.DATE)
    private Date entryDate;
    /**
     * æœ‰æ•ˆæœŸï¼ˆå•位天)
     */
    @ApiModelProperty("有效期(单位天)")
    private Integer valid;
    /**
     * çŠ¶æ€ï¼ˆ1-有效 2-逾期)
     */
    @ApiModelProperty("状态(1-有效 2-逾期)")
    private Integer status;
    /**
     * åˆ›å»ºè€…
     */
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    /**
     * åˆ›å»ºæ—¶é—´
     */
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    /**
     * ä¿®æ”¹è€…
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    /**
     * ä¿®æ”¹æ—¶é—´
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    /**
     * ç§Ÿæˆ·ID
     */
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
}
src/main/java/com/ruoyi/measuringinstrumentledger/service/MeasuringInstrumentLedgerRecordService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
package com.ruoyi.measuringinstrumentledger.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.measuringinstrumentledger.pojo.MeasuringInstrumentLedgerRecord;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
 * @author :yys
 * @date : 2025/8/5 9:22
 */
public interface MeasuringInstrumentLedgerRecordService extends IService<MeasuringInstrumentLedgerRecord> {
    /**
     * åˆ†é¡µæŸ¥è¯¢
     *
     * @param page
     * @param measuringInstrumentLedgerRecord
     * @return
     */
    IPage<MeasuringInstrumentLedgerRecord> listPage(Page page, MeasuringInstrumentLedgerRecord measuringInstrumentLedgerRecord);
    void export(HttpServletResponse response);
    boolean updateMeasuringInstrumentLedgerRecord(MeasuringInstrumentLedgerRecord measuringInstrumentLedgerRecord) throws IOException;
}
src/main/java/com/ruoyi/measuringinstrumentledger/service/MeasuringInstrumentLedgerService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,44 @@
package com.ruoyi.measuringinstrumentledger.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.measuringinstrumentledger.dto.MeasuringInstrumentLedgerDto;
import com.ruoyi.measuringinstrumentledger.pojo.MeasuringInstrumentLedger;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
 * @author :yys
 * @date : 2025/8/5 9:23
 */
public interface MeasuringInstrumentLedgerService extends IService<MeasuringInstrumentLedger> {
    /**
     * åˆ†é¡µæŸ¥è¯¢
     *
     * @param page
     * @param measuringInstrumentLedger
     * @return
     */
    IPage<MeasuringInstrumentLedger> listPage(Page page, MeasuringInstrumentLedger measuringInstrumentLedger);
    /**
     * æ£€å®š
     *
     * @param measuringInstrumentLedger
     * @return
     */
    boolean verifying(MeasuringInstrumentLedgerDto measuringInstrumentLedger) throws IOException;
    void export(HttpServletResponse response);
    /**
     * æ–°å¢ž
     *
     * @param measuringInstrumentLedger
     * @return
     */
    boolean add(MeasuringInstrumentLedger measuringInstrumentLedger) throws IOException;
}
src/main/java/com/ruoyi/measuringinstrumentledger/service/impl/MeasuringInstrumentLedgerRecordServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,175 @@
package com.ruoyi.measuringinstrumentledger.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.enums.FileNameType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.measuringinstrumentledger.mapper.MeasuringInstrumentLedgerMapper;
import com.ruoyi.measuringinstrumentledger.mapper.MeasuringInstrumentLedgerRecordMapper;
import com.ruoyi.measuringinstrumentledger.pojo.MeasuringInstrumentLedger;
import com.ruoyi.measuringinstrumentledger.pojo.MeasuringInstrumentLedgerRecord;
import com.ruoyi.measuringinstrumentledger.service.MeasuringInstrumentLedgerRecordService;
import com.ruoyi.other.mapper.TempFileMapper;
import com.ruoyi.other.pojo.TempFile;
import com.ruoyi.sales.mapper.CommonFileMapper;
import com.ruoyi.sales.pojo.CommonFile;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
/**
 * @author :yys
 * @date : 2025/8/5 9:24
 */
@Service
@Slf4j
public class MeasuringInstrumentLedgerRecordServiceImpl extends ServiceImpl<MeasuringInstrumentLedgerRecordMapper, MeasuringInstrumentLedgerRecord> implements MeasuringInstrumentLedgerRecordService {
    @Autowired
    private MeasuringInstrumentLedgerRecordMapper measuringInstrumentLedgerRecordMapper;
    @Autowired
    private MeasuringInstrumentLedgerMapper measuringInstrumentLedgerMapper;
    @Autowired
    private CommonFileMapper commonFileMapper;
    @Autowired
    private TempFileMapper tempFileMapper;
    @Value("${file.upload-dir}")
    private String uploadDir;
    @Override
    public IPage<MeasuringInstrumentLedgerRecord> listPage(Page page, MeasuringInstrumentLedgerRecord measuringInstrumentLedgerRecord) {
        IPage<MeasuringInstrumentLedgerRecord> measuringInstrumentLedgerRecordIPage = measuringInstrumentLedgerRecordMapper.listPage(page, measuringInstrumentLedgerRecord);
        measuringInstrumentLedgerRecordIPage.getRecords().forEach(item -> {
            LambdaQueryWrapper<CommonFile> salesLedgerFileWrapper = new LambdaQueryWrapper<>();
            salesLedgerFileWrapper.eq(CommonFile::getCommonId, item.getId())
                    .eq(CommonFile::getType, FileNameType.MEASURINGRecord.getValue());
            List<CommonFile> commonFiles = commonFileMapper.selectList(salesLedgerFileWrapper);
            item.setCommonFiles(commonFiles);
        });
        return measuringInstrumentLedgerRecordIPage;
    }
    @Override
    public void export(HttpServletResponse response) {
        List<MeasuringInstrumentLedgerRecord> list = measuringInstrumentLedgerRecordMapper.list( new MeasuringInstrumentLedgerRecord());
        ExcelUtil<MeasuringInstrumentLedgerRecord> util = new ExcelUtil<MeasuringInstrumentLedgerRecord>(MeasuringInstrumentLedgerRecord.class);
        util.exportExcel(response, list , "计量器具台账记录数据");
    }
    @Override
    public boolean updateMeasuringInstrumentLedgerRecord(MeasuringInstrumentLedgerRecord measuringInstrumentLedgerRecord) throws IOException {
        MeasuringInstrumentLedgerRecord measuringInstrumentLedgerRecord1 = measuringInstrumentLedgerRecordMapper.selectById(measuringInstrumentLedgerRecord.getId());
        if (measuringInstrumentLedgerRecord1 == null) {
            return false;
        }
        // æœ‰æ•ˆæœŸå˜æ›´ï¼Œé‡æ–°è®¡ç®—预计下次检定日期
        if(!measuringInstrumentLedgerRecord1.getValid().equals(measuringInstrumentLedgerRecord.getValid())){
            MeasuringInstrumentLedger measuringInstrumentLedger = measuringInstrumentLedgerMapper.selectById(measuringInstrumentLedgerRecord1.getMeasuringInstrumentLedgerId());
            if(measuringInstrumentLedger != null){
                measuringInstrumentLedger.setValid(measuringInstrumentLedgerRecord.getValid());
                measuringInstrumentLedger.setNextDate(new Date(measuringInstrumentLedger.getMostDate().getTime() + measuringInstrumentLedgerRecord.getValid() * 24 * 60 * 60 * 1000L));
            }
            measuringInstrumentLedgerMapper.updateById(measuringInstrumentLedger);
        }
        measuringInstrumentLedgerRecordMapper.updateById(measuringInstrumentLedgerRecord);
        // è®°å½•附件绑定
        migrateTempFilesToFormal(measuringInstrumentLedgerRecord.getId(), measuringInstrumentLedgerRecord.getTempFileIds(), FileNameType.MEASURINGRecord.getValue());
        return true;
    }
    /**
     * å°†ä¸´æ—¶æ–‡ä»¶è¿ç§»åˆ°æ­£å¼ç›®å½•
     *
     * @param businessId  ä¸šåŠ¡ID(销售台账ID)
     * @param tempFileIds ä¸´æ—¶æ–‡ä»¶ID列表
     * @throws IOException æ–‡ä»¶æ“ä½œå¼‚常
     */
    private void migrateTempFilesToFormal(Long businessId, List<String> tempFileIds,Integer fileType) throws IOException {
        if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(tempFileIds)) {
            return;
        }
        // æž„建正式目录路径(按业务类型和日期分组)
        String formalDir = uploadDir + LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE);
        Path formalDirPath = Paths.get(formalDir);
        // ç¡®ä¿æ­£å¼ç›®å½•存在(递归创建)
        if (!Files.exists(formalDirPath)) {
            Files.createDirectories(formalDirPath);
        }
        for (String tempFileId : tempFileIds) {
            // æŸ¥è¯¢ä¸´æ—¶æ–‡ä»¶è®°å½•
            TempFile tempFile = tempFileMapper.selectById(tempFileId);
            if (tempFile == null) {
                log.warn("临时文件不存在,跳过处理: {}", tempFileId);
                continue;
            }
            // æž„建正式文件名(包含业务ID和时间戳,避免冲突)
            String originalFilename = tempFile.getOriginalName();
            String fileExtension = FilenameUtils.getExtension(originalFilename);
            String formalFilename = businessId + "_" +
                    System.currentTimeMillis() + "_" +
                    UUID.randomUUID().toString().substring(0, 8) +
                    (StringUtils.hasText(fileExtension) ? "." + fileExtension : "");
            Path formalFilePath = formalDirPath.resolve(formalFilename);
            try {
                // æ‰§è¡Œæ–‡ä»¶è¿ç§»ï¼ˆä½¿ç”¨åŽŸå­æ“ä½œç¡®ä¿å®‰å…¨æ€§ï¼‰
                Files.move(
                        Paths.get(tempFile.getTempPath()),
                        formalFilePath,
                        StandardCopyOption.REPLACE_EXISTING,
                        StandardCopyOption.ATOMIC_MOVE
                );
                log.info("文件迁移成功: {} -> {}", tempFile.getTempPath(), formalFilePath);
                // æ›´æ–°æ–‡ä»¶è®°å½•(关联到业务ID)
                CommonFile fileRecord = new CommonFile();
                fileRecord.setCommonId(businessId);
                fileRecord.setName(originalFilename);
                fileRecord.setUrl(formalFilePath.toString());
                fileRecord.setCreateTime(LocalDateTime.now());
                fileRecord.setType(fileType);
                commonFileMapper.insert(fileRecord);
                // åˆ é™¤ä¸´æ—¶æ–‡ä»¶è®°å½•
                tempFileMapper.deleteById(tempFile);
                log.info("文件迁移成功: {} -> {}", tempFile.getTempPath(), formalFilePath);
            } catch (IOException e) {
                log.error("文件迁移失败: {}", tempFile.getTempPath(), e);
                // å¯é€‰æ‹©å›žæ»šäº‹åŠ¡æˆ–è®°å½•å¤±è´¥æ–‡ä»¶
                throw new IOException("文件迁移异常", e);
            }
        }
    }
}
src/main/java/com/ruoyi/measuringinstrumentledger/service/impl/MeasuringInstrumentLedgerServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,220 @@
package com.ruoyi.measuringinstrumentledger.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.enums.FileNameType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.measuringinstrumentledger.dto.MeasuringInstrumentLedgerDto;
import com.ruoyi.measuringinstrumentledger.mapper.MeasuringInstrumentLedgerMapper;
import com.ruoyi.measuringinstrumentledger.mapper.MeasuringInstrumentLedgerRecordMapper;
import com.ruoyi.measuringinstrumentledger.pojo.MeasuringInstrumentLedger;
import com.ruoyi.measuringinstrumentledger.pojo.MeasuringInstrumentLedgerRecord;
import com.ruoyi.measuringinstrumentledger.service.MeasuringInstrumentLedgerService;
import com.ruoyi.other.mapper.TempFileMapper;
import com.ruoyi.other.pojo.TempFile;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.sales.mapper.CommonFileMapper;
import com.ruoyi.sales.pojo.CommonFile;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
/**
 * @author :yys
 * @date : 2025/8/5 9:23
 */
@Service
@Slf4j
public class MeasuringInstrumentLedgerServiceImpl extends ServiceImpl<MeasuringInstrumentLedgerMapper, MeasuringInstrumentLedger> implements MeasuringInstrumentLedgerService {
    @Autowired
    private MeasuringInstrumentLedgerMapper measuringInstrumentLedgerMapper;
    @Autowired
    private MeasuringInstrumentLedgerRecordMapper measuringInstrumentLedgerRecordMapper;
    @Autowired
    private TempFileMapper tempFileMapper;
    @Autowired
    private CommonFileMapper commonFileMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Value("${file.upload-dir}")
    private String uploadDir;
    @Override
    public IPage<MeasuringInstrumentLedger> listPage(Page page, MeasuringInstrumentLedger measuringInstrumentLedger) {
        IPage<MeasuringInstrumentLedger> measuringInstrumentLedgerIPage = measuringInstrumentLedgerMapper.listPage(page, measuringInstrumentLedger);
        List<Integer>  types = new ArrayList<>();
        types.add(FileNameType.MEASURING.getValue());
        types.add(FileNameType.MEASURINGRecord.getValue());
        measuringInstrumentLedgerIPage.getRecords().forEach(item -> {
            LambdaQueryWrapper<MeasuringInstrumentLedgerRecord> measuringInstrumentLedgerRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
            measuringInstrumentLedgerRecordLambdaQueryWrapper.eq(MeasuringInstrumentLedgerRecord::getMeasuringInstrumentLedgerId, item.getId());
            List<MeasuringInstrumentLedgerRecord> measuringInstrumentLedgerRecords = measuringInstrumentLedgerRecordMapper.selectList(measuringInstrumentLedgerRecordLambdaQueryWrapper);
            List<Long> collect = new ArrayList<>();
            if(!CollectionUtils.isEmpty(measuringInstrumentLedgerRecords)){
                collect = measuringInstrumentLedgerRecords.stream().map(MeasuringInstrumentLedgerRecord::getId).collect(Collectors.toList());
            }
            collect.add(item.getId());
            LambdaQueryWrapper<CommonFile> salesLedgerFileWrapper = new LambdaQueryWrapper<>();
            salesLedgerFileWrapper.in(CommonFile::getCommonId, collect)
                    .in(CommonFile::getType,types);
            List<CommonFile> commonFiles = commonFileMapper.selectList(salesLedgerFileWrapper);
            item.setCommonFiles(commonFiles);
        });
        return measuringInstrumentLedgerIPage;
    }
    @Override
    public boolean verifying(MeasuringInstrumentLedgerDto req) throws IOException {
        MeasuringInstrumentLedger measuringInstrumentLedger = measuringInstrumentLedgerMapper.selectById(req.getId());
        if(measuringInstrumentLedger == null) {
            return false;
        }
        SysUser sysUser = sysUserMapper.selectUserById(measuringInstrumentLedger.getUserId());
        measuringInstrumentLedger.setValid(req.getValid());
        measuringInstrumentLedger.setMostDate(req.getRecordDate());
        measuringInstrumentLedger.setNextDate(new Date(req.getRecordDate().getTime() + 1000L * 60 * 60 * 24 * req.getValid()));
        MeasuringInstrumentLedgerRecord measuringInstrumentLedgerRecord = new MeasuringInstrumentLedgerRecord();
        if(measuringInstrumentLedgerMapper.updateById(measuringInstrumentLedger) > 0) {
            measuringInstrumentLedgerRecord.setMeasuringInstrumentLedgerId(req.getId());
            measuringInstrumentLedgerRecord.setRecordDate(req.getRecordDate());
            measuringInstrumentLedgerRecord.setEntryDate(req.getEntryDate());
            measuringInstrumentLedgerRecord.setValid(req.getValid());
            measuringInstrumentLedgerRecord.setUserId(req.getUserId());
            measuringInstrumentLedgerRecord.setUserName(sysUser.getUserName());
            measuringInstrumentLedgerRecordMapper.insert(measuringInstrumentLedgerRecord);
            // å°è´¦ç»‘定一次
//            if(!CollectionUtils.isEmpty(req.getTempFileIds())){
//                migrateTempFilesToFormal(measuringInstrumentLedger.getId(), req.getTempFileIds(), FileNameType.MEASURING.getValue());
//            }
            // å°è´¦è®°å½•绑定一次
            if(!CollectionUtils.isEmpty(req.getTempFileIds())){
                migrateTempFilesToFormal(measuringInstrumentLedgerRecord.getId(), req.getTempFileIds(), FileNameType.MEASURINGRecord.getValue());
            }
            return true;
        }
        return false;
    }
    @Override
    public void export(HttpServletResponse response) {
        List<MeasuringInstrumentLedger> list = measuringInstrumentLedgerMapper.listPage(new MeasuringInstrumentLedger());
        ExcelUtil<MeasuringInstrumentLedger> util = new ExcelUtil<MeasuringInstrumentLedger>(MeasuringInstrumentLedger.class);
        util.exportExcel(response, list , "客户档案数据");
    }
    @Override
    public boolean add(MeasuringInstrumentLedger measuringInstrumentLedger) throws IOException {
        SysUser sysUser = sysUserMapper.selectUserById(measuringInstrumentLedger.getUserId());
        if (sysUser == null) {
            return false;
        }
        measuringInstrumentLedger.setUserName(sysUser.getUserName());
        measuringInstrumentLedgerMapper.insert(measuringInstrumentLedger);
        if(!CollectionUtils.isEmpty(measuringInstrumentLedger.getTempFileIds())){
            migrateTempFilesToFormal(measuringInstrumentLedger.getId(), measuringInstrumentLedger.getTempFileIds(), FileNameType.MEASURING.getValue());
        }
        return true;
    }
    /**
     * å°†ä¸´æ—¶æ–‡ä»¶è¿ç§»åˆ°æ­£å¼ç›®å½•
     *
     * @param businessId  ä¸šåŠ¡ID(销售台账ID)
     * @param tempFileIds ä¸´æ—¶æ–‡ä»¶ID列表
     * @throws IOException æ–‡ä»¶æ“ä½œå¼‚常
     */
    private void migrateTempFilesToFormal(Long businessId, List<String> tempFileIds,Integer fileType) throws IOException {
        if (CollectionUtils.isEmpty(tempFileIds)) {
            return;
        }
        // æž„建正式目录路径(按业务类型和日期分组)
        String formalDir = uploadDir + LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE);
        Path formalDirPath = Paths.get(formalDir);
        // ç¡®ä¿æ­£å¼ç›®å½•存在(递归创建)
        if (!Files.exists(formalDirPath)) {
            Files.createDirectories(formalDirPath);
        }
        for (String tempFileId : tempFileIds) {
            // æŸ¥è¯¢ä¸´æ—¶æ–‡ä»¶è®°å½•
            TempFile tempFile = tempFileMapper.selectById(tempFileId);
            if (tempFile == null) {
                log.warn("临时文件不存在,跳过处理: {}", tempFileId);
                continue;
            }
            // æž„建正式文件名(包含业务ID和时间戳,避免冲突)
            String originalFilename = tempFile.getOriginalName();
            String fileExtension = FilenameUtils.getExtension(originalFilename);
            String formalFilename = businessId + "_" +
                    System.currentTimeMillis() + "_" +
                    UUID.randomUUID().toString().substring(0, 8) +
                    (StringUtils.hasText(fileExtension) ? "." + fileExtension : "");
            Path formalFilePath = formalDirPath.resolve(formalFilename);
            try {
                // æ‰§è¡Œæ–‡ä»¶è¿ç§»ï¼ˆä½¿ç”¨åŽŸå­æ“ä½œç¡®ä¿å®‰å…¨æ€§ï¼‰
                Files.move(
                        Paths.get(tempFile.getTempPath()),
                        formalFilePath,
                        StandardCopyOption.REPLACE_EXISTING,
                        StandardCopyOption.ATOMIC_MOVE
                );
                log.info("文件迁移成功: {} -> {}", tempFile.getTempPath(), formalFilePath);
                // æ›´æ–°æ–‡ä»¶è®°å½•(关联到业务ID)
                CommonFile fileRecord = new CommonFile();
                fileRecord.setCommonId(businessId);
                fileRecord.setName(originalFilename);
                fileRecord.setUrl(formalFilePath.toString());
                fileRecord.setCreateTime(LocalDateTime.now());
                fileRecord.setType(fileType);
                commonFileMapper.insert(fileRecord);
                // åˆ é™¤ä¸´æ—¶æ–‡ä»¶è®°å½•
                tempFileMapper.deleteById(tempFile);
                log.info("文件迁移成功: {} -> {}", tempFile.getTempPath(), formalFilePath);
            } catch (IOException e) {
                log.error("文件迁移失败: {}", tempFile.getTempPath(), e);
                // å¯é€‰æ‹©å›žæ»šäº‹åŠ¡æˆ–è®°å½•å¤±è´¥æ–‡ä»¶
                throw new IOException("文件迁移异常", e);
            }
        }
    }
}
src/main/java/com/ruoyi/other/service/impl/TempFileServiceImpl.java
@@ -2,11 +2,15 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.other.mapper.TempFileMapper;
import com.ruoyi.other.pojo.TempFile;
import com.ruoyi.other.service.TempFileService;
import com.ruoyi.sales.mapper.CommonFileMapper;
import com.ruoyi.sales.pojo.CommonFile;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.util.URLEncoder;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
@@ -18,7 +22,10 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.UUID;
@@ -28,6 +35,12 @@
    @Autowired
    private TempFileMapper tempFileMapper;
    @Autowired
    private CommonFileMapper commonFileMapper;
    @Value("${file.upload-dir}")
    private String uploadDir;
    @Value("${file.temp-dir}")
    private String tempDir;
@@ -67,6 +80,77 @@
        return tempFileRecord;
    }
    /**
     * å°†ä¸´æ—¶æ–‡ä»¶è¿ç§»åˆ°æ­£å¼ç›®å½•
     *
     * @param businessId  ä¸šåŠ¡ID(销售台账ID)
     * @param tempFileIds ä¸´æ—¶æ–‡ä»¶ID列表
     * @throws IOException æ–‡ä»¶æ“ä½œå¼‚常
     */
    public void migrateTempFilesToFormal(Long businessId, List<String> tempFileIds, Integer fileType) throws IOException {
        if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(tempFileIds)) {
            return;
        }
        // æž„建正式目录路径(按业务类型和日期分组)
        String formalDir = uploadDir + LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE);
        Path formalDirPath = Paths.get(formalDir);
        // ç¡®ä¿æ­£å¼ç›®å½•存在(递归创建)
        if (!Files.exists(formalDirPath)) {
            Files.createDirectories(formalDirPath);
        }
        for (String tempFileId : tempFileIds) {
            // æŸ¥è¯¢ä¸´æ—¶æ–‡ä»¶è®°å½•
            TempFile tempFile = tempFileMapper.selectById(tempFileId);
            if (tempFile == null) {
                log.warn("临时文件不存在,跳过处理: {}", tempFileId);
                continue;
            }
            // æž„建正式文件名(包含业务ID和时间戳,避免冲突)
            String originalFilename = tempFile.getOriginalName();
            String fileExtension = FilenameUtils.getExtension(originalFilename);
            String formalFilename = businessId + "_" +
                    System.currentTimeMillis() + "_" +
                    UUID.randomUUID().toString().substring(0, 8) +
                    (StringUtils.hasText(fileExtension) ? "." + fileExtension : "");
            Path formalFilePath = formalDirPath.resolve(formalFilename);
            try {
                // æ‰§è¡Œæ–‡ä»¶è¿ç§»ï¼ˆä½¿ç”¨åŽŸå­æ“ä½œç¡®ä¿å®‰å…¨æ€§ï¼‰
                Files.move(
                        Paths.get(tempFile.getTempPath()),
                        formalFilePath,
                        StandardCopyOption.REPLACE_EXISTING,
                        StandardCopyOption.ATOMIC_MOVE
                );
                log.info("文件迁移成功: {} -> {}", tempFile.getTempPath(), formalFilePath);
                // æ›´æ–°æ–‡ä»¶è®°å½•(关联到业务ID)
                CommonFile fileRecord = new CommonFile();
                fileRecord.setCommonId(businessId);
                fileRecord.setName(originalFilename);
                fileRecord.setUrl(formalFilePath.toString());
                fileRecord.setCreateTime(LocalDateTime.now());
                fileRecord.setType(fileType);
                commonFileMapper.insert(fileRecord);
                // åˆ é™¤ä¸´æ—¶æ–‡ä»¶è®°å½•
                tempFileMapper.deleteById(tempFile);
                log.info("文件迁移成功: {} -> {}", tempFile.getTempPath(), formalFilePath);
            } catch (IOException e) {
                log.error("文件迁移失败: {}", tempFile.getTempPath(), e);
                // å¯é€‰æ‹©å›žæ»šäº‹åŠ¡æˆ–è®°å½•å¤±è´¥æ–‡ä»¶
                throw new IOException("文件迁移异常", e);
            }
        }
    }
    @Scheduled(cron = "0 0 3 * * ?") // æ¯å¤©å‡Œæ™¨3点执行
    public void cleanupExpiredTempFiles() {
        LambdaQueryWrapper<TempFile> wrapper = new LambdaQueryWrapper<>();
src/main/java/com/ruoyi/project/system/controller/SysLoginController.java
@@ -73,7 +73,7 @@
     * 
     * @return ç”¨æˆ·ä¿¡æ¯
     */
    @GetMapping("getInfo")
    @GetMapping("/getInfo")
    public AjaxResult getInfo()
    {
        LoginUser loginUser = SecurityUtils.getLoginUser();
src/main/java/com/ruoyi/purchase/pojo/TicketRegistration.java
@@ -149,6 +149,9 @@
    @TableField(exist = false)
    private String issueDateEnd;
    @TableField(exist = false)
    private String supplierNameOrContractNo;
    @ApiModelProperty(value = "录入时间")
    private LocalDate enterDate;
}
src/main/java/com/ruoyi/purchase/service/impl/TicketRegistrationServiceImpl.java
@@ -329,9 +329,13 @@
    @Override
    public IPage<TicketRegistration> selectTicketRegistrationListPage(Page page, TicketRegistration ticketRegistration) {
        LambdaQueryWrapper<TicketRegistration> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(ticketRegistration.getPurchaseContractNumber())) {
            queryWrapper.like(TicketRegistration::getPurchaseContractNumber, ticketRegistration.getPurchaseContractNumber())
                    .like(TicketRegistration::getSupplierName, ticketRegistration.getSupplierName());
        if (StringUtils.isNotBlank(ticketRegistration.getSupplierNameOrContractNo())) {
            queryWrapper.and(wrapper -> wrapper
                    .like(TicketRegistration::getPurchaseContractNumber, ticketRegistration.getSupplierNameOrContractNo())
                    .or()
                    .like(TicketRegistration::getSupplierName, ticketRegistration.getSupplierNameOrContractNo())
                    .or()
                    .like(TicketRegistration::getSalesContractNo, ticketRegistration.getSupplierNameOrContractNo()));
        }
        if (!ObjectUtils.isEmpty(ticketRegistration.getIssueDateStart()) && !ObjectUtils.isEmpty(ticketRegistration.getIssueDateEnd())) {
            queryWrapper.between(TicketRegistration::getIssueDate, LocalDate.parse(ticketRegistration.getIssueDateStart(), DateTimeFormatter.ofPattern("yyyy-MM-dd")), LocalDate.parse(ticketRegistration.getIssueDateEnd(), DateTimeFormatter.ofPattern("yyyy-MM-dd")));
src/main/java/com/ruoyi/quality/controller/QualityInspectController.java
@@ -3,6 +3,7 @@
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.quality.dto.QualityInspectDto;
import com.ruoyi.quality.pojo.QualityInspect;
import com.ruoyi.quality.pojo.QualityInspectFile;
import com.ruoyi.quality.pojo.QualityInspectParam;
@@ -37,12 +38,12 @@
    /**
     * æ–°å¢ž
     * @param qualityInspect
     * @param qualityInspectDto
     * @return
     */
    @PostMapping("/add")
    public AjaxResult add(@RequestBody QualityInspect qualityInspect) {
        return AjaxResult.success(qualityInspectService.add(qualityInspect));
    public AjaxResult add(@RequestBody QualityInspectDto qualityInspectDto) {
        return AjaxResult.success(qualityInspectService.add(qualityInspectDto));
    }
    /**
@@ -72,17 +73,17 @@
     */
    @GetMapping("/{id}")
    public AjaxResult QualityInspectDetail(@PathVariable("id") Integer id) {
        return AjaxResult.success(qualityInspectService.getById(id));
        return AjaxResult.success(qualityInspectService.getDetailById(id));
    }
    /**
     * ä¿®æ”¹
     * @param qualityInspect
     * @param qualityInspectDto
     * @return
     */
    @PostMapping("/update")
    public AjaxResult update(@RequestBody QualityInspect qualityInspect) {
        return AjaxResult.success(qualityInspectService.updateQualityInspect(qualityInspect));
    public AjaxResult update(@RequestBody QualityInspectDto qualityInspectDto) {
        return AjaxResult.success(qualityInspectService.updateQualityInspect(qualityInspectDto));
    }
    /**
@@ -106,5 +107,23 @@
        qualityInspectService.qualityInspectExport(response, qualityInspect);
    }
    /**
     * æäº¤
     * @param id
     * @return
     */
    @PostMapping("/submit")
    public AjaxResult submit(Integer id) {
        return AjaxResult.success(qualityInspectService.submit(id));
    }
    /**
     * ä¸‹è½½
     * @param response
     * @param id
     */
    @PostMapping("/down")
    public void down(HttpServletResponse response,Integer id) {
        qualityInspectService.down(response, id);
    }
}
src/main/java/com/ruoyi/quality/controller/QualityTestStandardController.java
@@ -1,5 +1,6 @@
package com.ruoyi.quality.controller;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.quality.pojo.QualityTestStandard;
@@ -89,5 +90,15 @@
        qualityTestStandardService.qualityTestStandardListPageExport(response, qualityTestStandard);
    }
    /**
     * è¯¦æƒ…
     * @param productId
     * @return
     */
    @GetMapping("/product/{productId}")
    public AjaxResult QualityInspectDetail(@PathVariable("productId") Long productId) {
        return AjaxResult.success(qualityTestStandardService.list(Wrappers.<QualityTestStandard>lambdaQuery().eq(QualityTestStandard::getProductId,productId)));
    }
}
src/main/java/com/ruoyi/quality/dto/QualityInspectDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
package com.ruoyi.quality.dto;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.dto.DateQueryDto;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import com.ruoyi.quality.pojo.QualityInspect;
import com.ruoyi.quality.pojo.QualityInspectParam;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
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;
//质量检验新增编辑参数
@Data
public class QualityInspectDto extends QualityInspect implements Serializable {
    //检验项目
    private List<QualityInspectParam> qualityInspectParams;
}
src/main/java/com/ruoyi/quality/pojo/QualityInspect.java
@@ -133,5 +133,10 @@
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
    /**
     * ç±»åˆ«(0:未提交;1:已提交)
     */
    private Integer inspectState;
}
src/main/java/com/ruoyi/quality/pojo/QualityInspectParam.java
@@ -84,5 +84,9 @@
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
    // å¯¼å‡ºä½¿ç”¨
    @TableField(select = false, exist = false)
    private Integer index;
}
src/main/java/com/ruoyi/quality/service/IQualityInspectService.java
@@ -3,6 +3,7 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.quality.dto.QualityInspectDto;
import com.ruoyi.quality.pojo.QualityInspect;
import com.ruoyi.staff.pojo.StaffJoinLeaveRecord;
import com.ruoyi.staff.pojo.StaffOnJob;
@@ -13,11 +14,17 @@
public interface IQualityInspectService extends IService<QualityInspect> {
    int add(QualityInspect qualityInspect);
    int add(QualityInspectDto qualityInspectDto);
    int updateQualityInspect(QualityInspect qualityInspect);
    int updateQualityInspect(QualityInspectDto qualityInspectDto);
    IPage<QualityInspect> qualityInspectListPage(Page page, QualityInspect qualityInspect);
    void qualityInspectExport(HttpServletResponse response, QualityInspect qualityInspect);
    QualityInspectDto getDetailById(Integer id);
    int submit(Integer id);
    void down(HttpServletResponse response, Integer id);
}
src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java
@@ -2,17 +2,25 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
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.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.HackLoopTableRenderPolicy;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.quality.dto.QualityInspectDto;
import com.ruoyi.quality.mapper.QualityInspectMapper;
import com.ruoyi.quality.mapper.QualityInspectParamMapper;
import com.ruoyi.quality.mapper.QualityTestStandardMapper;
import com.ruoyi.quality.mapper.QualityUnqualifiedMapper;
import com.ruoyi.quality.pojo.QualityInspect;
import com.ruoyi.quality.pojo.QualityInspectParam;
import com.ruoyi.quality.pojo.QualityTestStandard;
import com.ruoyi.quality.pojo.QualityUnqualified;
import com.ruoyi.quality.service.IQualityInspectParamService;
import com.ruoyi.quality.service.IQualityInspectService;
import com.ruoyi.staff.mapper.StaffJoinLeaveRecordMapper;
@@ -26,6 +34,10 @@
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
@@ -40,47 +52,111 @@
    private QualityTestStandardMapper qualityTestStandardMapper;
    private QualityUnqualifiedMapper qualityUnqualifiedMapper;
    @Override
    public int add(QualityInspect qualityInspect) {
        String[] ignoreProperties = {"id"};//排除id属性
        //根据产品id查询指标维护对应新增检验参数
        List<QualityTestStandard> qualityTestStandards = qualityTestStandardMapper.selectList(Wrappers.<QualityTestStandard>lambdaQuery()
                .eq(QualityTestStandard::getProductId, qualityInspect.getProductId()));
        if (qualityTestStandards.size()>0){
    public int add(QualityInspectDto qualityInspectDto) {
        QualityInspect qualityInspect = new QualityInspect();
        BeanUtils.copyProperties(qualityInspectDto,qualityInspect);
        qualityInspect.setInspectState(0);//默认未提交
            qualityInspectMapper.insert(qualityInspect);
            List<QualityInspectParam> qualityInspectParams = qualityTestStandards.stream().map(qualityTestStandard -> {
                QualityInspectParam qualityInspectParam = new QualityInspectParam();
                BeanUtils.copyProperties(qualityTestStandard, qualityInspectParam,ignoreProperties);
        for (QualityInspectParam qualityInspectParam : qualityInspectDto.getQualityInspectParams()) {
                qualityInspectParam.setInspectId(qualityInspect.getId());
                return qualityInspectParam;
            }).collect(Collectors.toList());
            qualityInspectParamService.saveBatch(qualityInspectParams);
        }else{
            throw new BaseException("该产品没有维护检验指标,请检查!!!!!!!!");
        }
        qualityInspectParamService.saveBatch(qualityInspectDto.getQualityInspectParams());
        return 0;
    }
    @Override
    public int updateQualityInspect(QualityInspect qualityInspect) {
        String[] ignoreProperties = {"id"};//排除id属性
        //先删除所有检验参数再新增
        qualityInspectParamService.remove(Wrappers.<QualityInspectParam>lambdaQuery()
                .eq(QualityInspectParam::getInspectId,qualityInspect.getId()));
        //根据产品id查询指标维护对应新增检验参数
        List<QualityTestStandard> qualityTestStandards = qualityTestStandardMapper.selectList(Wrappers.<QualityTestStandard>lambdaQuery()
                .eq(QualityTestStandard::getProductId, qualityInspect.getProductId()));
        if (qualityTestStandards.size()>0){
            List<QualityInspectParam> qualityInspectParams = qualityTestStandards.stream().map(qualityTestStandard -> {
                QualityInspectParam qualityInspectParam = new QualityInspectParam();
                BeanUtils.copyProperties(qualityTestStandard, qualityInspectParam,ignoreProperties);
                qualityInspectParam.setInspectId(qualityInspect.getId());
                return qualityInspectParam;
            }).collect(Collectors.toList());
            qualityInspectParamService.saveBatch(qualityInspectParams);
        }else{
            throw new BaseException("该产品没有维护检验指标,请检查!!!!!!!!");
    public QualityInspectDto getDetailById(Integer id) {
        QualityInspect qualityInspect = qualityInspectMapper.selectById(id);
        List<QualityInspectParam> qualityInspectParams = qualityInspectParamService.list(Wrappers.<QualityInspectParam>lambdaQuery().eq(QualityInspectParam::getInspectId, id));
        QualityInspectDto qualityInspectDto = new QualityInspectDto();
        BeanUtils.copyProperties(qualityInspect,qualityInspectDto);
        qualityInspectDto.setQualityInspectParams(qualityInspectParams);
        return qualityInspectDto;
        }
    //提交
    @Override
    public int submit(Integer id) {
        QualityInspect qualityInspect = qualityInspectMapper.selectById(id);
        /*判断不合格*/
        if (ObjectUtils.isNotNull(qualityInspect.getCheckResult()) && qualityInspect.getCheckResult().equals("不合格")){
            QualityUnqualified qualityUnqualified = new QualityUnqualified();
            BeanUtils.copyProperties(qualityInspect,qualityUnqualified);
            qualityUnqualified.setInspectState(0);//待处理
            List<QualityInspectParam> inspectParams = qualityInspectParamService.list(Wrappers.<QualityInspectParam>lambdaQuery().eq(QualityInspectParam::getInspectId, id));
            String text = inspectParams.stream().map(QualityInspectParam::getParameterItem).collect(Collectors.joining(","));
            qualityUnqualified.setDefectivePhenomena(text+"这些指标中存在不合格");//不合格现象
            qualityUnqualifiedMapper.insert(qualityUnqualified);
        }
        qualityInspect.setInspectState(1);//已提交
        return qualityInspectMapper.updateById(qualityInspect);
    }
    /*生成检验报告*/
    @Override
    public void down(HttpServletResponse response, Integer id) {
        QualityInspect inspect = qualityInspectMapper.selectById(id);
        String inspectType="";
        switch (inspect.getInspectType()){
            case 0:
                inspectType="原材料检验";
                break;
            case 1:
                inspectType="过程检验";
                break;
            case 2:
                inspectType="出厂检验";
                break;
        }
        List<QualityInspectParam> paramList = qualityInspectParamService.list(Wrappers.<QualityInspectParam>lambdaQuery().eq(QualityInspectParam::getInspectId, id));
        int index = 1;
        for (QualityInspectParam detail : paramList) {
            detail.setIndex(index);
            index++;
        }
        InputStream inputStream = this.getClass().getResourceAsStream("/static/report-template.docx");
        Configure configure = Configure.builder()
                .bind("paramList", new HackLoopTableRenderPolicy())
                .build();
        String finalInspectType = inspectType;
        XWPFTemplate template = XWPFTemplate.compile(inputStream, configure).render(
                new HashMap<String, Object>() {{
                    put("inspect", inspect);
                    put("inspectType", finalInspectType);
                    put("paramList", paramList);
                }});
        try {
            response.setContentType("application/msword");
            String fileName = URLEncoder.encode(
                    "检验报告", "UTF-8");
            response.setHeader("Content-disposition",
                    "attachment;filename=" + fileName + ".docx");
            OutputStream os = response.getOutputStream();
            template.write(os);
            os.flush();
            os.close();
            inputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("导出失败");
        }
    }
    @Override
    public int updateQualityInspect(QualityInspectDto qualityInspectDto) {
        if (qualityInspectDto.getQualityInspectParams().size()>0) {
            qualityInspectParamService.remove(Wrappers.<QualityInspectParam>lambdaQuery().eq(QualityInspectParam::getInspectId,qualityInspectDto.getId()));
            for (QualityInspectParam qualityInspectParam : qualityInspectDto.getQualityInspectParams()) {
                qualityInspectParam.setInspectId(qualityInspectDto.getId());
            }
            qualityInspectParamService.saveBatch(qualityInspectDto.getQualityInspectParams());
        }
        QualityInspect qualityInspect = new QualityInspect();
        BeanUtils.copyProperties(qualityInspectDto,qualityInspect);
        return  qualityInspectMapper.updateById(qualityInspect);
    }
@@ -106,4 +182,6 @@
        }
    }
}
src/main/resources/application-demo.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,219 @@
# é¡¹ç›®ç›¸å…³é…ç½®
ruoyi:
  # åç§°
  name: RuoYi
  # ç‰ˆæœ¬
  version: 3.8.9
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2025
  # æ–‡ä»¶è·¯å¾„ ç¤ºä¾‹ï¼ˆ Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: /javaWork/product-inventory-management/file
  # èŽ·å–ip地址开关
  addressEnabled: false
  # éªŒè¯ç ç±»åž‹ math æ•°å­—计算 char å­—符验证
  captchaType: math
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 8089
  servlet:
    # åº”用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # è¿žæŽ¥æ•°æ»¡åŽçš„æŽ’队数,默认为100
    accept-count: 1000
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100
# æ—¥å¿—配置
logging:
  level:
    com.ruoyi: warn
    org.springframework: warn
minio:
  endpoint: http://114.132.189.42/
  port: 7019
  secure: false
  accessKey: admin
  secretKey: 12345678
  preview-expiry: 24 # é¢„览地址默认24小时
  default-bucket: uploadPath
# ç”¨æˆ·é…ç½®
user:
  password:
    # å¯†ç æœ€å¤§é”™è¯¯æ¬¡æ•°
    maxRetryCount: 5
    # å¯†ç é”å®šæ—¶é—´ï¼ˆé»˜è®¤10分钟)
    lockTime: 10
# Spring配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:mysql://114.132.189.42:9004/product-inventory-management-demo?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: 123456
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
        enabled: false
        url:
        username:
        password:
      # åˆå§‹è¿žæŽ¥æ•°
      initialSize: 5
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
      minIdle: 10
      # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
      maxActive: 20
      # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
      maxWait: 60000
      # é…ç½®è¿žæŽ¥è¶…æ—¶æ—¶é—´
      connectTimeout: 30000
      # é…ç½®ç½‘络超时时间
      socketTimeout: 60000
      # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      minEvictableIdleTimeMillis: 300000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        # è®¾ç½®ç™½åå•,不填则允许所有访问
        allow:
        url-pattern: /druid/*
        # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
        login-username: ruoyi
        login-password: 123456
      filter:
        stat:
          enabled: true
          # æ…¢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
  # èµ„源信息
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
    multipart:
      # å•个文件大小
      max-file-size: 1GB
      # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
      max-request-size: 2GB
  # æœåŠ¡æ¨¡å—
  devtools:
    restart:
      # çƒ­éƒ¨ç½²å¼€å…³
      enabled: false
  # redis é…ç½®
  redis:
    # åœ°å€
    host: 127.0.0.1
#    host: 172.17.0.1
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6379
    # æ•°æ®åº“索引
    database: 0
    # å¯†ç 
    password: root2022!
#    password:
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
    timeout: 10s
    lettuce:
      pool:
        # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
        min-idle: 0
        # è¿žæŽ¥æ± ä¸­çš„æœ€å¤§ç©ºé—²è¿žæŽ¥
        max-idle: 8
        # è¿žæŽ¥æ± çš„æœ€å¤§æ•°æ®åº“连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
# token配置
token:
  # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
  header: Authorization
  # ä»¤ç‰Œå¯†é’¥
  secret: abcdefghijklmnopqrstuvwxyz
  # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
  expireTime: 450
# MyBatis Plus配置
mybatis-plus:
  # æœç´¢æŒ‡å®šåŒ…别名   æ ¹æ®è‡ªå·±çš„项目来
  typeAliasesPackage: com.ruoyi.**.pojo
  # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # åŠ è½½å…¨å±€çš„é…ç½®æ–‡ä»¶
  configLocation: classpath:mybatis/mybatis-config.xml
  global-config:
    enable-sql-runner: true
    db-config:
      id-type: auto
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql
# Swagger配置
swagger:
  # æ˜¯å¦å¼€å¯swagger
  enabled: false
  # è¯·æ±‚前缀
  pathMapping: /dev-api
# é˜²æ­¢XSS攻击
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
  excludes: /system/notice
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
# ä»£ç ç”Ÿæˆ
gen:
  # ä½œè€…
  author: ruoyi
  # é»˜è®¤ç”ŸæˆåŒ…路径 system éœ€æ”¹æˆè‡ªå·±çš„æ¨¡å—名称 å¦‚ system monitor tool
  packageName: com.ruoyi.project.system
  # è‡ªåŠ¨åŽ»é™¤è¡¨å‰ç¼€ï¼Œé»˜è®¤æ˜¯true
  autoRemovePre: false
  # è¡¨å‰ç¼€ï¼ˆç”Ÿæˆç±»åä¸ä¼šåŒ…含表前缀,多个用逗号分隔)
  tablePrefix: sys_
  # æ˜¯å¦å…è®¸ç”Ÿæˆæ–‡ä»¶è¦†ç›–到本地(自定义路径),默认不允许
  allowOverwrite: false
file:
  temp-dir: /javaWork/product-inventory-management/file/temp/uploads
  upload-dir: /javaWork/product-inventory-management/file/prod/uploads
src/main/resources/mapper/account/AccountExpenseMapper.xml
@@ -56,4 +56,18 @@
        group by expense_type
    </select>
    <select id="report1" resultType="java.math.BigDecimal">
        SELECT
        sum(expense_money) account
        FROM account_expense ai
        where
        expense_type=#{dictValue}
        <if test="dateQueryDto.entryDateStart != null and dateQueryDto.entryDateStart != '' ">
            AND expense_date &gt;= DATE_FORMAT(#{dateQueryDto.entryDateStart},'%Y-%m-%d')
        </if>
        <if test="dateQueryDto.entryDateEnd != null and dateQueryDto.entryDateEnd != '' ">
            AND expense_date &lt;= DATE_FORMAT(#{dateQueryDto.entryDateEnd},'%Y-%m-%d')
        </if>
    </select>
</mapper>
src/main/resources/mapper/account/AccountIncomeMapper.xml
@@ -56,4 +56,17 @@
        </if>
        group by income_type
    </select>
    <select id="report1" resultType="java.math.BigDecimal">
        SELECT
        sum(income_money) account
        FROM account_income ai
        where
        income_type=#{dictValue}
        <if test="dateQueryDto.entryDateStart != null and dateQueryDto.entryDateStart != '' ">
            AND income_date &gt;= DATE_FORMAT(#{dateQueryDto.entryDateStart},'%Y-%m-%d')
        </if>
        <if test="dateQueryDto.entryDateEnd != null and dateQueryDto.entryDateEnd != '' ">
            AND income_date &lt;= DATE_FORMAT(#{dateQueryDto.entryDateEnd},'%Y-%m-%d')
        </if>
    </select>
</mapper>
src/main/resources/mapper/approve/ApproveProcessMapper.xml
@@ -32,7 +32,7 @@
        <if test="req.approveId != null and req.approveId != ''">
            and approve_id like concat('%',#{req.approveId},'%')
        </if>
        <if test="req.approveStatus != null and req.approveStatus != ''">
        <if test="req.approveStatus != null or req.approveStatus == 0">
            and approve_status = #{req.approveStatus}
        </if>
    </select>
src/main/resources/mapper/compensationperformance/CompensationPerformanceMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
<?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.compensationperformance.mapper.CompensationPerformanceMapper">
    <select id="listPage" resultType="com.ruoyi.compensationperformance.pojo.CompensationPerformance">
        select * from compensation_performance
        <where>
            <if test="req.name != null and req.name != ''">
                and `name` like concat('%',#{req.name},'%')
            </if>
            <if test="req.payDateStr != null and req.payDateStr != ''">
                and pay_date like concat('%',#{req.payDateStr},'%')
            </if>
        </where>
    </select>
</mapper>
src/main/resources/mapper/measuringinstrumentledger/MeasuringInstrumentLedgerMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,55 @@
<?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.measuringinstrumentledger.mapper.MeasuringInstrumentLedgerMapper">
    <select id="listPage" resultType="com.ruoyi.measuringinstrumentledger.pojo.MeasuringInstrumentLedger">
        SELECT
        id,
        user_id,
        user_name,
        code,
        name,
        model,
        most_date,
        valid,
        next_date,
        record_date,
        CASE
        WHEN next_date &gt;=  DATE_FORMAT(now(),'%Y-%m-%d') THEN 1
        ELSE 2
        END AS status,
        create_user,
        create_time,
        update_user,
        update_time,
        tenant_id
        FROM
        measuring_instrument_ledger
        <where>
            <!-- æŸ¥è¯¢æ¡ä»¶åŒä¸Š -->
            <if test="req.code != null and req.code != ''">
                AND code LIKE CONCAT('%', #{req.code}, '%')
            </if>
            <if test="req.name != null and req.name != ''">
                AND name LIKE CONCAT('%', #{req.name}, '%')
            </if>
            <if test="req.status != null">
                <choose>
                    <when test="req.status == 1">
                        AND next_date &gt;=  DATE_FORMAT(now(),'%Y-%m-%d')
                    </when>
                    <when test="req.status == 2">
                        AND next_date &lt;  DATE_FORMAT(now(),'%Y-%m-%d')
                    </when>
                </choose>
            </if>
            <if test="req.tenantId != null">
                AND tenant_id = #{req.tenantId}
            </if>
            <if test="req.recordDate != null">
                AND record_date = DATE_FORMAT(#{req.recordDate},'%Y-%m-%d')
            </if>
        </where>
        ORDER BY update_time DESC
    </select>
</mapper>
src/main/resources/mapper/measuringinstrumentledger/MeasuringInstrumentLedgerRecordMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,68 @@
<?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.measuringinstrumentledger.mapper.MeasuringInstrumentLedgerRecordMapper">
    <select id="listPage"
            resultType="com.ruoyi.measuringinstrumentledger.pojo.MeasuringInstrumentLedgerRecord">
        SELECT
        t1.id,
        t1.user_id,
        t1.user_name,
        t2.code,
        t2.name,
        t2.model,
        t1.valid,
        t1.record_date,
        t1.entry_date
        FROM
        measuring_instrument_ledger_record t1
        left join measuring_instrument_ledger t2 on t1.measuring_instrument_ledger_id = t2.id
        <where>
            <!-- æŸ¥è¯¢æ¡ä»¶åŒä¸Š -->
            <if test="req.code != null and req.code != ''">
                AND t2.code LIKE CONCAT('%', #{req.code}, '%')
            </if>
            <if test="req.name != null and req.name != ''">
                AND t2.name LIKE CONCAT('%', #{req.name}, '%')
            </if>
            <if test="req.entryDate != null">
                AND t1.entry_date = DATE_FORMAT(#{req.entryDate},'%Y-%m-%d')
            </if>
            <if test="req.recordDate != null">
                AND t1.record_date = DATE_FORMAT(#{req.recordDate},'%Y-%m-%d')
            </if>
        </where>
        ORDER BY t1.update_time DESC
    </select>
    <select id="list" resultType="com.ruoyi.measuringinstrumentledger.pojo.MeasuringInstrumentLedgerRecord">
        SELECT
        t1.id,
        t1.user_id,
        t1.user_name,
        t2.code,
        t2.name,
        t2.model,
        t1.valid,
        t1.record_date,
        t1.entry_date
        FROM
        measuring_instrument_ledger_record t1
        left join measuring_instrument_ledger t2 on t1.measuring_instrument_ledger_id = t2.id
        <where>
            <!-- æŸ¥è¯¢æ¡ä»¶åŒä¸Š -->
            <if test="req.code != null and req.code != ''">
                AND t2.code LIKE CONCAT('%', #{req.code}, '%')
            </if>
            <if test="req.name != null and req.name != ''">
                AND t2.name LIKE CONCAT('%', #{req.name}, '%')
            </if>
            <if test="req.entryDate != null">
                AND t1.entry_date = DATE_FORMAT(#{req.entryDate},'%Y-%m-%d')
            </if>
            <if test="req.recordDate != null">
                AND t1.record_date = DATE_FORMAT(#{req.recordDate},'%Y-%m-%d')
            </if>
        </where>
        ORDER BY t1.update_time DESC
    </select>
</mapper>
src/main/resources/static/report-template.docx
Binary files differ