From 091e3d2d05d4b92f5c10d25eb2f50a6fba799eb3 Mon Sep 17 00:00:00 2001 From: sion123 <450702724@qq.com> Date: Sat, 17 Jan 2026 19:33:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .claude/settings.local.json | 7 +- .../scripts/__pycache__/core.cpython-312.pyc | Bin 0 -> 10994 bytes docs/SQL建表语句.sql | 296 ++++++ frontend/app/web-gold/src/App.vue | 77 ++ .../src/components/GradientButton.vue | 3 - .../web-gold/src/components/SidebarNav.vue | 1 - .../web-gold/src/layouts/LayoutExamples.vue | 237 +++++ .../app/web-gold/src/layouts/MainLayout.vue | 2 +- frontend/app/web-gold/src/layouts/README.md | 297 ++++++ .../src/layouts/components/BasicLayout.vue | 125 +++ .../src/layouts/components/CardLayout.vue | 155 ++++ .../src/layouts/components/FormLayout.vue | 194 ++++ .../layouts/components/FullWidthLayout.vue | 122 +++ .../src/layouts/components/TabLayout.vue | 182 ++++ .../web-gold/src/layouts/components/index.js | 6 + frontend/app/web-gold/src/style.less | 55 +- .../src/views/content-style/Benchmark.vue | 63 +- .../components/BenchmarkTable.vue | 98 +- .../app/web-gold/src/views/dh/VoiceCopy.vue | 52 +- .../src/views/material/MaterialList.vue | 848 ------------------ .../src/views/material/MaterialListNew.vue | 30 +- .../web-gold/src/views/trends/Forecast.vue | 250 ++---- 22 files changed, 1871 insertions(+), 1229 deletions(-) create mode 100644 .claude/skills/ui-ux-pro-max/scripts/__pycache__/core.cpython-312.pyc create mode 100644 docs/SQL建表语句.sql create mode 100644 frontend/app/web-gold/src/layouts/LayoutExamples.vue create mode 100644 frontend/app/web-gold/src/layouts/README.md create mode 100644 frontend/app/web-gold/src/layouts/components/BasicLayout.vue create mode 100644 frontend/app/web-gold/src/layouts/components/CardLayout.vue create mode 100644 frontend/app/web-gold/src/layouts/components/FormLayout.vue create mode 100644 frontend/app/web-gold/src/layouts/components/FullWidthLayout.vue create mode 100644 frontend/app/web-gold/src/layouts/components/TabLayout.vue create mode 100644 frontend/app/web-gold/src/layouts/components/index.js delete mode 100644 frontend/app/web-gold/src/views/material/MaterialList.vue diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 67459dec40..71975880b0 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -53,7 +53,12 @@ "Skill(openspec:proposal:*)", "Bash(cmd /c:*)", "Bash(npx oxlint:*)", - "Bash(pnpm:*)" + "Bash(pnpm:*)", + "mcp__server-mysql__list_tables", + "mcp__server-mysql__connect_db", + "Skill(ui-ux-pro-max)", + "Skill(ui-ux-pro-max:*)", + "Bash(python:*)" ], "deny": [], "ask": [] diff --git a/.claude/skills/ui-ux-pro-max/scripts/__pycache__/core.cpython-312.pyc b/.claude/skills/ui-ux-pro-max/scripts/__pycache__/core.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..39222d1a1a3c3ecb12d460aeca65fae0ec40a040 GIT binary patch literal 10994 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 {}) text-align: center; display: flex; } + +.ant-select-selector { + background: var(--color-bg) !important; + border: 1px solid var(--color-border) !important; + border-radius: 4px !important; + transition: all 0.2s !important; + min-height: 32px !important; +} + +.ant-select-selection-item, +.ant-select-selection-placeholder { + line-height: 30px !important; + color: var(--color-text) !important; +} + +.ant-select-focused .ant-select-selector { + border-color: var(--color-primary) !important; + box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.1) !important; +} + +.ant-select:hover .ant-select-selector { + border-color: var(--color-primary) !important; +} + +.ant-select-arrow { + color: var(--color-text-secondary) !important; +} +.ant-modal .ant-modal-footer { + display: flex; +} diff --git a/frontend/app/web-gold/src/components/GradientButton.vue b/frontend/app/web-gold/src/components/GradientButton.vue index 455c344e63..a3cbbf4205 100644 --- a/frontend/app/web-gold/src/components/GradientButton.vue +++ b/frontend/app/web-gold/src/components/GradientButton.vue @@ -103,14 +103,11 @@ const buttonClass = computed(() => { cursor: pointer; transition: all 0.2s ease; background: var(--color-slate-900); - box-shadow: 0 10px 15px -3px rgba(59, 130, 246, 0.2), 0 4px 6px -2px rgba(59, 130, 246, 0.1); user-select: none; } .gradient-button:hover { background: var(--color-slate-800); - transform: translateY(-1px); - box-shadow: 0 20px 25px -5px rgba(59, 130, 246, 0.3), 0 10px 10px -5px rgba(59, 130, 246, 0.15); } .gradient-button:active { diff --git a/frontend/app/web-gold/src/components/SidebarNav.vue b/frontend/app/web-gold/src/components/SidebarNav.vue index 15a4c0397d..aa1cf75d4f 100644 --- a/frontend/app/web-gold/src/components/SidebarNav.vue +++ b/frontend/app/web-gold/src/components/SidebarNav.vue @@ -45,7 +45,6 @@ const items = computed(() => { children: [ { name: '素材列表', label: '素材列表', icon: 'grid' }, { name: '智能混剪', label: '智能混剪', icon: 'scissors' }, - { name: '素材分组', label: '素材分组', icon: 'folder' }, ] }, { diff --git a/frontend/app/web-gold/src/layouts/LayoutExamples.vue b/frontend/app/web-gold/src/layouts/LayoutExamples.vue new file mode 100644 index 0000000000..a68f616981 --- /dev/null +++ b/frontend/app/web-gold/src/layouts/LayoutExamples.vue @@ -0,0 +1,237 @@ + + + + + diff --git a/frontend/app/web-gold/src/layouts/MainLayout.vue b/frontend/app/web-gold/src/layouts/MainLayout.vue index 9689ad207d..660dbd4587 100644 --- a/frontend/app/web-gold/src/layouts/MainLayout.vue +++ b/frontend/app/web-gold/src/layouts/MainLayout.vue @@ -42,6 +42,6 @@ import SidebarNav from '@/components/SidebarNav.vue' .content-scroll { flex: 1 1 auto; overflow: auto; /* 右侧内容区域滚动 */ - padding: 0 16px 0 16px; + padding: 16px 0px 16px 16px; } diff --git a/frontend/app/web-gold/src/layouts/README.md b/frontend/app/web-gold/src/layouts/README.md new file mode 100644 index 0000000000..ead4b13832 --- /dev/null +++ b/frontend/app/web-gold/src/layouts/README.md @@ -0,0 +1,297 @@ +# 统一布局组件 + +为项目提供5种不同类型的布局组件,保持设计一致性和代码复用性。 + +## 布局组件类型 + +### 1. BasicLayout - 基础布局 +最通用的布局组件,适用于大多数页面。 + +**特点:** +- 标准页面头部(标题 + 副标题) +- 灵活的内容区域 +- 支持返回按钮和额外操作 + +**使用场景:** +- 列表页面 +- 详情页面 +- 数据统计页面 + +**示例:** +```vue + +``` + +### 2. CardLayout - 卡片布局 +内容包装在卡片中,提供更好的视觉层次。 + +**特点:** +- Ant Design Card 容器 +- 可配置的边距 +- 灵活的标题栏 + +**使用场景:** +- 表单页面 +- 配置页面 +- 详情展示页面 + +**示例:** +```vue + +``` + +### 3. TabLayout - 标签页布局 +多标签页内容组织。 + +**特点:** +- 动态标签页 +- 支持懒加载 +- 自定义标签页内容 + +**使用场景:** +- 设置页面 +- 数据对比 +- 多模块内容 + +**示例:** +```vue + + + +``` + +### 4. FullWidthLayout - 全宽布局 +充分利用屏幕宽度的布局。 + +**特点:** +- 全宽度内容 +- 自定义头部 +- 无卡片包装 + +**使用场景:** +- 数据可视化 +- 宽屏内容展示 +- 全屏应用 + +**示例:** +```vue + +``` + +### 5. FormLayout - 表单布局 +专门用于表单页面。 + +**特点:** +- 居中的表单容器 +- 内置提交/取消按钮 +- 加载状态管理 + +**使用场景:** +- 创建/编辑页面 +- 复杂表单 +- 向导式表单 + +**示例:** +```vue + +``` + +## 设计特色 + +### 1. 统一的设计语言 +- 使用项目的设计令牌(Design Tokens) +- 一致的颜色、字体、间距 +- Notion 风格的标签页设计 + +### 2. 响应式设计 +- 移动端友好 +- 自适应布局 +- 弹性内容区域 + +### 3. 可访问性 +- 语义化 HTML +- 键盘导航支持 +- 屏幕阅读器友好 + +### 4. 性能优化 +- 懒加载支持 +- keep-alive 兼容 +- 轻量级实现 + +## 导入方式 + +```javascript +// 单独导入 +import BasicLayout from '@/layouts/components/BasicLayout.vue' +import CardLayout from '@/layouts/components/CardLayout.vue' +import TabLayout from '@/layouts/components/TabLayout.vue' +import FullWidthLayout from '@/layouts/components/FullWidthLayout.vue' +import FormLayout from '@/layouts/components/FormLayout.vue' + +// 批量导入 +import { + BasicLayout, + CardLayout, + TabLayout, + FullWidthLayout, + FormLayout +} from '@/layouts/components' +``` + +## Props 说明 + +### 通用 Props + +| 属性 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| showBack | Boolean | false | 是否显示返回按钮 | +| title | String | '' | 页面标题 | +| subtitle | String | '' | 页面副标题 | + +### TabLayout 特有 Props + +| 属性 | 类型 | 必需 | 说明 | +|------|------|------|------| +| tabs | Array | 是 | 标签页配置数组 | +| activeKey | String | 否 | 当前激活的标签页 | + +### FormLayout 特有 Props + +| 属性 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| submitText | String | '提交' | 提交按钮文字 | +| cancelText | String | '取消' | 取消按钮文字 | +| showCancel | Boolean | true | 是否显示取消按钮 | +| submitLoading | Boolean | false | 提交按钮加载状态 | + +## 插槽(Slots) + +### 通用插槽 + +- `#extra` - 头部右侧额外操作区域 +- `#header` - 自定义头部内容(某些布局) + +### TabLayout 插槽 + +- `#tab1`, `#tab2`, ... - 标签页内容,名称为 tabs 中的 key + +## 事件(Events) + +### 通用事件 + +- `@back` - 点击返回按钮时触发 + +### TabLayout 事件 + +- `@change(key)` - 标签页切换时触发 + +### FormLayout 事件 + +- `@submit` - 点击提交按钮时触发 +- `@cancel` - 点击取消按钮时触发 + +## 最佳实践 + +1. **选择合适的布局** + - 简单内容 → BasicLayout + - 需要卡片容器 → CardLayout + - 多标签内容 → TabLayout + - 宽屏内容 → FullWidthLayout + - 表单页面 → FormLayout + +2. **保持一致性** + - 使用统一的设计令牌 + - 遵循项目的设计规范 + - 保持交互行为一致 + +3. **性能优化** + - 设置合适的 `forceRender` 属性 + - 使用 `keep-alive` 缓存组件 + - 避免不必要的重渲染 + +4. **可访问性** + - 为所有交互元素添加适当的标签 + - 确保键盘导航正常工作 + - 提供适当的焦点管理 diff --git a/frontend/app/web-gold/src/layouts/components/BasicLayout.vue b/frontend/app/web-gold/src/layouts/components/BasicLayout.vue new file mode 100644 index 0000000000..0589564f6c --- /dev/null +++ b/frontend/app/web-gold/src/layouts/components/BasicLayout.vue @@ -0,0 +1,125 @@ + + + + + diff --git a/frontend/app/web-gold/src/layouts/components/CardLayout.vue b/frontend/app/web-gold/src/layouts/components/CardLayout.vue new file mode 100644 index 0000000000..8845e8a428 --- /dev/null +++ b/frontend/app/web-gold/src/layouts/components/CardLayout.vue @@ -0,0 +1,155 @@ + + + + + diff --git a/frontend/app/web-gold/src/layouts/components/FormLayout.vue b/frontend/app/web-gold/src/layouts/components/FormLayout.vue new file mode 100644 index 0000000000..81ff17c468 --- /dev/null +++ b/frontend/app/web-gold/src/layouts/components/FormLayout.vue @@ -0,0 +1,194 @@ + + + + + diff --git a/frontend/app/web-gold/src/layouts/components/FullWidthLayout.vue b/frontend/app/web-gold/src/layouts/components/FullWidthLayout.vue new file mode 100644 index 0000000000..21cfb71813 --- /dev/null +++ b/frontend/app/web-gold/src/layouts/components/FullWidthLayout.vue @@ -0,0 +1,122 @@ + + + + + diff --git a/frontend/app/web-gold/src/layouts/components/TabLayout.vue b/frontend/app/web-gold/src/layouts/components/TabLayout.vue new file mode 100644 index 0000000000..877d928e51 --- /dev/null +++ b/frontend/app/web-gold/src/layouts/components/TabLayout.vue @@ -0,0 +1,182 @@ + + + + + diff --git a/frontend/app/web-gold/src/layouts/components/index.js b/frontend/app/web-gold/src/layouts/components/index.js new file mode 100644 index 0000000000..627b51137b --- /dev/null +++ b/frontend/app/web-gold/src/layouts/components/index.js @@ -0,0 +1,6 @@ +// 布局组件统一导出 +export { default as BasicLayout } from './BasicLayout.vue' +export { default as CardLayout } from './CardLayout.vue' +export { default as TabLayout } from './TabLayout.vue' +export { default as FullWidthLayout } from './FullWidthLayout.vue' +export { default as FormLayout } from './FormLayout.vue' diff --git a/frontend/app/web-gold/src/style.less b/frontend/app/web-gold/src/style.less index 6dd30fa1eb..679d5a60af 100644 --- a/frontend/app/web-gold/src/style.less +++ b/frontend/app/web-gold/src/style.less @@ -48,7 +48,7 @@ --color-gray-400: #9ca3af; --color-gray-700: #374151; - /* 主题设计令牌 */ + /* 主题设计令牌 - 现代化风格 */ --color-bg: var(--color-slate-50); --color-surface: #ffffff; --color-header: var(--color-slate-900); @@ -61,6 +61,24 @@ --color-primary: var(--color-blue-500); --color-primary-hover: var(--color-blue-600); + /* 新增:现代化的功能色 */ + --color-success: #10b981; + --color-success-bg: #ecfdf5; + --color-warning: #f59e0b; + --color-warning-bg: #fffbeb; + --color-error: #ef4444; + --color-error-bg: #fef2f2; + + /* 新增:Ant Design Vue 主题覆盖 */ + --ant-primary-color: var(--color-primary); + --ant-primary-color-hover: var(--color-primary-hover); + --ant-primary-color-active: var(--color-blue-700); + --ant-success-color: var(--color-success); + --ant-warning-color: var(--color-warning); + --ant-error-color: var(--color-error); + --ant-border-radius-base: var(--radius-button); + --ant-border-radius-sm: 4px; + /* 尺寸系统 */ --radius-card: 12px; --radius-button: 8px; @@ -81,6 +99,41 @@ --space-5: 20px; --space-6: 24px; --space-8: 32px; + + /* ================================ + Notion 风格设计变量 + ================================ */ + /* 极简配色 */ + --bg-primary: #ffffff; + --bg-secondary: #fafafa; + --bg-hover: #f7f6f3; + --bg-selected: #e9e9e7; + + /* 文字颜色 */ + --text-primary: #37352f; + --text-secondary: #787774; + --text-tertiary: #9b9a97; + --text-quaternary: #c1c0bd; + + /* 边框和分割线 */ + --border-light: #e9e9e7; + --border-medium: #d3d3d1; + --border-strong: #c1c0bd; + + /* 圆角 */ + --radius-none: 0; + --radius-sm: 3px; + --radius-md: 6px; + --radius-lg: 8px; + + /* 间距 */ + --space-xs: 4px; + --space-sm: 8px; + --space-md: 16px; + --space-lg: 24px; + --space-xl: 32px; + --space-2xl: 48px; + --space-3xl: 64px; } /* ================================ diff --git a/frontend/app/web-gold/src/views/content-style/Benchmark.vue b/frontend/app/web-gold/src/views/content-style/Benchmark.vue index b7f3dc9925..3154be4241 100644 --- a/frontend/app/web-gold/src/views/content-style/Benchmark.vue +++ b/frontend/app/web-gold/src/views/content-style/Benchmark.vue @@ -23,7 +23,6 @@ const promptStore = usePromptStore() const { data, selectedRowKeys, - expandedRowKeys, saveTableDataToSession, loadTableDataFromSession, processApiResponse, @@ -36,10 +35,9 @@ const { batchAnalyzeLoading, globalLoading, globalLoadingText, - analyzeVideo, batchAnalyze, getVoiceText, -} = useBenchmarkAnalysis(data, expandedRowKeys, saveTableDataToSession) +} = useBenchmarkAnalysis(data, saveTableDataToSession) // ==================== 表单状态 ==================== const form = ref({ @@ -110,8 +108,8 @@ async function handleExportToExcel() { return } - if (selectedRowKeys.value.length > 10) { - message.warning('最多只能导出10条数据,请重新选择') + if (selectedRowKeys.value.length > 20) { + message.warning('最多只能导出20条数据,请重新选择') return } @@ -189,26 +187,13 @@ async function handleResetForm() { await clearData() } -// ==================== 提示词操作函数 ==================== -function handleCopyPrompt(row) { - if (!row.prompt) { - message.warning('没有提示词可复制') - return - } - - navigator.clipboard.writeText(row.prompt).then(() => { - message.success('提示词已复制到剪贴板') - }).catch(() => { - message.error('复制失败') - }) -} - +// ==================== 批量提示词操作函数 ==================== function handleCopyBatchPrompt(prompt) { if (!prompt || !prompt.trim()) { message.warning('没有提示词可复制') return } - + navigator.clipboard.writeText(prompt).then(() => { message.success('提示词已复制到剪贴板') }).catch(() => { @@ -216,40 +201,25 @@ function handleCopyBatchPrompt(prompt) { }) } -// ==================== 创作相关函数 ==================== -function handleCreateContent(row) { - promptStore.setPrompt(row.prompt, row) - router.push('/content-style/copywriting') -} - function handleUseBatchPrompt(prompt) { if (!prompt || !prompt.trim()) { message.warning('暂无批量生成的提示词') return } - + promptStore.setPrompt(prompt, { batch: true }) router.push('/content-style/copywriting') } // ==================== 保存提示词到服务器 ==================== -function handleOpenSavePromptModal(row, batchPrompt = null) { - if (row) { - // 单个视频的提示词 - if (!row.prompt || !row.prompt.trim()) { - message.warning('没有提示词可保存') - return - } - savePromptContent.value = row.prompt - } else { - // 批量提示词:使用传入的 batchPrompt(AI 生成的内容),而不是原始的 mergedText - const promptToSave = batchPrompt || batchPromptMergedText.value - if (!promptToSave || !promptToSave.trim()) { - message.warning('没有提示词可保存') - return - } - savePromptContent.value = promptToSave +function handleOpenSavePromptModal(batchPrompt = null) { + // 批量提示词:使用传入的 batchPrompt(AI 生成的内容),而不是原始的 mergedText + const promptToSave = batchPrompt || batchPromptMergedText.value + if (!promptToSave || !promptToSave.trim()) { + message.warning('没有提示词可保存') + return } + savePromptContent.value = promptToSave savePromptModalVisible.value = true } @@ -277,14 +247,9 @@ defineOptions({ name: 'ContentStyleBenchmark' }) @@ -312,7 +277,7 @@ defineOptions({ name: 'ContentStyleBenchmark' }) :merged-text="batchPromptMergedText" :text-count="batchPromptTextCount" @copy="handleCopyBatchPrompt" - @save="(prompt) => handleOpenSavePromptModal(null, prompt)" + @save="(prompt) => handleOpenSavePromptModal(prompt)" @use="handleUseBatchPrompt" /> diff --git a/frontend/app/web-gold/src/views/content-style/components/BenchmarkTable.vue b/frontend/app/web-gold/src/views/content-style/components/BenchmarkTable.vue index eb39c2666e..4e7fe094d3 100644 --- a/frontend/app/web-gold/src/views/content-style/components/BenchmarkTable.vue +++ b/frontend/app/web-gold/src/views/content-style/components/BenchmarkTable.vue @@ -1,8 +1,6 @@