95 lines
3.2 KiB
C#
95 lines
3.2 KiB
C#
|
|
using Service.AI;
|
|||
|
|
|
|||
|
|
namespace Service.IconSearch;
|
|||
|
|
|
|||
|
|
public record SearchKeywordSettings
|
|||
|
|
{
|
|||
|
|
public string KeywordPromptTemplate { get; init; } =
|
|||
|
|
"为以下中文分类名称生成3-5个相关的英文搜索关键字,用于搜索图标:{categoryName}。" +
|
|||
|
|
"输出格式为JSON数组,例如:[\"food\", \"restaurant\", \"dining\"]。";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public class SearchKeywordGeneratorService(
|
|||
|
|
IOpenAiService openAiService,
|
|||
|
|
IOptions<SearchKeywordSettings> settings,
|
|||
|
|
ILogger<SearchKeywordGeneratorService> logger
|
|||
|
|
) : ISearchKeywordGeneratorService
|
|||
|
|
{
|
|||
|
|
private readonly SearchKeywordSettings _settings = settings.Value;
|
|||
|
|
|
|||
|
|
public async Task<List<string>> GenerateKeywordsAsync(string categoryName)
|
|||
|
|
{
|
|||
|
|
if (string.IsNullOrWhiteSpace(categoryName))
|
|||
|
|
{
|
|||
|
|
logger.LogWarning("分类名称为空,无法生成搜索关键字");
|
|||
|
|
return [];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
var prompt = _settings.KeywordPromptTemplate.Replace("{categoryName}", categoryName);
|
|||
|
|
var response = await openAiService.ChatAsync(prompt, timeoutSeconds: 15);
|
|||
|
|
|
|||
|
|
if (string.IsNullOrEmpty(response))
|
|||
|
|
{
|
|||
|
|
logger.LogWarning("AI未返回搜索关键字,分类:{CategoryName}", categoryName);
|
|||
|
|
return [];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var keywords = ParseKeywordsFromResponse(response);
|
|||
|
|
logger.LogInformation("为分类 {CategoryName} 生成了 {Count} 个搜索关键字:{Keywords}",
|
|||
|
|
categoryName, keywords.Count, string.Join(", ", keywords));
|
|||
|
|
|
|||
|
|
return keywords;
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
logger.LogError(ex, "生成搜索关键字失败,分类:{CategoryName}", categoryName);
|
|||
|
|
return [];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private List<string> ParseKeywordsFromResponse(string response)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
var jsonNode = JsonNode.Parse(response);
|
|||
|
|
if (jsonNode is JsonArray arrayNode)
|
|||
|
|
{
|
|||
|
|
var keywords = new List<string>();
|
|||
|
|
foreach (var item in arrayNode)
|
|||
|
|
{
|
|||
|
|
if (item is JsonValue value && value.TryGetValue(out string keyword))
|
|||
|
|
{
|
|||
|
|
keywords.Add(keyword);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return keywords;
|
|||
|
|
}
|
|||
|
|
else if (jsonNode is JsonObject jsonObject)
|
|||
|
|
{
|
|||
|
|
if (jsonObject.TryGetPropertyValue("keywords", out var keywordsNode) && keywordsNode is JsonArray arrayNode2)
|
|||
|
|
{
|
|||
|
|
var keywords = new List<string>();
|
|||
|
|
foreach (var item in arrayNode2)
|
|||
|
|
{
|
|||
|
|
if (item is JsonValue value && value.TryGetValue(out string keyword))
|
|||
|
|
{
|
|||
|
|
keywords.Add(keyword);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return keywords;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
logger.LogWarning("无法解析AI响应为关键字数组:{Response}", response);
|
|||
|
|
return [];
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
logger.LogError(ex, "解析AI响应失败:{Response}", response);
|
|||
|
|
return [];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|