diff --git a/apps/server/src/modules/search/actions.ts b/apps/server/src/modules/search/actions.ts index 1eea6973..00c0d13e 100644 --- a/apps/server/src/modules/search/actions.ts +++ b/apps/server/src/modules/search/actions.ts @@ -34,7 +34,7 @@ export const SEARCH_ACTIONS: readonly SearchAction[] = [ page("organize", "整理", "整理记录", "/console/organize", ["organize", "入库", "历史"]), page("files", "整理", "文件管理", "/console/files", ["files", "文件"]), page("trash", "整理", "回收站", "/console/files/trash", ["trash", "删除"]), - page("library", "整理", "媒体概览", "/console/library", ["library", "媒体库", "作品"]), + page("library", "整理", "媒体库", "/console/library", ["library", "媒体库", "作品"]), page("settings", "系统", "设置", "/console/settings", ["settings", "配置", "tmdb", "下载器"]), page("schedules", "概览", "定时任务", "/console/tasks?tab=plan", ["schedule", "cron", "巡检", "计划"]), page("audit", "系统", "审计", "/console/audit", ["audit", "日志"]), diff --git a/apps/web/app/components/console/nav.test.ts b/apps/web/app/components/console/nav.test.ts index ed954d18..08e2d01a 100644 --- a/apps/web/app/components/console/nav.test.ts +++ b/apps/web/app/components/console/nav.test.ts @@ -22,7 +22,7 @@ describe("控制台导航", () => { ["首页", "任务", "计划", "智能体会话"], ["站点", "RSS"], ["订阅", "规则"], - ["下载面板", "整理记录", "文件管理", "媒体概览"], + ["下载面板", "整理记录", "文件管理", "媒体库"], ["设置", "审计", "运行状态"], ]); // IA-3 逐项清单 14 项 + FE-6 计划页 @@ -44,7 +44,7 @@ describe("控制台导航", () => { it("按最长前缀匹配当前项", () => { expect(findNavItem("/console")?.label).toBe("首页"); expect(findNavItem("/console/")?.label).toBe("首页"); - expect(findNavItem("/console/library/abc")?.label).toBe("媒体概览"); + expect(findNavItem("/console/library/abc")?.label).toBe("媒体库"); expect(findNavItem("/console/tasks/r1")?.label).toBe("任务"); expect(findNavItem("/console/schedules")?.label).toBe("计划"); expect(findNavItem("/console/downloads")?.label).toBe("下载面板"); diff --git a/apps/web/app/components/console/nav.ts b/apps/web/app/components/console/nav.ts index 3419cd53..5405f755 100644 --- a/apps/web/app/components/console/nav.ts +++ b/apps/web/app/components/console/nav.ts @@ -46,19 +46,19 @@ export const NAV_GROUPS: NavGroup[] = [ to: "/console", label: "首页", icon: House, - description: "正在进行、需要处理、计划、最近结果与运行状态", + description: "在忙什么、要我处理什么、最近入库了什么", }, { to: "/console/tasks", label: "任务", icon: ListTodo, - description: "每次运行都是一条任务:定时、事件、手动、智能体触发都在这里", + description: "最近处理了什么、有没有失败", }, { to: "/console/schedules", label: "计划", icon: CalendarCog, - description: "定时任务的开关、间隔和下次运行:自动任务与智能体巡检", + description: "智能体巡检与自动任务的开关和间隔", }, { to: "/console/agent", @@ -75,7 +75,7 @@ export const NAV_GROUPS: NavGroup[] = [ to: "/console/sites", label: "站点", icon: Globe, - description: "站点、凭证、账号数据与健康;资源、抓取与 RSS", + description: "站点账号、资源与 RSS", }, { to: "/console/sources", label: "RSS", icon: Rss, description: "全部 RSS 与抓取状态" }, ], @@ -90,7 +90,7 @@ export const NAV_GROUPS: NavGroup[] = [ { title: "整理", items: [ - { to: "/console/downloads", label: "下载面板", icon: Download, description: "下载任务、下载计划与缓存水位" }, + { to: "/console/downloads", label: "下载面板", icon: Download, description: "下载任务、下载计划与下载盘" }, { to: "/console/organize", label: "整理记录", @@ -101,13 +101,13 @@ export const NAV_GROUPS: NavGroup[] = [ to: "/console/files", label: "文件管理", icon: FolderTree, - description: "浏览登记目录,改名、移动、删除与整理", + description: "浏览下载目录和媒体库,改名、移动、删除与整理", }, { to: "/console/library", - label: "媒体概览", + label: "媒体库", icon: Library, - description: "作品、季 / 集、收录版本、外部身份与未识别资源", + description: "作品、季与集、未识别资源", }, ], }, @@ -130,7 +130,7 @@ export const NAV_GROUPS: NavGroup[] = [ to: "/console/status", label: "运行状态", icon: Gauge, - description: "进程心跳、事件循环、数据库、磁盘与挂载根", + description: "服务是否正常、磁盘与数据库", }, ], }, diff --git a/apps/web/app/components/files/dialogs.tsx b/apps/web/app/components/files/dialogs.tsx index 4bedbd67..36a4ab1b 100644 --- a/apps/web/app/components/files/dialogs.tsx +++ b/apps/web/app/components/files/dialogs.tsx @@ -1049,7 +1049,7 @@ export function RefreshMetadataDialog({ items, onClose }: { items: FileEntry[]; {s.reason === "not_registered" ? "没有已入库文件" : s.reason === "no_entity" - ? "不属于任何已登记作品" + ? "不属于媒体库里的作品" : s.reason === "not_found" ? "作品不存在" : s.reason} diff --git a/apps/web/app/components/files/dir-tree.tsx b/apps/web/app/components/files/dir-tree.tsx index 6e60dfb0..886afdc4 100644 --- a/apps/web/app/components/files/dir-tree.tsx +++ b/apps/web/app/components/files/dir-tree.tsx @@ -2,7 +2,7 @@ import { ChevronRight, Download, Folder, FolderOpen, HardDrive, LoaderCircle, Tr import { useEffect, useState } from "react"; import { type FileRoot, useDirChildren } from "~/api/files.ts"; import { healthLabel } from "~/lib/labels.ts"; -import { cn, formatBytes } from "~/lib/utils.ts"; +import { cn } from "~/lib/utils.ts"; import { groupRoots, joinRel, segments } from "./model.ts"; type Loc = { root: string; path: string }; @@ -140,19 +140,13 @@ function RootNode({ {h.tone !== "neutral" ? : null} {h.label} - ) : ( - - - 正常 - - )} + ) : null} {root.pendingCount ? ( 未识别 {root.pendingCount} {root.pendingPartial ? "+" : ""} ) : null} - {root.usage ? 剩余 {formatBytes(root.usage.freeBytes, 1)} : null} {!root.writable && root.kind === "library" ? 只读 : null} diff --git a/apps/web/app/components/files/file-detail.tsx b/apps/web/app/components/files/file-detail.tsx index c492f0cf..18e6a8de 100644 --- a/apps/web/app/components/files/file-detail.tsx +++ b/apps/web/app/components/files/file-detail.tsx @@ -123,7 +123,7 @@ export function FileDetail({ value: e.type === "dir" ? e.dirSummary - ? `${e.dirSummary.videoCount}${e.dirSummary.partial ? "+" : ""} 个视频 · ${e.dirSummary.registeredCount} 个已登记` + ? `${e.dirSummary.videoCount}${e.dirSummary.partial ? "+" : ""} 个视频 · ${e.dirSummary.registeredCount} 个已入库` : "—" : formatBytes(e.size, 2), }, diff --git a/apps/web/app/components/files/model.test.ts b/apps/web/app/components/files/model.test.ts index 751f710d..9db096db 100644 --- a/apps/web/app/components/files/model.test.ts +++ b/apps/web/app/components/files/model.test.ts @@ -89,7 +89,7 @@ const base = { describe("状态与禁用原因", () => { it("状态徽标带文字,H&R 未满足为 warning,逃逸为 destructive", () => { - expect(entryStatusView({ ...base, status: "registered" })?.label).toBe("已登记"); + expect(entryStatusView({ ...base, status: "registered" })?.label).toBe("已入库"); expect( entryStatusView({ ...base, @@ -228,7 +228,7 @@ describe("v2 菜单与副行", () => { type: "dir" as const, dirSummary: { videoCount: 13, registeredCount: 0, partial: false }, })?.text, - ).toBe("13 视频 · 0 已登记"); + ).toBe("13 个视频 · 未入库"); // 没有 parsedHint(服务端解析不出标题)时不显示副行,前端不自己解析 expect(entrySubline({ ...video, parsedHint: null })).toBeNull(); }); diff --git a/apps/web/app/components/files/model.ts b/apps/web/app/components/files/model.ts index 0850ea1c..ea0457c2 100644 --- a/apps/web/app/components/files/model.ts +++ b/apps/web/app/components/files/model.ts @@ -19,14 +19,14 @@ export function entryStatusView(e: Pick , hideBelow: "lg" }, { - key: "rev", - header: "修订", + key: "updated", + header: "最后修改", cell: (g) => ( - - r{g.revision} + + {relTime(g.updatedAt)} ), hideBelow: "md", diff --git a/apps/web/app/components/rules/tabs.tsx b/apps/web/app/components/rules/tabs.tsx index b0ced928..224ca371 100644 --- a/apps/web/app/components/rules/tabs.tsx +++ b/apps/web/app/components/rules/tabs.tsx @@ -339,21 +339,26 @@ export function AtomsTab() { onRowClick={(a) => setDialog({ open: true, atom: a })} empty={{ icon: FlaskConical, title: "还没有自定义条件", description: "内置关键字覆盖不到时再新建。" }} /> - + {keywords.isPending ? ( ) : keywords.isError ? ( keywords.refetch()} /> ) : (
    - {builtins.map((k) => ( -
  • - {k.id} - - {k.supported ? k.description || k.name : "不支持,规则串里出现会报错"} - + {builtins + .filter((k) => k.supported) + .map((k) => ( +
  • + {k.id} + {k.description || k.name} +
  • + ))} + {builtins.some((k) => !k.supported) ? ( +
  • + 另有 {builtins.filter((k) => !k.supported).length} 个关键字暂不支持,写进规则串会报错
  • - ))} + ) : null}
)}
@@ -385,7 +390,7 @@ export function DefaultsTab({ groups }: { groups: RuleGroup[] | undefined }) {

- 订阅和收录版本没指定规则组时用这里的链。链上的组按顺序串联,任一组拒绝即拒绝,优先级取最后一个带层的组。 + 订阅和收录版本没指定规则组时用这里的链。按顺序检查,任一组不通过就不下载。

{dirty ? 未保存 : null} diff --git a/apps/web/app/components/search/command-palette.tsx b/apps/web/app/components/search/command-palette.tsx index 799284e9..6549f18c 100644 --- a/apps/web/app/components/search/command-palette.tsx +++ b/apps/web/app/components/search/command-palette.tsx @@ -1,5 +1,5 @@ import { type SearchAction, type SearchWork, tmdbImageUrl } from "@umt/contracts"; -import { ArrowRight, CornerDownLeft, Film, Globe, LoaderCircle, type LucideIcon, Search } from "lucide-react"; +import { CornerDownLeft, Film, Globe, LoaderCircle, type LucideIcon, Search } from "lucide-react"; import { type ReactNode, useEffect, useId, useMemo, useRef, useState } from "react"; import { Link, useNavigate } from "react-router"; import { useSearch } from "~/api/search.ts"; @@ -111,7 +111,6 @@ function PaletteBody({ initial }: { initial: string }) { 查看「{term}」的全部结果 ), - meta: "作品卡上可以选站点搜资源", hint: "打开", run: () => go(searchPagePath(term)), }); @@ -254,10 +253,6 @@ function PaletteBody({ initial }: { initial: string }) {
↑↓ 选择 ↵ 打开 - - - 搜资源在作品详情页 -
); diff --git a/apps/web/app/components/settings/account-passkeys.tsx b/apps/web/app/components/settings/account-passkeys.tsx index cbfa6734..cb8aae6b 100644 --- a/apps/web/app/components/settings/account-passkeys.tsx +++ b/apps/web/app/components/settings/account-passkeys.tsx @@ -196,7 +196,7 @@ export function PasskeyBlock({ disabled }: { disabled: boolean }) { {body} diff --git a/apps/web/app/components/sites/site-accounts-tab.tsx b/apps/web/app/components/sites/site-accounts-tab.tsx index 5f4e747f..2eddd0d6 100644 --- a/apps/web/app/components/sites/site-accounts-tab.tsx +++ b/apps/web/app/components/sites/site-accounts-tab.tsx @@ -239,7 +239,7 @@ function PasskeyForm({ site, label, has }: { site: SiteListItem; label: string; } }} > -

