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
}