4.11
package com.example.baoli.service;
import com.example.baoli.entity.*;
import com.example.baoli.repository.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
/**
* 业务流程服务 - 协调各模块间的业务逻辑
*/
@Service
public class BusinessProcessService {
@Autowired
private ProcurementRecordRepository procurementRecordRepository;
@Autowired
private InboundRecordRepository inboundRecordRepository;
@Autowired
private ApprovalRecordRepository approvalRecordRepository;
@Autowired
private OutboundRecordRepository outboundRecordRepository;
@Autowired
private SparePartRepository sparePartRepository;
@Autowired
private WorkOrderRepository workOrderRepository;
/**
* 采购到入库的完整流程
*/
@Transactional
public InboundRecord processProcurementToInbound(Long procurementId, InboundRecord inboundRecord) {
// 1. 获取采购记录
Optional<ProcurementRecord> optionalProcurement = procurementRecordRepository.findById(procurementId);
if (!optionalProcurement.isPresent()) {
throw new RuntimeException("采购记录不存在");
}
ProcurementRecord procurement = optionalProcurement.get();
// 2. 验证采购状态
if (!"已完成".equals(procurement.getStatus())) {
throw new RuntimeException("采购尚未完成,无法入库");
}
// 3. 创建入库记录,关联采购信息
inboundRecord.setProcurementId(procurement.getId());
inboundRecord.setSparePartName(procurement.getPartName());
inboundRecord.setSparePartModel(procurement.getPartModel());
// 4. 保存入库记录
InboundRecord savedRecord = inboundRecordRepository.save(inboundRecord);
// 5. 更新采购记录状态
procurement.setStatus("已入库");
procurementRecordRepository.save(procurement);
return savedRecord;
}
/**
* 审核通过后自动创建出库记录
*/
@Transactional
public OutboundRecord processApprovalToOutbound(Long approvalId, String approver) {
// 1. 获取审核记录
Optional<ApprovalRecord> optionalApproval = approvalRecordRepository.findById(approvalId);
if (!optionalApproval.isPresent()) {
throw new RuntimeException("审核记录不存在");
}
ApprovalRecord approval = optionalApproval.get();
// 2. 验证审核状态
if (!"已通过".equals(approval.getStatus())) {
throw new RuntimeException("审核尚未通过,无法出库");
}
// 3. 检查库存
Integer availableStock = sparePartRepository.getTotalAvailableStock(
approval.getSparePartName(), approval.getSparePartModel());
if (availableStock == null || availableStock < approval.getQuantity()) {
throw new RuntimeException("库存不足,无法出库");
}
// 4. 创建出库记录
OutboundRecord outboundRecord = new OutboundRecord();
outboundRecord.setApplicationId(approval.getApplicationId());
outboundRecord.setSparePartName(approval.getSparePartName());
outboundRecord.setSparePartModel(approval.getSparePartModel());
outboundRecord.setQuantity(approval.getQuantity());
outboundRecord.setApplicant(approval.getApplicant());
outboundRecord.setDepartment(approval.getDepartment());
outboundRecord.setOutboundType(approval.getApplicationType());
outboundRecord.setOutboundPerson(approver);
outboundRecord.setOutboundDate(LocalDateTime.now());
outboundRecord.setStatus("已出库");
// 设置预计归还时间(借用类型)
if ("维修借用".equals(approval.getApplicationType())) {
outboundRecord.setExpectedReturnDate(approval.getExpectedReturnDate());
}
// 5. 更新库存
updateStockForOutbound(approval.getSparePartName(), approval.getSparePartModel(), approval.getQuantity());
// 6. 保存出库记录
return outboundRecordRepository.save(outboundRecord);
}
/**
* 维修借用超时自动转为维修申领
*/
@Transactional
public void processOverdueBorrowToApplication() {
List<OutboundRecord> overdueRecords = outboundRecordRepository.findOverdueBorrowRecords(LocalDateTime.now());
for (OutboundRecord record : overdueRecords) {
// 1. 更新出库记录类型
record.setOutboundType("维修申领");
record.setRemarks(record.getRemarks() + " [系统自动转换:维修借用超时转为维修申领]");
outboundRecordRepository.save(record);
// 2. 创建对应的审核记录(已通过状态)
ApprovalRecord newApproval = new ApprovalRecord();
newApproval.setApplicationId("AUTO_" + System.currentTimeMillis());
newApproval.setApplicant(record.getApplicant());
newApproval.setDepartment(record.getDepartment());
newApproval.setSparePartName(record.getSparePartName());
newApproval.setSparePartModel(record.getSparePartModel());
newApproval.setQuantity(record.getQuantity());
newApproval.setApplicationType("维修申领");
newApproval.setStatus("已通过");
newApproval.setApprover("系统自动");
newApproval.setApprovalDate(LocalDateTime.now());
newApproval.setApprovalComments("维修借用超时自动转换"); // 修复此处,使用 setApprovalComments
approvalRecordRepository.save(newApproval);
System.out.println("维修借用超时转换:" + record.getApplicationId());
}
}
/**
* 故障备件自动生成工单
*/
@Transactional
public void generateWorkOrdersForFaultyParts() {
List<SparePart> faultyParts = sparePartRepository.findFaultyParts();
for (SparePart part : faultyParts) {
// 检查是否已存在工单
List<WorkOrder> existingOrders = workOrderRepository.findByPartNameAndPartModel(
part.getPartName(), part.getPartModel());
boolean hasActiveOrder = existingOrders.stream()
.anyMatch(order -> !"已关闭".equals(order.getStatus()));
if (!hasActiveOrder) {
WorkOrder workOrder = new WorkOrder();
workOrder.setOrderNumber(generateWorkOrderNumber());
workOrder.setPartName(part.getPartName());
workOrder.setPartModel(part.getPartModel());
workOrder.setEquipmentInfo("备件ID: " + part.getId());
workOrder.setFaultDescription("库存管理中发现故障备件,需要维修处理");
workOrder.setStatus("待处理");
workOrder.setProgress(0);
workOrder.setCreatedBy("系统自动生成");
workOrderRepository.save(workOrder);
System.out.println("自动生成工单:" + workOrder.getOrderNumber());
}
}
}
/**
* 库存预警检查
*/
public void checkStockAlerts() {
List<SparePart> lowStockParts = sparePartRepository.findLowStockParts();
for (SparePart part : lowStockParts) {
// 检查是否已有采购申请
List<ProcurementRecord> existingProcurements = procurementRecordRepository
.findByPartNameAndPartModel(part.getPartName(), part.getPartModel());
boolean hasActiveProcurement = existingProcurements.stream()
.anyMatch(proc -> !"已完成".equals(proc.getStatus()) && !"已取消".equals(proc.getStatus()));
if (!hasActiveProcurement) {
// 自动创建采购申请
ProcurementRecord procurement = new ProcurementRecord();
procurement.setApplicant("系统自动");
procurement.setPartName(part.getPartName());
procurement.setPartModel(part.getPartModel());
procurement.setQuantity(part.getMaxStock() - part.getQuantity()); // 补充到最大库存
procurement.setReason("库存不足自动触发采购");
procurement.setStatus("待上会");
procurement.setCurrentStock(part.getQuantity());
procurementRecordRepository.save(procurement);
System.out.println("库存预警自动采购:" + part.getPartName() + " " + part.getPartModel());
}
// 发送预警通知(这里可以集成短信、邮件等通知服务)
sendStockAlert(part);
}
}
/**
* 备件全生命周期跟踪
*/
public java.util.Map<String, Object> getSparePartLifecycle(String partName, String partModel) {
java.util.Map<String, Object> lifecycle = new java.util.HashMap<>();
// 1. 采购记录
List<ProcurementRecord> procurements = procurementRecordRepository
.findByPartNameAndPartModel(partName, partModel);
lifecycle.put("procurements", procurements);
// 2. 入库记录
List<InboundRecord> inbounds = inboundRecordRepository
.findBySparePartNameAndSparePartModel(partName, partModel);
lifecycle.put("inbounds", inbounds);
// 3. 审核记录
List<ApprovalRecord> approvals = approvalRecordRepository
.findBySparePartNameAndSparePartModel(partName, partModel);
lifecycle.put("approvals", approvals);
// 4. 出库记录
List<OutboundRecord> outbounds = outboundRecordRepository
.findBySparePartNameAndModel(partName, partModel);
lifecycle.put("outbounds", outbounds);
// 5. 工单记录
List<WorkOrder> workOrders = workOrderRepository
.findByPartNameAndPartModel(partName, partModel);
lifecycle.put("workOrders", workOrders);
// 6. 当前库存
List<SparePart> currentStock = sparePartRepository
.findByPartNameAndPartModel(partName, partModel);
lifecycle.put("currentStock", currentStock);
return lifecycle;
}
/**
* 更新出库库存
*/
private void updateStockForOutbound(String partName, String partModel, Integer quantity) {
List<SparePart> spareParts = sparePartRepository.findByPartNameAndPartModel(partName, partModel);
int remainingQuantity = quantity;
for (SparePart part : spareParts) {
if (remainingQuantity <= 0) break;
if (part.getQuantity() >= remainingQuantity) {
part.setQuantity(part.getQuantity() - remainingQuantity);
remainingQuantity = 0;
} else {
remainingQuantity -= part.getQuantity();
part.setQuantity(0);
}
sparePartRepository.save(part);
}
}
/**
* 生成工单号
*/
private String generateWorkOrderNumber() {
String timestamp = String.valueOf(System.currentTimeMillis());
return "WO" + timestamp.substring(timestamp.length() - 10);
}
/**
* 发送库存预警
*/
private void sendStockAlert(SparePart part) {
// 这里可以集成短信、邮件、消息推送等服务
System.out.println("库存预警:" + part.getPartName() + " " + part.getPartModel() +
" 当前库存: " + part.getQuantity() + " 最低库存: " + part.getMinStock());
}
/**
* 数据一致性检查
*/
public java.util.Map<String, Object> checkDataConsistency() {
java.util.Map<String, Object> result = new java.util.HashMap<>();
// 1. 检查出库记录与库存的一致性
List<OutboundRecord> outbounds = outboundRecordRepository.findAll();
int inconsistentOutbounds = 0;
for (OutboundRecord outbound : outbounds) {
Integer currentStock = sparePartRepository.getTotalAvailableStock(
outbound.getSparePartName(), outbound.getSparePartModel());
if (currentStock == null) {
inconsistentOutbounds++;
}
}
result.put("inconsistentOutbounds", inconsistentOutbounds);
// 2. 检查审核记录与出库记录的关联
List<ApprovalRecord> approvals = approvalRecordRepository.findByStatus("已通过");
int missingOutbounds = 0;
for (ApprovalRecord approval : approvals) {
List<OutboundRecord> relatedOutbounds = outboundRecordRepository
.findByApplicationId(approval.getApplicationId());
if (relatedOutbounds.isEmpty()) {
missingOutbounds++;
}
}
result.put("missingOutbounds", missingOutbounds);
// 3. 检查超时的维修借用
List<OutboundRecord> overdueRecords = outboundRecordRepository
.findOverdueBorrowRecords(LocalDateTime.now());
result.put("overdueRecords", overdueRecords.size());
return result;
}
}