liding
3 天以前 0f8f4c5de1d817aa87c4c79e966d3cfbd0997aeb
1.设备领用添加记录 2.采购添加运费
已修改9个文件
已添加8个文件
593 ■■■■■ 文件已修改
main-business/src/main/java/com/ruoyi/business/controller/EquipmentUsageDetailController.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/dto/EquipmentUsageDetailDto.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/dto/EquipmentUsageRecordDto.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/entity/EquipmentUsageDetail.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/entity/EquipmentUsageRecord.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/entity/PurchaseRegistration.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/mapper/EquipmentUsageDetailMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/service/EquipmentUsageDetailService.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/service/impl/EquipmentUsageDetailServiceImpl.java 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/service/impl/EquipmentUsageRecordServiceImpl.java 147 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/service/impl/PendingInventoryServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/service/impl/ProductionMasterServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/resources/db/migration/postgresql/V20250603160101__create_table_purchase_registration.sql 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/resources/db/migration/postgresql/V20250604111200__create_table_official_inventory.sql 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/resources/db/migration/postgresql/V20250707155600__create_table_equipment_usage_record.sql 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/resources/db/migration/postgresql/V20250723134500__create_table_equipment_usage_detail.sql 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/resources/mapper/EquipmentUsageDetailMapper.xml 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main-business/src/main/java/com/ruoyi/business/controller/EquipmentUsageDetailController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,43 @@
package com.ruoyi.business.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.business.dto.EquipmentManagementDto;
import com.ruoyi.business.dto.EquipmentUsageDetailDto;
import com.ruoyi.business.entity.EquipmentManagement;
import com.ruoyi.business.entity.EquipmentUsageDetail;
import com.ruoyi.business.mapper.EquipmentUsageDetailMapper;
import com.ruoyi.business.service.EquipmentManagementService;
import com.ruoyi.business.service.EquipmentUsageDetailService;
import com.ruoyi.common.core.domain.R;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.RestController;
/**
 * <p>
 * è®¾å¤‡ä½¿ç”¨æ˜Žç»†è¡¨ å‰ç«¯æŽ§åˆ¶å™¨
 * </p>
 *
 * @author ld
 * @since 2025-07-23
 */
@RestController
@AllArgsConstructor
@RequestMapping("/equipmentUsageDetail")
public class EquipmentUsageDetailController {
    private EquipmentUsageDetailService equipmentUsageDetailService;
    /**
     * è®¾å¤‡é¢†ç”¨å½’还记录查询
     */
    @GetMapping("/list")
    public R<IPage<EquipmentUsageDetailDto>> list(Page<EquipmentUsageDetail> page,EquipmentUsageDetailDto equipmentUsageDetailDto) {
        IPage<EquipmentUsageDetailDto> list = equipmentUsageDetailService.selectEquipmentUsageDetailList(page,equipmentUsageDetailDto);
        return R.ok(list);
    }
}
main-business/src/main/java/com/ruoyi/business/dto/EquipmentUsageDetailDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,25 @@
package com.ruoyi.business.dto;
import com.baomidou.mybatisplus.annotation.TableField;
import com.ruoyi.business.entity.EquipmentUsageDetail;
import lombok.Data;
@Data
public class EquipmentUsageDetailDto extends EquipmentUsageDetail {
    /**
     * è®¾å¤‡ç¼–号
     */
    @TableField(value = "equipment_no")
    private String equipmentNo;
    /**
     * è®¾å¤‡åç§°
     */
    @TableField(value = "equipment_name")
    private String equipmentName;
    /**
     * è§„格型号
     */
    @TableField(value = "specification")
    private String specification;
}
main-business/src/main/java/com/ruoyi/business/dto/EquipmentUsageRecordDto.java
@@ -11,4 +11,6 @@
    private String equipmentName; //设备名称
    private String userName; //领用人
    private Integer totalReturnNo; //已归还总数
}
main-business/src/main/java/com/ruoyi/business/entity/EquipmentUsageDetail.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@
package com.ruoyi.business.entity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import com.ruoyi.common.core.domain.MyBaseEntity;
/**
 * è®¾å¤‡ä½¿ç”¨æ˜Žç»†è¡¨ å®žä½“ç±»
 *
 * @author ld
 * @date 2025-07-23
 */
