maven
2025-08-05 60838d9bc1043bcc6cb171f9a30519e649b118b6
yys  新增计量器具台账,记录,修改分页插件,size=-1不分页
已修改2个文件
已添加14个文件
1400 ■■■■■ 文件已修改
src/main/java/com/ruoyi/common/enums/FileNameType.java 4 ●●● 补丁 | 查看 | 原始文档 | 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 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-demo.yml 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/measuringinstrumentledger/MeasuringInstrumentLedgerMapper.xml 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/measuringinstrumentledger/MeasuringInstrumentLedgerRecordMapper.xml 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/common/enums/FileNameType.java
@@ -5,7 +5,9 @@
    SALE(1),      // é”€å”®
    PURCHASE(2),  // é‡‡è´­
    INVOICE(3),     //发票
    PURCHASELEDGER(4);  //
    PURCHASELEDGER(4),
    MEASURING(5),  //计量器具台账
    MEASURINGRecord(6);  //计量器具台账记录
    private final int value;
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;
/**
 * @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());
            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.setNextDate(new Date(measuringInstrumentLedger.getMostDate().getTime() + measuringInstrumentLedgerRecord.getValid() * 24 * 60 * 60 * 1000L));
            }
            measuringInstrumentLedgerMapper.updateById(measuringInstrumentLedger);
        }
        // åˆ é™¤é™„ä»¶
        LambdaQueryWrapper<CommonFile> delWrapper = new LambdaQueryWrapper<>();
        delWrapper.eq(CommonFile::getCommonId, measuringInstrumentLedgerRecord.getId());
        commonFileMapper.delete(delWrapper);
        // è®°å½•附件绑定
        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,215 @@
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);
        measuringInstrumentLedgerIPage.getRecords().forEach(item -> {
            LambdaQueryWrapper<MeasuringInstrumentLedgerRecord> measuringInstrumentLedgerRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
            measuringInstrumentLedgerRecordLambdaQueryWrapper.eq(MeasuringInstrumentLedgerRecord::getMeasuringInstrumentLedgerId, item.getId());
            List<MeasuringInstrumentLedgerRecord> measuringInstrumentLedgerRecords = measuringInstrumentLedgerRecordMapper.selectList(measuringInstrumentLedgerRecordLambdaQueryWrapper);
            if(!CollectionUtils.isEmpty(measuringInstrumentLedgerRecords)){
                List<Long> collect = measuringInstrumentLedgerRecords.stream().map(MeasuringInstrumentLedgerRecord::getId).collect(Collectors.toList());
                collect.add(item.getId());
                LambdaQueryWrapper<CommonFile> salesLedgerFileWrapper = new LambdaQueryWrapper<>();
                salesLedgerFileWrapper.in(CommonFile::getCommonId, collect);
                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/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/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>