feat(web): 站点页技术信息里显示最近的失败页面样本
站点概览「站点」一栏的技术信息里列出最近 5 份失败样本(搜索 / 列表 / 详情 · 人机验证 / 页面结构无法识别 · HTTP 状态),展开看脱敏地址、错误、命中规则、关键响应头和页面正文,可下载文本;没有样本不显示。 Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
This commit is contained in:
1 parent
bd475a4ce1
commit
ec8b224482
5 files changed
+228
-2
No files matched your search
@@ -9,6 +9,8 @@ import {
|
||||
type SiteCredentialsBody,
|
||||
SiteCredentialsResult,
|
||||
SiteDefinitionView,
|
||||
SiteFailureSample,
|
||||
SiteFailureSampleSummary,
|
||||
SiteHealthResult,
|
||||
SiteListItem,
|
||||
SiteRefreshLoginAccepted,
|
||||
@@ -35,6 +37,8 @@ export const siteKeys = {
|
||||
accounts: (siteId?: string) => ["sites", "accounts", siteId ?? "all"] as const,
|
||||
snapshots: (siteId: string) => ["sites", "snapshots", siteId] as const,
|
||||
requestStats: (siteId: string) => ["sites", "request-stats", siteId] as const,
|
||||
failureSamples: (siteId: string) => ["sites", "failure-samples", siteId] as const,
|
||||
failureSample: (siteId: string, sampleId: string) => ["sites", "failure-samples", siteId, sampleId] as const,
|
||||
definitions: () => ["sites", "definitions"] as const,
|
||||
userData: (siteId: string, accountId?: string, days = 30) =>
|
||||
["sites", "user-data", siteId, accountId ?? "first", days] as const,
|
||||
@@ -105,6 +109,33 @@ export function useSiteRequestStats(siteId: string | undefined) {
|
||||
});
|
||||
}
|
||||
|
||||
/** 最近的失败留样(页面结构无法识别 / 人机验证;每站最近 5 份,不带正文) */
|
||||
export function useSiteFailureSamples(siteId: string | undefined) {
|
||||
return useQuery({
|
||||
queryKey: siteKeys.failureSamples(siteId ?? ""),
|
||||
enabled: !!siteId,
|
||||
queryFn: ({ signal }) =>
|
||||
apiParsed(z.object({ items: z.array(SiteFailureSampleSummary) }), "/api/v1/sites/:id/failure-samples", {
|
||||
pathParams: { id: siteId ?? "" },
|
||||
signal,
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 一份失败留样(带脱敏后的页面正文);展开时才取 */
|
||||
export function useSiteFailureSample(siteId: string, sampleId: string, enabled: boolean) {
|
||||
return useQuery({
|
||||
queryKey: siteKeys.failureSample(siteId, sampleId),
|
||||
enabled,
|
||||
staleTime: Number.POSITIVE_INFINITY,
|
||||
queryFn: ({ signal }) =>
|
||||
apiParsed(SiteFailureSample, "/api/v1/sites/:id/failure-samples/:sampleId", {
|
||||
pathParams: { id: siteId, sampleId },
|
||||
signal,
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 访问默认的一句话说明:"快照每 60 分钟 1 页 · 健康检测每 6 小时 · 详情缓存 24 小时" */
|
||||
export function accessSummary(s: SiteRequestStats): string {
|
||||
const dur = (sec: number) => (sec % 3600 === 0 ? `${sec / 3600} 小时` : `${Math.round(sec / 60)} 分钟`);
|
||||
|
||||
Reference in new issue
Block a user