@Data
@TableName("equipment_usage_detail")
public class EquipmentUsageDetail extends MyBaseEntity {
    private static final long serialVersionUID = 1L;
    /**
     * ä¸»é”®ID
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * å…³è”的使用记录ID
     */
    @TableField(value = "usage_id")
    private Long usageId;
    /**
     * å…³è”的设备ID
     */
    @TableField(value = "equipment_id")
    private Long equipmentId;
    /**
     * æ“ä½œç±»åž‹ï¼š1-领用,2-归还
     */
    @TableField(value = "operation_type")
    private Integer operationType;
    /**
     * æ“ä½œæ•°é‡
     */
    @TableField(value = "quantity")
    private Integer quantity;
    /**
     * æ“ä½œäººID
     */
    @TableField(value = "operator_id")
    private Long operatorId;
    /**
     * æ“ä½œäºº
     */
    @TableField(value = "operator")
    private String operator;
    /**
     * å¤‡æ³¨
     */
    @TableField(value = "remark")
    private String remark;
}
main-business/src/main/java/com/ruoyi/business/entity/EquipmentUsageRecord.java
@@ -1,6 +1,7 @@
package com.ruoyi.business.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import com.ruoyi.common.core.domain.MyBaseEntity;
@@ -29,10 +30,15 @@
    @TableField(value = "equipment_id")
    private Long equipmentId;
    /**
     * ä½¿ç”¨æ•°é‡
     * é¢†ç”¨æ•°é‡
     */
    @TableField(value = "usage_quantity")
    private Integer usageQuantity;
    /**
     * å½’还数量
     */
    @TableField(value = "return_quantity")
    private Integer returnQuantity;
    /**
     * ä½¿ç”¨äººID
     */
@@ -52,11 +58,13 @@
     * ä½¿ç”¨å¼€å§‹æ—¶é—´
     */
    @TableField(value = "usage_start_time")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDate usageStartTime;
    /**
     * ä½¿ç”¨ç»“束时间
     */
    @TableField(value = "usage_end_time")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDate usageEndTime;
    /**
     * å¤‡æ³¨ä¿¡æ¯
main-business/src/main/java/com/ruoyi/business/entity/PurchaseRegistration.java
@@ -88,4 +88,9 @@
     */
    @TableField(value = "registration_date")
    private LocalDate registrationDate;
    /**
     * è¿è´¹
     */
    @TableField(value = "freight")
    private BigDecimal freight;
}
main-business/src/main/java/com/ruoyi/business/mapper/EquipmentUsageDetailMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.ruoyi.business.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.business.entity.EquipmentUsageDetail;
import org.apache.ibatis.annotations.Mapper;
/**
 * <p>
 * è®¾å¤‡ä½¿ç”¨æ˜Žç»†è¡¨ Mapper æŽ¥å£
 * </p>
 *
 * @author ld
 * @since 2025-07-23
 */
@Mapper
public interface EquipmentUsageDetailMapper extends BaseMapper<EquipmentUsageDetail> {
}
main-business/src/main/java/com/ruoyi/business/service/EquipmentUsageDetailService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.ruoyi.business.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.business.dto.EquipmentUsageDetailDto;
import com.ruoyi.business.entity.EquipmentUsageDetail;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 * è®¾å¤‡ä½¿ç”¨æ˜Žç»†è¡¨ æœåŠ¡ç±»
 * </p>
 *
 * @author ld
 * @since 2025-07-23
 */
public interface EquipmentUsageDetailService extends IService<EquipmentUsageDetail> {
    IPage<EquipmentUsageDetailDto> selectEquipmentUsageDetailList(Page<EquipmentUsageDetail> page, EquipmentUsageDetailDto equipmentUsageDetailDto);
}
main-business/src/main/java/com/ruoyi/business/service/impl/EquipmentUsageDetailServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,118 @@
package com.ruoyi.business.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.ruoyi.business.dto.EquipmentManagementDto;
import com.ruoyi.business.dto.EquipmentUsageDetailDto;
import com.ruoyi.business.entity.EquipmentManagement;
import com.ruoyi.business.entity.EquipmentUsageDetail;
import com.ruoyi.business.entity.EquipmentUsageRecord;
import com.ruoyi.business.mapper.EquipmentManagementMapper;
import com.ruoyi.business.mapper.EquipmentUsageDetailMapper;
import com.ruoyi.business.mapper.EquipmentUsageRecordMapper;
import com.ruoyi.business.service.EquipmentManagementService;
import com.ruoyi.business.service.EquipmentUsageDetailService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.business.service.EquipmentUsageRecordService;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.bean.BeanUtils;
import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
 * <p>
 * è®¾å¤‡ä½¿ç”¨æ˜Žç»†è¡¨ æœåŠ¡å®žçŽ°ç±»
 * </p>
 *
 * @author ld
 * @since 2025-07-23
 */
