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.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
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.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.system.mapper.SysUserMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
*
* 设备使用记录表 服务实现类
*
*
* @author ld
* @since 2025-07-07
*/
@Service
@RequiredArgsConstructor
public class EquipmentUsageRecordServiceImpl extends ServiceImpl implements EquipmentUsageRecordService {
private final EquipmentUsageRecordMapper equipmentUsageRecordMapper;
private final EquipmentManagementMapper equipmentManagementMapper;
private final EquipmentUsageDetailMapper equipmentUsageDetailMapper;
private final SysUserMapper sysUserMapper;
@Override
public IPage selectUsageRecordList(Page page, EquipmentUsageRecordDto equipmentUsageRecordDto) {
Page entityPage = equipmentUsageRecordMapper.selectPage(page, null);
IPage dtoPage = new Page<>();
BeanUtils.copyProperties(entityPage, dtoPage);
List eqIds = entityPage.getRecords().stream().map(EquipmentUsageRecord::getEquipmentId).toList();
List userIds = entityPage.getRecords().stream().map(EquipmentUsageRecord::getUserId).toList();
//批量查询设备
Map equipmentManagementMap;
if (!eqIds.isEmpty()) {
List infos = equipmentManagementMapper.selectList(new LambdaQueryWrapper().in(EquipmentManagement::getId, eqIds));
equipmentManagementMap = infos.stream().collect(Collectors.toMap(EquipmentManagement::getId, Function.identity()));
} else {
equipmentManagementMap = new HashMap<>();
}
//人员查询
Map userMap;
if (!userIds.isEmpty()) {
List sysUsers = sysUserMapper.selectList(userIds);
userMap = sysUsers.stream().collect(Collectors.toMap(SysUser::getUserId, Function.identity()));
} else {
userMap = new HashMap<>();
}
//匹配数据
List dtoRecords = entityPage.getRecords().stream().map(entity -> {
EquipmentUsageRecordDto dto = new EquipmentUsageRecordDto();
BeanUtils.copyProperties(entity, dto);
EquipmentManagement equipment = equipmentManagementMap.get(entity.getEquipmentId());
if (equipment != null) {
dto.setEquipmentNo(equipment.getEquipmentNo());
dto.setEquipmentName(equipment.getEquipmentName());
}
SysUser sysUser = userMap.get(entity.getUserId());
if (sysUser != null) {
dto.setUserName(sysUser.getNickName());
}
int totalReturnNo = equipmentUsageDetailMapper.selectList(
new LambdaQueryWrapper()
.eq(EquipmentUsageDetail::getUsageId, entity.getId())
.eq(EquipmentUsageDetail::getOperationType,2))
.stream()
.mapToInt(EquipmentUsageDetail::getQuantity)
.sum();
dto.setTotalReturnNo(totalReturnNo);
return dto;
}).toList();
dtoPage.setRecords(dtoRecords);
return dtoPage;
}
@Override
@Transactional(rollbackFor = Exception.class)
public int addOrEditUsageRecord(EquipmentUsageRecordDto equipmentUsageRecordDto) {
// 参数校验
if (equipmentUsageRecordDto == null) {
throw new IllegalArgumentException("设备使用记录参数不能为空");
}
// 获取设备ID和操作数量
Long equipmentId = equipmentUsageRecordDto.getEquipmentId();
Long userId = equipmentUsageRecordDto.getUserId();
String username = sysUserMapper.selectUserById(userId).getNickName();
// 查询设备信息
EquipmentManagement equipment = equipmentManagementMapper.selectById(equipmentId);
if (equipment == null) {
throw new RuntimeException("设备不存在");
}
int result;
// 新增记录逻辑
if (Objects.isNull(equipmentUsageRecordDto.getId())) {
result = handleNewUsage(equipmentUsageRecordDto, equipment, userId, username);
} else {
// 编辑记录逻辑
EquipmentUsageRecord originalRecord = equipmentUsageRecordMapper.selectById(equipmentUsageRecordDto.getId());
if (originalRecord == null) {
throw new RuntimeException("领用记录不存在");
}
// 处理归还逻辑
if (equipmentUsageRecordDto.getEquipmentStatus() != 1) {
result = handleReturnOperation(equipmentUsageRecordDto, equipment, originalRecord, userId, username);
} else {
// 处理普通编辑逻辑(非归还状态)
result = handleEditOperation(equipmentUsageRecordDto, equipment, originalRecord, userId, username);
}
}
return result;
}
private int handleNewUsage(EquipmentUsageRecordDto dto, EquipmentManagement equipment, Long userId, String username) {
// 检查库存
if (equipment.getQuantity() < dto.getUsageQuantity()) {
throw new RuntimeException("库存不足,当前库存:" + equipment.getQuantity());
}
// 创建主记录
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);
// 保存主记录
int result = equipmentUsageRecordMapper.insert(record);
// 保存领用明细记录
if (result > 0) {
saveUsageDetail(record.getId(), record.getEquipmentId(), 1, dto.getUsageQuantity(), userId, username, "设备领用");
}
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());
int newReturnQuantity = originalRecord.getReturnQuantity() + returnQuantity;
updateRecord.setReturnQuantity(newReturnQuantity);
// 判断是否全部归还
boolean isFullReturn = newReturnQuantity == originalRecord.getUsageQuantity();
int newStatus = isFullReturn ? 3 : 2; // 3表示全部归还,2表示部分归还
updateRecord.setEquipmentStatus(newStatus);
updateRecord.setUsageEndTime(LocalDate.now());
// 恢复库存数量
equipment.setQuantity(equipment.getQuantity() + returnQuantity);
equipmentManagementMapper.updateById(equipment);
// 更新主记录
int result = equipmentUsageRecordMapper.updateById(updateRecord);
// 保存归还明细记录
if (result > 0) {
String remark = isFullReturn ? "设备归还(全部归还)" : "设备归还(部分归还)";
int operationType = isFullReturn ? 3 : 2; // 与主记录状态保持一致
saveUsageDetail(originalRecord.getId(), originalRecord.getEquipmentId(),
operationType, 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() - dto.getUsageQuantity();
// 检查调整后库存是否充足
int newInventory = equipment.getQuantity() + quantityDelta;
if (newInventory < 0) {
throw new RuntimeException("库存不足,调整后库存将为:" + newInventory);
}
// 调整库存
equipment.setQuantity(newInventory);
if (equipmentManagementMapper.updateById(equipment) == 0) {
throw new RuntimeException("库存更新失败,可能已被其他操作修改");
}
// 记录数量变更明细
saveUsageDetail(originalRecord.getId(), originalRecord.getEquipmentId(), 3, dto.getUsageQuantity(), userId, username,
"领用数量变更:" + originalRecord.getUsageQuantity() + "→" + dto.getUsageQuantity());
}
// 更新领用记录
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);
}
}