Files
ele-HeiXiu/src/theme/antd-theme.ts
YoungestSongMo a8ace232a4 feat: 任务列表UI重构 + 分页器/登录错误/请求拦截修复
【任务列表 UI 重构】(TaskHistory.tsx)
  - 列重新排序:任务ID(固定) → 创建时间 → 模型 → 输出类型 → 状态 → 提示词 → 时长 → 费用 → 供应商(隐藏) → 帧率/文件大小/标签/错误信息(隐藏) → 用户
  - 斑马纹行样式 + hover 增强 + 选中行高亮 + 暗色主题适配
  - 列可见性选择器(齿轮图标 Popover),持久化到 localStorage
  - 视频时长通过 VideoUiParams.duration 计算,非视频显示 "-"
  - 未知状态降级处理(resolveStatus → 显示原始 key)
  - 分页器固定预留 48px,避免 >20 条时分页器溢出可视区
  - 提示词搜索图标颜色用 CSS class 承载,避免 columns 依赖 token.colorPrimary 导致主题切换时 Table 重建

  【分页器修复】(antd-theme.ts)
  - Pagination 组件 token 添加 itemActiveColor: '#fff'
  - 激活页码数字与 #6366F1 主题背景形成对比,亮色/暗色均可见
  - 替代之前的 CSS !important hack

  【登录错误信息修复】(request.ts)
  - HTTP 401 拦截改为双重校验:status === 401 && data?.code === 401
  - 仅业务码也为 401 时才走 token 刷新流程
  - 其他业务码(如密码错误)透传后端 data.message,不再被 RefreshError 覆盖

  【全局中文 locale】(ThemeProvider.tsx)
  - ConfigProvider 添加 locale={zhCN},分页器显示"条/页"等中文
  - 避免逐个 Table 设置不完整 locale 导致 Pagination Select 退化为 Input

  【上下文稳定性】(HomeContent.tsx)
  - contextValue 用 useMemo 包裹,避免每次 render 新建对象导致无关重渲染
  - 配合 columns 依赖清理,减少主题切换时的级联更新

  【其他】
  - index.html CSP 策略增加 COS 域名白名单
  - OutputTypeMap 枚举值修复为 image='图片', video='视频', audio='音频'
  - TaskStatusMap STATUS_CONFIG 类型放宽为 Record<string,...> 兼容未知状态
  - 移除 computeDuration,替换为 getVideoDuration + formatDuration
  - LoginPage 移除未使用的 authState 依赖
2026-06-05 20:49:23 +08:00