@Service
@RequiredArgsConstructor
public class EquipmentUsageDetailServiceImpl extends ServiceImpl<EquipmentUsageDetailMapper, EquipmentUsageDetail> implements EquipmentUsageDetailService {
    private final EquipmentUsageDetailMapper equipmentUsageDetailMapper;
    private final EquipmentUsageRecordMapper equipmentUsageRecordMapper;
    private final EquipmentManagementMapper equipmentManagementMapper;
    @Override
    public IPage<EquipmentUsageDetailDto> selectEquipmentUsageDetailList(Page<EquipmentUsageDetail> page,EquipmentUsageDetailDto equipmentUsageDetailDto) {
        // å¿…须传递usageId参数
        if (equipmentUsageDetailDto.getUsageId() == null) {
            throw new BaseException("请选择使用记录");
        }
        LambdaQueryWrapper<EquipmentUsageDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(EquipmentUsageDetail::getUsageId, equipmentUsageDetailDto.getUsageId());
        Page<EquipmentUsageDetail> entityPage = equipmentUsageDetailMapper.selectPage(page, queryWrapper);
        IPage<EquipmentUsageDetailDto> dtoPage = new Page<>();
        BeanUtils.copyProperties(entityPage, dtoPage);
        // å…ˆèŽ·å–ä¸»è¡¨è®°å½•
        List<Long> usageIds = entityPage.getRecords().stream()
                .map(EquipmentUsageDetail::getUsageId)
                .distinct()
                .collect(Collectors.toList());
        if (!usageIds.isEmpty()) {
            // æŸ¥è¯¢å…³è”的使用记录
            List<EquipmentUsageRecord> usageRecords = equipmentUsageRecordMapper.selectList(
                    new LambdaQueryWrapper<EquipmentUsageRecord>()
                            .in(EquipmentUsageRecord::getId, usageIds)
            );
            // èŽ·å–æ‰€æœ‰è®¾å¤‡ID
            List<Long> equipmentIds = usageRecords.stream()
                    .map(EquipmentUsageRecord::getEquipmentId)
                    .distinct()
                    .collect(Collectors.toList());
            // æŸ¥è¯¢è®¾å¤‡ä¿¡æ¯
            Map<Long, EquipmentManagement> equipmentMap;
            if (!equipmentIds.isEmpty()) {
                equipmentMap = equipmentManagementMapper.selectList(
                        new LambdaQueryWrapper<EquipmentManagement>()
                                .in(EquipmentManagement::getId, equipmentIds)
                ).stream().collect(Collectors.toMap(EquipmentManagement::getId, Function.identity()));
            } else {
                equipmentMap = new HashMap<>();
            }
            // æž„建使用记录ID到设备ID的映射
            Map<Long, Long> usageIdToEquipmentIdMap = usageRecords.stream()
                    .collect(Collectors.toMap(EquipmentUsageRecord::getId, EquipmentUsageRecord::getEquipmentId));
            // è½¬æ¢DTO并填充设备信息
            List<EquipmentUsageDetailDto> dtoList = entityPage.getRecords().stream().map(detail -> {
                EquipmentUsageDetailDto detailDto = new EquipmentUsageDetailDto();
                BeanUtils.copyProperties(detail, detailDto);
                // èŽ·å–å…³è”çš„è®¾å¤‡ID
                Long equipmentId = usageIdToEquipmentIdMap.get(detail.getUsageId());
                if (equipmentId != null && equipmentMap.containsKey(equipmentId)) {
                    EquipmentManagement equipment = equipmentMap.get(equipmentId);
                    detailDto.setEquipmentNo(equipment.getEquipmentNo());
                    detailDto.setEquipmentName(equipment.getEquipmentName());
                    detailDto.setSpecification(equipment.getSpecification());
                }
                return detailDto;
            }).collect(Collectors.toList());
            dtoPage.setRecords(dtoList);
        } else {
            dtoPage.setRecords(Collections.emptyList());
        }
        return dtoPage;
    }
}
main-business/src/main/java/com/ruoyi/business/service/impl/EquipmentUsageRecordServiceImpl.java
@@ -8,8 +8,10 @@
import com.ruoyi.business.dto.EquipmentManagementDto;
import com.ruoyi.business.dto.EquipmentUsageRecordDto;
import com.ruoyi.business.entity.EquipmentManagement;
import com.ruoyi.business.entity.EquipmentUsageDetail;
import com.ruoyi.business.entity.EquipmentUsageRecord;
import com.ruoyi.business.mapper.EquipmentManagementMapper;
import com.ruoyi.business.mapper.EquipmentUsageDetailMapper;
import com.ruoyi.business.mapper.EquipmentUsageRecordMapper;
import com.ruoyi.business.service.EquipmentUsageRecordService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -43,6 +45,8 @@
    private final EquipmentUsageRecordMapper equipmentUsageRecordMapper;
    private final EquipmentManagementMapper equipmentManagementMapper;
    private final EquipmentUsageDetailMapper equipmentUsageDetailMapper;
    private final SysUserMapper sysUserMapper;
