using System; using System.Collections.Generic; using System.Linq; using UnityEngine; namespace Zion.ERP.Inventory { /// /// API配置验证器 /// public static class ApiConfigValidator { /// /// 验证结果 /// public class ValidationResult { /// /// 是否验证通过 /// public bool IsValid { get; set; } /// /// 错误信息列表 /// public List Errors { get; set; } = new List(); /// /// 警告信息列表 /// public List Warnings { get; set; } = new List(); /// /// 验证通过的信息 /// public List Info { get; set; } = new List(); } /// /// 验证API配置 /// /// 配置数据 /// 验证结果 public static ValidationResult Validate(ApiConfigData config) { var result = new ValidationResult(); if (config == null) { result.IsValid = false; result.Errors.Add("配置数据为空"); return result; } // 验证基本信息 ValidateBasicInfo(config, result); // 验证环境配置 ValidateEnvironments(config, result); // 验证API接口配置 ValidateEndpoints(config, result); // 验证全局参数 ValidateGlobalParameters(config, result); // 验证配置完整性 ValidateCompleteness(config, result); // 设置验证结果 result.IsValid = result.Errors.Count == 0; return result; } /// /// 验证基本信息 /// private static void ValidateBasicInfo(ApiConfigData config, ValidationResult result) { if (string.IsNullOrEmpty(config.Version)) { result.Errors.Add("版本号不能为空"); } else if (!IsValidVersion(config.Version)) { result.Errors.Add($"版本号格式不正确:{config.Version}"); } if (string.IsNullOrEmpty(config.Description)) { result.Warnings.Add("建议添加配置描述"); } result.Info.Add($"配置版本:{config.Version}"); result.Info.Add($"当前环境:{config.CurrentEnvironment}"); } /// /// 验证环境配置 /// private static void ValidateEnvironments(ApiConfigData config, ValidationResult result) { if (config.Environments == null || config.Environments.Count == 0) { result.Errors.Add("未配置任何环境"); return; } // 检查环境名称重复 var environmentNames = config.Environments.Select(e => e.Environment).ToList(); var duplicateEnvironments = environmentNames.GroupBy(x => x).Where(g => g.Count() > 1).Select(g => g.Key); foreach (var env in duplicateEnvironments) { result.Errors.Add($"环境名称重复:{env}"); } // 验证每个环境配置 foreach (var env in config.Environments) { ValidateEnvironment(env, result); } // 检查当前环境是否存在 var currentEnv = config.Environments.FirstOrDefault(e => e.Environment == config.CurrentEnvironment); if (currentEnv == null) { result.Errors.Add($"当前环境 {config.CurrentEnvironment} 不存在"); } else if (!currentEnv.IsEnabled) { result.Warnings.Add($"当前环境 {config.CurrentEnvironment} 未启用"); } result.Info.Add($"配置了 {config.Environments.Count} 个环境"); } /// /// 验证单个环境配置 /// private static void ValidateEnvironment(ApiEnvironmentConfig env, ValidationResult result) { if (string.IsNullOrEmpty(env.BaseUrl)) { result.Errors.Add($"环境 {env.Environment} 的基础URL不能为空"); } else if (!IsValidUrl(env.BaseUrl)) { result.Errors.Add($"环境 {env.Environment} 的基础URL格式不正确:{env.BaseUrl}"); } if (env.DefaultTimeout <= 0) { result.Errors.Add($"环境 {env.Environment} 的默认超时时间必须大于0"); } if (env.DefaultRetryCount < 0) { result.Errors.Add($"环境 {env.Environment} 的默认重试次数不能为负数"); } if (string.IsNullOrEmpty(env.Description)) { result.Warnings.Add($"建议为环境 {env.Environment} 添加描述"); } } /// /// 验证API接口配置 /// private static void ValidateEndpoints(ApiConfigData config, ValidationResult result) { if (config.Endpoints == null || config.Endpoints.Count == 0) { result.Warnings.Add("未配置任何API接口"); return; } // 检查接口名称重复 var endpointNames = config.Endpoints.Select(e => e.Name).ToList(); var duplicateEndpoints = endpointNames.GroupBy(x => x).Where(g => g.Count() > 1).Select(g => g.Key); foreach (var endpoint in duplicateEndpoints) { result.Errors.Add($"API接口名称重复:{endpoint}"); } // 验证每个接口配置 foreach (var endpoint in config.Endpoints) { ValidateEndpoint(endpoint, result); } result.Info.Add($"配置了 {config.Endpoints.Count} 个API接口"); result.Info.Add($"启用了 {config.Endpoints.Count(e => e.IsEnabled)} 个API接口"); } /// /// 验证单个API接口配置 /// private static void ValidateEndpoint(ApiEndpoint endpoint, ValidationResult result) { if (string.IsNullOrEmpty(endpoint.Name)) { result.Errors.Add("API接口名称不能为空"); } else if (!IsValidEndpointName(endpoint.Name)) { result.Errors.Add($"API接口名称格式不正确:{endpoint.Name}"); } if (string.IsNullOrEmpty(endpoint.Description)) { result.Warnings.Add($"建议为API接口 {endpoint.Name} 添加描述"); } if (string.IsNullOrEmpty(endpoint.UrlTemplate)) { result.Errors.Add($"API接口 {endpoint.Name} 的URL模板不能为空"); } else { ValidateUrlTemplate(endpoint.UrlTemplate, endpoint.Name, result); } if (string.IsNullOrEmpty(endpoint.Method)) { result.Errors.Add($"API接口 {endpoint.Name} 的HTTP方法不能为空"); } else if (!IsValidHttpMethod(endpoint.Method)) { result.Errors.Add($"API接口 {endpoint.Name} 的HTTP方法不正确:{endpoint.Method}"); } if (endpoint.Timeout <= 0) { result.Errors.Add($"API接口 {endpoint.Name} 的超时时间必须大于0"); } if (endpoint.RetryCount < 0) { result.Errors.Add($"API接口 {endpoint.Name} 的重试次数不能为负数"); } // 验证参数配置 if (endpoint.Parameters != null) { foreach (var param in endpoint.Parameters) { ValidateParameter(param, $"API接口 {endpoint.Name}", result); } } } /// /// 验证URL模板 /// private static void ValidateUrlTemplate(string urlTemplate, string endpointName, ValidationResult result) { // 检查是否包含必需的基础URL占位符 if (!urlTemplate.Contains("{BaseUrl}") && !urlTemplate.StartsWith("http")) { result.Errors.Add($"API接口 {endpointName} 的URL模板缺少基础URL占位符或完整的URL"); } // 检查占位符格式 var placeholders = ExtractPlaceholders(urlTemplate); foreach (var placeholder in placeholders) { if (!IsValidPlaceholder(placeholder)) { result.Warnings.Add($"API接口 {endpointName} 的URL模板包含未知占位符:{placeholder}"); } } } /// /// 验证全局参数 /// private static void ValidateGlobalParameters(ApiConfigData config, ValidationResult result) { if (config.GlobalParameters == null || config.GlobalParameters.Count == 0) { result.Info.Add("未配置全局参数"); return; } // 检查参数名称重复 var paramNames = config.GlobalParameters.Select(p => p.Name).ToList(); var duplicateParams = paramNames.GroupBy(x => x).Where(g => g.Count() > 1).Select(g => g.Key); foreach (var param in duplicateParams) { result.Errors.Add($"全局参数名称重复:{param}"); } // 验证每个参数 foreach (var param in config.GlobalParameters) { ValidateParameter(param, "全局参数", result); } result.Info.Add($"配置了 {config.GlobalParameters.Count} 个全局参数"); } /// /// 验证单个参数 /// private static void ValidateParameter(ApiParameter param, string context, ValidationResult result) { if (string.IsNullOrEmpty(param.Name)) { result.Errors.Add($"{context} 参数名称不能为空"); } if (param.IsRequired && string.IsNullOrEmpty(param.Value)) { result.Errors.Add($"{context} {param.Name} 是必需参数,但值为空"); } if (string.IsNullOrEmpty(param.Description)) { result.Warnings.Add($"建议为{context} {param.Name} 添加描述"); } } /// /// 验证配置完整性 /// private static void ValidateCompleteness(ApiConfigData config, ValidationResult result) { // 检查是否有启用的环境 var enabledEnvironments = config.Environments?.Where(e => e.IsEnabled).ToList(); if (enabledEnvironments == null || enabledEnvironments.Count == 0) { result.Errors.Add("没有启用的环境配置"); } // 检查是否有启用的API接口 var enabledEndpoints = config.Endpoints?.Where(e => e.IsEnabled).ToList(); if (enabledEndpoints == null || enabledEndpoints.Count == 0) { result.Warnings.Add("没有启用的API接口"); } // 检查配置的完整性 if (config.Environments != null && config.Environments.Count > 0 && config.Endpoints != null && config.Endpoints.Count > 0) { result.Info.Add("配置结构完整"); } } /// /// 验证版本号格式 /// private static bool IsValidVersion(string version) { return System.Text.RegularExpressions.Regex.IsMatch(version, @"^\d+\.\d+\.\d+$"); } /// /// 验证URL格式 /// private static bool IsValidUrl(string url) { return Uri.TryCreate(url, UriKind.Absolute, out _); } /// /// 验证API接口名称格式 /// private static bool IsValidEndpointName(string name) { return System.Text.RegularExpressions.Regex.IsMatch(name, @"^[A-Za-z][A-Za-z0-9_]*$"); } /// /// 验证HTTP方法 /// private static bool IsValidHttpMethod(string method) { var validMethods = new[] { "GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS" }; return validMethods.Contains(method.ToUpper()); } /// /// 验证占位符 /// private static bool IsValidPlaceholder(string placeholder) { var validPlaceholders = new[] { "BaseUrl", "PaperId", "ExamRoomId" }; return validPlaceholders.Contains(placeholder); } /// /// 提取URL模板中的占位符 /// private static List ExtractPlaceholders(string urlTemplate) { var placeholders = new List(); var matches = System.Text.RegularExpressions.Regex.Matches(urlTemplate, @"\{([^}]+)\}"); foreach (System.Text.RegularExpressions.Match match in matches) { placeholders.Add(match.Groups[1].Value); } return placeholders; } /// /// 打印验证结果 /// public static void PrintValidationResult(ValidationResult result) { if (result.IsValid) { Debug.Log("✅ API配置验证通过"); } else { Debug.LogError("❌ API配置验证失败"); } if (result.Errors.Count > 0) { Debug.LogError("错误信息:"); foreach (var error in result.Errors) { Debug.LogError($" - {error}"); } } if (result.Warnings.Count > 0) { Debug.LogWarning("警告信息:"); foreach (var warning in result.Warnings) { Debug.LogWarning($" - {warning}"); } } if (result.Info.Count > 0) { Debug.Log("信息:"); foreach (var info in result.Info) { Debug.Log($" - {info}"); } } } } }