314 lines
7.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ============================================================
// Ant Design 主题适配器 —— 蓝紫渐变主题(亮色 + 暗色)
// 通过 ConfigProvider 的 theme 属性覆盖 Ant Design 默认主题变量,
// 确保与 Tailwind 主题令牌tokens.ts / globals.css同步。
// ============================================================
import type { ThemeConfig } from 'antd';
import { theme } from 'antd';
import {
colorPrimary,
colorPrimaryLight,
colorSuccess,
colorWarning,
colorError,
colorInfo,
colorTextBase,
colorTextSecondary,
colorBgBase,
colorBgContainer,
colorBgElevated,
colorBgLayout,
colorBorder,
colorBorderSecondary,
borderRadiusBase,
borderRadiusLG,
borderRadiusSM,
borderRadiusXS,
fontFamily,
fontFamilyCode,
fontSizeBase,
fontSizeLG,
fontSizeSM,
fontSizeXL,
boxShadowBase,
boxShadowLG,
gradientPrimary,
// 暗色令牌
darkColorTextBase,
darkColorTextSecondary,
darkColorTextTertiary,
darkColorBgBase,
darkColorBgContainer,
darkColorBgElevated,
darkColorBgLayout,
darkColorBorder,
darkColorBorderSecondary,
} from './tokens';
// ============================================================
// 共享的组件级覆盖(亮色 & 暗色通用)
// ============================================================
const sharedComponents: ThemeConfig['components'] = {
Button: {
colorPrimary,
colorPrimaryHover: colorPrimaryLight,
colorPrimaryActive: '#4F46E5',
primaryShadow: '0 2px 0 rgba(99, 102, 241, 0.15)',
borderRadius: borderRadiusBase,
defaultBorderColor: colorBorder,
},
Menu: {
itemSelectedBg: '#EEF2FF',
itemSelectedColor: colorPrimary,
itemHoverBg: '#F5F3FF',
itemActiveBg: '#E0E7FF',
},
Tabs: {
itemSelectedColor: colorPrimary,
itemHoverColor: colorPrimaryLight,
inkBarColor: colorPrimary,
},
Modal: {
borderRadiusLG,
},
Card: {
borderRadiusLG,
},
Tag: {
defaultBg: '#EEF2FF',
defaultColor: colorPrimary,
},
Input: {
activeBorderColor: colorPrimary,
hoverBorderColor: colorPrimaryLight,
},
Select: {
activeBorderColor: colorPrimary,
hoverBorderColor: colorPrimaryLight,
},
DatePicker: {
activeBorderColor: colorPrimary,
hoverBorderColor: colorPrimaryLight,
},
Switch: {
colorPrimary,
colorPrimaryHover: colorPrimaryLight,
},
Slider: {
colorPrimary,
colorPrimaryBorder: colorPrimary,
colorPrimaryBorderHover: colorPrimaryLight,
},
Progress: {
defaultColor: colorPrimary,
},
Spin: {
colorPrimary,
},
Breadcrumb: {
linkColor: colorPrimary,
linkHoverColor: colorPrimaryLight,
lastItemColor: colorTextBase,
},
Pagination: {
itemActiveBg: colorPrimary,
itemActiveColor: '#fff',
colorPrimary,
colorPrimaryHover: colorPrimaryLight,
},
Notification: {
borderRadiusLG,
},
Tooltip: {
borderRadius: borderRadiusSM,
},
};
// ============================================================
// 共享的 token 基座(不变部分)
// ============================================================
const sharedTokens = {
// 品牌色
colorPrimary,
colorPrimaryBg: '#EEF2FF',
colorPrimaryBgHover: '#E0E7FF',
colorPrimaryBorder: '#C7D2FE',
colorPrimaryBorderHover: '#A5B4FC',
colorPrimaryHover: colorPrimaryLight,
colorPrimaryActive: '#4F46E5',
colorPrimaryTextHover: colorPrimaryLight,
colorPrimaryText: colorPrimary,
colorPrimaryTextActive: '#4338CA',
// 功能色
colorSuccess,
colorWarning,
colorError,
colorInfo,
// 圆角
borderRadius: borderRadiusBase,
borderRadiusLG,
borderRadiusSM,
borderRadiusXS,
// 字体
fontFamily,
fontFamilyCode,
fontSize: fontSizeBase,
fontSizeLG,
fontSizeSM,
fontSizeXL,
fontSizeHeading1: 28,
fontSizeHeading2: 24,
fontSizeHeading3: 20,
fontSizeHeading4: 18,
fontSizeHeading5: 16,
// 间距
padding: 16,
paddingLG: 24,
paddingSM: 12,
paddingXS: 8,
paddingXXS: 4,
// 链接
colorLink: colorPrimary,
colorLinkHover: colorPrimaryLight,
colorLinkActive: '#4F46E5',
};
// ============================================================
// 🌞 亮色主题配置
// ============================================================
export const lightTheme: ThemeConfig = {
algorithm: theme.defaultAlgorithm,
token: {
...sharedTokens,
// 文字色 — 亮色
colorText: colorTextBase,
colorTextSecondary,
colorTextTertiary: '#9CA3AF',
// 背景色 — 亮色
colorBgBase,
colorBgContainer,
colorBgElevated,
colorBgLayout,
// 边框 — 亮色
colorBorder,
colorBorderSecondary,
// 阴影
boxShadow: boxShadowBase,
boxShadowSecondary: boxShadowLG,
},
components: {
...sharedComponents,
Layout: {
siderBg: `linear-gradient(180deg, #1E1B4B 0%, #312E81 100%)`,
headerBg: colorBgBase,
bodyBg: colorBgLayout,
},
Table: {
headerBg: '#EEF2FF',
headerColor: colorTextBase,
rowHoverBg: '#F5F3FF',
borderColor: colorBorderSecondary,
},
},
};
// ============================================================
// 🌙 暗色主题配置
// ============================================================
export const darkTheme: ThemeConfig = {
algorithm: theme.darkAlgorithm,
token: {
...sharedTokens,
// 暗色模式下品牌色适当提亮以保证对比度
colorPrimary: colorPrimaryLight,
colorPrimaryHover: '#A5B4FC',
colorPrimaryActive: colorPrimary,
colorPrimaryBg: '#1E1B4B',
colorPrimaryBgHover: '#312E81',
colorPrimaryBorder: '#4338CA',
colorPrimaryBorderHover: colorPrimary,
colorPrimaryTextHover: '#A5B4FC',
colorPrimaryText: colorPrimaryLight,
colorPrimaryTextActive: colorPrimary,
// 链接
colorLink: colorPrimaryLight,
colorLinkHover: '#A5B4FC',
colorLinkActive: colorPrimary,
// 文字色 — 暗色
colorText: darkColorTextBase,
colorTextSecondary: darkColorTextSecondary,
colorTextTertiary: darkColorTextTertiary,
// 背景色 — 暗色
colorBgBase: darkColorBgBase,
colorBgContainer: darkColorBgContainer,
colorBgElevated: darkColorBgElevated,
colorBgLayout: darkColorBgLayout,
// 边框 — 暗色
colorBorder: darkColorBorder,
colorBorderSecondary: darkColorBorderSecondary,
// 阴影 — 暗色模式下用更深的投影
boxShadow: '0 1px 3px 0 rgba(0, 0, 0, 0.3), 0 1px 2px -1px rgba(0, 0, 0, 0.3)',
boxShadowSecondary: '0 10px 15px -3px rgba(0, 0, 0, 0.4), 0 4px 6px -4px rgba(0, 0, 0, 0.4)',
},
components: {
...sharedComponents,
Button: {
...sharedComponents?.Button,
defaultBorderColor: darkColorBorder,
},
Menu: {
itemSelectedBg: '#1E2460',
itemSelectedColor: colorPrimaryLight,
itemHoverBg: '#151A48',
itemActiveBg: '#0F1442',
},
Layout: {
siderBg: `linear-gradient(180deg, #050818 0%, #0D1140 100%)`,
headerBg: darkColorBgContainer,
bodyBg: darkColorBgLayout,
},
Table: {
headerBg: '#0F1340',
headerColor: darkColorTextBase,
rowHoverBg: '#181D52',
borderColor: darkColorBorderSecondary,
},
Tag: {
defaultBg: '#1A1F54',
defaultColor: colorPrimaryLight,
},
},
};
// ============================================================
// 辅助导出
// ============================================================
/** 根据 isDark 获取对应的主题配置 */
export function getThemeConfig(isDark: boolean): ThemeConfig {
return isDark ? darkTheme : lightTheme;
}
export { gradientPrimary };