yuan
2026-06-26 0ac445694a8ffc0e26e54d788d889b3797edf7a0
feat: 添加备件领用记录功能,包括数据库表
已修改9个文件
已添加8个文件
355 ■■■■■ 文件已修改
doc/spare_parts_requisition_record.sql 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/device/pojo/DeviceMaintenance.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/device/pojo/DeviceRepair.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/device/service/impl/DeviceMaintenanceServiceImpl.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/device/service/impl/DeviceRepairServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/measuringinstrumentledger/controller/SparePartsController.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/measuringinstrumentledger/controller/SparePartsRequisitionRecordController.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/measuringinstrumentledger/dto/SparePartsUseDto.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/measuringinstrumentledger/mapper/SparePartsMapper.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/measuringinstrumentledger/mapper/SparePartsRequisitionRecordMapper.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/measuringinstrumentledger/pojo/SparePartsRequisitionRecord.java 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/measuringinstrumentledger/service/SparePartsRequisitionRecordService.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/measuringinstrumentledger/service/SparePartsService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/measuringinstrumentledger/service/impl/SparePartsRequisitionRecordServiceImpl.java 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/measuringinstrumentledger/service/impl/SparePartsServiceImpl.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/measuringinstrumentledger/SparePartsMapper.xml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/measuringinstrumentledger/SparePartsRequisitionRecordMapper.xml 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/spare_parts_requisition_record.sql
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
CREATE TABLE IF NOT EXISTS `spare_parts_requisition_record`
(
    `id`               bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
    `spare_parts_id`   bigint         DEFAULT NULL COMMENT '备件ID',
    `spare_parts_name` varchar(255)   DEFAULT NULL COMMENT '备件名称',
    `quantity`         decimal(18, 2) DEFAULT NULL COMMENT '领用数量',
    `device_ledger_id` bigint         DEFAULT NULL COMMENT '设备台账ID',
    `device_name`      varchar(255)   DEFAULT NULL COMMENT '设备名称',
    `source_type`      int            DEFAULT NULL COMMENT '来源类型 0ç»´ä¿® 1保养',
    `source_text`      varchar(32)    DEFAULT NULL COMMENT '来源文本',
    `source_id`        bigint         DEFAULT NULL COMMENT '来源单据ID',
    `operator`         varchar(64)    DEFAULT NULL COMMENT '操作人',
    `dept_id`          bigint         DEFAULT NULL COMMENT '部门ID',
    `create_user`      int            DEFAULT NULL COMMENT '创建人',
    `create_time`      datetime       DEFAULT NULL COMMENT '创建时间',
    `update_user`      int            DEFAULT NULL COMMENT '更新人',
    `update_time`      datetime       DEFAULT NULL COMMENT '更新时间',
    `tenant_id`        bigint         DEFAULT NULL COMMENT '租户ID',
    PRIMARY KEY (`id`),
    KEY `idx_spare_parts_id` (`spare_parts_id`),
    KEY `idx_source` (`source_type`, `source_id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4 COMMENT ='备件领用记录';
src/main/java/com/ruoyi/device/pojo/DeviceMaintenance.java
@@ -12,6 +12,8 @@
import java.time.LocalDateTime;
import java.util.List;
import com.ruoyi.measuringinstrumentledger.dto.SparePartsUseDto;
@Data
@TableName("device_maintenance")
@ApiModel("设备保养记录")
@@ -101,4 +103,12 @@
    @ApiModelProperty("临时文件ID列表")
    @TableField(exist = false)
    private List<String> tempFileIds;
    @ApiModelProperty("备件ID集合(逗号分隔)")
    @TableField(exist = false)
    private String sparePartsIds;
    @ApiModelProperty("备件领用明细")
    @TableField(exist = false)
    private List<SparePartsUseDto> sparePartsUseList;
}
src/main/java/com/ruoyi/device/pojo/DeviceRepair.java
@@ -10,6 +10,9 @@
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import com.ruoyi.measuringinstrumentledger.dto.SparePartsUseDto;
@Data
@TableName("device_repair")
@@ -83,5 +86,13 @@
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
    @ApiModelProperty("备件ID集合(逗号分隔)")
    @TableField(exist = false)
    private String sparePartsIds;
    @ApiModelProperty("备件领用明细")
    @TableField(exist = false)
    private List<SparePartsUseDto> sparePartsUseList;
}
src/main/java/com/ruoyi/device/service/impl/DeviceMaintenanceServiceImpl.java
@@ -13,6 +13,7 @@
import com.ruoyi.device.service.DeviceMaintenanceFileService;
import com.ruoyi.device.service.IDeviceMaintenanceService;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.measuringinstrumentledger.service.SparePartsRequisitionRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -32,6 +33,9 @@
    @Autowired
    private DeviceMaintenanceFileService deviceMaintenanceFileService;
    @Autowired
    private SparePartsRequisitionRecordService sparePartsRequisitionRecordService;
    @Override
    public IPage<DeviceMaintenanceDto> queryPage(Page page, DeviceMaintenanceDto deviceMaintenanceDto) {
@@ -65,6 +69,10 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult updateDeviceDeviceMaintenance(DeviceMaintenance deviceMaintenance) {
        DeviceMaintenance existing = this.getById(deviceMaintenance.getId());
        if (existing == null) {
            return AjaxResult.error("保养记录不存在");
        }
        // å¤„理临时文件关联
        if (deviceMaintenance.getTempFileIds() != null && !deviceMaintenance.getTempFileIds().isEmpty()) {
            for (String tempId : deviceMaintenance.getTempFileIds()) {
@@ -77,6 +85,15 @@
        }
        if (this.updateById(deviceMaintenance)) {
            if (deviceMaintenance.getSparePartsUseList() != null && !deviceMaintenance.getSparePartsUseList().isEmpty()) {
                sparePartsRequisitionRecordService.processSparePartsUse(
                        existing.getDeviceLedgerId(),
                        existing.getDeviceName(),
                        existing.getId(),
                        1,
                        "保养",
                        deviceMaintenance.getSparePartsUseList());
            }
            return AjaxResult.success();
        }
        return AjaxResult.error();
src/main/java/com/ruoyi/device/service/impl/DeviceRepairServiceImpl.java
@@ -19,6 +19,7 @@
import com.ruoyi.device.service.DeviceDefectRecordService;
import com.ruoyi.device.service.IDeviceLedgerService;
import com.ruoyi.device.service.IDeviceRepairService;
import com.ruoyi.measuringinstrumentledger.service.SparePartsRequisitionRecordService;
import com.ruoyi.other.service.TempFileService;
import com.ruoyi.sales.mapper.CommonFileMapper;
import com.ruoyi.sales.pojo.CommonFile;
@@ -58,6 +59,9 @@
    @Autowired
    private TempFileService tempFileService;
    @Autowired
    private SparePartsRequisitionRecordService sparePartsRequisitionRecordService;
    @Override
    public IPage<DeviceRepairDto> queryPage(Page page, DeviceRepairDto deviceRepairDto) {
@@ -94,6 +98,7 @@
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submitDeviceMaintain(DeviceRepair deviceRepair) {
        if (deviceRepair == null || deviceRepair.getId() == null) {
            throw new ServiceException("报修单ID不能为空");
@@ -127,6 +132,13 @@
        if (!this.updateById(existing)) {
            throw new ServiceException("提交维修失败");
        }
        sparePartsRequisitionRecordService.processSparePartsUse(
                existing.getDeviceLedgerId(),
                existing.getDeviceName(),
                existing.getId(),
                0,
                "ç»´ä¿®",
                deviceRepair.getSparePartsUseList());
        clearDefectRecordsIfNeeded(existing.getId());
    }
src/main/java/com/ruoyi/measuringinstrumentledger/controller/SparePartsController.java
@@ -58,4 +58,10 @@
        return AjaxResult.success(sparePartsService.removeById(id));
    }
    @GetMapping("/listByDevice/{deviceLedgerId}")
    @ApiOperation("备件分类-按设备查询")
    public AjaxResult listByDevice(@PathVariable Long deviceLedgerId) {
        return AjaxResult.success(sparePartsService.listByDeviceLedgerId(deviceLedgerId));
    }
}
src/main/java/com/ruoyi/measuringinstrumentledger/controller/SparePartsRequisitionRecordController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,35 @@
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.domain.AjaxResult;
import com.ruoyi.measuringinstrumentledger.pojo.SparePartsRequisitionRecord;
import com.ruoyi.measuringinstrumentledger.service.SparePartsRequisitionRecordService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/sparePartsRequisitionRecord")
@Api(tags = "备件领用记录")
public class SparePartsRequisitionRecordController {
    @Autowired
    private SparePartsRequisitionRecordService sparePartsRequisitionRecordService;
    @GetMapping("/listPage")
    @ApiOperation("备件领用记录-分页查询")
    @Log(title = "备件领用记录-分页查询", businessType = BusinessType.OTHER)
    public AjaxResult listPage(Page page, SparePartsRequisitionRecord query) {
        if (query == null) {
            query = new SparePartsRequisitionRecord();
        }
        IPage<SparePartsRequisitionRecord> result = sparePartsRequisitionRecordService.listPage(page, query);
        return AjaxResult.success(result);
    }
}
src/main/java/com/ruoyi/measuringinstrumentledger/dto/SparePartsUseDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.ruoyi.measuringinstrumentledger.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class SparePartsUseDto {
    @ApiModelProperty("备件ID")
    private Long id;
    @ApiModelProperty("领用数量")
    private BigDecimal quantity;
}
src/main/java/com/ruoyi/measuringinstrumentledger/mapper/SparePartsMapper.java
@@ -5,10 +5,14 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.measuringinstrumentledger.dto.SparePartsDto;
import com.ruoyi.measuringinstrumentledger.pojo.SpareParts;
import io.lettuce.core.dynamic.annotation.Param;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface SparePartsMapper extends BaseMapper<SpareParts> {
    IPage<SparePartsDto> listPage(Page page,@Param("spareParts") SpareParts spareParts);
    IPage<SparePartsDto> listPage(Page page, SpareParts spareParts);
    List<SparePartsDto> listByDeviceLedgerId(@Param("deviceLedgerId") Long deviceLedgerId);
}
src/main/java/com/ruoyi/measuringinstrumentledger/mapper/SparePartsRequisitionRecordMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
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.SparePartsRequisitionRecord;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface SparePartsRequisitionRecordMapper extends BaseMapper<SparePartsRequisitionRecord> {
    IPage<SparePartsRequisitionRecord> listPage(Page page, @Param("query") SparePartsRequisitionRecord query);
}
src/main/java/com/ruoyi/measuringinstrumentledger/pojo/SparePartsRequisitionRecord.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,71 @@
package com.ruoyi.measuringinstrumentledger.pojo;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
@TableName("spare_parts_requisition_record")
public class SparePartsRequisitionRecord {
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty("备件ID")
    private Long sparePartsId;
    @ApiModelProperty("备件名称")
    private String sparePartsName;
    @ApiModelProperty("领用数量")
    private BigDecimal quantity;
    @ApiModelProperty("设备台账ID")
    private Long deviceLedgerId;
    @ApiModelProperty("设备名称")
    private String deviceName;
    @ApiModelProperty("来源类型 0ç»´ä¿® 1保养")
    private Integer sourceType;
    @ApiModelProperty("来源文本")
    private String sourceText;
    @ApiModelProperty("来源单据ID")
    private Long sourceId;
    @ApiModelProperty("操作人")
    private String operator;
    @ApiModelProperty("部门ID")
    private Long deptId;
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    @TableField(fill = FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
}
src/main/java/com/ruoyi/measuringinstrumentledger/service/SparePartsRequisitionRecordService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
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.SparePartsUseDto;
import com.ruoyi.measuringinstrumentledger.pojo.SparePartsRequisitionRecord;
import java.util.List;
public interface SparePartsRequisitionRecordService extends IService<SparePartsRequisitionRecord> {
    IPage<SparePartsRequisitionRecord> listPage(Page page, SparePartsRequisitionRecord query);
    void processSparePartsUse(Long deviceLedgerId, String deviceName, Long sourceId,
                              Integer sourceType, String sourceText, List<SparePartsUseDto> useList);
}
src/main/java/com/ruoyi/measuringinstrumentledger/service/SparePartsService.java
@@ -13,4 +13,6 @@
    IPage<SparePartsDto> listPage(Page page, SpareParts spareParts);
    List<SparePartsDto> getTree();
    List<SparePartsDto> listByDeviceLedgerId(Long deviceLedgerId);
}
src/main/java/com/ruoyi/measuringinstrumentledger/service/impl/SparePartsRequisitionRecordServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,78 @@
package com.ruoyi.measuringinstrumentledger.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.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.measuringinstrumentledger.dto.SparePartsUseDto;
import com.ruoyi.measuringinstrumentledger.mapper.SparePartsMapper;
import com.ruoyi.measuringinstrumentledger.mapper.SparePartsRequisitionRecordMapper;
import com.ruoyi.measuringinstrumentledger.pojo.SpareParts;
import com.ruoyi.measuringinstrumentledger.pojo.SparePartsRequisitionRecord;
import com.ruoyi.measuringinstrumentledger.service.SparePartsRequisitionRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.List;
@Service
public class SparePartsRequisitionRecordServiceImpl
        extends ServiceImpl<SparePartsRequisitionRecordMapper, SparePartsRequisitionRecord>
        implements SparePartsRequisitionRecordService {
    @Autowired
    private SparePartsRequisitionRecordMapper sparePartsRequisitionRecordMapper;
    @Autowired
    private SparePartsMapper sparePartsMapper;
    @Override
    public IPage<SparePartsRequisitionRecord> listPage(Page page, SparePartsRequisitionRecord query) {
        return sparePartsRequisitionRecordMapper.listPage(page, query);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void processSparePartsUse(Long deviceLedgerId, String deviceName, Long sourceId,
                                     Integer sourceType, String sourceText,
                                     List<SparePartsUseDto> useList) {
        if (useList == null || useList.isEmpty()) {
            return;
        }
        String operator = SecurityUtils.getLoginUser().getNickName();
        for (SparePartsUseDto useItem : useList) {
            if (useItem == null || useItem.getId() == null) {
                continue;
            }
            BigDecimal quantity = useItem.getQuantity();
            if (quantity == null || quantity.compareTo(BigDecimal.ZERO) <= 0) {
                throw new ServiceException("领用数量必须大于0");
            }
            SpareParts sparePart = sparePartsMapper.selectById(useItem.getId());
            if (sparePart == null) {
                throw new ServiceException("备件不存在");
            }
            if (sparePart.getQuantity() == null || sparePart.getQuantity().compareTo(quantity) < 0) {
                throw new ServiceException("备件[" + sparePart.getName() + "]库存不足");
            }
            sparePart.setQuantity(sparePart.getQuantity().subtract(quantity));
            sparePartsMapper.updateById(sparePart);
            SparePartsRequisitionRecord record = new SparePartsRequisitionRecord();
            record.setSparePartsId(sparePart.getId());
            record.setSparePartsName(sparePart.getName());
            record.setQuantity(quantity);
            record.setDeviceLedgerId(deviceLedgerId);
            record.setDeviceName(deviceName);
            record.setSourceId(sourceId);
            record.setSourceType(sourceType);
            record.setSourceText(StringUtils.isNotEmpty(sourceText) ? sourceText : (sourceType == 0 ? "ç»´ä¿®" : "保养"));
            record.setOperator(operator);
            sparePartsRequisitionRecordMapper.insert(record);
        }
    }
}
src/main/java/com/ruoyi/measuringinstrumentledger/service/impl/SparePartsServiceImpl.java
@@ -52,6 +52,14 @@
        return buildTree(records);
    }
    @Override
    public List<SparePartsDto> listByDeviceLedgerId(Long deviceLedgerId) {
        if (deviceLedgerId == null) {
            return new ArrayList<>();
        }
        return sparePartsMapper.listByDeviceLedgerId(deviceLedgerId);
    }
    /**
     * å°†æ‰å¹³ç»“构数据转换为树形结构
src/main/resources/mapper/measuringinstrumentledger/SparePartsMapper.xml
@@ -11,4 +11,12 @@
            </if>
        </where>
    </select>
    <select id="listByDeviceLedgerId" resultType="com.ruoyi.measuringinstrumentledger.dto.SparePartsDto">
        select sp.*
        from spare_parts sp
        where sp.status = '正常'
          and FIND_IN_SET(#{deviceLedgerId}, sp.device_ids) > 0
        order by sp.id desc
    </select>
</mapper>
src/main/resources/mapper/measuringinstrumentledger/SparePartsRequisitionRecordMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
<?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.SparePartsRequisitionRecordMapper">
    <select id="listPage" resultType="com.ruoyi.measuringinstrumentledger.pojo.SparePartsRequisitionRecord">
        SELECT *
        FROM spare_parts_requisition_record
        <where>
            <if test="query.sparePartsName != null and query.sparePartsName != ''">
                AND spare_parts_name LIKE CONCAT('%', #{query.sparePartsName}, '%')
            </if>
            <if test="query.sourceType != null">
                AND source_type = #{query.sourceType}
            </if>
        </where>
        ORDER BY create_time DESC
    </select>
</mapper>