@@ -83,6 +87,15 @@
            if (sysUser != null) {
                dto.setUserName(sysUser.getNickName());
            }
            int totalReturnNo = equipmentUsageDetailMapper.selectList(
                            new LambdaQueryWrapper<EquipmentUsageDetail>()
                                    .eq(EquipmentUsageDetail::getUsageId, entity.getId())
                                    .eq(EquipmentUsageDetail::getOperationType,2))
                    .stream()
                    .mapToInt(EquipmentUsageDetail::getQuantity)
                    .sum();
            dto.setTotalReturnNo(totalReturnNo);
            return dto;
        }).toList();
        dtoPage.setRecords(dtoRecords);
@@ -97,13 +110,10 @@
            throw new IllegalArgumentException("设备使用记录参数不能为空");
        }
        // å¤åˆ¶å±žæ€§åˆ°å®žä½“对象
        EquipmentUsageRecord equipmentUsageRecord = new EquipmentUsageRecord();
        BeanUtils.copyProperties(equipmentUsageRecordDto, equipmentUsageRecord);
        // èŽ·å–è®¾å¤‡ID和领用数量
        // èŽ·å–è®¾å¤‡ID和操作数量
        Long equipmentId = equipmentUsageRecordDto.getEquipmentId();
        Integer newUsageQuantity = equipmentUsageRecordDto.getUsageQuantity();
        Long userId = equipmentUsageRecordDto.getUserId();
        String username = sysUserMapper.selectUserById(userId).getNickName();
        // æŸ¥è¯¢è®¾å¤‡ä¿¡æ¯
        EquipmentManagement equipment = equipmentManagementMapper.selectById(equipmentId);
