import { ArrowRight } from "lucide-react"; import { Link } from "react-router"; import { consolePath } from "~/components/console/nav.ts"; import { Button } from "~/components/ui/button.tsx"; import { BrowserProvidersBlock } from "./browser-providers.tsx"; import { num, str } from "./resource-section.tsx"; import { type CardSpec, n, SettingsCard, SettingsGate } from "./settings-card.tsx"; // 站点默认(site-center §8):站点没单独设置时用的限流、快照周期、UA、代理;浏览器服务(BR-1)。 // 站点、凭证、账号在「站点」页管理;站点级覆盖在站点的"编辑"里。 const DEFAULTS_CARD: CardSpec = { anchor: "defaults", title: "默认值", description: "站点没有单独设置时使用。限流不会比站点定义自带的更快。", fields: [ { name: "sites.defaultRateLimit.requestsPerMinute", label: "每分钟请求数", kind: "number", hint: "每个站点各自计数", }, { name: "sites.defaultRateLimit.concurrency", label: "并发", kind: "number", hint: "同一站点同时进行的请求" }, { name: "sites.defaultSnapshotIntervalSec", label: "抓取周期(分钟)", kind: "number", hint: "站点开了定时抓取但没设周期时使用;5–10080", }, { name: "sites.defaultSnapshotMaxPages", label: "抓取页数", kind: "number", hint: "定时和手动抓取最多抓几页列表;站点定义更少时按站点;1–20", }, { name: "sites.defaultHealthCheckIntervalSec", label: "健康检测间隔(小时)", kind: "number", hint: "同一站点两次定时检测至少隔这么久;站点定义更长时按站点", }, { name: "sites.defaultDetailCacheSec", label: "详情缓存(小时)", kind: "number", hint: "期内不重复抓同一条资源详情;0 为不缓存", }, { name: "sites.userDataMaxSeedingPages", label: "做种列表页数上限", kind: "number", hint: "拉取用户数据时最多翻几页做种列表;1–50", }, { name: "sites.userAgent", label: "User-Agent", kind: "text", hint: "账号没填 UA 时,登录和拉取用户数据用这个", wide: true, }, { name: "sites.proxyUrl", label: "代理地址", kind: "url", placeholder: "http://127.0.0.1:7890", hint: "只对开了「使用代理」的站点生效;留空不用代理", wide: true, }, ], fromSettings: (s) => ({ "sites.defaultRateLimit.requestsPerMinute": n(s.sites.defaultRateLimit.requestsPerMinute), "sites.defaultRateLimit.concurrency": n(s.sites.defaultRateLimit.concurrency), "sites.defaultSnapshotIntervalSec": n(Math.round(s.sites.defaultSnapshotIntervalSec / 60)), "sites.userDataMaxSeedingPages": n(s.sites.userDataMaxSeedingPages), "sites.defaultSnapshotMaxPages": n(s.sites.defaultSnapshotMaxPages), "sites.defaultHealthCheckIntervalSec": n(s.sites.defaultHealthCheckIntervalSec / 3600), "sites.defaultDetailCacheSec": n(s.sites.defaultDetailCacheSec / 3600), "sites.userAgent": s.sites.userAgent, "sites.proxyUrl": s.sites.proxyUrl ?? "", }), toPatch: (v, s) => { const min = num(v["sites.defaultSnapshotIntervalSec"]); const rpm = num(v["sites.defaultRateLimit.requestsPerMinute"]); const concurrency = num(v["sites.defaultRateLimit.concurrency"]); const healthH = num(v["sites.defaultHealthCheckIntervalSec"]); const detailH = num(v["sites.defaultDetailCacheSec"]); return { sites: { defaultRateLimit: { ...s.sites.defaultRateLimit, requestsPerMinute: rpm, concurrency, }, defaultSnapshotIntervalSec: min === undefined ? undefined : Math.round(min * 60), userDataMaxSeedingPages: num(v["sites.userDataMaxSeedingPages"]), defaultSnapshotMaxPages: num(v["sites.defaultSnapshotMaxPages"]), defaultHealthCheckIntervalSec: healthH === undefined ? undefined : Math.round(healthH * 3600), defaultDetailCacheSec: detailH === undefined ? undefined : Math.round(detailH * 3600), userAgent: str(v["sites.userAgent"]) || undefined, proxyUrl: str(v["sites.proxyUrl"]) || null, }, }; }, }; export function SitesSection() { return (
站点和凭证在「站点」页管理;单个站点的限流、周期、代理在站点的"编辑"里改。