From 50c6fd8ac8c762269641a51cc111ec3f3ea72cff Mon Sep 17 00:00:00 2001 From: zzh <1368735060@qq.com> Date: Wed, 1 Jul 2026 12:36:28 +0800 Subject: [PATCH] fix(xhs): reject offline agent for analysis and normalize browse task results Validate agent is online before starting analysis tasks; normalize list_feeds JSON when persisting task reports. Co-authored-by: Cursor --- .../Services/Xhs/XhsAnalysisService.cs | 25 +++++++++++- .../Services/Xhs/XhsTaskService.cs | 2 +- src/Oms.Application/Shared/XhsHelper.cs | 38 +++++++++++++++++++ 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/src/Oms.Application/Services/Xhs/XhsAnalysisService.cs b/src/Oms.Application/Services/Xhs/XhsAnalysisService.cs index 528919e..e27f64b 100644 --- a/src/Oms.Application/Services/Xhs/XhsAnalysisService.cs +++ b/src/Oms.Application/Services/Xhs/XhsAnalysisService.cs @@ -18,6 +18,7 @@ public class XhsAnalysisService : ApplicationService private IXhsAnalysisSessionRepository AnalysisSessionRepository => LazyServiceProvider.GetRequiredService(); private IXhsTaskRepository TaskRepository => LazyServiceProvider.GetRequiredService(); private IXhsSkillRepository SkillRepository => LazyServiceProvider.GetRequiredService(); + private IXhsAgentRepository AgentRepository => LazyServiceProvider.GetRequiredService(); private ICustomerRepository CustomerRepository => LazyServiceProvider.GetRequiredService(); [HttpPost("/xhs/analysis/start")] @@ -167,10 +168,11 @@ public class XhsAnalysisService : ApplicationService }; await AnalysisSessionRepository.InsertAsync(session); + var agentId = await ResolveTaskAgentIdAsync(customerId, input.AgentId); var task = new XhsTask { CustomerId = customerId, - AgentId = input.AgentId, + AgentId = agentId, TaskType = taskType, ToolName = toolName, ArgumentsJson = OmsDocHelper.SerializeJson(args) ?? "{}", @@ -269,6 +271,27 @@ public class XhsAnalysisService : ApplicationService }; } + private async Task ResolveTaskAgentIdAsync(int customerId, int? requestedAgentId) + { + if (requestedAgentId is not > 0) + { + return null; + } + + var agent = await AgentRepository.FirstOrDefaultAsync(x => x.Id == requestedAgentId.Value); + if (agent == null || agent.CustomerId != customerId) + { + throw new BusinessException("Agent 不存在"); + } + + if (!XhsHelper.IsAgentOnline(agent)) + { + throw new BusinessException("所选 Agent 离线,请先在「启动服务」确认在线后再采集"); + } + + return agent.Id; + } + private static string BuildSessionName(string analysisType, string? keyword) => analysisType switch { diff --git a/src/Oms.Application/Services/Xhs/XhsTaskService.cs b/src/Oms.Application/Services/Xhs/XhsTaskService.cs index 40fcafb..49f11ac 100644 --- a/src/Oms.Application/Services/Xhs/XhsTaskService.cs +++ b/src/Oms.Application/Services/Xhs/XhsTaskService.cs @@ -146,7 +146,7 @@ public class XhsTaskService : ApplicationService if (status == XhsTaskStatusCodes.Succeeded) { - session.FeedsJson = OmsDocHelper.SerializeJson(input.Result); + session.FeedsJson = OmsDocHelper.SerializeJson(XhsHelper.NormalizeBrowseTaskResult(input.Result)); await AnalysisSessionRepository.UpdateAsync(session); } else if (status == XhsTaskStatusCodes.Failed) diff --git a/src/Oms.Application/Shared/XhsHelper.cs b/src/Oms.Application/Shared/XhsHelper.cs index 3594f44..3e07e76 100644 --- a/src/Oms.Application/Shared/XhsHelper.cs +++ b/src/Oms.Application/Shared/XhsHelper.cs @@ -79,4 +79,42 @@ public static class XhsHelper var json = OmsDocHelper.SerializeJson(feeds) ?? string.Empty; return json.Length <= 12000 ? json : json[..12000]; } + + /// + /// Agent 上报的 browse 结果可能是 { summary, raw },raw 内为 CLI JSON 输出。 + /// + public static object? NormalizeBrowseTaskResult(object? result) + { + if (result == null) + { + return null; + } + + var json = OmsDocHelper.SerializeJson(result); + var obj = OmsDocHelper.DeserializeJson>(json); + if (obj == null) + { + return result; + } + + if (obj.ContainsKey("feeds") || obj.ContainsKey("items") || obj.ContainsKey("notes")) + { + return obj; + } + + if (obj.TryGetValue("raw", out var raw) && raw != null) + { + var rawText = raw.ToString(); + if (!string.IsNullOrWhiteSpace(rawText)) + { + var parsed = OmsDocHelper.DeserializeJsonObject(rawText); + if (parsed != null) + { + return parsed; + } + } + } + + return result; + } }