@@ -111,20 +121,10 @@
            throw new RuntimeException("设备不存在");
        }
        int result;
        // æ–°å¢žè®°å½•逻辑
        if (Objects.isNull(equipmentUsageRecordDto.getId())) {
            // æ£€æŸ¥åº“存是否充足
            if (equipment.getQuantity() < newUsageQuantity) {
                throw new RuntimeException("库存不足,当前库存:" + equipment.getQuantity());
            }
            // æ‰£å‡åº“å­˜
            equipment.setQuantity(equipment.getQuantity() - newUsageQuantity);
            equipmentManagementMapper.updateById(equipment);
            // è®¾ç½®ä½¿ç”¨å¼€å§‹æ—¶é—´ä¸ºå½“前时间
            equipmentUsageRecord.setUsageStartTime(LocalDate.now());
            return equipmentUsageRecordMapper.insert(equipmentUsageRecord);
            result = handleNewUsage(equipmentUsageRecordDto, equipment, userId, username);
        } else {
            // ç¼–辑记录逻辑
            EquipmentUsageRecord originalRecord = equipmentUsageRecordMapper.selectById(equipmentUsageRecordDto.getId());
@@ -134,29 +134,90 @@
            // å¤„理归还逻辑
            if (equipmentUsageRecordDto.getEquipmentStatus() == 2) {
                // æ£€æŸ¥å½’还数量是否合法
                if (newUsageQuantity > originalRecord.getUsageQuantity()) {
                    throw new RuntimeException("归还数量不能超过原领用数量");
                result = handleReturnOperation(equipmentUsageRecordDto, equipment, originalRecord, userId, username);
            } else {
                // å¤„理普通编辑逻辑(非归还状态)
                result = handleEditOperation(equipmentUsageRecordDto, equipment, originalRecord, userId, username);
            }
        }
        return result;
                }
                // è®¡ç®—实际归还数量(原领用数量 - æ–°é¢†ç”¨æ•°é‡ï¼‰
                int returnedQuantity = originalRecord.getUsageQuantity() - newUsageQuantity;
    private int handleNewUsage(EquipmentUsageRecordDto dto, EquipmentManagement equipment, Long userId, String username) {
        // æ£€æŸ¥åº“å­˜
        if (equipment.getQuantity() < dto.getUsageQuantity()) {
            throw new RuntimeException("库存不足,当前库存:" + equipment.getQuantity());
        }
                // æ¢å¤éƒ¨åˆ†åº“å­˜
                equipment.setQuantity(equipment.getQuantity() + returnedQuantity);
        // åˆ›å»ºä¸»è®°å½•
        EquipmentUsageRecord record = new EquipmentUsageRecord();
        BeanUtils.copyProperties(dto, record);
        record.setUsageStartTime(LocalDate.now());
        record.setEquipmentStatus(1); // ä½¿ç”¨ä¸­çŠ¶æ€
        record.setReturnQuantity(0);
        // æ‰£å‡åº“å­˜
        equipment.setQuantity(equipment.getQuantity() - dto.getUsageQuantity());
                equipmentManagementMapper.updateById(equipment);
                // å¦‚果全部归还,设置归还时间
                if (newUsageQuantity == 0) {
                    equipmentUsageRecord.setUsageEndTime(LocalDate.now());
                }
                return equipmentUsageRecordMapper.updateById(equipmentUsageRecord);
        // ä¿å­˜ä¸»è®°å½•
        int result = equipmentUsageRecordMapper.insert(record);
        // ä¿å­˜é¢†ç”¨æ˜Žç»†è®°å½•
        if (result > 0) {
            saveUsageDetail(record.getId(), record.getEquipmentId(), 1, dto.getUsageQuantity(), userId, username, "设备领用");
            }
            // å¤„理普通编辑逻辑(非归还状态)
            if (!newUsageQuantity.equals(originalRecord.getUsageQuantity())) {
        return result;
    }
    private int handleReturnOperation(EquipmentUsageRecordDto dto, EquipmentManagement equipment,
                                      EquipmentUsageRecord originalRecord, Long userId, String username) {
        // èŽ·å–æœ¬æ¬¡å½’è¿˜æ•°é‡
        Integer returnQuantity = dto.getReturnQuantity();
        if (returnQuantity == null || returnQuantity <= 0) {
            throw new RuntimeException("归还数量必须大于0");
        }
        // è®¡ç®—剩余未归还数量
        int remainingQuantity = originalRecord.getUsageQuantity() - originalRecord.getReturnQuantity();
        if (returnQuantity > remainingQuantity) {
            throw new RuntimeException("归还数量不能超过未归还数量,剩余未归还数量:" + remainingQuantity);
        }
        // æ›´æ–°ä¸»è®°å½•
        EquipmentUsageRecord updateRecord = new EquipmentUsageRecord();
        updateRecord.setId(originalRecord.getId());
        updateRecord.setReturnQuantity(originalRecord.getReturnQuantity() + returnQuantity);
        updateRecord.setEquipmentStatus(2); // å·²å½’还状态
        updateRecord.setUsageEndTime(LocalDate.now());
        // å¦‚果全部归还,更新状态和时间
//        if (updateRecord.getReturnQuantity().equals(originalRecord.getUsageQuantity())) {
//
//        }
        // æ¢å¤åº“å­˜
        equipment.setQuantity(equipment.getQuantity() + returnQuantity);
        equipmentManagementMapper.updateById(equipment);
        // æ›´æ–°ä¸»è®°å½•
        int result = equipmentUsageRecordMapper.updateById(updateRecord);
        // ä¿å­˜å½’还明细记录
        if (result > 0) {
            String remark = "设备归还" + (updateRecord.getEquipmentStatus() == 2 ? "(全部归还)" : "(部分归还)");
            saveUsageDetail(originalRecord.getId(), originalRecord.getEquipmentId(), 2, returnQuantity, userId, username, remark);
        }
        return result;
    }
    private int handleEditOperation(EquipmentUsageRecordDto dto, EquipmentManagement equipment,
                                    EquipmentUsageRecord originalRecord, Long userId, String username) {
        // æ£€æŸ¥é¢†ç”¨æ•°é‡æ˜¯å¦æœ‰å˜åŒ–
        if (!dto.getUsageQuantity().equals(originalRecord.getUsageQuantity())) {
                // è®¡ç®—库存变化量(旧数量 - æ–°æ•°é‡ï¼‰
                int quantityDelta = originalRecord.getUsageQuantity() - newUsageQuantity;
            int quantityDelta = originalRecord.getUsageQuantity() - dto.getUsageQuantity();
                // æ£€æŸ¥è°ƒæ•´åŽåº“存是否充足
                int newInventory = equipment.getQuantity() + quantityDelta;
@@ -169,10 +230,28 @@
                if (equipmentManagementMapper.updateById(equipment) == 0) {
                    throw new RuntimeException("库存更新失败,可能已被其他操作修改");
                }
            // è®°å½•数量变更明细
            saveUsageDetail(originalRecord.getId(), originalRecord.getEquipmentId(), 3, dto.getUsageQuantity(), userId, username,
                    "领用数量变更:" + originalRecord.getUsageQuantity() + "→" + dto.getUsageQuantity());
            }
            // æ›´æ–°é¢†ç”¨è®°å½•
            return equipmentUsageRecordMapper.updateById(equipmentUsageRecord);
        EquipmentUsageRecord updateRecord = new EquipmentUsageRecord();
        BeanUtils.copyProperties(dto, updateRecord);
        return equipmentUsageRecordMapper.updateById(updateRecord);
        }
    private void saveUsageDetail(Long usageId, Long equipmentId, Integer operationType, Integer quantity,
                                 Long operatorId, String operator, String remark) {
        EquipmentUsageDetail detail = new EquipmentUsageDetail();
        detail.setUsageId(usageId);
        detail.setEquipmentId(equipmentId);
        detail.setOperationType(operationType);
        detail.setQuantity(quantity);
        detail.setOperatorId(operatorId);
        detail.setOperator(operator);
        detail.setRemark(remark);
        equipmentUsageDetailMapper.insert(detail);
    }
}
main-business/src/main/java/com/ruoyi/business/service/impl/PendingInventoryServiceImpl.java
@@ -316,7 +316,7 @@
            // 2. å‡†å¤‡å¾…入库记录
            Long userId = SecurityUtils.getUserId();
            PendingInventory pendingInventory = new PendingInventory();
            pendingInventory.setUnit("t");
            pendingInventory.setUnit("吨");
            pendingInventory.setRegistrantId(userId);
            pendingInventory.setRegistrationDate(LocalDate.now());
            pendingInventory.setSupplierName("配煤计算器方案入库");
