From 3cbebb5f9bb28052725eba2017bc747c1279589b Mon Sep 17 00:00:00 2001 From: Zyy Date: Sun, 1 Nov 2026 01:40:09 +0800 Subject: [PATCH] feat(frontend): adopt UI v0.8.0 and refine form feedback Unify theme namespaces and plugin theme delivery, improve validation and empty states, and pin UI v0.8.0 plus plugin workbench v0.9.0. Co-authored-by: Codex --- docs/theme.md | 77 +++--- frontend/package.json | 2 +- frontend/pnpm-lock.yaml | 59 +++- .../components/AccountGroupCheckboxGrid.vue | 6 +- frontend/src/components/AccountGroupMarks.vue | 2 +- frontend/src/components/ApiKeyConfigModal.vue | 8 +- frontend/src/components/AppBrandMark.vue | 4 +- frontend/src/components/AppLanguageMenu.vue | 2 +- frontend/src/components/ClientImportModal.vue | 8 +- frontend/src/components/HelpPopover.vue | 2 +- frontend/src/components/ProviderIconGroup.vue | 8 +- .../RequestLocationDetectButton.vue | 2 +- .../src/components/RequestLocationFields.vue | 29 +- .../components/account/AccountPlanBadge.vue | 24 +- .../account/AccountQuotaWindowDetails.vue | 34 +-- .../account/AccountUpstreamBadge.vue | 6 +- .../account/AccountUpstreamStatus.vue | 4 +- .../AccountRequestTimeline.vue | 4 +- .../account/account-usage-window/index.vue | 8 +- .../account/account-usage-window/presenter.ts | 36 +-- frontend/src/components/charts/tooltip.ts | 3 +- .../ClientProfilePresetFields.vue | 2 +- .../ClientProfilePreviewPanel.vue | 14 +- frontend/src/components/schema-form/index.vue | 2 +- .../usage/HealthTimelinePointPopover.vue | 38 +-- .../usage/RequestHealthTimelineCard.vue | 21 +- .../src/components/usage/UsageBillingCell.vue | 14 +- .../components/usage/UsageClientIpCell.vue | 2 +- .../components/usage/UsageDetailPopover.vue | 10 +- .../src/components/usage/UsageLatencyCell.vue | 32 +-- .../src/components/usage/UsageModelCell.vue | 8 +- .../components/usage/UsagePerformanceCell.vue | 8 +- .../usage/UsageReasoningEffortCell.vue | 6 +- .../components/usage/UsageRecordsTable.vue | 14 +- .../src/components/usage/UsageRouteCell.vue | 4 +- .../src/components/usage/UsageTimeCell.vue | 2 +- .../src/components/usage/UsageTokenCell.vue | 18 +- .../components/usage/UsageTransportBadge.vue | 2 +- .../src/components/usage/shared/health.ts | 36 +-- .../src/components/usage/shared/presenter.ts | 6 +- frontend/src/composables/useChartPalette.ts | 30 +- frontend/src/composables/useThemeColor.ts | 5 +- frontend/src/i18n/locales/en/settings.json | 3 +- .../src/i18n/locales/zh-Hans/settings.json | 3 +- .../src/i18n/locales/zh-Hant/settings.json | 3 +- frontend/src/layout/components/AppSidebar.vue | 105 ++++--- .../components/FloatingSidebarToggle.vue | 4 +- .../components/system-update-modal/index.vue | 78 +++--- .../system-update-modal/presenter.ts | 24 +- frontend/src/layout/index.vue | 2 +- frontend/src/stores/modules/theme.ts | 72 ++--- frontend/src/utils/color.ts | 8 +- frontend/src/utils/location.ts | 7 - .../components/AccountApiKeyFields.vue | 32 +-- .../components/AccountBatchEditModal.vue | 33 ++- .../components/AccountCapacityIndicator.vue | 2 +- .../components/AccountConcurrencyTable.vue | 12 +- .../components/AccountConnectionTestModal.vue | 60 ++-- .../accounts/components/AccountEditModal.vue | 56 +++- .../accounts/components/AccountFilters.vue | 8 +- .../components/AccountIdentityCell.vue | 6 +- .../components/AccountModelAccessField.vue | 33 ++- .../components/AccountNotesPopover.vue | 6 +- .../components/AccountOverviewCards.vue | 14 +- .../accounts/components/AccountProxyField.vue | 4 +- .../components/AccountSettingsFields.vue | 15 +- .../components/AccountTableActions.vue | 20 +- .../accounts/components/AccountUsagePanel.vue | 48 ++-- .../AccountOAuthFields.vue | 16 +- .../AccountSetupFields.vue | 5 +- .../components/account-create-modal/index.vue | 77 +++--- .../account-create-modal/presenter.ts | 5 +- .../account-import-tasks/TaskDetail.vue | 32 +-- .../components/account-import-tasks/index.vue | 2 +- .../account-import-tasks/presenter.ts | 24 +- .../ActivityInsights.vue | 16 +- .../account-profile-modal/Metrics.vue | 4 +- .../account-profile-modal/ProfileHero.vue | 4 +- .../account-profile-modal/Skeleton.vue | 2 +- .../account-profile-modal/Subscription.vue | 14 +- .../account-profile-modal/TokenActivity.vue | 14 +- .../account-profile-modal/index.vue | 6 +- .../ForecastCapacity.vue | 34 +-- .../account-quota-forecast-modal/Skeleton.vue | 4 +- .../account-quota-forecast-modal/index.vue | 10 +- .../account-quota-panel/Credits.vue | 8 +- .../components/account-quota-panel/Entry.vue | 24 +- .../account-quota-panel/PoolChart.vue | 10 +- .../ResetCreditAutomation.vue | 12 +- .../account-quota-panel/ResetCredits.vue | 32 +-- .../account-quota-panel/UpstreamPool.vue | 6 +- .../account-quota-panel/UsageLimits.vue | 10 +- .../components/account-quota-panel/index.vue | 6 +- .../account-quota-summary-cell/Entry.vue | 2 +- .../WindowGroup.vue | 6 +- .../account-quota-summary-cell/index.vue | 10 +- .../components/account-status-badge/index.vue | 50 ++-- .../account-status-badge/presenter.ts | 40 +-- .../composables/useAccountApiKeyFormRules.ts | 63 +++++ .../composables/useAccountBatchEditor.ts | 25 +- .../composables/useAccountConnectionTest.ts | 16 +- .../accounts/composables/useAccountEditor.ts | 54 +--- .../composables/useAccountOnboarding.ts | 14 +- .../useAccountSettingsFormRules.ts | 60 ++++ frontend/src/views/accounts/constants.ts | 10 +- frontend/src/views/accounts/index.vue | 8 +- .../src/views/accounts/utils/accountCreate.ts | 20 +- .../src/views/accounts/utils/accountName.ts | 6 + .../views/accounts/utils/schedulingForm.ts | 51 +--- .../views/accounts/utils/upstreamApiKey.ts | 23 -- .../components/AccountOverviewCard.vue | 70 ++--- .../components/DashboardAccountIdentity.vue | 12 +- .../dashboard/components/DashboardContent.vue | 2 +- .../components/DashboardHeartbeat.vue | 4 +- .../views/dashboard/components/MetricCard.vue | 32 +-- .../dashboard/components/RequestTrendCard.vue | 18 +- .../dashboard/components/WireProfileCard.vue | 52 ++-- .../composables/useRequestTrendChart.ts | 7 +- frontend/src/views/dashboard/constants.ts | 20 +- frontend/src/views/dashboard/presenter.ts | 44 +-- .../groups/components/AccountGroupActions.vue | 6 +- .../groups/components/AccountGroupFilters.vue | 2 +- .../components/AccountGroupFormModal.vue | 35 ++- .../components/AccountGroupMetricsCell.vue | 12 +- .../groups/composables/useAccountGroups.ts | 12 +- frontend/src/views/groups/index.vue | 20 +- .../key-usage/components/KeyUsageBudget.vue | 16 +- .../key-usage/components/KeyUsageHeader.vue | 18 +- .../key-usage/components/KeyUsageRecords.vue | 4 +- .../key-usage/components/KeyUsageSkeleton.vue | 14 +- .../key-usage/components/KeyUsageSummary.vue | 20 +- frontend/src/views/key-usage/index.vue | 6 +- frontend/src/views/key-usage/utils/metrics.ts | 20 +- .../views/keys/components/ApiKeyActions.vue | 10 +- .../keys/components/ApiKeyBudgetCell.vue | 16 +- .../components/ApiKeyBudgetResetModal.vue | 20 +- .../keys/components/ApiKeyCreatedModal.vue | 8 +- .../views/keys/components/ApiKeyFilters.vue | 2 +- .../views/keys/components/ApiKeyFormModal.vue | 4 +- .../keys/components/ApiKeyIdentityCell.vue | 4 +- .../keys/components/ApiKeyPrefixCell.vue | 2 +- .../views/keys/components/ApiKeyScopeCell.vue | 2 +- .../keys/components/ApiKeyStatusBadge.vue | 6 +- .../keys/composables/useApiKeyFormRules.ts | 4 +- frontend/src/views/keys/index.vue | 8 +- .../login/components/LoginBackground.vue | 86 +++--- .../src/views/login/components/LoginPanel.vue | 78 +++--- .../login/components/LoginThemeToggle.vue | 8 +- frontend/src/views/login/index.vue | 228 +++++++-------- .../plugins/components/PluginAssetPicker.vue | 20 +- .../components/PluginBindingEditor.vue | 4 +- .../components/PluginCapabilityTags.vue | 4 +- .../plugins/components/PluginCatalogPanel.vue | 14 +- .../components/PluginConfigurationFields.vue | 8 +- .../components/PluginConfigurationModal.vue | 4 +- .../components/PluginConfigurationSummary.vue | 10 +- .../plugins/components/PluginDetailModal.vue | 6 +- .../plugins/components/PluginEnableModal.vue | 22 +- .../components/PluginExtensionsPanel.vue | 10 +- .../PluginFrontendAuthenticationEditor.vue | 8 +- .../plugins/components/PluginHelpPopover.vue | 4 +- .../views/plugins/components/PluginIcon.vue | 2 +- .../plugins/components/PluginInstallModal.vue | 261 ++++++++++-------- .../components/PluginLegacyConfigurations.vue | 12 +- .../plugins/components/PluginManagement.vue | 18 +- .../components/PluginManagementFrame.vue | 2 +- .../plugins/components/PluginPageLoading.vue | 2 +- .../components/PluginResourcePicker.vue | 2 +- .../components/PluginRollbackModal.vue | 4 +- .../plugins/components/PluginRuntimeLoad.vue | 10 +- .../plugins/components/PluginStatusNotice.vue | 10 +- .../components/PluginUpdateCheckModal.vue | 22 +- .../plugins/components/PluginVersionCard.vue | 22 +- .../components/PluginVersionsPanel.vue | 2 +- .../components/SourceCredentialPicker.vue | 8 +- .../plugins/management/bridge-runtime.ts | 7 +- .../src/views/plugins/management/frame.ts | 16 +- .../proxies/components/ProxyAccountsModal.vue | 12 +- .../views/proxies/components/ProxyActions.vue | 6 +- .../components/ProxyBatchCreateFields.vue | 14 +- .../proxies/components/ProxyBatchResults.vue | 16 +- .../proxies/components/ProxyFormModal.vue | 76 ++++- .../views/proxies/components/ProxyRegion.vue | 6 +- .../views/proxies/composables/useProxies.ts | 33 +-- frontend/src/views/proxies/index.vue | 32 +-- frontend/src/views/proxies/utils/batch.ts | 18 +- .../components/AccountAffinityCard.vue | 14 +- .../settings/components/AccountWarmupCard.vue | 12 +- .../settings/components/AdminApiKeyCard.vue | 12 +- .../settings/components/AdminPasswordCard.vue | 8 +- .../settings/components/ClientProfileCard.vue | 4 +- .../components/ConcurrencyPolicyCard.vue | 20 +- .../settings/components/ModelAliasesCard.vue | 57 ++-- .../components/RequestHistoryCard.vue | 8 +- .../components/RequestLocationCard.vue | 8 +- .../settings/components/ResetCreditCard.vue | 10 +- .../components/ResponseBodyLimitCard.vue | 8 +- .../components/RotationStrategyCard.vue | 18 +- .../components/SettingsAccessSection.vue | 4 - .../components/SmartSchedulingModal.vue | 6 +- .../settings/components/TokenRefreshCard.vue | 10 +- .../components/backup/BackupRecordsCard.vue | 14 +- .../components/backup/BackupStatusBadge.vue | 24 +- .../components/backup/BackupStorageCard.vue | 8 +- .../components/backup/R2GuideModal.vue | 16 +- .../components/ClientCliInstallPanel.vue | 14 +- .../components/ClientDesktopInstallPanel.vue | 8 +- .../ClientDesktopOfflineDownloads.vue | 26 +- .../components/ClientInstallCommandList.vue | 6 +- .../components/ClientVersionGuideModal.vue | 2 +- .../components/ClientVersionPolicyCard.vue | 14 +- .../components/client-version/index.vue | 6 - .../AccountErrorProtectionCard.vue | 126 ++++----- .../ProtectionConditionEditor.vue | 14 +- .../error-protection/ProtectionRuleEditor.vue | 6 +- .../error-protection/ProtectionRuleRow.vue | 8 +- .../components/error-protection/form.ts | 12 +- .../components/privacy/PolicyPreview.vue | 16 +- .../components/privacy/PrivacyPolicyCard.vue | 6 +- .../components/privacy/RuleEditor.vue | 10 +- .../components/privacy/RulesTable.vue | 4 +- .../components/privacy/StepFields.vue | 4 +- .../settings/components/privacy/StepList.vue | 18 +- .../settings/composables/useSettingsForm.ts | 211 ++------------ .../composables/useSettingsFormRules.ts | 98 +++++++ frontend/src/views/settings/index.vue | 62 +++-- .../settings/pricing/PricingBatchModal.vue | 10 +- .../views/settings/pricing/PricingEditor.vue | 10 +- .../settings/pricing/PricingRateFields.vue | 12 +- .../settings/pricing/PricingSyncModal.vue | 22 +- .../views/settings/pricing/PricingTable.vue | 14 +- .../views/settings/pricing/PricingToolbar.vue | 6 +- .../views/settings/pricing/PricingUnit.vue | 4 +- frontend/src/views/settings/pricing/index.vue | 4 +- frontend/src/views/settings/utils/version.ts | 40 +++ .../components/AppearanceSettingsSection.vue | 8 +- .../theme/components/ThemeColorTokenField.vue | 18 +- .../components/ThemeComponentPreview.vue | 108 ++++---- .../components/ThemeComponentTokenPanel.vue | 92 +++--- .../theme/components/ThemeEditorPreview.vue | 10 +- .../components/ThemeGlobalTokenPanel.vue | 52 ++-- .../components/ThemeNumberTokenField.vue | 8 +- .../theme/components/ThemePreviewCanvas.vue | 16 +- .../theme/components/ThemePreviewScope.vue | 6 +- .../theme/components/ThemeTextTokenField.vue | 6 +- .../views/theme/composables/useThemeEditor.ts | 35 +-- .../views/usage/components/UsageCostCard.vue | 22 +- .../usage/components/UsageDetailCodePanel.vue | 6 +- .../usage/components/UsageDetailFieldGrid.vue | 2 +- .../usage/components/UsageDiagnosticCard.vue | 26 +- .../components/UsageErrorDetailModal.vue | 16 +- .../views/usage/components/UsageFilters.vue | 2 +- .../usage/components/UsageHealthCard.vue | 14 +- .../usage/components/UsagePerformanceCard.vue | 6 +- .../components/UsageRecordDetailModal.vue | 16 +- .../usage/components/UsageStatusCodeBadge.vue | 10 +- .../usage/components/UsageSummaryCards.vue | 23 +- .../usage/composables/useUsageInsights.ts | 9 +- frontend/src/views/usage/index.vue | 6 +- frontend/src/views/usage/utils/detail.ts | 10 +- modules/plugins | 2 +- modules/ui | 2 +- 262 files changed, 2763 insertions(+), 2576 deletions(-) create mode 100644 frontend/src/views/accounts/composables/useAccountApiKeyFormRules.ts create mode 100644 frontend/src/views/accounts/composables/useAccountSettingsFormRules.ts create mode 100644 frontend/src/views/accounts/utils/accountName.ts create mode 100644 frontend/src/views/settings/composables/useSettingsFormRules.ts create mode 100644 frontend/src/views/settings/utils/version.ts diff --git a/docs/theme.md b/docs/theme.md index 0eb785deb..93bf770ff 100644 --- a/docs/theme.md +++ b/docs/theme.md @@ -90,12 +90,12 @@ ```mermaid flowchart LR - A[Pinia 持久化配置] --> B[resolveTheme] + A[Pinia 持久化配置] --> B[createTheme] B --> C[Seed Token] C --> D[Map Token] D --> E[Alias Token] E --> F[Component Token] - F --> G[#cp-runtime-theme] + F --> G[#z-runtime-theme] G --> H[Vue / Tailwind / ECharts] B --> I[Theme Editor 草稿] @@ -119,7 +119,7 @@ flowchart LR [SDK 页面与宿主桥](../backend/crates/gateway-plugin/sdk/docs/capabilities.md#页面宿主桥-v2)。 `theme/` 根目录只保留公开入口 `index.ts` 和唯一类型文件 `types.ts`;内部实现按 `core/`、`derive/`、`runtime/` 分层,不增加嵌套 barrel。 纯派生模块不访问 DOM,`theme/runtime/browser.ts` 不包含派生规则,Theme Store 不复制算法。 -普通 Map 字段按 camelCase → kebab-case 统一生成 `--cp-*`;Semantic 与 Preset Color 仅维护各自的短角色表。 +普通 Map 字段按 camelCase → kebab-case 统一生成 `--z-*`;Semantic 与 Preset Color 仅维护各自的短角色表。 `ThemeTokenName` 在 `types.ts` 中由 Map 契约推导,无需手写重复的联合类型和对象映射 下文未带宿主路径的 `theme/`、`styles/` 均指 `codex-proxy-ui/src/` 下的目录,联调入口见[开发文档](development.md#源码联调) @@ -215,20 +215,20 @@ Quaternary;主按钮白字与功能色文字遵循各自的容器配对规则 ### Alias Token -Alias 按视觉角色命名,使用 `--cp-` 命名空间;整体分层对齐 Ant Design,并以 Container / On Container 表达成对的 +Alias 按视觉角色命名,使用 `--z-` 命名空间;整体分层对齐 Ant Design,并以 Container / On Container 表达成对的 语义表面与前景: | 角色 | CSS Token | 主要消费者 | | --- | --- | --- | -| 品牌交互 | `--cp-color-primary*` | 主操作、选中态、焦点与强调 | -| 链接 | `--cp-color-link*` | 普通文本链接 | -| 表面 | `--cp-color-bg-*` | 页面、容器、浮层和遮罩 | -| 填充 | `--cp-color-fill-*` | 轨道、弱背景和静态层级 | -| 文字 | `--cp-color-text*` | 标题、正文和辅助信息 | -| 选择 | `--cp-control-item-bg-active*` | Segmented、Select 和选择控件 | -| 焦点 | `--cp-control-outline` | 键盘焦点和输入反馈 | -| 功能色 | `--cp-color-info / success / warning / error-*` | 系统反馈与状态 | -| 预设彩色 | `--cp-color-{blue,cyan,green,orange,purple,red}-{container,container-strong,border,solid,text,on-container}` | 分类标签与数据强调 | +| 品牌交互 | `--z-color-primary*` | 主操作、选中态、焦点与强调 | +| 链接 | `--z-color-link*` | 普通文本链接 | +| 表面 | `--z-color-bg-*` | 页面、容器、浮层和遮罩 | +| 填充 | `--z-color-fill-*` | 轨道、弱背景和静态层级 | +| 文字 | `--z-color-text*` | 标题、正文和辅助信息 | +| 选择 | `--z-control-item-bg-active*` | Segmented、Select 和选择控件 | +| 焦点 | `--z-control-outline` | 键盘焦点和输入反馈 | +| 功能色 | `--z-color-info / success / warning / error-*` | 系统反馈与状态 | +| 预设彩色 | `--z-color-{blue,cyan,green,orange,purple,red}-{container,container-strong,border,solid,text,on-container}` | 分类标签与数据强调 | Alias 不在页面中追加修色;中性与彩色文字在派生层执行各自的背景配对约束。Component Token 直接覆盖时不会自动重算同组件的其他状态;需要保持梯度关系时应修改 Seed,而不是逐个覆盖 Map Token @@ -239,16 +239,16 @@ Token 直接覆盖时不会自动重算同组件的其他状态;需要保持 | 组件 | 代表 Token | | --- | --- | -| Button | `--cp-button-primary-color / bg / hover-bg / active-bg`、`--cp-button-secondary-bg / hover-bg / active-bg` | -| IconButton | `--cp-icon-button-secondary-bg / hover-bg / active-bg` | -| Input | `--cp-input-bg / hover-bg / active-bg / error-active-bg` 与对应 Shadow | -| Menu | `--cp-menu-item-selected-bg` | -| Popover | `--cp-popover-header-bg` | -| Table | `--cp-table-row-bg / stripe-bg / hover-bg / selected-bg / selected-hover-bg / height` | -| Card | `--cp-card-bg / border-radius / shadow` | -| Layout | `--cp-layout-sider-bg / shadow` | -| Scrollbar | `--cp-scrollbar-thumb-bg / hover-bg` | -| BrandMark | `--cp-brand-mark-bg` | +| Button | `--z-button-primary-color / bg / hover-bg / active-bg`、`--z-button-secondary-bg / hover-bg / active-bg` | +| IconButton | `--z-icon-button-secondary-bg / hover-bg / active-bg` | +| Input | `--z-input-bg / hover-bg / active-bg / error-active-bg` 与对应 Shadow | +| Menu | `--z-menu-item-selected-bg` | +| Popover | `--z-popover-header-bg` | +| Table | `--z-table-row-bg / stripe-bg / hover-bg / selected-bg / selected-hover-bg / height` | +| Card | `--z-card-bg / border-radius / shadow` | +| Layout | `--z-layout-sider-bg / shadow` | +| Scrollbar | `--z-scrollbar-thumb-bg / hover-bg` | +| BrandMark | `--z-brand-mark-bg` | 组件状态由 UI 库的 Component 派生层统一生成,页面不维护混色系数: @@ -308,13 +308,17 @@ Theme Store 统一读取持久化配置并初始化主题,首个 Vue 组件渲 ### CSS Variables 提交 +主题内部和持久化配置使用 `color-primary`、`input-bg` 等语义 Token 名,不包含 CSS 前缀。 +UI 构建插件 `CodexProxyUI({ themePrefix: 'z' })` 同时配置变量生成与样式引用,默认前缀为 `z`; +它与组件导出名、DOM 类名和 utility 类名独立,修改后需重新构建。配置方式见 UI 的[主题定制](../modules/ui/playground/guide/theme.md#自定义主题前缀) + 全局主题由 `` 中唯一的运行时样式节点承载: ```html - @@ -324,14 +328,15 @@ Theme Store 统一读取持久化配置并初始化主题,首个 Vue 组件渲 全局弹窗通过 Teleport 挂到 `body` 后仍继承根变量 > [!NOTE] -> Theme Editor 预览是例外:草稿 Token 以内联变量写在影子环境的局部根节点上,仅影响预览,不污染已保存主题 +> Theme Editor 预览是例外:草稿 Token 经 `createThemeVars()` 转换后以内联变量写在影子环境的局部根节点上,仅影响预览,不污染已保存主题 ### 切换与图表 - 用户主动切换时,以点击位置为圆心运行 View Transition;不支持时使用 180ms 颜色过渡 - 初始化、系统主题变化或减少动态效果时直接提交,不播放扩散动画 - 每次有效提交只增加一次 `themeRevision`,相同签名不会重复刷新 -- `useThemeColor()` 在正式页面读取根 CSS Variables,在影子预览中优先读取注入的局部 Token +- `useThemeColor()` 接收语义 Token 名,通过 `getThemeVarName()` 读取当前前缀下的 CSS Variables;影子预览优先读取注入的局部变量 +- 插件桥接传递语义 Token,由插件构建元数据指定的前缀生成 CSS 变量,宿主与插件可独立配置 - 图表 Option 在主题 revision 或预览 Token 改变后重算,`BaseChart` 通过 `setOption` 更新现有 Canvas ## 主题编辑器 @@ -381,24 +386,24 @@ Store 在其他入口发生变化时更新保存基线;没有未保存修改 ### CSS Token -- 全局 Token:`--cp-color-bg-container`、`--cp-font-size` -- Component Token:`--cp-table-row-hover-bg`、`--cp-input-active-shadow` -- Preset Color Token:`--cp-color-purple-container-strong`、`--cp-color-cyan-on-container` +- 全局 Token:`--z-color-bg-container`、`--z-font-size` +- Component Token:`--z-table-row-hover-bg`、`--z-input-active-shadow` +- Preset Color Token:`--z-color-purple-container-strong`、`--z-color-cyan-on-container` - 业务组件按[通用颜色消费](#通用颜色消费)选择角色,不在主题层声明业务域名称 -- Map 与 Component 字段由 `theme/core/tokens.ts` 统一生成 CSS Token;禁止在解析器中再写平行的逐项映射表 +- Map 与 Component 字段由 `theme/core/tokens.ts` 统一生成语义 Token,运行时通过 `createThemeVars()` 输出 CSS 变量;禁止在解析器中再写平行的逐项映射表 - 不使用 `accent`、`soft`、`current`、`subtle` 等与现有角色重叠的平行词汇 ### Vue 与 Tailwind CSS 4 -组件优先使用 `bg-cp-*`、`text-cp-*`、`shadow-cp-*`、`rounded-cp-*` 等由 `@theme inline` 暴露的 utility: +组件优先使用 `bg-z-*`、`text-z-*`、`shadow-z-*`、`rounded-z-*` 等由 `@theme inline` 暴露的 utility: ```vue -
+
...
``` -仅当值需要在 CSS 函数、SVG 或局部派生中参与计算时,直接读取 `var(--cp-*)`。不在页面组件中重新实现色阶、 +仅当值需要在 CSS 函数、SVG 或局部派生中参与计算时,CSS 中直接读取 `var(--z-*)`,JavaScript 中通过 `getThemeVarName()` 生成变量名。不在页面组件中重新实现色阶、 对比度或明暗算法 共享包的 `styles/tailwind.css` 是唯一 `@theme inline` 注册表,只注册 Tailwind 名称,不保存主题值。注册表按基础、排版、颜色、圆角、阴影、间距与尺寸排序; @@ -426,8 +431,8 @@ utility / arbitrary variant;Vue Transition、跨浏览器 Range、动态富文 ### 增加预置主题 1. 在 `ThemeColorPresetId` 增加稳定 ID -2. 在 `THEME_COLOR_PRESETS` 声明名称、描述与主色 Seed -3. 不新增页面特判,确认预置可通过同一 `resolveTheme()` 派生 +2. 在 `themeColorPresets` 声明名称、描述与主色 Seed +3. 不新增页面特判,确认预置可通过同一 `createTheme()` 派生 4. 在浅色、深色和系统模式下检查文本、浮层、Input、表格与图表 ### 增加全局 Seed 或 Alias diff --git a/frontend/package.json b/frontend/package.json index 9ddc437ac..5aaeb181d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -17,7 +17,7 @@ }, "dependencies": { "@boxicons/vue": "1.0.1", - "@codex-proxy/ui": "github:zyycn/codex-proxy-ui#v0.7.0", + "@codex-proxy/ui": "github:zyycn/codex-proxy-ui#v0.8.0", "@fontsource-variable/inter": "^5.3.0", "@fontsource-variable/jetbrains-mono": "^5.3.0", "@lucide/vue": "^1.61.0", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 956fd02c7..a8671814a 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -195,8 +195,8 @@ importers: specifier: 1.0.1 version: 1.0.1(vue@3.5.44(typescript@6.0.3)) '@codex-proxy/ui': - specifier: github:zyycn/codex-proxy-ui#v0.7.0 - version: https://codeload.github.com/zyycn/codex-proxy-ui/tar.gz/0692ca034be88de6faf88bc76f1a6e9e7ad65225(axios@1.20.0(debug@4.4.3))(change-case@5.4.4)(vite@8.3.5(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.0))(vue@3.5.44(typescript@6.0.3)) + specifier: github:zyycn/codex-proxy-ui#v0.8.0 + version: https://codeload.github.com/zyycn/codex-proxy-ui/tar.gz/d6100447010715c1203e67a4195fc6d875ff6249(axios@1.20.0(debug@4.4.3))(change-case@5.4.4)(jiti@2.7.0)(postcss@8.5.30)(vite@8.3.5(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.0))(vue@3.5.44(typescript@6.0.3))(yaml@2.9.0) '@fontsource-variable/inter': specifier: ^5.3.0 version: 5.3.0 @@ -443,9 +443,9 @@ packages: resolution: {integrity: sha512-dlT1m5e/0yUL0kRNcQn7yGLVThkgbB0Ga/1AmfDDC/8ik6AIiSf2QLQO2zPYvefsHP0aFgxO93cVLCCfDp7kzQ==} engines: {node: '>= 20.12.0'} - '@codex-proxy/ui@https://codeload.github.com/zyycn/codex-proxy-ui/tar.gz/0692ca034be88de6faf88bc76f1a6e9e7ad65225': - resolution: {gitHosted: true, integrity: sha512-JJesyJ1Y/QcdXhBtmKX6k0GyUgOSxiV8sJrUymvLyKjC8NhHLmtpXWt/evZcjYBDyJEIRll85bmSmtMF9/Wpqw==, tarball: https://codeload.github.com/zyycn/codex-proxy-ui/tar.gz/0692ca034be88de6faf88bc76f1a6e9e7ad65225} - version: 0.7.0 + '@codex-proxy/ui@https://codeload.github.com/zyycn/codex-proxy-ui/tar.gz/d6100447010715c1203e67a4195fc6d875ff6249': + resolution: {gitHosted: true, integrity: sha512-XNPErDXqq9OxvgLgSb0gVRGmI9Yf+Vx0dTjoZKzaAaCOX9exSirU5kEr9mJBeuo9E1DDw8817xV0B5Od9zH+5A==, tarball: https://codeload.github.com/zyycn/codex-proxy-ui/tar.gz/d6100447010715c1203e67a4195fc6d875ff6249} + version: 0.8.0 engines: {node: '>=24'} peerDependencies: vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -2618,6 +2618,10 @@ packages: resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==} engines: {node: '>= 12.0.0'} + lilconfig@3.1.4: + resolution: {integrity: sha512-zJZyBmQhArDRefuWTypZxwDpFDIYmrj8ypSBvwGD5P13Y95s6DjzKgu4DVdGbeQa5PDEsAOCAPNk4X+QOR006w==} + engines: {node: '>=14'} + local-pkg@1.2.1: resolution: {integrity: sha512-++gUqRDEvcnN6Zhqrr+y/CkVEHhlrR96vZn3nZZPYzMcBUyBtTKzB9NadClFIsIVSsu+3i9tfk/erqy9kAmt7Q==} engines: {node: '>=14'} @@ -2645,6 +2649,11 @@ packages: markdown-table@3.0.4: resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + marked-alert@2.1.2: + resolution: {integrity: sha512-EFNRZ08d8L/iEIPLTlQMDjvwIsj03gxWCczYTht6DCiHJIZhMk4NK5gtPY9UqAYb09eV5VGT+jD4lp396E0I+w==} + peerDependencies: + marked: '>=7.0.0' + marked@18.1.0: resolution: {integrity: sha512-PamYXWWWg2nboG3oX5Ffzpy3EFZROqZJK9hSlMmUnekp7TxPs5DcT95vwd46m73/exfKCRVMtgXoPMI4FEJL6w==} engines: {node: '>= 20'} @@ -2973,6 +2982,24 @@ packages: pnpm-workspace-yaml@1.9.1: resolution: {integrity: sha512-Xj/T2X6DNAWbtk/9UQ0/TJRswltiHZevmcMjqoL7WrpJi67lu3qaslU4+I+zJ8wtwqmuvAE0KkB8rbv2ZdogBg==} + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + postcss-selector-parser@7.1.6: resolution: {integrity: sha512-7qASPzhKF2l2KLboRZux8CCTRMdGiV08vWmyKzPz22qZ7ZjQBOeY7rNzNoCLSUiftJ7HUq0GERHmxw/t0dCdMw==} engines: {node: '>=4'} @@ -3525,7 +3552,7 @@ snapshots: fast-wrap-ansi: 0.2.2 sisteransi: 1.0.5 - '@codex-proxy/ui@https://codeload.github.com/zyycn/codex-proxy-ui/tar.gz/0692ca034be88de6faf88bc76f1a6e9e7ad65225(axios@1.20.0(debug@4.4.3))(change-case@5.4.4)(vite@8.3.5(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.0))(vue@3.5.44(typescript@6.0.3))': + '@codex-proxy/ui@https://codeload.github.com/zyycn/codex-proxy-ui/tar.gz/d6100447010715c1203e67a4195fc6d875ff6249(axios@1.20.0(debug@4.4.3))(change-case@5.4.4)(jiti@2.7.0)(postcss@8.5.30)(vite@8.3.5(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.0))(vue@3.5.44(typescript@6.0.3))(yaml@2.9.0)': dependencies: '@ant-design/colors': 8.0.1 '@ant-design/fast-color': 3.0.1 @@ -3538,6 +3565,8 @@ snapshots: es-toolkit: 1.53.0 gsap: 3.15.0 marked: 18.1.0 + marked-alert: 2.1.2(marked@18.1.0) + postcss-load-config: 6.0.1(jiti@2.7.0)(postcss@8.5.30)(yaml@2.9.0) sortablejs: 1.15.7 vue: 3.5.44(typescript@6.0.3) optionalDependencies: @@ -3550,10 +3579,14 @@ snapshots: - focus-trap - fuse.js - idb-keyval + - jiti - jwt-decode - nprogress + - postcss - qrcode + - tsx - universal-cookie + - yaml '@dprint/formatter@0.5.1': {} @@ -5486,6 +5519,8 @@ snapshots: lightningcss-win32-arm64-msvc: 1.33.0 lightningcss-win32-x64-msvc: 1.33.0 + lilconfig@3.1.4: {} + local-pkg@1.2.1: dependencies: mlly: 1.8.2 @@ -5514,6 +5549,10 @@ snapshots: markdown-table@3.0.4: {} + marked-alert@2.1.2(marked@18.1.0): + dependencies: + marked: 18.1.0 + marked@18.1.0: {} math-intrinsics@1.1.0: {} @@ -6053,6 +6092,14 @@ snapshots: dependencies: yaml: 2.9.0 + postcss-load-config@6.0.1(jiti@2.7.0)(postcss@8.5.30)(yaml@2.9.0): + dependencies: + lilconfig: 3.1.4 + optionalDependencies: + jiti: 2.7.0 + postcss: 8.5.30 + yaml: 2.9.0 + postcss-selector-parser@7.1.6: dependencies: cssesc: 3.0.0 diff --git a/frontend/src/components/AccountGroupCheckboxGrid.vue b/frontend/src/components/AccountGroupCheckboxGrid.vue index c62488f8f..c44e6e42c 100644 --- a/frontend/src/components/AccountGroupCheckboxGrid.vue +++ b/frontend/src/components/AccountGroupCheckboxGrid.vue @@ -35,7 +35,7 @@ function updateGroup(groupId: string, selected: boolean) {
@@ -46,10 +46,10 @@ function updateGroup(groupId: string, selected: boolean) { @update:model-value="updateGroup(group.id, $event)" /> - {{ t('common.status.disabled') }} + {{ t('common.status.disabled') }}
-

+

{{ loading ? t('groups.selector.loading') : t('groups.selector.empty') }}

diff --git a/frontend/src/components/AccountGroupMarks.vue b/frontend/src/components/AccountGroupMarks.vue index 026034bd3..7dd6cc735 100644 --- a/frontend/src/components/AccountGroupMarks.vue +++ b/frontend/src/components/AccountGroupMarks.vue @@ -32,5 +32,5 @@ const fullNames = computed(() => :title="group.name" /> - — + — diff --git a/frontend/src/components/ApiKeyConfigModal.vue b/frontend/src/components/ApiKeyConfigModal.vue index a214aafc2..960fa6a1f 100644 --- a/frontend/src/components/ApiKeyConfigModal.vue +++ b/frontend/src/components/ApiKeyConfigModal.vue @@ -79,10 +79,10 @@ function importToClient() { /> -
+
{{ configPath }} @@ -96,9 +96,9 @@ function importToClient() {
-
+
           
diff --git a/frontend/src/components/AppBrandMark.vue b/frontend/src/components/AppBrandMark.vue index 678e79fed..d3ba648c5 100644 --- a/frontend/src/components/AppBrandMark.vue +++ b/frontend/src/components/AppBrandMark.vue @@ -12,7 +12,7 @@ const mistGradientId = `${id}-brand-mist` -