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 CreateTemplateAsync(CNCBrandTemplate template); Task UpdateTemplateAsync(int templateId, CNCBrandTemplate template); Task DeleteTemplateAsync(int templateId); Task GetTemplateByIdAsync(int templateId); Task> GetAllTemplatesAsync(); Task> GetTemplatesByBrandAsync(string brandName); Task> GetActiveTemplatesAsync(); Task ValidateTemplateAsync(CNCBrandTemplate template); Task TestTemplateAsync(int templateId); Task CloneTemplateAsync(int templateId, string newName); Task EnableTemplateAsync(int templateId); Task DisableTemplateAsync(int templateId); } public interface ITagMappingService { Task CreateTagMappingAsync(TagMapping mapping); Task UpdateTagMappingAsync(int mappingId, TagMapping mapping); Task DeleteTagMappingAsync(int mappingId); Task GetTagMappingByIdAsync(int mappingId); Task> GetAllTagMappingsAsync(); Task> GetMappingsByTemplateAsync(int templateId); Task MapDeviceTagAsync(TagData deviceTag, int templateId); Task> MapDeviceTagsAsync(IEnumerable deviceTags, int templateId); Task ValidateTagMappingAsync(TagMapping mapping); } public interface ITemplateValidationService { Task ValidateTemplateStructureAsync(CNCBrandTemplate template); Task ValidateTagMappingsAsync(CNCBrandTemplate template); Task ValidateDataParsingRulesAsync(CNCBrandTemplate template); Task> ValidateTemplateForDeviceAsync(int templateId, int deviceId); Task TestTemplateDataParsingAsync(CNCBrandTemplate template, string sampleData); Task> GetMissingRequiredTagsAsync(CNCBrandTemplate template); } public interface ITemplateMigrationService { Task MigrateTemplateAsync(CNCBrandTemplate oldTemplate, string targetBrand); Task ValidateMigrationCompatibilityAsync(CNCBrandTemplate sourceTemplate, string targetBrand); Task GenerateMigrationReportAsync(CNCBrandTemplate template, string targetBrand); Task> 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 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 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 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 GetTemplateByIdAsync(int templateId) { return await _templateRepository.GetByIdAsync(templateId); } public async Task> GetAllTemplatesAsync() { return await _templateRepository.GetAllAsync(); } public async Task> GetTemplatesByBrandAsync(string brandName) { return await _templateRepository.GetByBrandAsync(brandName); } public async Task> GetActiveTemplatesAsync() { return await _templateRepository.GetActiveTemplatesAsync(); } public async Task 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 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 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 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"" } ] }"; } } }