mirror of
https://github.com/fawney19/Aether.git
synced 2026-01-11 12:08:30 +08:00
Initial commit
This commit is contained in:
72
frontend/src/config/constants.ts
Normal file
72
frontend/src/config/constants.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* 应用全局常量配置
|
||||
*/
|
||||
|
||||
// 应用配置
|
||||
export const APP_CONFIG = {
|
||||
NAME: 'Aether',
|
||||
VERSION: '9.1.0',
|
||||
DESCRIPTION: 'Claude API 代理服务管理平台',
|
||||
} as const
|
||||
|
||||
// 网络配置
|
||||
export const NETWORK_CONFIG = {
|
||||
API_TIMEOUT: 30000, // 30秒
|
||||
REQUEST_RETRY_LIMIT: 3, // 最大重试次数
|
||||
MODULE_LOAD_RETRY_LIMIT: 2, // 模块加载失败重试次数
|
||||
} as const
|
||||
|
||||
// 认证配置
|
||||
export const AUTH_CONFIG = {
|
||||
TOKEN_REFRESH_INTERVAL: 100, // 延迟检查认证状态(ms)
|
||||
MAX_RETRY_COUNT: 3, // token刷新最大重试次数
|
||||
} as const
|
||||
|
||||
// Toast 配置
|
||||
export const TOAST_CONFIG = {
|
||||
SUCCESS_DURATION: 3000, // 成功消息持续时间(ms)
|
||||
ERROR_DURATION: 5000, // 错误消息持续时间(ms)
|
||||
WARNING_DURATION: 5000, // 警告消息持续时间(ms)
|
||||
INFO_DURATION: 3000, // 信息消息持续时间(ms)
|
||||
} as const
|
||||
|
||||
// 日志级别
|
||||
export const LogLevel = {
|
||||
DEBUG: 'DEBUG',
|
||||
INFO: 'INFO',
|
||||
WARN: 'WARN',
|
||||
ERROR: 'ERROR',
|
||||
} as const
|
||||
|
||||
export type LogLevel = typeof LogLevel[keyof typeof LogLevel]
|
||||
|
||||
// 业务相关常量
|
||||
export const BUSINESS_CONSTANTS = {
|
||||
// Provider 相关
|
||||
PROVIDER_DEFAULT_PRIORITY: 100,
|
||||
PROVIDER_MIN_PRIORITY: 0,
|
||||
PROVIDER_MAX_PRIORITY: 999,
|
||||
|
||||
// API Key 相关
|
||||
API_KEY_MIN_LENGTH: 10,
|
||||
API_KEY_MAX_LENGTH: 500,
|
||||
|
||||
// 分页配置
|
||||
DEFAULT_PAGE_SIZE: 20,
|
||||
MAX_PAGE_SIZE: 100,
|
||||
} as const
|
||||
|
||||
// 错误消息
|
||||
export const ERROR_MESSAGES = {
|
||||
NETWORK_ERROR: '无法连接到服务器,请检查网络连接',
|
||||
AUTH_FAILED: '认证失败,请重新登录',
|
||||
PERMISSION_DENIED: '权限不足',
|
||||
SERVER_ERROR: '服务器错误,请稍后重试',
|
||||
INVALID_INPUT: '输入数据无效',
|
||||
OPERATION_FAILED: '操作失败',
|
||||
} as const
|
||||
|
||||
// 环境判断
|
||||
export const isDev = import.meta.env.DEV
|
||||
export const isProd = import.meta.env.PROD
|
||||
export const isTest = import.meta.env.MODE === 'test'
|
||||
161
frontend/src/config/design-system.ts
Normal file
161
frontend/src/config/design-system.ts
Normal file
@@ -0,0 +1,161 @@
|
||||
/**
|
||||
* 设计系统配置
|
||||
* 基于 shadcn/ui 的自定义样式系统
|
||||
*/
|
||||
|
||||
export const spacing = {
|
||||
xs: '0.25rem', // 4px
|
||||
sm: '0.5rem', // 8px
|
||||
md: '1rem', // 16px
|
||||
lg: '1.5rem', // 24px
|
||||
xl: '2rem', // 32px
|
||||
'2xl': '3rem', // 48px
|
||||
'3xl': '4rem', // 64px
|
||||
} as const
|
||||
|
||||
export const borderRadius = {
|
||||
sm: 'var(--radius-sm)',
|
||||
md: 'var(--radius-md)',
|
||||
lg: 'var(--radius-lg)',
|
||||
xl: '1rem',
|
||||
'2xl': '1.5rem',
|
||||
'3xl': '2rem',
|
||||
full: '9999px',
|
||||
} as const
|
||||
|
||||
export const shadows = {
|
||||
'2xs': 'var(--shadow-2xs)',
|
||||
xs: 'var(--shadow-xs)',
|
||||
sm: 'var(--shadow-sm)',
|
||||
md: 'var(--shadow-md)',
|
||||
lg: 'var(--shadow-lg)',
|
||||
xl: 'var(--shadow-xl)',
|
||||
'2xl': 'var(--shadow-2xl)',
|
||||
} as const
|
||||
|
||||
export const animations = {
|
||||
duration: {
|
||||
fast: '150ms',
|
||||
normal: '250ms',
|
||||
slow: '350ms',
|
||||
},
|
||||
easing: {
|
||||
default: 'cubic-bezier(0.4, 0, 0.2, 1)',
|
||||
in: 'cubic-bezier(0.4, 0, 1, 1)',
|
||||
out: 'cubic-bezier(0, 0, 0.2, 1)',
|
||||
inOut: 'cubic-bezier(0.4, 0, 0.2, 1)',
|
||||
},
|
||||
} as const
|
||||
|
||||
export const typography = {
|
||||
fontSize: {
|
||||
xs: '0.75rem', // 12px
|
||||
sm: '0.875rem', // 14px
|
||||
base: '1rem', // 16px
|
||||
lg: '1.125rem', // 18px
|
||||
xl: '1.25rem', // 20px
|
||||
'2xl': '1.5rem', // 24px
|
||||
'3xl': '1.875rem', // 30px
|
||||
'4xl': '2.25rem', // 36px
|
||||
'5xl': '3rem', // 48px
|
||||
},
|
||||
fontWeight: {
|
||||
normal: '400',
|
||||
medium: '500',
|
||||
semibold: '600',
|
||||
bold: '700',
|
||||
},
|
||||
lineHeight: {
|
||||
tight: '1.25',
|
||||
normal: '1.5',
|
||||
relaxed: '1.75',
|
||||
},
|
||||
} as const
|
||||
|
||||
export const breakpoints = {
|
||||
sm: '640px',
|
||||
md: '768px',
|
||||
lg: '1024px',
|
||||
xl: '1280px',
|
||||
'2xl': '1536px',
|
||||
} as const
|
||||
|
||||
/**
|
||||
* 组件变体配置
|
||||
*/
|
||||
export const componentVariants = {
|
||||
card: {
|
||||
default: 'bg-card border border-border rounded-lg shadow-sm',
|
||||
elevated: 'bg-card border border-border rounded-lg shadow-md',
|
||||
glass: 'surface-glass',
|
||||
},
|
||||
button: {
|
||||
sizes: {
|
||||
sm: 'px-3 py-1.5 text-sm',
|
||||
md: 'px-4 py-2 text-base',
|
||||
lg: 'px-6 py-3 text-lg',
|
||||
},
|
||||
},
|
||||
input: {
|
||||
sizes: {
|
||||
sm: 'h-8 px-3 text-sm',
|
||||
md: 'h-10 px-4 text-base',
|
||||
lg: 'h-12 px-5 text-lg',
|
||||
},
|
||||
},
|
||||
} as const
|
||||
|
||||
/**
|
||||
* 布局配置
|
||||
*/
|
||||
export const layout = {
|
||||
container: {
|
||||
sm: '640px',
|
||||
md: '768px',
|
||||
lg: '1024px',
|
||||
xl: '1280px',
|
||||
'2xl': '1400px',
|
||||
},
|
||||
sidebar: {
|
||||
width: '18rem', // 288px
|
||||
collapsedWidth: '4rem', // 64px
|
||||
},
|
||||
header: {
|
||||
height: '4rem', // 64px
|
||||
},
|
||||
spacing: {
|
||||
page: '1rem', // 页面边距
|
||||
section: '2rem', // 区块间距
|
||||
},
|
||||
} as const
|
||||
|
||||
/**
|
||||
* 颜色语义化配置
|
||||
*/
|
||||
export const colors = {
|
||||
status: {
|
||||
success: 'text-green-600 dark:text-green-400',
|
||||
warning: 'text-amber-600 dark:text-amber-400',
|
||||
error: 'text-destructive',
|
||||
info: 'text-blue-600 dark:text-blue-400',
|
||||
},
|
||||
badge: {
|
||||
success: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400',
|
||||
warning: 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400',
|
||||
error: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400',
|
||||
info: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400',
|
||||
neutral: 'bg-muted text-muted-foreground',
|
||||
},
|
||||
} as const
|
||||
|
||||
export default {
|
||||
spacing,
|
||||
borderRadius,
|
||||
shadows,
|
||||
animations,
|
||||
typography,
|
||||
breakpoints,
|
||||
componentVariants,
|
||||
layout,
|
||||
colors,
|
||||
}
|
||||
338
frontend/src/config/theme.ts
Normal file
338
frontend/src/config/theme.ts
Normal file
@@ -0,0 +1,338 @@
|
||||
/**
|
||||
* 主题配置系统
|
||||
*
|
||||
* 基于 shadcn/ui 和项目自定义颜色体系
|
||||
* 提供统一的主题变量、间距、圆角、阴影等配置
|
||||
*/
|
||||
|
||||
/**
|
||||
* 颜色系统
|
||||
*
|
||||
* 项目使用书本纸张主题色:
|
||||
* - book-cloth: 书籍封面布料色 (#cc785c / #d4a27f)
|
||||
* - kraft: 牛皮纸色 (#b97847 / #c9a26f)
|
||||
* - manilla: 马尼拉纸色 (#e8ddc5 / #d4c5a9)
|
||||
* - cloud: 云白色 (#f5f3ed / #2a2723)
|
||||
*/
|
||||
export const themeColors = {
|
||||
// 主色调
|
||||
primary: {
|
||||
light: '#cc785c', // book-cloth light
|
||||
dark: '#d4a27f', // book-cloth dark
|
||||
hover: {
|
||||
light: '#b86d52',
|
||||
dark: '#c29470'
|
||||
}
|
||||
},
|
||||
|
||||
// 次要色调
|
||||
secondary: {
|
||||
light: '#b97847', // kraft light
|
||||
dark: '#c9a26f', // kraft dark
|
||||
hover: {
|
||||
light: '#a56a3f',
|
||||
dark: '#b8915e'
|
||||
}
|
||||
},
|
||||
|
||||
// 强调色
|
||||
accent: {
|
||||
light: '#e8ddc5', // manilla light
|
||||
dark: '#d4c5a9', // manilla dark
|
||||
},
|
||||
|
||||
// 背景色
|
||||
background: {
|
||||
light: {
|
||||
base: '#fafaf7', // cloud light
|
||||
elevated: '#ffffff',
|
||||
muted: '#f5f3ed'
|
||||
},
|
||||
dark: {
|
||||
base: '#191714', // cloud dark
|
||||
elevated: '#262624',
|
||||
muted: '#2a2723'
|
||||
}
|
||||
},
|
||||
|
||||
// 边框色
|
||||
border: {
|
||||
light: {
|
||||
default: '#e5e4df',
|
||||
hover: 'rgba(204, 120, 92, 0.3)',
|
||||
focus: 'rgba(204, 120, 92, 0.4)'
|
||||
},
|
||||
dark: {
|
||||
default: 'rgba(227, 224, 211, 0.12)',
|
||||
hover: 'rgba(212, 162, 127, 0.4)',
|
||||
focus: 'rgba(212, 162, 127, 0.5)'
|
||||
}
|
||||
},
|
||||
|
||||
// 状态色
|
||||
status: {
|
||||
success: {
|
||||
light: '#10b981',
|
||||
dark: '#34d399'
|
||||
},
|
||||
warning: {
|
||||
light: '#f59e0b',
|
||||
dark: '#fbbf24'
|
||||
},
|
||||
error: {
|
||||
light: '#ef4444',
|
||||
dark: '#f87171'
|
||||
},
|
||||
info: {
|
||||
light: '#3b82f6',
|
||||
dark: '#60a5fa'
|
||||
}
|
||||
}
|
||||
} as const
|
||||
|
||||
/**
|
||||
* 间距系统
|
||||
*
|
||||
* 基于 8px 网格系统
|
||||
*/
|
||||
export const spacing = {
|
||||
// 基础间距
|
||||
xs: '4px',
|
||||
sm: '8px',
|
||||
md: '12px',
|
||||
lg: '16px',
|
||||
xl: '24px',
|
||||
'2xl': '32px',
|
||||
'3xl': '48px',
|
||||
'4xl': '64px',
|
||||
|
||||
// 页面布局间距
|
||||
page: {
|
||||
padding: '24px',
|
||||
maxWidth: '1400px'
|
||||
},
|
||||
|
||||
// 区块间距
|
||||
section: {
|
||||
gap: '32px',
|
||||
padding: '24px'
|
||||
},
|
||||
|
||||
// 卡片间距
|
||||
card: {
|
||||
padding: '20px',
|
||||
gap: '16px'
|
||||
},
|
||||
|
||||
// 表单间距
|
||||
form: {
|
||||
fieldGap: '16px',
|
||||
labelGap: '8px'
|
||||
}
|
||||
} as const
|
||||
|
||||
/**
|
||||
* 圆角系统
|
||||
*/
|
||||
export const radius = {
|
||||
none: '0',
|
||||
sm: '6px',
|
||||
md: '8px',
|
||||
lg: '12px',
|
||||
xl: '16px',
|
||||
'2xl': '20px',
|
||||
full: '9999px',
|
||||
|
||||
// 组件圆角
|
||||
button: '8px',
|
||||
card: '12px',
|
||||
input: '8px',
|
||||
dialog: '16px'
|
||||
} as const
|
||||
|
||||
/**
|
||||
* 阴影系统
|
||||
*/
|
||||
export const shadows = {
|
||||
none: 'none',
|
||||
sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
|
||||
md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
|
||||
lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
|
||||
xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',
|
||||
'2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)',
|
||||
|
||||
// 组件阴影
|
||||
card: {
|
||||
light: '0 1px 3px rgba(0, 0, 0, 0.1)',
|
||||
dark: '0 1px 3px rgba(0, 0, 0, 0.3)'
|
||||
},
|
||||
elevated: {
|
||||
light: '0 4px 6px rgba(0, 0, 0, 0.1)',
|
||||
dark: '0 4px 6px rgba(0, 0, 0, 0.4)'
|
||||
},
|
||||
button: {
|
||||
light: '0 1px 2px rgba(0, 0, 0, 0.05)',
|
||||
dark: '0 1px 2px rgba(0, 0, 0, 0.2)'
|
||||
}
|
||||
} as const
|
||||
|
||||
/**
|
||||
* 字体系统
|
||||
*/
|
||||
export const typography = {
|
||||
// 字体家族
|
||||
fontFamily: {
|
||||
sans: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
|
||||
mono: 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace'
|
||||
},
|
||||
|
||||
// 字体大小
|
||||
fontSize: {
|
||||
xs: '0.75rem', // 12px
|
||||
sm: '0.875rem', // 14px
|
||||
base: '1rem', // 16px
|
||||
lg: '1.125rem', // 18px
|
||||
xl: '1.25rem', // 20px
|
||||
'2xl': '1.5rem', // 24px
|
||||
'3xl': '1.875rem', // 30px
|
||||
'4xl': '2.25rem', // 36px
|
||||
'5xl': '3rem' // 48px
|
||||
},
|
||||
|
||||
// 字重
|
||||
fontWeight: {
|
||||
normal: '400',
|
||||
medium: '500',
|
||||
semibold: '600',
|
||||
bold: '700'
|
||||
},
|
||||
|
||||
// 行高
|
||||
lineHeight: {
|
||||
tight: '1.25',
|
||||
normal: '1.5',
|
||||
relaxed: '1.75',
|
||||
loose: '2'
|
||||
}
|
||||
} as const
|
||||
|
||||
/**
|
||||
* 动画系统
|
||||
*/
|
||||
export const animations = {
|
||||
// 过渡时间
|
||||
duration: {
|
||||
fast: '150ms',
|
||||
normal: '200ms',
|
||||
slow: '300ms',
|
||||
slower: '500ms'
|
||||
},
|
||||
|
||||
// 缓动函数
|
||||
easing: {
|
||||
default: 'cubic-bezier(0.4, 0, 0.2, 1)',
|
||||
in: 'cubic-bezier(0.4, 0, 1, 1)',
|
||||
out: 'cubic-bezier(0, 0, 0.2, 1)',
|
||||
inOut: 'cubic-bezier(0.4, 0, 0.2, 1)'
|
||||
}
|
||||
} as const
|
||||
|
||||
/**
|
||||
* 断点系统
|
||||
*/
|
||||
export const breakpoints = {
|
||||
sm: '640px',
|
||||
md: '768px',
|
||||
lg: '1024px',
|
||||
xl: '1280px',
|
||||
'2xl': '1536px'
|
||||
} as const
|
||||
|
||||
/**
|
||||
* Z-index 层级系统
|
||||
*/
|
||||
export const zIndex = {
|
||||
base: 0,
|
||||
dropdown: 1000,
|
||||
sticky: 1020,
|
||||
fixed: 1030,
|
||||
modalBackdrop: 1040,
|
||||
modal: 1050,
|
||||
popover: 1060,
|
||||
tooltip: 1070
|
||||
} as const
|
||||
|
||||
/**
|
||||
* 组件默认配置
|
||||
*/
|
||||
export const componentDefaults = {
|
||||
button: {
|
||||
height: {
|
||||
sm: '32px',
|
||||
md: '40px',
|
||||
lg: '44px'
|
||||
},
|
||||
padding: {
|
||||
sm: '8px 12px',
|
||||
md: '10px 16px',
|
||||
lg: '12px 20px'
|
||||
}
|
||||
},
|
||||
|
||||
input: {
|
||||
height: {
|
||||
sm: '32px',
|
||||
md: '40px',
|
||||
lg: '44px'
|
||||
}
|
||||
},
|
||||
|
||||
card: {
|
||||
padding: spacing.card.padding,
|
||||
borderRadius: radius.card
|
||||
},
|
||||
|
||||
dialog: {
|
||||
sizes: {
|
||||
sm: '400px',
|
||||
md: '600px',
|
||||
lg: '800px',
|
||||
xl: '1000px'
|
||||
}
|
||||
},
|
||||
|
||||
table: {
|
||||
rowHeight: '52px',
|
||||
headerHeight: '48px'
|
||||
}
|
||||
} as const
|
||||
|
||||
/**
|
||||
* 完整主题配置
|
||||
*/
|
||||
export const theme = {
|
||||
colors: themeColors,
|
||||
spacing,
|
||||
radius,
|
||||
shadows,
|
||||
typography,
|
||||
animations,
|
||||
breakpoints,
|
||||
zIndex,
|
||||
components: componentDefaults
|
||||
} as const
|
||||
|
||||
/**
|
||||
* 主题类型
|
||||
*/
|
||||
export type Theme = typeof theme
|
||||
export type ThemeColors = typeof themeColors
|
||||
export type Spacing = typeof spacing
|
||||
export type Radius = typeof radius
|
||||
export type Shadows = typeof shadows
|
||||
export type Typography = typeof typography
|
||||
|
||||
/**
|
||||
* 导出默认主题
|
||||
*/
|
||||
export default theme
|
||||
Reference in New Issue
Block a user