Passkey

+

站点 Passkey(RSS 与下载链接用)

用于 RSS 和下载链接,不参与登录。{has ? "已保存;再次保存会替换。" : "还没有保存。"}

diff --git a/apps/web/app/components/sites/site-card.tsx b/apps/web/app/components/sites/site-card.tsx index d93c4ef7..2db342b7 100644 --- a/apps/web/app/components/sites/site-card.tsx +++ b/apps/web/app/components/sites/site-card.tsx @@ -27,7 +27,6 @@ import { cn } from "~/lib/utils.ts"; import type { SiteDialog, useSiteChecks } from "./site-dialogs.tsx"; import { ACCOUNT_OVERALL, - AUTH_KIND_LABEL, bytes, dataAccount, healthLine, @@ -36,7 +35,6 @@ import { loginFailureText, overallStatus, primaryAccount, - rateLimitText, ratioText, } from "./site-fields.ts"; @@ -197,21 +195,8 @@ function CheckButtons({ site, checks, compact }: Omit & { com function AccountBadges({ site }: { site: SiteListItem }) { const st = ACCOUNT_OVERALL[overallStatus(site)]; - const acc = primaryAccount(site.accounts); - const hasPasskey = site.accounts?.some((a) => a.hasPasskey || a.authKind === "passkey"); - return ( - <> - 账号{st.label} - {acc && acc.authKind !== "passkey" ? ( - - {AUTH_KIND_LABEL[acc.authKind]} - - ) : null} - {hasPasskey ? ( - Passkey - ) : null} - - ); + // 正常不标;登录方式不做徽章(DEAI-2) + return st.tone === "success" ? null : 账号{st.label}; } function Stat({ label, children, className }: { label: string; children: ReactNode; className?: string }) { @@ -307,14 +292,14 @@ export function SiteCard({ site, checks, onDialog }: Props) {
{relTime(acc?.lastLoginAt)}
-
健康检测
+
状态
{health.text}
-
抓取
+
资源更新
{!site.snapshotEnabled ? "未开启" @@ -323,10 +308,6 @@ export function SiteCard({ site, checks, onDialog }: Props) { : "还没抓取过"}
-
-
限流
-
{rateLimitText(site.rateLimit)}
-