feat: add spare part management services

This commit is contained in:
chiguyong 2026-03-24 00:39:39 +08:00
parent d042bf46c8
commit 799e358d0f
2 changed files with 297 additions and 0 deletions

View File

@ -0,0 +1,27 @@
package com.ether.pms.mdm.service;
import com.ether.pms.mdm.entity.SparePart;
import com.ether.pms.mdm.entity.SparePartCategory;
import com.ether.pms.mdm.entity.SparePartRecord;
import java.util.List;
import java.util.UUID;
public interface SparePartService {
// 分类管理
List<SparePartCategory> getCategories();
SparePartCategory createCategory(SparePartCategory category);
// 备件管理
SparePart createSparePart(SparePart sparePart);
SparePart updateSparePart(UUID id, SparePart sparePart);
void deleteSparePart(UUID id);
SparePart getSparePartById(UUID id);
List<SparePart> getSparePartsByProject(UUID projectId);
List<SparePart> getSparePartsByCategory(UUID categoryId);
List<SparePart> getLowStockParts(UUID projectId);
// 库存管理
SparePartRecord inStock(UUID sparePartId, Integer quantity, UUID recordedBy, String remarks);
SparePartRecord outStock(UUID sparePartId, Integer quantity, UUID relatedOrderId, UUID recordedBy, String remarks);
List<SparePartRecord> getSparePartRecords(UUID sparePartId);
}

View File

