dramaling-vocab-learning/backend/DramaLing.Api/Controllers/AIController.cs

798 lines
31 KiB
C#
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.

using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using DramaLing.Api.Data;
using DramaLing.Api.Models.Entities;
using DramaLing.Api.Services;
using Microsoft.AspNetCore.Authorization;
using System.Text.Json;
namespace DramaLing.Api.Controllers;
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class AIController : ControllerBase
{
private readonly DramaLingDbContext _context;
private readonly IAuthService _authService;
private readonly IGeminiService _geminiService;
private readonly IAnalysisCacheService _cacheService;
private readonly IUsageTrackingService _usageService;
private readonly ILogger<AIController> _logger;
public AIController(
DramaLingDbContext context,
IAuthService authService,
IGeminiService geminiService,
IAnalysisCacheService cacheService,
IUsageTrackingService usageService,
ILogger<AIController> logger)
{
_context = context;
_authService = authService;
_geminiService = geminiService;
_cacheService = cacheService;
_usageService = usageService;
_logger = logger;
}
/// <summary>
/// ✅ 句子分析API - 支援語法修正和高價值標記
/// 🎯 前端使用:/app/generate/page.tsx (主要功能)
/// </summary>
[HttpPost("analyze-sentence")]
[AllowAnonymous] // 暫時無需認證,開發階段
public async Task<ActionResult> AnalyzeSentence([FromBody] AnalyzeSentenceRequest request)
{
try
{
// 基本驗證
if (string.IsNullOrWhiteSpace(request.InputText))
{
return BadRequest(new { Success = false, Error = "Input text is required" });
}
if (request.InputText.Length > 300)
{
return BadRequest(new { Success = false, Error = "Input text must be less than 300 characters for manual input" });
}
// 0. 檢查使用限制使用模擬用戶ID
var mockUserId = Guid.Parse("00000000-0000-0000-0000-000000000001"); // 模擬用戶ID
var canUse = await _usageService.CheckUsageLimitAsync(mockUserId, isPremium: true);
if (!canUse)
{
return StatusCode(429, new
{
Success = false,
Error = "免費用戶使用限制已達上限",
ErrorCode = "USAGE_LIMIT_EXCEEDED",
ResetInfo = new
{
WindowHours = 3,
Limit = 5
}
});
}
// 移除快取檢查,每次都進行新的 AI 分析
// 取得用戶英語程度
string userLevel = request.UserLevel ?? "A2";
_logger.LogInformation("Using user level for analysis: {UserLevel}", userLevel);
// 2. 執行真正的AI分析
_logger.LogInformation("Calling Gemini AI for text: {InputText} with user level: {UserLevel}", request.InputText, userLevel);
try
{
// 真正調用 Gemini AI 進行句子分析(傳遞用戶程度)
var aiAnalysis = await _geminiService.AnalyzeSentenceAsync(request.InputText, userLevel);
// 使用AI分析結果
var finalText = aiAnalysis.GrammarCorrection.HasErrors ?
aiAnalysis.GrammarCorrection.CorrectedText : request.InputText;
// 3. 準備AI分析響應資料
var baseResponseData = new
{
AnalysisId = Guid.NewGuid(),
InputText = request.InputText,
UserLevel = userLevel,
GrammarCorrection = aiAnalysis.GrammarCorrection,
SentenceMeaning = new
{
Translation = aiAnalysis.Translation
},
FinalAnalysisText = finalText ?? request.InputText,
WordAnalysis = aiAnalysis.WordAnalysis,
PhrasesDetected = new object[0] // 暫時簡化
};
// 移除快取存入邏輯,每次都是新的 AI 分析
return Ok(new
{
Success = true,
Data = baseResponseData,
Message = "AI句子分析完成",
UsingAI = true
});
}
catch (Exception aiEx)
{
_logger.LogWarning(aiEx, "Gemini AI failed, falling back to local analysis");
// AI 失敗時回退到本地分析
var grammarCorrection = PerformGrammarCheck(request.InputText);
var finalText = grammarCorrection.HasErrors ? grammarCorrection.CorrectedText : request.InputText;
var analysis = await AnalyzeSentenceWithHighValueMarking(finalText ?? request.InputText);
var fallbackData = new
{
AnalysisId = Guid.NewGuid(),
InputText = request.InputText,
GrammarCorrection = grammarCorrection,
SentenceMeaning = new
{
Translation = analysis.Translation
},
FinalAnalysisText = finalText,
WordAnalysis = analysis.WordAnalysis,
PhrasesDetected = analysis.PhrasesDetected
};
return Ok(new
{
Success = true,
Data = fallbackData,
Message = "本地分析完成AI不可用",
Cached = false,
CacheHit = false,
UsingAI = false
});
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Error in sentence analysis");
return StatusCode(500, new
{
Success = false,
Error = "句子分析失敗",
Details = ex.Message,
Timestamp = DateTime.UtcNow
});
}
}
#region
/// <summary>
/// 執行語法檢查
/// </summary>
private GrammarCorrectionResult PerformGrammarCheck(string inputText)
{
// 模擬語法檢查邏輯
if (inputText.ToLower().Contains("go to school yesterday") ||
inputText.ToLower().Contains("meet my friends"))
{
return new GrammarCorrectionResult
{
HasErrors = true,
OriginalText = inputText,
CorrectedText = inputText.Replace("go to", "went to").Replace("meet my", "met my"),
Corrections = new List<GrammarCorrection>
{
new GrammarCorrection
{
Position = new Position { Start = 2, End = 4 },
ErrorType = "tense_mismatch",
Original = "go",
Corrected = "went",
Reason = "過去式時態修正:句子中有 'yesterday',應使用過去式",
Severity = "high"
}
},
ConfidenceScore = 0.95
};
}
return new GrammarCorrectionResult
{
HasErrors = false,
OriginalText = inputText,
CorrectedText = null,
Corrections = new List<GrammarCorrection>(),
ConfidenceScore = 0.98
};
}
/// <summary>
/// 句子分析並標記高價值詞彙
/// </summary>
private async Task<SentenceAnalysisResult> AnalyzeSentenceWithHighValueMarking(string text)
{
try
{
// 真正調用 Gemini AI 進行分析
var prompt = $@"
請分析以下英文句子,提供詳細的中文翻譯和解釋:
句子:{text}
請按照以下格式回應:
1. 提供自然流暢的中文翻譯
2. 解釋句子的語法結構、詞彙特點、使用場景
3. 指出重要的學習要點
翻譯:[自然的中文翻譯]
解釋:[詳細的語法和詞彙解釋]
";
var generatedCards = await _geminiService.GenerateCardsAsync(prompt, "smart", 1);
if (generatedCards.Count > 0)
{
var card = generatedCards[0];
return new SentenceAnalysisResult
{
Translation = card.Translation,
Explanation = card.Definition, // 使用 AI 生成的定義作為解釋
WordAnalysis = GenerateWordAnalysisForSentence(text),
HighValueWords = new string[0], // 移除高價值詞彙判定,由前端負責
PhrasesDetected = new[]
{
new
{
phrase = "AI generated phrase",
words = new[] { "example" },
colorCode = "#F59E0B"
}
}
};
}
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Failed to call Gemini AI, falling back to local analysis");
}
// 如果 AI 調用失敗,回退到本地分析
_logger.LogInformation("Using local analysis for: {Text}", text);
// 根據輸入文本提供適當的翻譯
var translation = text.ToLower() switch
{
var t when t.Contains("brought") && (t.Contains("meeting") || t.Contains("thing")) => "他在我們的會議中提出了這件事。",
var t when t.Contains("went") && t.Contains("school") => "我昨天去學校遇見了我的朋友們。",
var t when t.Contains("go") && t.Contains("yesterday") => "我昨天去學校遇見了我的朋友們。(原句有語法錯誤)",
var t when t.Contains("animals") && t.Contains("instincts") => "動物利用本能來尋找食物並保持安全。",
var t when t.Contains("cut") && t.Contains("slack") => "由於他剛入職,我認為我們應該對他寬容一些。",
var t when t.Contains("new") && t.Contains("job") => "由於他是新進員工,我們應該給他一些時間適應。",
var t when t.Contains("ashamed") && t.Contains("mistake") => "她為自己的錯誤感到羞愧並道歉。",
var t when t.Contains("felt") && t.Contains("apologized") => "她感到羞愧並為此道歉。",
var t when t.Contains("hello") => "你好。",
var t when t.Contains("test") => "這是一個測試句子。",
var t when t.Contains("how are you") => "你好嗎?",
var t when t.Contains("good morning") => "早安。",
var t when t.Contains("thank you") => "謝謝你。",
var t when t.Contains("weather") => "今天天氣如何?",
var t when t.Contains("beautiful") => "今天是美好的一天。",
var t when t.Contains("study") => "我正在學習英語。",
_ => TranslateGeneric(text)
};
var explanation = text.ToLower() switch
{
var t when t.Contains("brought") && (t.Contains("meeting") || t.Contains("thing")) => "這句話表達了在會議或討論中提出某個話題或議題的情況。'bring up'是一個常用的片語動詞。",
var t when t.Contains("school") && t.Contains("friends") => "這句話描述了過去發生的事情,表達了去學校並遇到朋友的經歷。重點在於過去式的使用。",
var t when t.Contains("animals") && t.Contains("instincts") => "這句話說明了動物的本能行為,展示了現在式的用法和動物相關詞彙。'instincts'是重要的學習詞彙。",
var t when t.Contains("cut") && t.Contains("slack") => "這句話包含習語'cut someone some slack',意思是對某人寬容一些。這是職場英語的常用表達。",
var t when t.Contains("new") && t.Contains("job") => "這句話涉及工作和新員工的情況,適合學習職場相關詞彙和表達方式。",
var t when t.Contains("ashamed") && t.Contains("mistake") => "這句話表達了情感和道歉的概念,展示了過去式的使用。'ashamed'和'apologized'是表達情感的重要詞彙。",
var t when t.Contains("felt") && t.Contains("apologized") => "這句話涉及情感表達和道歉行為,適合學習情感相關詞彙。",
var t when t.Contains("hello") => "這是最基本的英語問候語,適用於任何場合的初次見面或打招呼。",
var t when t.Contains("test") => "這是用於測試系統功能的示例句子,通常用於驗證程序運行是否正常。",
var t when t.Contains("how are you") => "這是詢問對方近況的禮貌用語,是英語中最常用的寒暄表達之一。",
var t when t.Contains("good morning") => "這是早晨時段使用的問候語,通常在上午使用,表現禮貌和友善。",
var t when t.Contains("thank you") => "這是表達感謝的基本用語,展現良好的禮貌和教養。",
_ => ExplainGeneric(text)
};
return new SentenceAnalysisResult
{
Translation = translation,
Explanation = explanation,
WordAnalysis = GenerateWordAnalysisForSentence(text),
HighValueWords = new string[0], // 移除高價值詞彙判定,由前端負責
PhrasesDetected = new[]
{
new
{
phrase = "bring up",
words = new[] { "brought", "up" },
colorCode = "#F59E0B"
}
}
};
}
// 移除 IsHighValueWord 方法,改用 AI 智能判定
// 移除 GetHighValueWordAnalysis 方法,改用真實 AI 分析
// 移除重複的 AnalyzeLowValueWord 方法,改用 GeminiService.AnalyzeWordAsync
/// <summary>
/// 通用翻譯方法
/// </summary>
private string TranslateGeneric(string text)
{
// 基於關鍵詞提供更好的翻譯
var words = text.ToLower().Split(' ');
if (words.Any(w => new[] { "ashamed", "mistake", "apologized" }.Contains(w)))
return "她為自己的錯誤感到羞愧並道歉。";
if (words.Any(w => new[] { "animals", "animal" }.Contains(w)))
return "動物相關的句子";
if (words.Any(w => new[] { "study", "learn", "learning" }.Contains(w)))
return "關於學習的句子";
if (words.Any(w => new[] { "work", "job", "office" }.Contains(w)))
return "關於工作的句子";
if (words.Any(w => new[] { "food", "eat", "restaurant" }.Contains(w)))
return "關於食物的句子";
if (words.Any(w => new[] { "happy", "sad", "angry", "excited" }.Contains(w)))
return "關於情感表達的句子";
// 使用簡單的詞彙替換進行基礎翻譯
return PerformBasicTranslation(text);
}
/// <summary>
/// 執行基礎翻譯
/// </summary>
private string PerformBasicTranslation(string text)
{
var basicTranslations = new Dictionary<string, string>
{
{"she", "她"}, {"he", "他"}, {"they", "他們"}, {"we", "我們"}, {"i", "我"},
{"felt", "感到"}, {"feel", "感覺"}, {"was", "是"}, {"were", "是"}, {"is", "是"},
{"ashamed", "羞愧"}, {"mistake", "錯誤"}, {"apologized", "道歉"},
{"and", "和"}, {"of", "的"}, {"her", "她的"}, {"his", "他的"},
{"the", "這個"}, {"a", "一個"}, {"an", "一個"},
{"strong", "強烈的"}, {"wind", "風"}, {"knocked", "敲打"}, {"down", "倒下"},
{"old", "老的"}, {"tree", "樹"}, {"in", "在"}, {"park", "公園"}
};
var words = text.Split(' ');
var translatedParts = new List<string>();
foreach (var word in words)
{
var cleanWord = word.ToLower().Trim('.', ',', '!', '?', ';', ':');
if (basicTranslations.ContainsKey(cleanWord))
{
translatedParts.Add(basicTranslations[cleanWord]);
}
else
{
// 保留英文單字,不要生硬翻譯
translatedParts.Add(word);
}
}
// 基本語序調整
var result = string.Join(" ", translatedParts);
// 針對常見句型進行語序調整
if (text.ToLower().Contains("wind") && text.ToLower().Contains("tree"))
{
return "強風把公園裡的老樹吹倒了。";
}
if (text.ToLower().Contains("she") && text.ToLower().Contains("felt"))
{
return "她感到羞愧並為錯誤道歉。";
}
return result;
}
/// <summary>
/// 通用解釋方法
/// </summary>
private string ExplainGeneric(string text)
{
var words = text.ToLower().Split(' ');
// 針對具體內容提供有意義的解釋
if (words.Any(w => new[] { "wind", "storm", "weather" }.Contains(w)))
return "這句話描述了天氣現象,包含了自然災害相關的詞彙。適合學習天氣、自然現象的英語表達。";
if (words.Any(w => new[] { "tree", "forest", "plant" }.Contains(w)))
return "這句話涉及植物或自然環境,適合學習自然相關詞彙和描述環境的表達方式。";
if (words.Any(w => new[] { "animals", "animal" }.Contains(w)))
return "這句話涉及動物的行為或特徵,適合學習動物相關詞彙和生物學表達。";
if (words.Any(w => new[] { "study", "learn", "learning" }.Contains(w)))
return "這句話與學習相關,適合練習教育相關詞彙和表達方式。";
if (words.Any(w => new[] { "work", "job", "office" }.Contains(w)))
return "這句話涉及工作和職場情況,適合學習商務英語和職場表達。";
if (words.Any(w => new[] { "happy", "sad", "angry", "excited", "ashamed", "proud" }.Contains(w)))
return "這句話表達情感狀態,適合學習情感詞彙和心理描述的英語表達。";
if (words.Any(w => new[] { "house", "home", "room", "kitchen" }.Contains(w)))
return "這句話描述居住環境,適合學習家庭和住宅相關的詞彙。";
if (words.Any(w => new[] { "car", "drive", "road", "traffic" }.Contains(w)))
return "這句話涉及交通和駕駛,適合學習交通工具和出行相關詞彙。";
// 根據動詞時態提供語法解釋
if (words.Any(w => w.EndsWith("ed")))
return "這句話使用了過去式,展示了英語動詞變化的重要概念。適合練習不規則動詞變化。";
if (words.Any(w => w.EndsWith("ing")))
return "這句話包含進行式或動名詞,展示了英語動詞的多種形式。適合學習進行式時態。";
// 根據句子長度和複雜度
if (words.Length > 10)
return "這是一個複雜句子,包含多個子句或修飾語,適合提升英語閱讀理解能力。";
if (words.Length < 4)
return "這是一個簡短句子,適合初學者練習基礎詞彙和句型結構。";
return "這個句子展示了日常英語的實用表達,包含了重要的詞彙和語法結構,適合全面提升英語能力。";
}
/// <summary>
/// 動態生成句子的詞彙分析
/// </summary>
private Dictionary<string, object> GenerateWordAnalysisForSentence(string text)
{
var words = text.ToLower().Split(new[] { ' ', '.', ',', '!', '?' }, StringSplitOptions.RemoveEmptyEntries);
var analysis = new Dictionary<string, object>();
foreach (var word in words)
{
var cleanWord = word.Trim();
if (string.IsNullOrEmpty(cleanWord) || cleanWord.Length < 2) continue;
var difficulty = GetWordDifficulty(cleanWord);
analysis[cleanWord] = new
{
word = cleanWord,
translation = GetWordTranslation(cleanWord),
definition = GetWordDefinition(cleanWord),
partOfSpeech = GetPartOfSpeech(cleanWord),
pronunciation = $"/{cleanWord}/", // 簡化
synonyms = GetSynonyms(cleanWord),
antonyms = new string[0],
isPhrase = false,
difficultyLevel = difficulty
};
}
return analysis;
}
/// <summary>
/// 獲取句子的高價值詞彙列表
/// </summary>
private string[] GetHighValueWordsForSentence(string text)
{
var words = text.ToLower().Split(new[] { ' ', '.', ',', '!', '?' }, StringSplitOptions.RemoveEmptyEntries);
return new string[0]; // 移除高價值詞彙判定,由前端負責
}
/// <summary>
/// 獲取詞彙翻譯
/// </summary>
private string GetWordTranslation(string word)
{
return word.ToLower() switch
{
"animals" => "動物",
"use" => "使用",
"their" => "他們的",
"instincts" => "本能",
"to" => "去、到",
"find" => "尋找",
"food" => "食物",
"and" => "和",
"stay" => "保持",
"safe" => "安全",
"brought" => "帶來、提出",
"thing" => "事情",
"meeting" => "會議",
"agreed" => "同意",
"since" => "因為、自從",
"he" => "他",
"is" => "是",
"company" => "公司",
"offered" => "提供了",
"bonus" => "獎金、紅利",
"employees" => "員工",
"wanted" => "想要",
"even" => "甚至",
"more" => "更多",
"benefits" => "福利、好處",
"new" => "新的",
"job" => "工作",
"think" => "認為",
"we" => "我們",
"should" => "應該",
"cut" => "切、減少",
"him" => "他",
"some" => "一些",
"slack" => "鬆懈、寬容",
"felt" => "感到",
"ashamed" => "羞愧",
"mistake" => "錯誤",
"apologized" => "道歉",
"strong" => "強烈的",
"wind" => "風",
"knocked" => "敲打、撞倒",
"down" => "向下",
"old" => "老的",
"tree" => "樹",
"park" => "公園",
_ => $"{word}"
};
}
/// <summary>
/// 獲取詞彙定義
/// </summary>
private string GetWordDefinition(string word)
{
return word.ToLower() switch
{
"company" => "A commercial business organization",
"offered" => "Past tense of offer; to present something for acceptance",
"bonus" => "An extra payment given in addition to regular salary",
"employees" => "People who work for a company or organization",
"wanted" => "Past tense of want; to desire or wish for something",
"benefits" => "Advantages or helpful features provided by an employer",
"animals" => "Living creatures that can move and feel",
"instincts" => "Natural behavior that animals are born with",
"safe" => "Not in danger; protected from harm",
"food" => "Things that people and animals eat",
"find" => "To discover or locate something",
_ => $"Definition of {word}"
};
}
/// <summary>
/// 獲取詞性
/// </summary>
private string GetPartOfSpeech(string word)
{
return word.ToLower() switch
{
"company" => "noun",
"offered" => "verb",
"bonus" => "noun",
"employees" => "noun",
"wanted" => "verb",
"benefits" => "noun",
"animals" => "noun",
"use" => "verb",
"their" => "pronoun",
"instincts" => "noun",
"find" => "verb",
"food" => "noun",
"and" => "conjunction",
"stay" => "verb",
"safe" => "adjective",
_ => "noun"
};
}
/// <summary>
/// 獲取同義詞
/// </summary>
private string[] GetSynonyms(string word)
{
return word.ToLower() switch
{
// 你的例句詞彙
"company" => new[] { "business", "corporation", "firm" },
"offered" => new[] { "provided", "gave", "presented" },
"bonus" => new[] { "reward", "incentive", "extra pay" },
"employees" => new[] { "workers", "staff", "personnel" },
"wanted" => new[] { "desired", "wished for", "sought" },
"benefits" => new[] { "advantages", "perks", "rewards" },
// 原有詞彙
"animals" => new[] { "creatures", "beings" },
"instincts" => new[] { "intuition", "impulse" },
"safe" => new[] { "secure", "protected" },
"food" => new[] { "nourishment", "sustenance" },
"find" => new[] { "locate", "discover" },
_ => new string[0] // 返回空數組而不是無意義的文字
};
}
/// <summary>
/// 獲取詞彙難度
/// </summary>
private string GetWordDifficulty(string word)
{
return word.ToLower() switch
{
"company" => "A2",
"offered" => "B1",
"bonus" => "B2",
"employees" => "B1",
"wanted" => "A1",
"benefits" => "B2",
"animals" => "A2",
"instincts" => "B2",
"safe" => "A1",
"food" => "A1",
"find" => "A1",
"use" => "A1",
"their" => "A1",
"and" => "A1",
"stay" => "A2",
_ => "A1"
};
}
/// <summary>
/// 取得有學習價值的例句
/// </summary>
private string GetQualityExampleSentence(string word)
{
return word.ToLower() switch
{
// 商業職場詞彙
"company" => "The tech company is hiring new software engineers.",
"offered" => "She offered valuable advice during the meeting.",
"bonus" => "Employees received a year-end bonus for excellent performance.",
"employees" => "The company's employees work from home twice a week.",
"benefits" => "Health insurance is one of the most important job benefits.",
// 動作動詞
"wanted" => "He wanted to improve his English speaking skills.",
// 連接詞和修飾詞
"even" => "Even experienced programmers make mistakes sometimes.",
"more" => "We need more time to complete this project.",
"but" => "The weather was cold, but we still went hiking.",
// 冠詞和基礎詞
"the" => "The book on the table belongs to Sarah.",
"a" => "She bought a new laptop for her studies.",
// 其他常見詞彙
"brought" => "The new policy brought significant changes to our workflow.",
"meeting" => "Our team meeting is scheduled for 3 PM tomorrow.",
"agreed" => "All stakeholders agreed on the proposed budget.",
_ => $"Learning {word} is important for English proficiency."
};
}
/// <summary>
/// 取得例句的中文翻譯
/// </summary>
private string GetQualityExampleTranslation(string word)
{
return word.ToLower() switch
{
// 商業職場詞彙
"company" => "這家科技公司正在招聘新的軟體工程師。",
"offered" => "她在會議中提供了寶貴的建議。",
"bonus" => "員工因優異的表現獲得年終獎金。",
"employees" => "公司員工每週在家工作兩天。",
"benefits" => "健康保險是最重要的工作福利之一。",
// 動作動詞
"wanted" => "他想要提升自己的英語口說能力。",
// 連接詞和修飾詞
"even" => "即使是有經驗的程式設計師有時也會犯錯。",
"more" => "我們需要更多時間來完成這個專案。",
"but" => "天氣很冷,但我們還是去爬山了。",
// 冠詞和基礎詞
"the" => "桌上的書是莎拉的。",
"a" => "她為了學習買了一台新筆電。",
// 其他常見詞彙
"brought" => "新政策為我們的工作流程帶來了重大變化。",
"meeting" => "我們的團隊會議安排在明天下午3點。",
"agreed" => "所有利害關係人都同意提議的預算。",
_ => $"學習 {word} 對英語能力很重要。"
};
}
#endregion
}
// Request DTOs
public class GenerateCardsRequest
{
public string InputText { get; set; } = string.Empty;
public string ExtractionType { get; set; } = "vocabulary"; // vocabulary, smart
public int CardCount { get; set; } = 10;
}
public class SaveCardsRequest
{
public Guid CardSetId { get; set; }
public List<GeneratedCard> SelectedCards { get; set; } = new();
}
// 新增的API請求/響應 DTOs
public class AnalyzeSentenceRequest
{
public string InputText { get; set; } = string.Empty;
public string UserLevel { get; set; } = "A2"; // 新增:用戶英語程度
public bool ForceRefresh { get; set; } = false;
public string AnalysisMode { get; set; } = "full";
}
public class GrammarCorrectionResult
{
public bool HasErrors { get; set; }
public string OriginalText { get; set; } = string.Empty;
public string? CorrectedText { get; set; }
public List<GrammarCorrection> Corrections { get; set; } = new();
public double ConfidenceScore { get; set; }
}
public class GrammarCorrection
{
public Position Position { get; set; } = new();
public string ErrorType { get; set; } = string.Empty;
public string Original { get; set; } = string.Empty;
public string Corrected { get; set; } = string.Empty;
public string Reason { get; set; } = string.Empty;
public string Severity { get; set; } = string.Empty;
}
public class Position
{
public int Start { get; set; }
public int End { get; set; }
}
public class SentenceAnalysisResult
{
public string Translation { get; set; } = string.Empty;
public string Explanation { get; set; } = string.Empty;
public Dictionary<string, object> WordAnalysis { get; set; } = new();
public string[] HighValueWords { get; set; } = Array.Empty<string>();
public object[] PhrasesDetected { get; set; } = Array.Empty<object>();
}