@@ -352,7 +352,7 @@
            // 5. è®¾ç½®ä»·æ ¼å’Œæ•°é‡
            BigDecimal cost = safeGetBigDecimal(map, "cost");
            BigDecimal tonnage = safeGetBigDecimal(map, "totalTonnage");
            BigDecimal tonnage = safeGetBigDecimal(map, "createCoalQuantity");
            if (cost == null || tonnage == null) {
                throw new BaseException("成本或吨位不能为空");
main-business/src/main/java/com/ruoyi/business/service/impl/ProductionMasterServiceImpl.java
@@ -295,7 +295,7 @@
            PendingInventory pending = new PendingInventory();
            pending.setCoalId(p.getCoalId());
            pending.setInventoryQuantity(p.getProductionQuantity());
            pending.setUnit("t");
            pending.setUnit("吨");
            pending.setSupplierName(formattedDate + " - " + "生产加工入库");
            // éžç©ºå¤„理
main-business/src/main/resources/db/migration/postgresql/V20250603160101__create_table_purchase_registration.sql
@@ -15,6 +15,7 @@
    total_price_excluding_tax DECIMAL(10, 2) NOT NULL,           -- ä¸å«ç¨Žæ€»ä»·ï¼Œä¸å…è®¸ä¸ºç©º
    registrant_id             BIGINT         NOT NULL,           -- ç™»è®°äººid,不允许为空
    registration_date         DATE           NOT NULL,           -- ç™»è®°æ—¥æœŸï¼Œä¸å…è®¸ä¸ºç©º
    freight                   DECIMAL(10, 2) NOT NULL,           -- è¿è´¹
    deleted                   INT            NOT NULL DEFAULT 0, -- è½¯åˆ é™¤æ ‡å¿—:0=未删除,1=已删除
    create_by                 VARCHAR(255),                      -- åˆ›å»ºäººç”¨æˆ·å
@@ -39,6 +40,8 @@
COMMENT ON COLUMN purchase_registration.total_price_excluding_tax IS '不含税总价';
COMMENT ON COLUMN purchase_registration.registrant_id IS '登记人id';
COMMENT ON COLUMN purchase_registration.registration_date IS '登记日期';
COMMENT ON COLUMN purchase_registration.freight IS '运费';
COMMENT ON COLUMN purchase_registration.deleted IS '软删除标志,0=未删除,1=已删除';
COMMENT ON COLUMN purchase_registration.create_by IS '创建该记录的用户';
COMMENT ON COLUMN purchase_registration.create_time IS '记录创建时间';
main-business/src/main/resources/db/migration/postgresql/V20250604111200__create_table_official_inventory.sql
@@ -41,6 +41,9 @@
COMMENT ON COLUMN official_inventory.registration_date IS '登记日期';
COMMENT ON COLUMN official_inventory.merge_id IS '合并id';
COMMENT ON COLUMN official_inventory.coal_plan_id IS '煤质方案id';
COMMENT ON COLUMN official_inventory.pending_id IS '待入库id';
COMMENT ON COLUMN official_inventory.price_excluding_tax IS '不含税单价';
COMMENT ON COLUMN official_inventory.total_price_excluding_tax IS '不含税总价';
COMMENT ON COLUMN official_inventory.deleted IS '软删除标志,0=未删除,1=已删除';
COMMENT ON COLUMN official_inventory.create_by IS '创建该记录的用户';
main-business/src/main/resources/db/migration/postgresql/V20250707155600__create_table_equipment_usage_record.sql
@@ -3,7 +3,8 @@
(
id                   BIGSERIAL          PRIMARY KEY,        -- ä¸»é”®ID,自动递增
    equipment_id         BIGINT         NOT NULL,           -- è®¾å¤‡ID,关联设备信息表,不允许为空
    usage_quantity       INT            NOT NULL,           -- ä½¿ç”¨æ•°é‡ï¼Œä¸å…è®¸ä¸ºç©º
    usage_quantity   INT       NOT NULL,           -- é¢†ç”¨æ•°é‡ï¼Œä¸å…è®¸ä¸ºç©º
    return_quantity  INT,                          -- å½’还数量
    user_id              BIGINT         NOT NULL,           -- ä½¿ç”¨äººID,关联用户表,不允许为空
    department_id        BIGINT         ,                   -- éƒ¨é—¨ID,关联部门表,不允许为空
    equipment_status     BIGINT    NOT NULL,                -- è®¾å¤‡çŠ¶æ€:1.使用中 2.已归还
@@ -19,21 +20,38 @@
);
-- ä¸ºè¡¨æ·»åŠ æ³¨é‡Š
COMMENT ON TABLE equipment_usage_record IS '设备使用记录表';
COMMENT
ON TABLE equipment_usage_record IS '设备使用记录表';
-- ä¸ºå­—段添加注释
COMMENT ON COLUMN equipment_usage_record.id IS '主键ID';
COMMENT ON COLUMN equipment_usage_record.equipment_id IS '设备ID';
COMMENT ON COLUMN equipment_usage_record.usage_quantity IS '使用数量';
COMMENT ON COLUMN equipment_usage_record.user_id IS '使用人ID';
COMMENT ON COLUMN equipment_usage_record.department_id IS '部门ID';
COMMENT ON COLUMN equipment_usage_record.equipment_status IS '设备状态:1.使用中 2.已归还';
COMMENT ON COLUMN equipment_usage_record.usage_start_time IS '使用开始时间';
COMMENT ON COLUMN equipment_usage_record.usage_end_time IS '使用结束时间';
COMMENT ON COLUMN equipment_usage_record.remarks IS '备注信息';
COMMENT
ON COLUMN equipment_usage_record.id IS '主键ID';
COMMENT
ON COLUMN equipment_usage_record.equipment_id IS '设备ID';
COMMENT
ON COLUMN equipment_usage_record.usage_quantity IS '领用数量';
COMMENT
ON COLUMN equipment_usage_record.return_quantity IS '归还数量';
COMMENT
ON COLUMN equipment_usage_record.user_id IS '使用人ID';
COMMENT
ON COLUMN equipment_usage_record.department_id IS '部门ID';
COMMENT
ON COLUMN equipment_usage_record.equipment_status IS '设备状态:1.使用中 2.已归还';
COMMENT
ON COLUMN equipment_usage_record.usage_start_time IS '使用开始时间';
COMMENT
ON COLUMN equipment_usage_record.usage_end_time IS '使用结束时间';
COMMENT
ON COLUMN equipment_usage_record.remarks IS '备注信息';
COMMENT ON COLUMN equipment_usage_record.deleted IS '软删除标志,0=未删除,1=已删除';
COMMENT ON COLUMN equipment_usage_record.create_by IS '创建该记录的用户';
COMMENT ON COLUMN equipment_usage_record.create_time IS '记录创建时间';
COMMENT ON COLUMN equipment_usage_record.update_by IS '最后修改该记录的用户';
COMMENT ON COLUMN equipment_usage_record.update_time IS '记录最后更新时间';
COMMENT
ON COLUMN equipment_usage_record.deleted IS '软删除标志,0=未删除,1=已删除';
COMMENT
ON COLUMN equipment_usage_record.create_by IS '创建该记录的用户';
COMMENT
ON COLUMN equipment_usage_record.create_time IS '记录创建时间';
COMMENT
ON COLUMN equipment_usage_record.update_by IS '最后修改该记录的用户';
COMMENT
ON COLUMN equipment_usage_record.update_time IS '记录最后更新时间';
main-business/src/main/resources/db/migration/postgresql/V20250723134500__create_table_equipment_usage_detail.sql
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,53 @@
-- åˆ›å»ºè®¾å¤‡ä½¿ç”¨æ˜Žç»†è¡¨ equipment_usage_detail
DROP TABLE IF EXISTS equipment_usage_detail;
CREATE TABLE equipment_usage_detail
(
    id             BIGSERIAL PRIMARY KEY,       -- ä¸»é”®ID,自动递增
    usage_id       BIGINT NOT NULL,             -- å…³è”的使用记录ID
    equipment_id   BIGINT NOT NULL,             -- å…³è”的设备ID
    operation_type INT    NOT NULL,             -- æ“ä½œç±»åž‹ï¼š1-领用,2-归还
    quantity       INT    NOT NULL,             -- æ“ä½œæ•°é‡
    operator_id    BIGINT NOT NULL,             -- æ“ä½œäººID
    operator       VARCHAR(255),                -- æ“ä½œäºº
    remark         VARCHAR(255),                -- å¤‡æ³¨
    deleted        INT    NOT NULL DEFAULT 0,   -- è½¯åˆ é™¤æ ‡å¿—:0=未删除,1=已删除
    create_by      VARCHAR(255),                -- åˆ›å»ºäººç”¨æˆ·å
    create_time    TIMESTAMP WITHOUT TIME ZONE, -- åˆ›å»ºæ—¶é—´ï¼Œé»˜è®¤å½“前时间
    update_by      VARCHAR(255),                -- æœ€åŽæ›´æ–°äººç”¨æˆ·å
    update_time    TIMESTAMP WITHOUT TIME ZONE  -- æœ€åŽæ›´æ–°æ—¶é—´
);
-- ä¸ºè¡¨æ·»åŠ æ³¨é‡Š
COMMENT
ON TABLE equipment_usage_detail IS '设备使用明细表';
-- ä¸ºå­—段添加注释
COMMENT
ON COLUMN equipment_usage_detail.id IS '主键ID';
COMMENT
ON COLUMN equipment_usage_detail.usage_id IS '关联的使用记录ID';
COMMENT
ON COLUMN equipment_usage_detail.equipment_id IS '关联的设备ID';
COMMENT
ON COLUMN equipment_usage_detail.operation_type IS '操作类型:1-领用,2-归还';
COMMENT
ON COLUMN equipment_usage_detail.quantity IS '操作数量';
COMMENT
ON COLUMN equipment_usage_detail.operator_id IS '操作人ID';
COMMENT
ON COLUMN equipment_usage_detail.operator IS '操作人';
COMMENT
ON COLUMN equipment_usage_detail.remark IS '备注';
COMMENT
ON COLUMN equipment_usage_detail.deleted IS '软删除标志,0=未删除,1=已删除';
COMMENT
ON COLUMN equipment_usage_detail.create_by IS '创建该记录的用户';
COMMENT
ON COLUMN equipment_usage_detail.create_time IS '记录创建时间';
COMMENT
ON COLUMN equipment_usage_detail.update_by IS '最后修改该记录的用户';
COMMENT
ON COLUMN equipment_usage_detail.update_time IS '记录最后更新时间';
main-business/src/main/resources/mapper/EquipmentUsageDetailMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.business.mapper.EquipmentUsageDetailMapper">
        <!-- é€šç”¨æŸ¥è¯¢æ˜ å°„结果 -->
        <resultMap id="BaseResultMap" type="com.ruoyi.business.entity.EquipmentUsageDetail">
                    <id column="id" property="id" />
                <result column="deleted" property="deleted" />
                <result column="create_by" property="createBy" />
                <result column="create_time" property="createTime" />
                <result column="update_by" property="updateBy" />
                <result column="update_time" property="updateTime" />
                    <result column="usage_id" property="usageId" />
                    <result column="operation_type" property="operationType" />
                    <result column="quantity" property="quantity" />
                    <result column="operator_id" property="operatorId" />
                    <result column="operator" property="operator" />
                    <result column="remark" property="remark" />
        </resultMap>
        <!-- é€šç”¨æŸ¥è¯¢ç»“果列 -->
        <sql id="Base_Column_List">
                deleted,
                create_by,
                create_time,
                update_by,
                update_time,
            id, usage_id, operation_type, quantity, operator_id, operator, remark
        </sql>
</mapper>