|
|
@@ -111,10 +111,11 @@ public sealed class SnovioCompanyFilter
|
|
|
public SnovioStringListFilter? Industries { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
- /// 公司规模,例如 1-10、51-200、10001+。
|
|
|
+ /// 公司规模数组,例如 ["1-10", "51-200", "10001+", "Self"]。
|
|
|
+ /// Snovio 要求数组格式,单值也请传单元素数组。
|
|
|
/// </summary>
|
|
|
[JsonPropertyName("size")]
|
|
|
- public string? Size { get; set; }
|
|
|
+ public List<string>? Size { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 公司营收最小值和最大值,单位由 Snov.io 数据源定义。
|
|
|
@@ -305,7 +306,9 @@ public sealed class SnovioCompanySearchResultResponse
|
|
|
|
|
|
/// <summary>
|
|
|
/// 公司搜索结果数据。
|
|
|
+/// 兼容 Snov.io 任务处理中时 data 为空数组的响应。
|
|
|
/// </summary>
|
|
|
+[System.Text.Json.Serialization.JsonConverter(typeof(SnovioCompanySearchResultDataConverter))]
|
|
|
public sealed class SnovioCompanySearchResultData
|
|
|
{
|
|
|
/// <summary>
|
|
|
@@ -333,6 +336,84 @@ public sealed class SnovioCompanySearchResultData
|
|
|
public List<SnovioCompanySearchCompany> Companies { get; set; } = new();
|
|
|
}
|
|
|
|
|
|
+/// <summary>
|
|
|
+/// 兼容 Snov.io 公司搜索结果中 data 为对象、空数组或 null 的响应转换器。
|
|
|
+/// 任务处理中(in_progress)时 Snovio 返回 "data": [],此时按空结果处理,由轮询继续等待。
|
|
|
+/// </summary>
|
|
|
+internal sealed class SnovioCompanySearchResultDataConverter
|
|
|
+ : System.Text.Json.Serialization.JsonConverter<SnovioCompanySearchResultData>
|
|
|
+{
|
|
|
+ public override SnovioCompanySearchResultData Read(
|
|
|
+ ref Utf8JsonReader reader,
|
|
|
+ Type typeToConvert,
|
|
|
+ JsonSerializerOptions options)
|
|
|
+ {
|
|
|
+ if (reader.TokenType == JsonTokenType.Null)
|
|
|
+ return new SnovioCompanySearchResultData();
|
|
|
+
|
|
|
+ if (reader.TokenType == JsonTokenType.StartArray)
|
|
|
+ {
|
|
|
+ // 处理中返回空数组,直接跳过。
|
|
|
+ using var _ = JsonDocument.ParseValue(ref reader);
|
|
|
+ return new SnovioCompanySearchResultData();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (reader.TokenType == JsonTokenType.StartObject)
|
|
|
+ {
|
|
|
+ using var document = JsonDocument.ParseValue(ref reader);
|
|
|
+ var root = document.RootElement;
|
|
|
+ var result = new SnovioCompanySearchResultData();
|
|
|
+
|
|
|
+ if (root.TryGetProperty("total", out var totalElement) &&
|
|
|
+ totalElement.ValueKind == JsonValueKind.Number &&
|
|
|
+ totalElement.TryGetInt64(out var total))
|
|
|
+ {
|
|
|
+ result.Total = total;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (root.TryGetProperty("page", out var pageElement) &&
|
|
|
+ pageElement.ValueKind == JsonValueKind.Number &&
|
|
|
+ pageElement.TryGetInt32(out var page))
|
|
|
+ {
|
|
|
+ result.Page = page;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (root.TryGetProperty("total_pages", out var totalPagesElement) &&
|
|
|
+ totalPagesElement.ValueKind == JsonValueKind.Number &&
|
|
|
+ totalPagesElement.TryGetInt32(out var totalPages))
|
|
|
+ {
|
|
|
+ result.TotalPages = totalPages;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (root.TryGetProperty("companies", out var companiesElement) &&
|
|
|
+ companiesElement.ValueKind == JsonValueKind.Array)
|
|
|
+ {
|
|
|
+ result.Companies = companiesElement.Deserialize<List<SnovioCompanySearchCompany>>(options)
|
|
|
+ ?? new List<SnovioCompanySearchCompany>();
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ throw new System.Text.Json.JsonException(
|
|
|
+ "Snov.io 公司搜索结果响应中的 data 必须是对象、数组或 null。");
|
|
|
+ }
|
|
|
+
|
|
|
+ public override void Write(
|
|
|
+ Utf8JsonWriter writer,
|
|
|
+ SnovioCompanySearchResultData value,
|
|
|
+ JsonSerializerOptions options)
|
|
|
+ {
|
|
|
+ writer.WriteStartObject();
|
|
|
+ writer.WriteNumber("total", value.Total);
|
|
|
+ writer.WriteNumber("page", value.Page);
|
|
|
+ writer.WriteNumber("total_pages", value.TotalPages);
|
|
|
+ writer.WritePropertyName("companies");
|
|
|
+ System.Text.Json.JsonSerializer.Serialize(writer, value.Companies, options);
|
|
|
+ writer.WriteEndObject();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// Snov.io 公司搜索结果中的公司信息。
|
|
|
/// </summary>
|