mixvideo-v2/apps/desktop/src/services/tolerantJsonService.ts

289 lines
8.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { invoke } from '@tauri-apps/api/core';
export interface ParseJsonRequest {
text: string;
config?: JsonParserConfig;
}
export interface JsonParserConfig {
max_text_length?: number;
enable_comments?: boolean;
enable_unquoted_keys?: boolean;
enable_trailing_commas?: boolean;
timeout_ms?: number;
recovery_strategies?: string[];
}
export interface ParseStatistics {
total_nodes: number;
error_nodes: number;
error_rate: number;
parse_time_ms: number;
recovery_strategies_used: string[];
}
export interface ParseJsonResponse {
success: boolean;
data?: any;
statistics?: ParseStatistics;
error?: string;
}
/**
* 容错JSON解析服务
* 提供与后端JSON解析器的交互接口
*/
export class TolerantJsonService {
/**
* 解析JSON文本
*/
static async parseJson(request: ParseJsonRequest): Promise<ParseJsonResponse> {
try {
const response = await invoke<ParseJsonResponse>('parse_json_tolerant', { request });
return response;
} catch (error) {
throw new Error(`JSON解析失败: ${error instanceof Error ? error.message : '未知错误'}`);
}
}
/**
* 验证JSON格式
*/
static async validateJson(text: string): Promise<boolean> {
try {
return await invoke<boolean>('validate_json_format', { text });
} catch (error) {
throw new Error(`JSON验证失败: ${error instanceof Error ? error.message : '未知错误'}`);
}
}
/**
* 格式化JSON文本
*/
static async formatJson(text: string, indent: number = 2): Promise<string> {
try {
return await invoke<string>('format_json_text', { text, indent });
} catch (error) {
throw new Error(`JSON格式化失败: ${error instanceof Error ? error.message : '未知错误'}`);
}
}
/**
* 获取支持的恢复策略列表
*/
static async getRecoveryStrategies(): Promise<string[]> {
try {
return await invoke<string[]>('get_recovery_strategies');
} catch (error) {
throw new Error(`获取恢复策略失败: ${error instanceof Error ? error.message : '未知错误'}`);
}
}
/**
* 获取默认解析器配置
*/
static async getDefaultConfig(): Promise<JsonParserConfig> {
try {
return await invoke<JsonParserConfig>('get_default_parser_config');
} catch (error) {
throw new Error(`获取默认配置失败: ${error instanceof Error ? error.message : '未知错误'}`);
}
}
/**
* 批量解析JSON文本
*/
static async batchParseJson(
texts: string[],
config?: JsonParserConfig,
onProgress?: (current: number, total: number) => void
): Promise<ParseJsonResponse[]> {
const results: ParseJsonResponse[] = [];
for (let i = 0; i < texts.length; i++) {
try {
const result = await this.parseJson({ text: texts[i], config });
results.push(result);
onProgress?.(i + 1, texts.length);
} catch (error) {
results.push({
success: false,
error: error instanceof Error ? error.message : '解析失败'
});
onProgress?.(i + 1, texts.length);
}
}
return results;
}
/**
* 预设配置
*/
static getPresetConfigs(): Record<string, JsonParserConfig> {
return {
// 严格模式 - 只使用标准JSON解析
strict: {
max_text_length: 1024 * 1024,
enable_comments: false,
enable_unquoted_keys: false,
enable_trailing_commas: false,
timeout_ms: 10000,
recovery_strategies: ['StandardJson']
},
// 宽松模式 - 启用所有容错功能
lenient: {
max_text_length: 1024 * 1024,
enable_comments: true,
enable_unquoted_keys: true,
enable_trailing_commas: true,
timeout_ms: 30000,
recovery_strategies: ['StandardJson', 'ManualFix', 'RegexExtract', 'PartialParse']
},
// AI模式 - 专门处理AI模型返回的数据
ai_model: {
max_text_length: 2 * 1024 * 1024, // 2MB
enable_comments: true,
enable_unquoted_keys: true,
enable_trailing_commas: true,
timeout_ms: 60000, // 1分钟
recovery_strategies: ['ManualFix', 'RegexExtract', 'PartialParse', 'StandardJson']
},
// 快速模式 - 优先性能
fast: {
max_text_length: 512 * 1024, // 512KB
enable_comments: false,
enable_unquoted_keys: true,
enable_trailing_commas: true,
timeout_ms: 5000,
recovery_strategies: ['StandardJson', 'ManualFix']
}
};
}
/**
* 获取错误恢复策略的描述
*/
static getStrategyDescriptions(): Record<string, string> {
return {
'StandardJson': '标准JSON解析 - 使用原生JSON.parse()',
'YamlStringParsing': 'YAML智能解析 - 自动识别并解析字符串中的YAML内容',
'ManualFix': '手动修复 - 自动修复常见格式错误',
'RegexExtract': '正则提取 - 使用正则表达式提取JSON片段',
'PartialParse': '部分解析 - 尝试解析部分有效的JSON内容'
};
}
/**
* 分析解析统计信息
*/
static analyzeStatistics(stats: ParseStatistics): {
quality: 'excellent' | 'good' | 'fair' | 'poor';
recommendations: string[];
} {
const { error_rate, parse_time_ms, recovery_strategies_used } = stats;
let quality: 'excellent' | 'good' | 'fair' | 'poor';
const recommendations: string[] = [];
// 根据错误率判断质量
if (error_rate === 0) {
quality = 'excellent';
} else if (error_rate < 0.1) {
quality = 'good';
} else if (error_rate < 0.3) {
quality = 'fair';
recommendations.push('建议检查JSON格式存在较多语法错误');
} else {
quality = 'poor';
recommendations.push('JSON格式存在严重问题建议手动检查和修复');
}
// 根据解析时间给出建议
if (parse_time_ms > 1000) {
recommendations.push('解析时间较长建议减少文本长度或简化JSON结构');
}
// 根据使用的恢复策略给出建议
if (recovery_strategies_used.includes('PartialParse')) {
recommendations.push('使用了部分解析,可能存在数据不完整的情况');
}
if (recovery_strategies_used.includes('RegexExtract')) {
recommendations.push('使用了正则提取,建议检查提取的内容是否完整');
}
if (recovery_strategies_used.length === 0) {
recommendations.push('JSON格式标准无需额外处理');
}
return { quality, recommendations };
}
/**
* 生成解析报告
*/
static generateReport(
input: string,
result: ParseJsonResponse,
config: JsonParserConfig
): string {
const lines: string[] = [];
lines.push('# JSON解析报告');
lines.push('');
lines.push(`**解析时间**: ${new Date().toLocaleString()}`);
lines.push(`**输入长度**: ${input.length} 字符`);
lines.push(`**解析状态**: ${result.success ? '成功' : '失败'}`);
lines.push('');
if (result.success && result.statistics) {
const stats = result.statistics;
const analysis = this.analyzeStatistics(stats);
lines.push('## 统计信息');
lines.push(`- 解析时间: ${stats.parse_time_ms}ms`);
lines.push(`- 错误率: ${(stats.error_rate * 100).toFixed(2)}%`);
lines.push(`- 总节点数: ${stats.total_nodes}`);
lines.push(`- 错误节点数: ${stats.error_nodes}`);
lines.push(`- 数据质量: ${analysis.quality}`);
lines.push('');
if (stats.recovery_strategies_used.length > 0) {
lines.push('## 使用的恢复策略');
stats.recovery_strategies_used.forEach(strategy => {
const description = this.getStrategyDescriptions()[strategy] || strategy;
lines.push(`- ${description}`);
});
lines.push('');
}
if (analysis.recommendations.length > 0) {
lines.push('## 建议');
analysis.recommendations.forEach(rec => {
lines.push(`- ${rec}`);
});
lines.push('');
}
} else if (result.error) {
lines.push('## 错误信息');
lines.push(result.error);
lines.push('');
}
lines.push('## 配置信息');
lines.push(`- 最大文本长度: ${config.max_text_length || 'N/A'}`);
lines.push(`- 支持注释: ${config.enable_comments ? '是' : '否'}`);
lines.push(`- 无引号键: ${config.enable_unquoted_keys ? '是' : '否'}`);
lines.push(`- 尾随逗号: ${config.enable_trailing_commas ? '是' : '否'}`);
lines.push(`- 超时时间: ${config.timeout_ms || 'N/A'}ms`);
return lines.join('\n');
}
}
export default TolerantJsonService;