@ -0,0 +1,270 @@
package com.ether.pms.mdm.service.impl;
import com.ether.pms.common.BusinessException;
import com.ether.pms.mdm.entity.SparePart;
import com.ether.pms.mdm.entity.SparePartCategory;
import com.ether.pms.mdm.entity.SparePartRecord;
import com.ether.pms.mdm.repository.SparePartCategoryRepository;
import com.ether.pms.mdm.repository.SparePartRecordRepository;
import com.ether.pms.mdm.repository.SparePartRepository;
import com.ether.pms.mdm.service.SparePartService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.UUID;
@Service
@RequiredArgsConstructor
public class SparePartServiceImpl implements SparePartService {
private final SparePartRepository sparePartRepository;
private final SparePartCategoryRepository sparePartCategoryRepository;
private final SparePartRecordRepository sparePartRecordRepository;
private static final DateTimeFormatter CODE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
// ==================== 分类管理 ====================
@Override
public List<SparePartCategory> getCategories() {
return sparePartCategoryRepository.findAll();
}
@Override
@Transactional
public SparePartCategory createCategory(SparePartCategory category) {
// 生成分类编码 CC + 时间戳
String categoryCode = generateCategoryCode();
category.setCategoryCode(categoryCode);
return sparePartCategoryRepository.save(category);
}
// ==================== 备件管理 ====================
@Override
@Transactional
public SparePart createSparePart(SparePart sparePart) {
// 生成备件编码 SP + 时间戳
String sparePartCode = generateSparePartCode();
sparePart.setSparePartCode(sparePartCode);
// 设置默认状态为ACTIVE
if (sparePart.getStatus() == null) {
sparePart.setStatus(SparePart.Status.ACTIVE);
}
// 初始化库存为0
if (sparePart.getCurrentStock() == null) {
sparePart.setCurrentStock(0);
}
return sparePartRepository.save(sparePart);
}
@Override
@Transactional
public SparePart updateSparePart(UUID id, SparePart sparePart) {
SparePart existing = getSparePartById(id);
if (sparePart.getSparePartName() != null) {
existing.setSparePartName(sparePart.getSparePartName());
}
if (sparePart.getCategoryId() != null) {
existing.setCategoryId(sparePart.getCategoryId());
}
if (sparePart.getSpecification() != null) {
existing.setSpecification(sparePart.getSpecification());
}
if (sparePart.getUnit() != null) {
existing.setUnit(sparePart.getUnit());
}
if (sparePart.getSafeStock() != null) {
existing.setSafeStock(sparePart.getSafeStock());
}
if (sparePart.getUnitPrice() != null) {
existing.setUnitPrice(sparePart.getUnitPrice());
}
if (sparePart.getSupplier() != null) {
existing.setSupplier(sparePart.getSupplier());
}
if (sparePart.getSupplierContact() != null) {
existing.setSupplierContact(sparePart.getSupplierContact());
}
if (sparePart.getLocation() != null) {
existing.setLocation(sparePart.getLocation());
}
if (sparePart.getRemarks() != null) {
existing.setRemarks(sparePart.getRemarks());
}
if (sparePart.getStatus() != null) {
existing.setStatus(sparePart.getStatus());
}
return sparePartRepository.save(existing);
}
@Override
@Transactional
public void deleteSparePart(UUID id) {
SparePart sparePart = getSparePartById(id);
sparePart.setStatus(SparePart.Status.INACTIVE);
sparePartRepository.save(sparePart);
}
@Override
public SparePart getSparePartById(UUID id) {
return sparePartRepository.findById(id)
.orElseThrow(() -> new BusinessException(6101, "备件不存在"));
}
@Override
public List<SparePart> getSparePartsByProject(UUID projectId) {
return sparePartRepository.findByProjectIdAndStatus(projectId, SparePart.Status.ACTIVE);
}
@Override
public List<SparePart> getSparePartsByCategory(UUID categoryId) {
return sparePartRepository.findByCategoryId(categoryId);
}
@Override
public List<SparePart> getLowStockParts(UUID projectId) {
return sparePartRepository.findLowStockParts(projectId);
}
// ==================== 库存管理 ====================
@Override
@Transactional
public SparePartRecord inStock(UUID sparePartId, Integer quantity, UUID recordedBy, String remarks) {
if (quantity == null || quantity <= 0) {
throw new BusinessException(6102, "入库数量必须大于0");
}
SparePart sparePart = getSparePartById(sparePartId);
// 更新库存
sparePart.setCurrentStock(sparePart.getCurrentStock() + quantity);
sparePartRepository.save(sparePart);
// 创建入库记录
return createSparePartRecord(sparePartId, SparePartRecord.RecordType.IN, quantity, recordedBy, remarks);
}
@Override
@Transactional
public SparePartRecord outStock(UUID sparePartId, Integer quantity, UUID relatedOrderId, UUID recordedBy, String remarks) {
if (quantity == null || quantity <= 0) {
throw new BusinessException(6103, "出库数量必须大于0");
}
SparePart sparePart = getSparePartById(sparePartId);
// 校验库存是否充足
if (sparePart.getCurrentStock() < quantity) {
throw new BusinessException(6104, "库存不足,当前库存:" + sparePart.getCurrentStock() + ",需要出库:" + quantity);
}
// 更新库存
sparePart.setCurrentStock(sparePart.getCurrentStock() - quantity);
sparePartRepository.save(sparePart);
// 创建出库记录
return createSparePartRecordWithOrder(sparePartId, SparePartRecord.RecordType.OUT, quantity, relatedOrderId, recordedBy, remarks);
}
@Override
public List<SparePartRecord> getSparePartRecords(UUID sparePartId) {
return sparePartRecordRepository.findBySparePartIdOrderByRecordDateDesc(sparePartId);
}
// ==================== 私有方法 ====================
/**
* 生成备件编码SP + yyyyMMddHHmmss
*/
private String generateSparePartCode() {
String timestamp = LocalDateTime.now().format(CODE_FORMATTER);
String sparePartCode = "SP" + timestamp;
// 确保编码唯一
int suffix = 1;
while (sparePartRepository.existsBySparePartCode(sparePartCode)) {
sparePartCode = "SP" + timestamp + "_" + suffix;
suffix++;
}
return sparePartCode;
}
/**
* 生成分类编码CC + yyyyMMddHHmmss
*/
private String generateCategoryCode() {
String timestamp = LocalDateTime.now().format(CODE_FORMATTER);
String categoryCode = "CC" + timestamp;
// 检查编码是否存在
int suffix = 1;
while (sparePartCategoryRepository.findByCategoryCode(categoryCode).isPresent()) {
categoryCode = "CC" + timestamp + "_" + suffix;
suffix++;
}
return categoryCode;
}
/**
* 创建库存记录
*/
private SparePartRecord createSparePartRecord(UUID sparePartId, SparePartRecord.RecordType recordType,
Integer quantity, UUID recordedBy, String remarks) {
SparePart sparePart = getSparePartById(sparePartId);
SparePartRecord record = new SparePartRecord();
record.setRecordCode(generateRecordCode(recordType));
record.setRecordType(recordType);
record.setSparePartId(sparePartId);
record.setQuantity(quantity);
record.setBalance(sparePart.getCurrentStock());
record.setRecordedBy(recordedBy);
record.setRemarks(remarks);
record.setRecordDate(LocalDateTime.now());
return sparePartRecordRepository.save(record);
}
/**
* 创建带订单信息的库存记录
*/
private SparePartRecord createSparePartRecordWithOrder(UUID sparePartId, SparePartRecord.RecordType recordType,
Integer quantity, UUID relatedOrderId, UUID recordedBy, String remarks) {
SparePart sparePart = getSparePartById(sparePartId);
SparePartRecord record = new SparePartRecord();
record.setRecordCode(generateRecordCode(recordType));
record.setRecordType(recordType);
record.setSparePartId(sparePartId);
record.setQuantity(quantity);
record.setBalance(sparePart.getCurrentStock());
record.setRelatedOrderId(relatedOrderId);
record.setRecordedBy(recordedBy);
record.setRemarks(remarks);
record.setRecordDate(LocalDateTime.now());
return sparePartRecordRepository.save(record);
}
/**
* 生成记录编码REC + 类型 + 时间戳
*/
private String generateRecordCode(SparePartRecord.RecordType recordType) {
String typeCode = recordType.name();
String timestamp = LocalDateTime.now().format(CODE_FORMATTER);
return "REC" + typeCode + timestamp;
}
}