You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

272 lines
11 KiB
C#

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Haoliang.Models.Template;
using Haoliang.Models.Device;
using Haoliang.Models.DataCollection;
namespace Haoliang.Core.Services
{
public interface ITemplateService
{
Task<CNCBrandTemplate> CreateTemplateAsync(CNCBrandTemplate template);
Task<CNCBrandTemplate> UpdateTemplateAsync(int templateId, CNCBrandTemplate template);
Task<bool> DeleteTemplateAsync(int templateId);
Task<CNCBrandTemplate> GetTemplateByIdAsync(int templateId);
Task<IEnumerable<CNCBrandTemplate>> GetAllTemplatesAsync();
Task<IEnumerable<CNCBrandTemplate>> GetTemplatesByBrandAsync(string brandName);
Task<IEnumerable<CNCBrandTemplate>> GetActiveTemplatesAsync();
Task<bool> ValidateTemplateAsync(CNCBrandTemplate template);
Task TestTemplateAsync(int templateId);
Task<CNCBrandTemplate> CloneTemplateAsync(int templateId, string newName);
Task<bool> EnableTemplateAsync(int templateId);
Task<bool> DisableTemplateAsync(int templateId);
}
public interface ITagMappingService
{
Task<TagMapping> CreateTagMappingAsync(TagMapping mapping);
Task<TagMapping> UpdateTagMappingAsync(int mappingId, TagMapping mapping);
Task<bool> DeleteTagMappingAsync(int mappingId);
Task<TagMapping> GetTagMappingByIdAsync(int mappingId);
Task<IEnumerable<TagMapping>> GetAllTagMappingsAsync();
Task<IEnumerable<TagMapping>> GetMappingsByTemplateAsync(int templateId);
Task<TagMapping> MapDeviceTagAsync(TagData deviceTag, int templateId);
Task<Dictionary<string, TagData>> MapDeviceTagsAsync(IEnumerable<TagData> deviceTags, int templateId);
Task ValidateTagMappingAsync(TagMapping mapping);
}
public interface ITemplateValidationService
{
Task<bool> ValidateTemplateStructureAsync(CNCBrandTemplate template);
Task<bool> ValidateTagMappingsAsync(CNCBrandTemplate template);
Task<bool> ValidateDataParsingRulesAsync(CNCBrandTemplate template);
Task<IEnumerable<ValidationError>> ValidateTemplateForDeviceAsync(int templateId, int deviceId);
Task<bool> TestTemplateDataParsingAsync(CNCBrandTemplate template, string sampleData);
Task<IEnumerable<string>> GetMissingRequiredTagsAsync(CNCBrandTemplate template);
}
public interface ITemplateMigrationService
{
Task<CNCBrandTemplate> MigrateTemplateAsync(CNCBrandTemplate oldTemplate, string targetBrand);
Task<bool> ValidateMigrationCompatibilityAsync(CNCBrandTemplate sourceTemplate, string targetBrand);
Task<MigrationReport> GenerateMigrationReportAsync(CNCBrandTemplate template, string targetBrand);
Task<IEnumerable<MigrationIssue>> DetectMigrationIssuesAsync(CNCBrandTemplate template, string targetBrand);
}
public class TemplateManager : ITemplateService
{
private readonly ITemplateRepository _templateRepository;
private readonly ITagMappingService _tagMappingService;
private readonly ITemplateValidationService _validationService;
private readonly ITemplateMigrationService _migrationService;
public TemplateManager(
ITemplateRepository templateRepository,
ITagMappingService tagMappingService,
ITemplateValidationService validationService,
ITemplateMigrationService migrationService)
{
_templateRepository = templateRepository;
_tagMappingService = tagMappingService;
_validationService = validationService;
_migrationService = migrationService;
}
public async Task<CNCBrandTemplate> CreateTemplateAsync(CNCBrandTemplate template)
{
// 验证模板
var validationErrors = await _validationService.ValidateTemplateStructureAsync(template);
if (validationErrors.Count > 0)
{
throw new InvalidOperationException($"Template validation failed: {string.Join(", ", validationErrors)}");
}
// 设置初始状态
template.IsEnabled = true;
template.CreateTime = DateTime.Now;
template.UpdateTime = DateTime.Now;
var createdTemplate = await _templateRepository.AddAsync(template);
// 验证标签映射
await _validationService.ValidateTagMappingsAsync(createdTemplate);
return createdTemplate;
}
public async Task<CNCBrandTemplate> UpdateTemplateAsync(int templateId, CNCBrandTemplate template)
{
var existingTemplate = await _templateRepository.GetByIdAsync(templateId);
if (existingTemplate == null)
{
throw new KeyNotFoundException($"Template with ID {templateId} not found");
}
// 验证更新后的模板
var validationErrors = await _validationService.ValidateTemplateStructureAsync(template);
if (validationErrors.Count > 0)
{
throw new InvalidOperationException($"Template validation failed: {string.Join(", ", validationErrors)}");
}
template.TemplateId = templateId;
template.UpdateTime = DateTime.Now;
var updatedTemplate = await _templateRepository.UpdateAsync(template);
// 如果标签有变化,重新验证
if (HasTagMappingsChanged(existingTemplate, template))
{
await _validationService.ValidateTagMappingsAsync(updatedTemplate);
}
return updatedTemplate;
}
public async Task<bool> DeleteTemplateAsync(int templateId)
{
// 检查模板是否被使用
var isTemplateInUse = await _templateRepository.IsTemplateInUseAsync(templateId);
if (isTemplateInUse)
{
throw new InvalidOperationException("Cannot delete template that is currently in use by devices");
}
return await _templateRepository.DeleteAsync(templateId);
}
public async Task<CNCBrandTemplate> GetTemplateByIdAsync(int templateId)
{
return await _templateRepository.GetByIdAsync(templateId);
}
public async Task<IEnumerable<CNCBrandTemplate>> GetAllTemplatesAsync()
{
return await _templateRepository.GetAllAsync();
}
public async Task<IEnumerable<CNCBrandTemplate>> GetTemplatesByBrandAsync(string brandName)
{
return await _templateRepository.GetByBrandAsync(brandName);
}
public async Task<IEnumerable<CNCBrandTemplate>> GetActiveTemplatesAsync()
{
return await _templateRepository.GetActiveTemplatesAsync();
}
public async Task<bool> ValidateTemplateAsync(CNCBrandTemplate template)
{
return await _validationService.ValidateTemplateStructureAsync(template);
}
public async Task TestTemplateAsync(int templateId)
{
var template = await _templateRepository.GetByIdAsync(templateId);
if (template == null)
{
throw new KeyNotFoundException($"Template with ID {templateId} not found");
}
// 使用模板进行数据解析测试
await _validationService.TestTemplateDataParsingAsync(template, GetSampleData(template));
}
public async Task<CNCBrandTemplate> CloneTemplateAsync(int templateId, string newName)
{
var originalTemplate = await _templateRepository.GetByIdAsync(templateId);
if (originalTemplate == null)
{
throw new KeyNotFoundException($"Template with ID {templateId} not found");
}
var clonedTemplate = new CNCBrandTemplate
{
TemplateName = newName,
BrandName = originalTemplate.BrandName,
Description = $"Cloned from {originalTemplate.TemplateName}",
IsEnabled = false, // 新克隆的模板默认禁用
Version = originalTemplate.Version,
TemplateJson = originalTemplate.TemplateJson,
CreateTime = DateTime.Now,
UpdateTime = DateTime.Now
};
return await CreateTemplateAsync(clonedTemplate);
}
public async Task<bool> EnableTemplateAsync(int templateId)
{
var template = await _templateRepository.GetByIdAsync(templateId);
if (template == null)
{
return false;
}
template.IsEnabled = true;
template.UpdateTime = DateTime.Now;
return await _templateRepository.UpdateAsync(template) != null;
}
public async Task<bool> DisableTemplateAsync(int templateId)
{
var template = await _templateRepository.GetByIdAsync(templateId);
if (template == null)
{
return false;
}
// 检查是否还有设备在使用此模板
var isTemplateInUse = await _templateRepository.IsTemplateInUseAsync(templateId);
if (isTemplateInUse)
{
throw new InvalidOperationException("Cannot disable template that is currently in use by devices");
}
template.IsEnabled = false;
template.UpdateTime = DateTime.Now;
return await _templateRepository.UpdateAsync(template) != null;
}
private bool HasTagMappingsChanged(CNCBrandTemplate oldTemplate, CNCBrandTemplate newTemplate)
{
// 简单比较JSON内容是否变化
return oldTemplate.TemplateJson != newTemplate.TemplateJson;
}
private string GetSampleData(CNCBrandTemplate template)
{
// 返回模拟的设备数据用于测试
return @"{
""device"": ""FANUC_01"",
""desc"": ""CNC Machine"",
""tags"": [
{
""id"": ""_io_status"",
""desc"": ""I/O Status"",
""quality"": 0,
""value"": 1,
""time"": ""2024-01-01T10:00:00""
},
{
""id"": ""Tag5"",
""desc"": ""NC Program"",
""quality"": 0,
""value"": ""O1234"",
""time"": ""2024-01-01T10:00:00""
},
{
""id"": ""Tag8"",
""desc"": ""Cumulative Count"",
""quality"": 0,
""value"": 12345.00000,
""time"": ""2024-01-01T10:00:00""
}
]
}";
}
}
}