package com.ruoyi.system.service.impl; import cn.hutool.core.bean.BeanUtil; 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.basic.PageInfo; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.system.constants.ApprovalApplicationCodePrefix; import com.ruoyi.system.dto.AssetRepairRecordAddDTO; import com.ruoyi.system.dto.asset.AssetRepairCompleteDTO; import com.ruoyi.system.mapper.AssetRepairRecordMapper; import com.ruoyi.system.model.AssetRepairRecord; import com.ruoyi.system.model.AssetRepairRecordItem; import com.ruoyi.system.model.AssetRepairRequest; import com.ruoyi.system.query.AssetRepairRecordPageQuery; import com.ruoyi.system.query.AssetRepairRequestListQuery; import com.ruoyi.system.service.AssetRepairRecordItemService; import com.ruoyi.system.service.AssetRepairRecordService; import com.ruoyi.system.service.AssetRepairRequestService; import com.ruoyi.system.service.AssetTypeService; import com.ruoyi.system.vo.AssetRepairRequestVO; import com.ruoyi.system.vo.asset.AssetRepairRecordAssetVO; import com.ruoyi.system.vo.asset.AssetRepairRecordDetailVO; import com.ruoyi.system.vo.asset.AssetRepairRecordPageVO; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; import java.util.Objects; /** *

* 资产维修主表 服务实现类 *

* * @author WuGuanFengYue * @since 2025-09-15 */ @Service @RequiredArgsConstructor(onConstructor_ = {@Lazy}) public class AssetRepairRecordServiceImpl extends ServiceImpl implements AssetRepairRecordService { private final AssetRepairRequestService assetRepairRequestService; private final AssetRepairRecordItemService assetRepairRecordItemService; private final AssetTypeService assetTypeService; @Override public PageInfo pageList(AssetRepairRequestListQuery query) { PageInfo pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); List list = this.baseMapper.pageList(query,pageInfo); pageInfo.setRecords(list); return pageInfo; } @Override public IPage getRepairRecordPageList(AssetRepairRecordPageQuery pageQuery) { Page page = new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize()); return this.baseMapper.getRepairRecordPageList(page, pageQuery); } @Override @Transactional(rollbackFor = Exception.class) public void addRepairRecord(AssetRepairRecordAddDTO addDTO) { // 1. 生成维修单号 String repairNo = generateRepairNo(); // 2. 校验报修单是否存在(如果提供了报修单号) Integer repairRequestId = null; if (StringUtils.hasText(addDTO.getRepairRequestNo())) { repairRequestId = validateRepairRequest(addDTO.getRepairRequestNo()); } // 3. 创建维修记录实体 AssetRepairRecord repairRecord = new AssetRepairRecord(); repairRecord.setRepairNo(repairNo); repairRecord.setRepairRequestId(repairRequestId); BeanUtil.copyProperties(addDTO, repairRecord); repairRecord.setCreateBy(SecurityUtils.getUsername()); // 4. 保存维修记录主表 boolean saved = this.save(repairRecord); if (!saved) { throw new RuntimeException("保存维修记录失败"); } // 5. 保存维修资产关联关系 saveRepairRecordItems(repairRecord.getId(), addDTO.getAssetMainIds()); } /** * 生成维修单号 * 格式:WX + 日期 + 4位序号 */ private String generateRepairNo() { String dateStr = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")); // 查询当天已生成的维修单号数量 Long count = this.lambdaQuery() .likeRight(AssetRepairRecord::getRepairNo, ApprovalApplicationCodePrefix.ASSET_REPAIR) .ge(AssetRepairRecord::getCreateTime, LocalDate.now().atStartOfDay()) .lt(AssetRepairRecord::getCreateTime, LocalDate.now().plusDays(1).atStartOfDay()) .count(); // 生成4位序号,从0001开始 int sequence = (count != null ? count.intValue() : 0) + 1; String sequenceStr = String.format("%04d", sequence); return ApprovalApplicationCodePrefix.ASSET_REPAIR + dateStr + sequenceStr; } /** * 校验报修单是否存在 * @param repairRequestNo 报修单号 * @return 报修单ID */ private Integer validateRepairRequest(String repairRequestNo) { AssetRepairRequest repairRequest = assetRepairRequestService.lambdaQuery() .eq(AssetRepairRequest::getRepairNo, repairRequestNo) .eq(AssetRepairRequest::getDisabled, false) .one(); if (repairRequest == null) { throw new RuntimeException("报修单不存在:" + repairRequestNo); } return repairRequest.getId(); } /** * 保存维修记录资产关联关系 * @param repairRecordId 维修记录ID * @param assetMainIds 资产ID列表 */ private void saveRepairRecordItems(Integer repairRecordId, List assetMainIds) { if (assetMainIds == null || assetMainIds.isEmpty()) { throw new RuntimeException("维修资产ID列表不能为空"); } List items = new ArrayList<>(); for (Integer assetMainId : assetMainIds) { AssetRepairRecordItem item = new AssetRepairRecordItem(); item.setRepairRecordId(repairRecordId); item.setAssetMainId(assetMainId); items.add(item); } boolean saved = assetRepairRecordItemService.saveBatch(items); if (!saved) { throw new RuntimeException("保存维修资产关联关系失败"); } } @Override public AssetRepairRecordDetailVO getRepairRecordDetail(Integer id) { // 1. 查询主表信息 AssetRepairRecord repairRecord = this.getById(id); if (repairRecord == null) { throw new RuntimeException("维修记录不存在"); } // 2. 转换主表信息到VO AssetRepairRecordDetailVO detailVO = new AssetRepairRecordDetailVO(); BeanUtil.copyProperties(repairRecord, detailVO); // 4. 查询关联的资产列表 List assetList = this.baseMapper.getRepairAssetList(id); detailVO.setAssetList(assetList); return detailVO; } @Transactional(rollbackFor = Exception.class) @Override public void completeRepair(AssetRepairCompleteDTO dto) { //查询维修记录资产关联表 AssetRepairRecordItem item = assetRepairRecordItemService.lambdaQuery().eq(AssetRepairRecordItem::getRepairRecordId, dto.getRepairRecordId()) .eq(AssetRepairRecordItem::getAssetMainId, dto.getAssetMainId()).one(); if (Objects.isNull(item)) { throw new ServiceException("维修记录不存在"); } item.setRepairFinishTime(Objects.nonNull(dto.getRepairFinishTime()) ? dto.getRepairFinishTime() : LocalDateTime.now()); item.setRepairFee(dto.getRepairFee()); item.setStatus(1); assetRepairRecordItemService.updateById(item); //统计未维修的资产数量 TODO 待验证 Long count = assetRepairRecordItemService.lambdaQuery() .eq(AssetRepairRecordItem::getRepairRecordId, dto.getRepairRecordId()).eq(AssetRepairRecordItem::getStatus, 0) .count(); if (count.equals(0L)) { //更新主表状态 AssetRepairRecord repairRecord = this.getById(dto.getRepairRecordId()); repairRecord.setRepairStatus(2); this.updateById(repairRecord); //查询关联保修单 if (Objects.nonNull(repairRecord.getRepairRequestId())) { //更新关联报修单状态 assetRepairRequestService.lambdaUpdate().set(AssetRepairRequest::getRepairStatus, 1) .eq(AssetRepairRequest::getId, repairRecord.getRepairRequestId()) .update(); } } } }