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}");
}
}
}
}
}