From c98aa733645c84332ae4851f3c0c695cac109c81 Mon Sep 17 00:00:00 2001 From: Cccc_ Date: Sat, 3 Jan 2026 16:09:22 +0800 Subject: [PATCH] style: use united style --- frontend/index.html | 7 +- frontend/public/favicon.svg | 20 + frontend/src/antd-theme.js | 227 +- frontend/src/components/CrontabEditor.vue | 197 +- frontend/src/components/FieldConfigEditor.vue | 38 +- frontend/src/components/FieldTreeNode.vue | 50 +- frontend/src/components/Layout.vue | 6 +- frontend/src/components/Navbar.vue | 62 +- frontend/src/components/common/EmptyState.vue | 119 ++ .../src/components/common/LoadingState.vue | 106 + frontend/src/components/common/StatsCard.vue | 196 ++ frontend/src/composables/useAsyncAction.js | 84 + frontend/src/composables/usePollStatus.js | 128 ++ frontend/src/style.css | 1843 +++++++++-------- frontend/src/views/DashboardView.vue | 51 +- frontend/src/views/SettingsView.vue | 20 +- frontend/src/views/TaskRecordsView.vue | 92 +- frontend/src/views/TasksView.vue | 89 +- frontend/src/views/admin/TemplatesView.vue | 61 +- frontend/tailwind.config.js | 22 +- 20 files changed, 2099 insertions(+), 1319 deletions(-) create mode 100644 frontend/public/favicon.svg create mode 100644 frontend/src/components/common/EmptyState.vue create mode 100644 frontend/src/components/common/LoadingState.vue create mode 100644 frontend/src/components/common/StatsCard.vue create mode 100644 frontend/src/composables/useAsyncAction.js create mode 100644 frontend/src/composables/usePollStatus.js diff --git a/frontend/index.html b/frontend/index.html index 7d082ee..f60ac5a 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -1,10 +1,11 @@ - + - + - frontend + 接龙自动打卡 +
diff --git a/frontend/public/favicon.svg b/frontend/public/favicon.svg new file mode 100644 index 0000000..180ccba --- /dev/null +++ b/frontend/public/favicon.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + diff --git a/frontend/src/antd-theme.js b/frontend/src/antd-theme.js index f29d504..cb2d21f 100644 --- a/frontend/src/antd-theme.js +++ b/frontend/src/antd-theme.js @@ -2,180 +2,211 @@ import { theme } from 'ant-design-vue' /** * Ant Design Vue 主题配置 - * 匹配现有 Material Design 3 色彩系统 + * 严格遵循 Material Design 3 规范 * @param {boolean} isDark - 是否为暗色模式 */ export default function getAntdTheme(isDark = false) { return { token: { - // 主色调 - 绿色(与 MD3 primary 保持一致) + // === Material Design 3 Color System === + + // Primary - 主色调(绿色) colorPrimary: isDark ? '#81c784' : '#4caf50', - // 成功色 + // Secondary colors colorSuccess: isDark ? '#81c784' : '#4caf50', - - // 警告色 colorWarning: '#ff9800', - - // 错误色 - colorError: '#f56c6c', - - // 信息色 - 蓝色(与 MD3 secondary 保持一致) + colorError: '#f44336', // MD3 标准错误色 colorInfo: isDark ? '#64b5f6' : '#2196f3', - // 背景色 - colorBgBase: isDark ? '#121212' : '#ffffff', - colorBgContainer: isDark ? '#1c1c1e' : '#ffffff', - colorBgElevated: isDark ? '#2c2c2e' : '#ffffff', - colorBgLayout: isDark ? '#121212' : '#fafafa', - colorBgSpotlight: isDark ? '#2c2c2e' : '#ffffff', + // === Surface & Background (MD3 规范) === + colorBgBase: isDark ? '#1c1b1f' : '#ffffff', + colorBgContainer: isDark ? '#1c1b1f' : '#ffffff', + colorBgElevated: isDark ? '#26252a' : '#ffffff', + colorBgLayout: isDark ? '#1c1b1f' : '#fefbff', // MD3 标准背景色 + colorBgSpotlight: isDark ? '#26252a' : '#ffffff', - // 文字色 - colorText: isDark ? '#e5e5e7' : '#1c1b1f', - colorTextSecondary: isDark ? '#a0a0a3' : '#64748b', - colorTextTertiary: isDark ? '#808083' : '#94a3b8', - colorTextQuaternary: isDark ? '#606063' : '#cbd5e1', + // === Typography (MD3 规范) === + colorText: isDark ? '#e6e1e5' : '#1c1b1f', // On-surface + colorTextSecondary: isDark ? '#cac4d0' : '#49454f', // On-surface-variant + colorTextTertiary: isDark ? '#938f99' : '#79747e', + colorTextQuaternary: isDark ? '#79747e' : '#938f99', - // 边框色 - colorBorder: isDark ? '#3a3a3c' : '#e5e7eb', - colorBorderSecondary: isDark ? '#2c2c2e' : '#f3f4f6', + // === Borders === + colorBorder: isDark ? '#49454f' : '#d1cdd6', + colorBorderSecondary: isDark ? '#3a3740' : '#e3e1e6', + colorSplit: isDark ? '#49454f' : '#e3e1e6', - // 分割线颜色 - colorSplit: isDark ? '#3a3a3c' : '#e5e7eb', + // === Shape System === + borderRadius: 12, // Medium shape + borderRadiusLG: 16, // Large shape + borderRadiusSM: 8, // Small shape + borderRadiusXS: 4, // Extra small shape - // 边框圆角 - 与 Material Design 3 一致 - borderRadius: 12, + // === Typography === + fontFamily: "'Roboto', 'Inter', system-ui, -apple-system, sans-serif", + fontSize: 14, // Body Medium + fontSizeLG: 16, // Body Large + fontSizeSM: 12, // Body Small + lineHeight: 1.428, // 20/14 = 1.428 + lineHeightLG: 1.5, // 24/16 = 1.5 - // 字体家族 - fontFamily: "'Inter', 'Segoe UI', 'Roboto', system-ui, -apple-system, sans-serif", - - // 链接色 + // === Links === colorLink: isDark ? '#64b5f6' : '#2196f3', colorLinkHover: isDark ? '#90caf9' : '#1976d2', colorLinkActive: isDark ? '#42a5f5' : '#1565c0', - // 字体大小 - fontSize: 14, - - // 行高 - lineHeight: 1.5715, - - // 控制组件高度 + // === Components === controlHeight: 40, + controlHeightLG: 48, + controlHeightSM: 32, + + // === Motion (MD3 规范) === + motionDurationSlow: '0.3s', + motionDurationMid: '0.2s', + motionDurationFast: '0.1s', }, components: { - // Card 组件定制 + // === Card 组件 (MD3 Elevated Card) === Card: { borderRadiusLG: 16, - boxShadowTertiary: isDark - ? '0 1px 3px 1px rgba(0, 0, 0, 0.5)' - : '0 1px 3px 1px rgba(0, 0, 0, 0.08)', paddingLG: 24, - colorBgContainer: isDark ? '#1c1c1e' : '#ffffff', - colorBorderSecondary: isDark ? '#3a3a3c' : '#f0f0f0', - colorTextHeading: isDark ? '#e5e5e7' : '#1c1b1f', + colorBgContainer: isDark ? '#1c1b1f' : '#ffffff', + colorBorderSecondary: isDark ? '#49454f' : '#e3e1e6', + colorTextHeading: isDark ? '#e6e1e5' : '#1c1b1f', }, - // Button 组件定制 + // === Button 组件 (MD3 规范) === Button: { - borderRadius: 24, // 圆角按钮,类似 MD3 + borderRadius: 20, // MD3 Filled Button 圆角 + borderRadiusLG: 24, + borderRadiusSM: 16, controlHeight: 40, + controlHeightLG: 48, + controlHeightSM: 32, fontSize: 14, - colorText: isDark ? '#e5e5e7' : '#1c1b1f', - colorBgContainer: isDark ? '#2c2c2e' : '#ffffff', + fontSizeLG: 16, + fontSizeSM: 12, + paddingContentHorizontal: 24, + colorText: isDark ? '#e6e1e5' : '#1c1b1f', + colorBgContainer: isDark ? '#26252a' : '#ffffff', }, - // Input 组件定制 + // === Input 组件 (MD3 Text Field) === Input: { borderRadius: 12, controlHeight: 40, - colorBgContainer: isDark ? '#2c2c2e' : '#ffffff', - colorText: isDark ? '#e5e5e7' : '#1c1b1f', - colorTextPlaceholder: isDark ? '#808083' : '#94a3b8', - colorBorder: isDark ? '#3a3a3c' : '#e5e7eb', + colorBgContainer: isDark ? '#26252a' : '#ffffff', + colorText: isDark ? '#e6e1e5' : '#1c1b1f', + colorTextPlaceholder: isDark ? '#938f99' : '#79747e', + colorBorder: isDark ? '#49454f' : '#d1cdd6', }, - // Select 组件定制 + // === Select 组件 === Select: { borderRadius: 12, controlHeight: 40, - colorBgContainer: isDark ? '#2c2c2e' : '#ffffff', - colorBgElevated: isDark ? '#2c2c2e' : '#ffffff', - colorText: isDark ? '#e5e5e7' : '#1c1b1f', - colorTextPlaceholder: isDark ? '#808083' : '#94a3b8', - colorBorder: isDark ? '#3a3a3c' : '#e5e7eb', + colorBgContainer: isDark ? '#26252a' : '#ffffff', + colorBgElevated: isDark ? '#26252a' : '#ffffff', + colorText: isDark ? '#e6e1e5' : '#1c1b1f', + colorTextPlaceholder: isDark ? '#938f99' : '#79747e', + colorBorder: isDark ? '#49454f' : '#d1cdd6', }, - // Modal 组件定制 + // === Modal 组件 (MD3 Dialog) === Modal: { - borderRadiusLG: 16, - colorBgElevated: isDark ? '#1c1c1e' : '#ffffff', - colorText: isDark ? '#e5e5e7' : '#1c1b1f', - colorTextHeading: isDark ? '#e5e5e7' : '#1c1b1f', + borderRadiusLG: 28, // MD3 Dialog 使用 Extra Large 圆角 + colorBgElevated: isDark ? '#1c1b1f' : '#ffffff', + colorText: isDark ? '#e6e1e5' : '#1c1b1f', + colorTextHeading: isDark ? '#e6e1e5' : '#1c1b1f', }, - // Table 组件定制 + // === Table 组件 === Table: { borderRadius: 12, - colorBgContainer: isDark ? '#1c1c1e' : '#ffffff', - colorFillAlter: isDark ? '#2c2c2e' : '#f5f7fa', - colorText: isDark ? '#e5e5e7' : '#1c1b1f', - colorTextHeading: isDark ? '#e5e5e7' : '#1c1b1f', - colorBorderSecondary: isDark ? '#3a3a3c' : '#f0f0f0', + colorBgContainer: isDark ? '#1c1b1f' : '#ffffff', + colorFillAlter: isDark ? '#26252a' : '#f5f5f5', + colorText: isDark ? '#e6e1e5' : '#1c1b1f', + colorTextHeading: isDark ? '#e6e1e5' : '#1c1b1f', + colorBorderSecondary: isDark ? '#49454f' : '#e3e1e6', }, - // Tabs 组件定制 + // === Tabs 组件 === Tabs: { borderRadius: 12, - colorText: isDark ? '#e5e5e7' : '#1c1b1f', - colorBgContainer: isDark ? '#1c1c1e' : '#ffffff', + colorText: isDark ? '#e6e1e5' : '#1c1b1f', + colorBgContainer: isDark ? '#1c1b1f' : '#ffffff', }, - // Menu 组件定制 + // === Menu 组件 === Menu: { - colorItemBg: isDark ? '#1c1c1e' : '#ffffff', - colorItemBgHover: isDark ? '#2c2c2e' : '#f5f7fa', - colorItemBgSelected: isDark ? '#2c2c2e' : '#e8f5e9', - colorItemText: isDark ? '#e5e5e7' : '#1c1b1f', + colorItemBg: isDark ? '#1c1b1f' : '#ffffff', + colorItemBgHover: isDark ? '#26252a' : '#f5f5f5', + colorItemBgSelected: isDark ? '#3a4a3f' : '#e8f5e9', + colorItemText: isDark ? '#e6e1e5' : '#1c1b1f', colorItemTextSelected: isDark ? '#81c784' : '#4caf50', + borderRadius: 12, }, - // Dropdown 组件定制 + // === Dropdown 组件 === Dropdown: { - colorBgElevated: isDark ? '#2c2c2e' : '#ffffff', - colorText: isDark ? '#e5e5e7' : '#1c1b1f', + colorBgElevated: isDark ? '#26252a' : '#ffffff', + colorText: isDark ? '#e6e1e5' : '#1c1b1f', + borderRadiusLG: 12, }, - // Descriptions 组件定制 + // === Descriptions 组件 === Descriptions: { - colorText: isDark ? '#e5e5e7' : '#1c1b1f', - colorTextSecondary: isDark ? '#a0a0a3' : '#64748b', - colorBgContainer: isDark ? '#1c1c1e' : '#ffffff', - colorFillAlter: isDark ? '#2c2c2e' : '#f5f7fa', + colorText: isDark ? '#e6e1e5' : '#1c1b1f', + colorTextSecondary: isDark ? '#cac4d0' : '#49454f', + colorBgContainer: isDark ? '#1c1b1f' : '#ffffff', + colorFillAlter: isDark ? '#201f24' : '#f3f4f6', // Label 背景色 = surface-container + colorSplit: isDark ? '#49454f' : '#e3e1e6', + borderRadiusLG: 8, // 设置 Descriptions 容器圆角 }, - // Alert 组件定制 + // === Alert 组件 === Alert: { borderRadiusLG: 12, - colorText: isDark ? '#e5e5e7' : '#1c1b1f', + colorText: isDark ? '#e6e1e5' : '#1c1b1f', }, - // Drawer 组件定制 + // === Drawer 组件 === Drawer: { - colorBgElevated: isDark ? '#1c1c1e' : '#ffffff', - colorText: isDark ? '#e5e5e7' : '#1c1b1f', + colorBgElevated: isDark ? '#1c1b1f' : '#ffffff', + colorText: isDark ? '#e6e1e5' : '#1c1b1f', + borderRadiusLG: 16, }, - // Form 组件定制 + // === Form 组件 === Form: { - colorText: isDark ? '#e5e5e7' : '#1c1b1f', - colorTextHeading: isDark ? '#e5e5e7' : '#1c1b1f', + colorText: isDark ? '#e6e1e5' : '#1c1b1f', + colorTextHeading: isDark ? '#e6e1e5' : '#1c1b1f', }, - // Empty 组件定制 + // === Empty 组件 === Empty: { - colorTextDescription: isDark ? '#a0a0a3' : '#94a3b8', + colorTextDescription: isDark ? '#938f99' : '#79747e', + }, + + // === Tag 组件 === + Tag: { + borderRadiusSM: 16, // 药丸形 + colorText: isDark ? '#e6e1e5' : '#1c1b1f', + }, + + // === Switch 组件 === + Switch: { + colorPrimary: isDark ? '#81c784' : '#4caf50', + colorText: isDark ? '#e6e1e5' : '#1c1b1f', + }, + + // === Tooltip 组件 === + Tooltip: { + colorBgSpotlight: isDark ? '#313033' : '#f5f5f5', // Tooltip 背景色(跟随主题) + colorTextLightSolid: isDark ? '#ffffff' : '#1c1b1f', // Tooltip 文本颜色(跟随主题) + borderRadius: 8, }, }, diff --git a/frontend/src/components/CrontabEditor.vue b/frontend/src/components/CrontabEditor.vue index 7b77e83..53dac39 100644 --- a/frontend/src/components/CrontabEditor.vue +++ b/frontend/src/components/CrontabEditor.vue @@ -325,191 +325,174 @@ onBeforeUnmount(() => { diff --git a/frontend/src/components/FieldConfigEditor.vue b/frontend/src/components/FieldConfigEditor.vue index 1a945c5..596e637 100644 --- a/frontend/src/components/FieldConfigEditor.vue +++ b/frontend/src/components/FieldConfigEditor.vue @@ -9,7 +9,7 @@ placeholder="在表单中显示的名称" allow-clear /> - 显示名称 + 显示名称 @@ -24,7 +24,7 @@ - 用户填写时使用的输入控件 + 用户填写时使用的输入控件 @@ -38,22 +38,22 @@ class="w-full" > - 字符串 (string) + 字符串 (string) - 整数 (int) + 整数 (int) - 浮点数 (double) + 浮点数 (double) - 布尔值 (bool) + 布尔值 (bool) - JSON对象 (json) - 用于Values字段 + JSON对象 (json) - 用于Values字段 - 数据存储时的类型 + 数据存储时的类型 @@ -72,7 +72,7 @@ :rows="3" allow-clear /> - +