using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Mapster; using Microsoft.Extensions.Logging; using NPP.SmartSchedue.Api.Contracts.Services.Equipment; using NPP.SmartSchedue.Api.Contracts.Services.Equipment.Dto; using NPP.SmartSchedue.Api.Contracts.Domain.Equipment; using ZhonTai.Admin.Services; using ZhonTai.DynamicApi; namespace NPP.SmartSchedue.Api.Services.Equipment; /// /// 设备本地服务实现(专用于SmartSchedule模块) /// 提供设备信息的本地化查询功能,避免跨服务调用 /// public class EquipmentLocalService : BaseService, IEquipmentLocalService, IDynamicApi { private readonly IEquipmentRepository _equipmentRepository; private readonly IEquipmentMaintenanceRepository _maintenanceRepository; private readonly IEquipmentCalibrationRepository _calibrationRepository; private readonly ILogger _logger; public EquipmentLocalService( IEquipmentRepository equipmentRepository, IEquipmentMaintenanceRepository maintenanceRepository, IEquipmentCalibrationRepository calibrationRepository, ILogger logger) { _equipmentRepository = equipmentRepository; _maintenanceRepository = maintenanceRepository; _calibrationRepository = calibrationRepository; _logger = logger; } /// /// 获取设备列表 /// public async Task> GetListAsync(GetEquipmentListInput input) { try { var query = _equipmentRepository.Select; // 应用查询条件 if (!string.IsNullOrEmpty(input.EquipmentType)) { query = query.Where(e => e.EquipmentType == input.EquipmentType); } if (input.Status.HasValue) { query = query.Where(e => e.Status == input.Status.Value); } if (!string.IsNullOrEmpty(input.Name)) { query = query.Where(e => e.Name.Contains(input.Name)); } if (!string.IsNullOrEmpty(input.InternalNumber)) { query = query.Where(e => e.InternalNumber.Contains(input.InternalNumber)); } if (input.ResponsiblePersonId.HasValue) { query = query.Where(e => e.ResponsiblePersonId == input.ResponsiblePersonId.Value); } if (input.ProcessID.HasValue) { query = query.Where(e => e.ProcessID == input.ProcessID.Value); } var entities = await query.ToListAsync(); var result = entities.Adapt>(); // 填充维护和校验日期信息 foreach (var item in result) { await FillMaintenanceAndCalibrationDatesAsync(item); } _logger.LogInformation("成功获取设备列表,数量: {Count}", result.Count); return result; } catch (Exception ex) { _logger.LogError(ex, "获取设备列表时发生异常"); throw; } } /// /// 获取设备详情 /// public async Task GetAsync(long id) { try { var entity = await _equipmentRepository.GetAsync(id); if (entity == null) { _logger.LogWarning("设备不存在,ID: {Id}", id); return null; } var result = entity.Adapt(); await FillMaintenanceAndCalibrationDatesAsync(result); _logger.LogInformation("成功获取设备详情,ID: {Id}", id); return result; } catch (Exception ex) { _logger.LogError(ex, "获取设备详情时发生异常,ID: {Id}", id); throw; } } /// /// 获取可用设备列表 /// public async Task> GetAvailableEquipmentAsync(DateTime date, long? processId = null) { try { var query = _equipmentRepository.Select.Where(e => e.Status == EquipmentStatus.Normal); // 如果指定了工序,过滤适配的设备 if (processId.HasValue) { query = query.Where(e => e.ProcessID == processId.Value); } var entities = await query.ToListAsync(); var result = new List(); foreach (var entity in entities) { var equipment = entity.Adapt(); await FillMaintenanceAndCalibrationDatesAsync(equipment); // 检查设备在指定日期是否可用 if (IsEquipmentAvailableForDate(equipment, date)) { result.Add(equipment); } } _logger.LogInformation("成功获取可用设备列表,日期: {Date}, 工序ID: {ProcessId}, 数量: {Count}", date, processId, result.Count); return result; } catch (Exception ex) { _logger.LogError(ex, "获取可用设备列表时发生异常,日期: {Date}, 工序ID: {ProcessId}", date, processId); throw; } } /// /// 检查设备是否可用 /// public async Task IsEquipmentAvailableAsync(long equipmentId, DateTime date) { try { var equipment = await GetAsync(equipmentId); if (equipment == null) { return false; } var isAvailable = IsEquipmentAvailableForDate(equipment, date); _logger.LogInformation("设备可用性检查完成,设备ID: {EquipmentId}, 日期: {Date}, 可用: {Available}", equipmentId, date, isAvailable); return isAvailable; } catch (Exception ex) { _logger.LogError(ex, "检查设备可用性时发生异常,设备ID: {EquipmentId}, 日期: {Date}", equipmentId, date); return false; // 保守策略:异常时返回不可用 } } /// /// 获取需要维护的设备列表 /// public async Task> GetNeedMaintenanceAsync(DateTime date) { try { var equipmentIds = await _maintenanceRepository.GetMaintenanceEquipmentIdsAsync(date); var result = new List(); foreach (var equipmentId in equipmentIds) { var equipment = await GetAsync(equipmentId); if (equipment != null && IsMaintenanceNeededOnDate(equipment, date)) { result.Add(equipment); } } _logger.LogInformation("成功获取需要维护的设备列表,日期: {Date}, 数量: {Count}", date, result.Count); return result; } catch (Exception ex) { _logger.LogError(ex, "获取需要维护的设备列表时发生异常,日期: {Date}", date); return new List(); } } /// /// 获取需要校验的设备列表 /// public async Task> GetNeedCalibrationAsync(DateTime date) { try { var equipmentIds = await _calibrationRepository.GetCalibrationEquipmentIdsAsync(date); var result = new List(); foreach (var equipmentId in equipmentIds) { var equipment = await GetAsync(equipmentId); if (equipment != null && IsCalibrationNeededOnDate(equipment, date)) { result.Add(equipment); } } _logger.LogInformation("成功获取需要校验的设备列表,日期: {Date}, 数量: {Count}", date, result.Count); return result; } catch (Exception ex) { _logger.LogError(ex, "获取需要校验的设备列表时发生异常,日期: {Date}", date); return new List(); } } /// /// 批量检查设备可用性 /// public async Task> BatchCheckEquipmentAvailabilityAsync(List equipmentIds, DateTime date) { try { _logger.LogInformation("批量检查设备可用性,设备数量: {Count}, 日期: {Date}", equipmentIds.Count, date); var result = new Dictionary(); var tasks = equipmentIds.Select(async equipmentId => { var isAvailable = await IsEquipmentAvailableAsync(equipmentId, date); return new { EquipmentId = equipmentId, IsAvailable = isAvailable }; }); var results = await Task.WhenAll(tasks); foreach (var item in results) { result[item.EquipmentId] = item.IsAvailable; } _logger.LogInformation("批量检查设备可用性完成"); return result; } catch (Exception ex) { _logger.LogError(ex, "批量检查设备可用性时发生异常"); // 保守策略:所有设备都标记为不可用 return equipmentIds.ToDictionary(id => id, _ => false); } } #region 私有辅助方法 /// /// 填充维护和校验日期信息 /// private async Task FillMaintenanceAndCalibrationDatesAsync(EquipmentListOutput equipment) { try { // 获取最新的维护记录 var maintenanceRecords = await _maintenanceRepository.GetByEquipmentIdAsync(equipment.Id); if (maintenanceRecords != null && maintenanceRecords.Count > 0) { var lastMaintenance = maintenanceRecords .Where(m => m.Status == MaintenanceStatus.Completed) .OrderByDescending(m => m.MaintenanceDate) .FirstOrDefault(); if (lastMaintenance != null) { equipment.LastMaintenanceDate = lastMaintenance.MaintenanceDate; equipment.NextMaintenanceDate = lastMaintenance.NextPlannedDate; } } // 获取最新的校验记录 var calibrationRecords = await _calibrationRepository.GetByEquipmentIdAsync(equipment.Id); if (calibrationRecords != null && calibrationRecords.Count > 0) { var lastCalibration = calibrationRecords .Where(c => c.Status == CalibrationStatus.Completed) .OrderByDescending(c => c.CalibrationDate) .FirstOrDefault(); if (lastCalibration != null) { equipment.LastCalibrationDate = lastCalibration.CalibrationDate; equipment.NextCalibrationDate = lastCalibration.NextPlannedDate; } } } catch (Exception ex) { _logger.LogWarning(ex, "填充设备维护和校验日期信息时发生异常,设备ID: {EquipmentId}", equipment.Id); } } /// /// 检查设备在指定日期是否可用 /// private bool IsEquipmentAvailableForDate(EquipmentListOutput equipment, DateTime date) { // 基本状态检查:只有正常状态的设备才可用 if (equipment.Status != EquipmentStatus.Normal) { return false; } // 维护日期检查:如果指定日期需要维护,则不可用 if (equipment.NextMaintenanceDate.HasValue && equipment.NextMaintenanceDate.Value.Date == date.Date) { return false; } // 校验日期检查:如果指定日期需要校验,则不可用 if (equipment.NextCalibrationDate.HasValue && equipment.NextCalibrationDate.Value.Date == date.Date) { return false; } return true; } /// /// 检查设备是否需要在指定日期进行维护 /// private bool IsMaintenanceNeededOnDate(EquipmentListOutput equipment, DateTime date) { return equipment.NextMaintenanceDate.HasValue && equipment.NextMaintenanceDate.Value.Date == date.Date; } /// /// 检查设备是否需要在指定日期进行校验 /// private bool IsCalibrationNeededOnDate(EquipmentListOutput equipment, DateTime date) { return equipment.NextCalibrationDate.HasValue && equipment.NextCalibrationDate.Value.Date == date.Date; } #endregion }