diff --git a/doc/project/01-需求文档/~$规格说明书v1.3.docx b/doc/project/01-需求文档/~$规格说明书v1.3.docx new file mode 100644 index 0000000..984a40e Binary files /dev/null and b/doc/project/01-需求文档/~$规格说明书v1.3.docx differ diff --git a/src/README.md b/src/README.md deleted file mode 100644 index b51ab8d..0000000 --- a/src/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# 源代码模块说明 - -占位内容:后续补充各子模块结构、构建与运行说明。 diff --git a/src/frontend/.gitignore b/src/frontend/.gitignore index a547bf3..a57524f 100644 --- a/src/frontend/.gitignore +++ b/src/frontend/.gitignore @@ -22,3 +22,7 @@ dist-ssr *.njsproj *.sln *.sw? + + +repomix-output.xml +node_modules \ No newline at end of file diff --git a/src/frontend/README.md b/src/frontend/README.md index 5da2aae..1511959 100644 --- a/src/frontend/README.md +++ b/src/frontend/README.md @@ -1,516 +1,5 @@ -# Museguard Platform (Frontend) +# Vue 3 + Vite -这是一个基于 **Vue 3 + Vite** 构建的现代化前端项目,旨在提供一套完整的 **图像隐私防护与效果评估** 解决方案。 +This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 ` + + + + + +{ + "name": "museguard", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "repomix": "^1.9.2", + "vue": "^3.5.24", + "vue-router": "^4.6.3" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^6.0.1", + "vite": "^7.2.4" + } +} + + + +# Vue 3 + Vite + +This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 ` + + + + + + + + + + + + + + + + + + + + + + + +import { createApp } from 'vue' +import './style.css' +import App from './App.vue' +import router from './router' + +const app = createApp(App) +app.use(router) +app.mount('#app') + + + +import { createRouter, createWebHistory } from 'vue-router' + +const router = createRouter({ + history: createWebHistory(), + routes: [ + { + path: '/login', + name: 'Login', + component: () => import('../views/LoginView.vue') + }, + { + path: '/', + name: 'Main', + component: () => import('../views/MainFlow.vue'), + children: [ + // 子页面路由 - 按主页面分组 + { + path: 'home/PrincipleDiagram', + name: 'PrincipleDiagram', + component: () => import('../views/home/subpages/PrincipleDiagram.vue'), + meta: { parent: 'home' } + }, + { + path: 'home/SamplePreview', + name: 'SamplePreview', + component: () => import('../views/home/subpages/SamplePreview.vue'), + meta: { parent: 'home' } + }, + { + path: 'home/PaperSupport', + name: 'PaperSupport', + component: () => import('../views/home/subpages/PaperSupport.vue'), + meta: { parent: 'home' } + }, + { + path: 'page1/UniversalMode', + name: 'UniversalMode', + component: () => import('../views/Page1/subpages/UniversalMode.vue'), + meta: { parent: 'page1' } + }, + { + path: 'page1/QuickMode', + name: 'QuickMode', + component: () => import('../views/Page1/subpages/QuickMode.vue'), + meta: { parent: 'page1' } + }, + { + path: 'page2/:subpage', + name: 'Page2Sub', + component: () => import('../views/Page2/subpages/SubpageContainer.vue'), + meta: { parent: 'page2' } + }, + { + path: 'page3/:subpage', + name: 'Page3Sub', + component: () => import('../views/Page3/subpages/SubpageContainer.vue'), + meta: { parent: 'page3' } + }, + { + path: 'page4/:subpage', + name: 'Page4Sub', + component: () => import('../views/Page4/subpages/SubpageContainer.vue'), + meta: { parent: 'page4' } + }, + { + path: 'page5/:subpage', + name: 'Page5Sub', + component: () => import('../views/Page5/subpages/SubpageContainer.vue'), + meta: { parent: 'page5' } + } + ] + } + ] +}) + +export default router + + + +/* ===== Global CSS Variables ===== */ +:root { + /* Fonts */ + + --font-family: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", sans-serif; + --font-base: clamp(14px, 1.5vw, 18px); + --font-weight-base: 500; + + + /* Space Units */ + --space-unit: clamp(4px, 0.5vw, 8px); + --space-xs: calc(var(--space-unit) * 1); + --space-sm: calc(var(--space-unit) * 2); + --space-md: calc(var(--space-unit) * 4); + --space-lg: calc(var(--space-unit) * 8); + --space-xl: calc(var(--space-unit) * 16); + + /* Dimensions */ + /* Navbar: Adjusted to be narrower as per image/request hint, but expandable */ + --navbar-width: 260px; + --navbar-width-min: 80px; + --navbar-height-pct: 75%; /* 15% top to 75% height */ + + /* Colors - Updated Palette */ + /* 60% Light Grey/Beige */ + --color-bg-primary: #F0EFEB; + --color-bg-secondary: #EBE9E4; + + /* 30% Yellow/Orange (Accent) */ + --color-accent-mild: #d1c9b7; + --color-accent-primary: #FFD166; + --color-accent-secondary: #FF9F1C; + + /* 10% Dark Blue/Black (Contrast) */ + --color-contrast-dark: #18283b; /* Dark Black/Blue */ + --color-contrast-light: #2c3e50; + + /* Text Colors */ + --color-text-main: #18283b; + --color-text-light: #f5f6fa; + --color-text-muted: #8392a5; + + /* Navbar Specifics (From your prompt) */ + --background: #F0EFEB; /* Matching main bg */ + --navbar-dark-primary: #18283b; + --navbar-dark-secondary: #2c3e50; + --navbar-light-primary: #f5f6fa; + --navbar-light-secondary: #8392a5; + + /* Animation Speeds */ + --transition-fast: 0.2s ease-out; + --transition-normal: 0.35s ease-out; + --transition-smooth: 0.5s cubic-bezier(0.4, 0, 0.2, 1); + + /* Z-Index */ + --z-nav: 100; + --z-close-btn: 110; + --z-subpage: 50; + --z-mainpage: 10; +} + +/* ===== Reset & Base ===== */ +*, *::before, *::after { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +html { + font-size: var(--font-base); + scroll-behavior: smooth; + background: var(--color-bg-primary); + color: var(--color-text-main); +} + +body { + font-family: var(--font-family); + line-height: 1.6; + overflow: hidden; /* Main flow handles scrolling */ + background: var(--color-bg-primary); +} + +/* Input selection */ +*:not(input):not(textarea) { user-select: none; -webkit-user-select: none; } +input, textarea { user-select: text; -webkit-user-select: text; } + +/* ===== UI Component: Cards ===== */ +/* Base Card */ +.ui-card { + position: relative; + border-radius: 24px; /* Medium rounded */ + transition: transform var(--transition-fast), box-shadow var(--transition-fast); + overflow: hidden; +} + +.ui-card.interactive { + cursor: pointer; +} + +.ui-card.interactive:hover { + transform: translateY(-4px); + box-shadow: 0 12px 24px rgba(0,0,0,0.1); +} + +/* Card Variants */ +.ui-card.glass { + background: rgba(255, 255, 255, 0.25); + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + border: 1px solid rgba(255, 255, 255, 0.3); +} + +.ui-card.solid { + background: #FFFFFF; + border: 1px solid rgba(0,0,0,0.05); +} + +.ui-card.gradient { + background: linear-gradient(135deg, var(--color-bg-secondary), #ffffff); +} + +/* Card Shapes */ +.ui-card.circle { border-radius: 50%; aspect-ratio: 1/1; display: flex; align-items: center; justify-content: center; } +.ui-card.rect { border-radius: 24px; } + +/* ===== UI Component: Buttons ===== */ +.ui-btn { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0.8em 1.6em; + font-weight: 600; + border: none; + cursor: pointer; + transition: all var(--transition-fast); + font-size: 1rem; + gap: 0.5em; +} + +.ui-btn:hover { + transform: scale(1.02); +} + +.ui-btn:active { + transform: scale(0.98); +} + +/* Button Variants */ +.ui-btn.glass { + background: rgba(24, 40, 59, 0.1); /* Using dark color but low opacity */ + backdrop-filter: blur(4px); + border: 1px solid rgba(24, 40, 59, 0.1); + color: var(--color-text-main); +} +.ui-btn.glass:hover { + background: rgba(24, 40, 59, 0.15); +} + +.ui-btn.solid { + background: var(--color-contrast-dark); + color: var(--color-text-light); +} +.ui-btn.solid:hover { + background: var(--color-contrast-light); + box-shadow: 0 4px 12px rgba(24, 40, 59, 0.3); +} + +.ui-btn.gradient { + background: linear-gradient(135deg, var(--color-accent-secondary), var(--color-accent-primary)); + color: var(--color-text-main); +} +.ui-btn.gradient:hover { + filter: brightness(1.1); + box-shadow: 0 4px 12px rgba(255, 159, 28, 0.4); +} + +/* Button Shapes */ +.ui-btn.rounded { border-radius: 999px; } +.ui-btn.rect { border-radius: 12px; } + + +/* ===== Layout Classes ===== */ +.layout-main { + display: flex; + width: 100vw; + height: 100vh; + position: relative; +} + +.layout-content { + /* Content pushed by nav is handled via margin or absolute positioning in components */ + flex: 1; + height: 100%; + position: relative; + margin-left: var(--navbar-width-min); /* Default collapsed state margin */ + transition: margin-left 0.2s; +} + +/* Waterfall Container */ +.scroll-container { + left:auto; + height: 100vh; + overflow-y: hidden; /* We control scroll manually for custom animation */ + position: relative; +} + +/* Sections */ +.scroll-section { + height: 100vh; + width: 100%; + position: absolute; + top: 0; + left: 0; + transition: transform 0.6s cubic-bezier(0.6, 0, 0.2, 1), opacity 0.4s ease; + opacity: 0; + pointer-events: none; + z-index: 1; + display: flex; /* Center content default */ + align-items: center; + justify-content: center; + padding: 2rem; +} + +.scroll-section.active { + opacity: 1; + pointer-events: auto; + z-index: 5; + transform: translateY(0); +} + +.scroll-section.prev { + transform: translateY(-100%); + opacity: 0; +} + +.scroll-section.next { + transform: translateY(100%); + opacity: 0; +} + +/* Subpage Wrapper */ +.subpage-wrapper { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: var(--z-subpage); + background: var(--color-bg-primary); /* Same as background */ + padding-left: var(--navbar-width-min); +} + +.subpage-enter-active, .subpage-leave-active { + transition: transform var(--transition-smooth), opacity var(--transition-smooth); +} +.subpage-enter-from, .subpage-leave-to { + transform: scale(0.95) translateY(20px); + opacity: 0; +} + +*, *::before, *::after { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +html { + font-size: var(--font-base); + scroll-behavior: smooth; + background: var(--color-bg-primary); + color: var(--color-text-main); +} + +body { + font-family: var(--font-family); + line-height: 1.6; + overflow: hidden; /* Main flow handles scrolling */ + background: var(--color-bg-primary); + /* 增加字距优化 */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +/* ===== Typography (Global Refactor) ===== */ + +/* Headings Shared Styles */ +h1, h2, h3, h4, h5, h6 { + font-family: var(--font-family); + color: var(--color-contrast-dark); + line-height: 1.2; + margin-bottom: 0.5em; + font-weight: 700; +} + +/* H1 - 用于主标题 (虽然你主要问的是 h2/h3/p,但统一规划更好) */ +h1 { + font-size: clamp(2rem, 4vw, 3.5rem); + letter-spacing: -0.02em; +} + +/* H2 - 用于页面级标题或大卡片标题 */ +h2 { + font-size: clamp(1.5rem, 2.5vw, 2.2rem); + font-weight: 600; + letter-spacing: -0.01em; + color: var(--color-text-main); + margin-bottom: var(--space-sm); +} + +/* H3 - 用于模块标题或卡片内部标题 */ +h3 { + font-size: clamp(1.2rem, 2vw, 1.5rem); + font-weight: 600; + color: var(--color-text-main); + margin-bottom: var(--space-xs); +} + +/* H4 - 用于小标题 */ +h4 { + font-size: 1.1rem; + font-weight: 600; + color: var(--color-text-muted); /* 稍微淡一点 */ +} + +/* Paragraphs - 正文 */ +p { + font-size: 1rem; + line-height: 1.65; /* 稍微增加行高提升可读性 */ + color: var(--color-text-main); /* 默认深色 */ + margin-bottom: 1em; + max-width: 65ch; /* 限制每行字数,提升阅读体验 */ +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [vue()], +}) + + + diff --git a/src/frontend/src/App.vue b/src/frontend/src/App.vue index 5da5610..9b1015e 100644 --- a/src/frontend/src/App.vue +++ b/src/frontend/src/App.vue @@ -1,39 +1,9 @@ - \ No newline at end of file + diff --git a/src/frontend/src/Style.css b/src/frontend/src/Style.css index 8b1888b..65e433f 100644 --- a/src/frontend/src/Style.css +++ b/src/frontend/src/Style.css @@ -1,587 +1,332 @@ -/* 变量与重置 */ +/* ===== Global CSS Variables ===== */ :root { - font-size: 16px; - --primary-color: #333; -} - -body { - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; - background-color: #f5f5f5; /* 全局默认背景 */ -} - -#app { - width: 100%; + /* Fonts */ + + --font-family: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", sans-serif; + --font-base: clamp(14px, 1.5vw, 18px); + --font-weight-base: 500; + + + /* Space Units */ + --space-unit: clamp(4px, 0.5vw, 8px); + --space-xs: calc(var(--space-unit) * 1); + --space-sm: calc(var(--space-unit) * 2); + --space-md: calc(var(--space-unit) * 4); + --space-lg: calc(var(--space-unit) * 8); + --space-xl: calc(var(--space-unit) * 16); + + /* Dimensions */ + /* Navbar: Adjusted to be narrower as per image/request hint, but expandable */ + --navbar-width: 260px; + --navbar-width-min: 80px; + --navbar-height-pct: 75%; /* 15% top to 75% height */ + + /* Colors - Updated Palette */ + /* 60% Light Grey/Beige */ + --color-bg-primary: #F0EFEB; + --color-bg-secondary: #EBE9E4; + + /* 30% Yellow/Orange (Accent) */ + --color-accent-mild: #d1c9b7; + --color-accent-primary: #FFD166; + --color-accent-secondary: #FF9F1C; + + /* 10% Dark Blue/Black (Contrast) */ + --color-contrast-dark: #18283b; /* Dark Black/Blue */ + --color-contrast-light: #2c3e50; + + /* Text Colors */ + --color-text-main: #18283b; + --color-text-light: #f5f6fa; + --color-text-muted: #8392a5; + + /* Navbar Specifics (From your prompt) */ + --background: #F0EFEB; /* Matching main bg */ + --navbar-dark-primary: #18283b; + --navbar-dark-secondary: #2c3e50; + --navbar-light-primary: #f5f6fa; + --navbar-light-secondary: #8392a5; + + /* Animation Speeds */ + --transition-fast: 0.2s ease-out; + --transition-normal: 0.35s ease-out; + --transition-smooth: 0.5s cubic-bezier(0.4, 0, 0.2, 1); + + /* Z-Index */ + --z-nav: 100; + --z-close-btn: 110; + --z-subpage: 50; + --z-mainpage: 10; +} + +/* ===== Reset & Base ===== */ +*, *::before, *::after { + box-sizing: border-box; margin: 0; padding: 0; } - -.std-input, .std-select { - padding: 0.8rem; - border: 1px solid #333; - font-size: 1.05rem; - width: 100%; - box-sizing: border-box; +html { + font-size: var(--font-base); + scroll-behavior: smooth; + background: var(--color-bg-primary); + color: var(--color-text-main); } - -/* ShareStyle.css - 六大页面通用样式库 */ -.shared-page-container { - min-height: 100vh; - /* 默认高度处理,适配有无 Navbar 的情况 */ - height: calc(100vh - 6rem); - background-color: #f5f5f5; /* 默认灰底 */ - display: flex; - flex-direction: column; /* 默认垂直排列,方便扩展 */ - align-items: center; /* 水平居中 */ - justify-content: center; /* 垂直居中 */ - position: relative; - width: 100%; - box-sizing: border-box; +body { + font-family: var(--font-family); + line-height: 1.6; + overflow: hidden; /* Main flow handles scrolling */ + background: var(--color-bg-primary); } +/* Input selection */ +*:not(input):not(textarea) { user-select: none; -webkit-user-select: none; } +input, textarea { user-select: text; -webkit-user-select: text; } - -/* --- 卡片网格布局--- */ -.shared-card-grid { - display: flex; - justify-content: center; - align-items: stretch; - gap: 2rem; /* 统一间距 */ - width: 90%; - max-width: 80rem; - padding: 0 2rem; - box-sizing: border-box; +/* ===== UI Component: Cards ===== */ +/* Base Card */ +.ui-card { + position: relative; + border-radius: 24px; /* Medium rounded */ + transition: transform var(--transition-fast), box-shadow var(--transition-fast); + overflow: hidden; } -/* --- 通用交互卡片 --- */ -.shared-card { - background: white; - border: 0.125rem solid #000; - padding: 1.5rem; - display: flex; - flex-direction: column; - align-items: center; - justify-content: space-between; - transition: transform 0.2s, box-shadow 0.2s; +.ui-card.interactive { cursor: pointer; - width: 18rem; - min-height: 25rem; } -.shared-card:hover { - transform: translateY(-0.3rem); - box-shadow: 0 0.5rem 1rem rgba(0,0,0,0.15); +.ui-card.interactive:hover { + transform: translateY(-4px); + box-shadow: 0 12px 24px rgba(0,0,0,0.1); } -.shared-card-title { - font-size: 1.4rem; - font-weight: bold; - margin-bottom: 1rem; - text-align: center; +/* Card Variants */ +.ui-card.glass { + background: rgba(255, 255, 255, 0.25); + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + border: 1px solid rgba(255, 255, 255, 0.3); } -.shared-card-content { - flex: 1; - width: 100%; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - text-align: center; - color: #555; - font-size: 0.95rem; +.ui-card.solid { + background: #FFFFFF; + border: 1px solid rgba(0,0,0,0.05); } -/* 卡片内的视觉占位区域 (灰色虚线框等) */ -.shared-card-visual { - flex: 1; - width: 100%; - margin-bottom: 1.5rem; - display: flex; - justify-content: center; - align-items: center; - border: 1px dashed #999; - background-color: #f9f9f9; - color: #555; - font-size: 0.9rem; +.ui-card.gradient { + background: linear-gradient(135deg, var(--color-bg-secondary), #ffffff); } -/* --- 操作按钮组 --- */ -.shared-action-group { - display: flex; - flex-direction: column; - gap: 0.8rem; - width: 100%; - align-items: center; -} +/* Card Shapes */ +.ui-card.circle { border-radius: 50%; aspect-ratio: 1/1; display: flex; align-items: center; justify-content: center; } +.ui-card.rect { border-radius: 24px; } -/* 通用按钮样式 */ -.shared-btn { - padding: 0.6rem 1rem; - font-size: 1.1rem; - cursor: pointer; - width: 100%; - border: 0.125rem solid #000; - background: white; - transition: all 0.2s; - text-align: center; -} - -.shared-btn:hover { - background: #f0f0f0; -} - -/* 实心/强调按钮 */ -.shared-btn-primary { - background: white; - font-weight: bold; -} -.shared-btn-primary:hover { - background: #000; - color: white; -} - -/* --- 模态框 (Modal) --- */ -.shared-modal-overlay { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-color: rgba(0, 0, 0, 0.5); - display: flex; - justify-content: center; +/* ===== UI Component: Buttons ===== */ +.ui-btn { + display: inline-flex; align-items: center; - z-index: 2000; -} - -.shared-modal-content { - background: white; - padding: 2rem; - border: 0.125rem solid #000; - border-radius: 0.5rem; - width: 30rem; - max-width: 90%; - text-align: center; - display: flex; - flex-direction: column; - gap: 1rem; -} - -.shared-modal-title { - margin: 0; - font-size: 1.5rem; -} - -.shared-modal-text { - color: #555; - line-height: 1.6; - text-align: left; -} - -.shared-modal-close-btn { - align-self: center; - padding: 0.5rem 2rem; - background: #333; - color: white; + justify-content: center; + padding: 0.8em 1.6em; + font-weight: 600; border: none; cursor: pointer; + transition: all var(--transition-fast); font-size: 1rem; - margin-top: 1rem; -} - -.shared-modal-close-btn:hover { - background: #000; + gap: 0.5em; } - -/* ========================================= - 1. 全局基础 (Global Base) - ========================================= */ -/* 所有页面通用的容器几何属性 (颜色和对齐方式由各页面自己决定) */ -.page-container { - height: calc(100vh - 6rem); - display: flex; - position: relative; - overflow: hidden; - width: 100%; - box-sizing: border-box; +.ui-btn:hover { + transform: scale(1.02); } -/* 通用返回按钮定位 */ -.back-btn-container { - position: fixed; /* 不随页面滚动 */ - top: 8rem; - left: 1rem; - z-index: 10; - width: 15rem; +.ui-btn:active { + transform: scale(0.98); } -/* 通用返回按钮样式 */ -.common-back-btn { - border: 0.125rem solid #000; - background: white; - padding: 0.625rem 2rem; - font-size: 1.1rem; - cursor: pointer; - text-align: center; - flex-shrink: 0; - width: 10rem; - box-sizing: border-box; - white-space: nowrap; - - /* 禁止文字选中 */ - user-select: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - -webkit-touch-callout: none; +/* Button Variants */ +.ui-btn.glass { + background: rgba(24, 40, 59, 0.1); /* Using dark color but low opacity */ + backdrop-filter: blur(4px); + border: 1px solid rgba(24, 40, 59, 0.1); + color: var(--color-text-main); } - - -.common-back-btn:hover { - background: #333; - color: white; +.ui-btn.glass:hover { + background: rgba(24, 40, 59, 0.15); } -.shared-back-link { - background: none; - border: none; - color: #333; - cursor: pointer; - font-size: 0.95rem; - padding: 0; +.ui-btn.solid { + background: var(--color-contrast-dark); + color: var(--color-text-light); } -.shared-back-link:hover { - text-decoration: underline; - color: #000; +.ui-btn.solid:hover { + background: var(--color-contrast-light); + box-shadow: 0 4px 12px rgba(24, 40, 59, 0.3); } -/* 页面标题 (通用) */ -.page-title { - text-align: center; - margin-bottom: 1.5rem; - font-size: 1.6rem; - font-weight: bold; +.ui-btn.gradient { + background: linear-gradient(135deg, var(--color-accent-secondary), var(--color-accent-primary)); + color: var(--color-text-main); } - -/* ========================================= - 2. 侧边栏任务系统 (Sidebar System) - 共用于: ev, gen, topic - ========================================= */ -.sidebar-placeholder { - width: 0; - flex-shrink: 0; +.ui-btn.gradient:hover { + filter: brightness(1.1); + box-shadow: 0 4px 12px rgba(255, 159, 28, 0.4); } -.task-card { - position: absolute; - top: 10rem; - left: 1.25rem; - width: 15rem; - background: white; - border: 0.125rem solid #000; - padding: 1rem; - display: flex; - flex-direction: column; - cursor: pointer; - transition: transform 0.2s, box-shadow 0.2s; - height: auto; - max-height: calc(100vh - 15rem); - box-sizing: border-box; - z-index: 10; -} - -.task-card:hover { - transform: translateY(-2px); - box-shadow: 0 4px 8px rgba(0,0,0,0.1); -} +/* Button Shapes */ +.ui-btn.rounded { border-radius: 999px; } +.ui-btn.rect { border-radius: 12px; } -.task-title { - font-size: 1.1rem; - text-align: center; - margin-bottom: 1rem; - border-bottom: 1px solid #eee; - padding-bottom: 0.5rem; -} -.task-list { - list-style: none; - padding: 0; - margin: 0; - flex: 1; - overflow-y: auto; -} - -.task-item { - margin-bottom: 1rem; - padding: 0.5rem; - border: 1px solid #ddd; - background: #fafafa; -} - -.task-header { +/* ===== Layout Classes ===== */ +.layout-main { display: flex; - justify-content: space-between; - margin-bottom: 0.5rem; - font-size: 0.9rem; -} - -.progress-bar-container { - height: 0.5rem; - background: #eee; - border-radius: 0.25rem; - overflow: hidden; + width: 100vw; + height: 100vh; + position: relative; } -.progress-bar { +.layout-content { + /* Content pushed by nav is handled via margin or absolute positioning in components */ + flex: 1; height: 100%; - background: #333; -} - -.task-footer { - margin-top: 1rem; - text-align: center; - font-size: 0.9rem; - color: #666; - border-top: 1px solid #eee; - padding-top: 0.5rem; + position: relative; + margin-left: var(--navbar-width-min); /* Default collapsed state margin */ + transition: margin-left 0.2s; } -/* ========================================= - 3. 主表单布局系统 (Main Form Layout) - 共用于: ev, gen, topic - ========================================= */ -.main-form-area { - flex: 1; - display: flex; - justify-content: center; - align-items: center; - margin-left: 19.25rem; - margin-right: 10rem; - height: 100%; - overflow-y: auto; +/* Waterfall Container */ +.scroll-container { + left:auto; + height: 100vh; + overflow-y: hidden; /* We control scroll manually for custom animation */ + position: relative; } -.form-container { - background: white; - border: 0.125rem solid #000; - padding: 3rem; +/* Sections */ +.scroll-section { + height: 100vh; width: 100%; - max-width: 90rem; - height: auto; - min-height: 60%; - display: flex; - flex-direction: column; + position: absolute; + top: 0; + left: 0; + transition: transform 0.6s cubic-bezier(0.6, 0, 0.2, 1), opacity 0.4s ease; + opacity: 0; + pointer-events: none; + z-index: 1; + display: flex; /* Center content default */ + align-items: center; justify-content: center; - gap: 2.5rem; - box-shadow: 0 0.5rem 1rem rgba(0,0,0,0.08); -} - -@media (min-width: 1600px) { - .form-container { - max-width: 95%; - } -} - -/* ========================================= - 4. 通用UI组件 (UI Components) - 共用于: 绝大多数页面 - ========================================= */ - -/* --- 4.1 表单元素 --- */ -.form-row { - display: flex; - gap: 2rem; - align-items: flex-start; -} - -.form-group { - flex: 1; - display: flex; - flex-direction: column; - gap: 0.75rem; -} - -.form-group label { - font-weight: bold; - font-size: 1.2rem; -} - -.std-input, .std-select { - padding: 0.8rem; - border: 1px solid #333; - font-size: 1.05rem; - width: 100%; - box-sizing: border-box; - outline: none; + padding: 2rem; } -.std-input:focus { - border-color: #000; - box-shadow: 0 0 0 1px #000; +.scroll-section.active { + opacity: 1; + pointer-events: auto; + z-index: 5; + transform: translateY(0); } -.hint-text { - font-size: 0.9rem; - color: #666; - margin-top: 0.2rem; +.scroll-section.prev { + transform: translateY(-100%); + opacity: 0; } -/* --- 4.2 单选组与VIP标签 --- */ -.radio-group { - display: flex; - gap: 2rem; - align-items: center; - height: 2.5rem; +.scroll-section.next { + transform: translateY(100%); + opacity: 0; } -.radio-group label { - font-weight: normal; - cursor: pointer; - display: flex; - align-items: center; - gap: 0.5rem; - font-size: 1.1rem; +/* Subpage Wrapper */ +.subpage-wrapper { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: var(--z-subpage); + background: var(--color-bg-primary); /* Same as background */ + padding-left: var(--navbar-width-min); } -.vip-option { - position: relative; - color: purple; - font-weight: bold !important; +.subpage-enter-active, .subpage-leave-active { + transition: transform var(--transition-smooth), opacity var(--transition-smooth); } - -.vip-tag { - background: purple; - color: white; - font-size: 0.7rem; - padding: 0.1rem 0.3rem; - border-radius: 4px; - margin-left: 0.3rem; +.subpage-enter-from, .subpage-leave-to { + transform: scale(0.95) translateY(20px); + opacity: 0; } -/* --- 4.3 按钮集合 --- */ -/* 底部大按钮 (ev, gen, topic) */ -.start-btn { - background: #333; - color: white; - border: none; - padding: 1rem 4rem; - font-size: 1.25rem; - cursor: pointer; - transition: background 0.2s, transform 0.1s; -} - -.start-btn:hover { - background: #000; - transform: translateY(-1px); +*, *::before, *::after { + box-sizing: border-box; + margin: 0; + padding: 0; } -/* 操作栏 (ev, gen, topic) */ -.action-row { - margin-top: auto; - justify-content: space-between; - align-items: center; - border-top: 1px solid #eee; - padding-top: 2rem; - display: flex; +html { + font-size: var(--font-base); + scroll-behavior: smooth; + background: var(--color-bg-primary); + color: var(--color-text-main); } -/* 小操作按钮 (列表页用) */ -.action-btn { - padding: 0.4rem 0.8rem; - border: 1px solid #000; - background: #fff; - cursor: pointer; - font-size: 0.9rem; - min-width: 5rem; - text-align: center; +body { + font-family: var(--font-family); + line-height: 1.6; + overflow: hidden; /* Main flow handles scrolling */ + background: var(--color-bg-primary); + /* 增加字距优化 */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } -.action-btn:hover { background: #f0f0f0; } -/* 资源选择/上传按钮 */ -.source-btn, .upload-btn { - border: 1px solid #333; - background: #eaf4ff; /* source-btn默认 */ - padding: 0.8rem 1.5rem; - cursor: pointer; - color: #0056b3; - font-weight: bold; - text-align: left; - font-size: 1.05rem; - transition: all 0.2s; -} -.upload-btn { background: #f0f0f0; color: #333; } /* upload-btn 覆盖 */ +/* ===== Typography (Global Refactor) ===== */ -.source-btn:hover, .upload-btn:hover { - box-shadow: 0 2px 5px rgba(0,0,0,0.1); - filter: brightness(0.95); +/* Headings Shared Styles */ +h1, h2, h3, h4, h5, h6 { + font-family: var(--font-family); + color: var(--color-contrast-dark); + line-height: 1.2; + margin-bottom: 0.5em; + font-weight: 700; } -/* --- 4.4 其他通用组件 --- */ -/* 文件名显示 */ -.file-name { - font-size: 0.95rem; - color: #555; - font-style: italic; +/* H1 - 用于主标题 (虽然你主要问的是 h2/h3/p,但统一规划更好) */ +h1 { + font-size: clamp(2rem, 4vw, 3.5rem); + letter-spacing: -0.02em; } -/* 数据集/状态概况条 */ -.dataset-summary { - font-size: 1rem; - color: #333; - background: #f6f8fb; - border: 1px solid #e0e6f0; - padding: 1rem 1.25rem; - border-radius: 0.4rem; - margin-top: 0.5rem; -} -.dataset-summary .highlight { - display: inline-block; - margin: 0 0.3rem; - padding: 0.1rem 0.5rem; - background: #111; - color: #fff; - border-radius: 0.3rem; - font-weight: bold; -} - -/* 模态框遮罩 */ -.modal-overlay, .shared-modal-overlay { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-color: rgba(0, 0, 0, 0.5); - display: flex; - justify-content: center; - align-items: center; - z-index: 2000; +/* H2 - 用于页面级标题或大卡片标题 */ +h2 { + font-size: clamp(1.5rem, 2.5vw, 2.2rem); + font-weight: 600; + letter-spacing: -0.01em; + color: var(--color-text-main); + margin-bottom: var(--space-sm); } -/* 上传区域容器 */ -.upload-section { - display: flex; - align-items: center; - gap: 1rem; +/* H3 - 用于模块标题或卡片内部标题 */ +h3 { + font-size: clamp(1.2rem, 2vw, 1.5rem); + font-weight: 600; + color: var(--color-text-main); + margin-bottom: var(--space-xs); } -/* 列表滚动容器 (res) */ -.content-scroll-wrapper { - flex: 1; - overflow-y: auto; - display: flex; - flex-direction: column; - gap: 1rem; - padding-right: 0.5rem; +/* H4 - 用于小标题 */ +h4 { + font-size: 1.1rem; + font-weight: 600; + color: var(--color-text-muted); /* 稍微淡一点 */ } -/* 空状态 */ -.empty-hint, .empty-row { - text-align: center; - color: #999; +/* Paragraphs - 正文 */ +p { font-size: 1rem; + line-height: 1.65; /* 稍微增加行高提升可读性 */ + color: var(--color-text-main); /* 默认深色 */ + margin-bottom: 1em; + max-width: 65ch; /* 限制每行字数,提升阅读体验 */ } \ No newline at end of file diff --git a/src/frontend/src/components/Button.vue b/src/frontend/src/components/Button.vue new file mode 100644 index 0000000..b296620 --- /dev/null +++ b/src/frontend/src/components/Button.vue @@ -0,0 +1,52 @@ + + + + + \ No newline at end of file diff --git a/src/frontend/src/components/NavBar.vue b/src/frontend/src/components/NavBar.vue index 263f62d..fc4318a 100644 --- a/src/frontend/src/components/NavBar.vue +++ b/src/frontend/src/components/NavBar.vue @@ -1,81 +1,380 @@ - - - - - \ No newline at end of file diff --git a/src/frontend/src/components/TaskDetails.vue b/src/frontend/src/components/TaskDetails.vue deleted file mode 100644 index a1f5057..0000000 --- a/src/frontend/src/components/TaskDetails.vue +++ /dev/null @@ -1,169 +0,0 @@ - - - - - diff --git a/src/frontend/src/components/TaskSideBar.vue b/src/frontend/src/components/TaskSideBar.vue index dd2da5e..e46a746 100644 --- a/src/frontend/src/components/TaskSideBar.vue +++ b/src/frontend/src/components/TaskSideBar.vue @@ -1,25 +1,31 @@ @@ -28,19 +34,121 @@ import { computed } from 'vue' const props = defineProps({ - tasks: { - type: Array, - default: () => [] - }, - maxSlots: { - type: Number, - default: 5 - } + tasks: { type: Array, default: () => [] }, + maxSlots: { type: Number, default: 5 } }) -defineEmits(['back', 'details']) +const remainingSlots = computed(() => Math.max(0, props.maxSlots - props.tasks.length)) + -const remainingSlots = computed(() => { - return Math.max(0, props.maxSlots - props.tasks.length) -}) - \ No newline at end of file + \ No newline at end of file diff --git a/src/frontend/src/main.js b/src/frontend/src/main.js index 98feb02..e3a485c 100644 --- a/src/frontend/src/main.js +++ b/src/frontend/src/main.js @@ -1,6 +1,8 @@ import { createApp } from 'vue' -import './Style.css' +import './style.css' import App from './App.vue' import router from './router' -createApp(App).use(router).mount('#app') +const app = createApp(App) +app.use(router) +app.mount('#app') diff --git a/src/frontend/src/router/index.js b/src/frontend/src/router/index.js index 5c03a7d..e990a91 100644 --- a/src/frontend/src/router/index.js +++ b/src/frontend/src/router/index.js @@ -1,176 +1,77 @@ import { createRouter, createWebHistory } from 'vue-router' -const routes = [ - { - path: '/login', - name: 'Login', - component: () => import('../views/Login.vue'), - meta: { requiresAuth: false, hideNavBar: true } - }, - { - path: '/register', - name: 'Register', - component: () => import('../views/Register.vue'), - meta: { requiresAuth: false, hideNavBar: true } - }, - { - path: '/', - name: 'Home', - component: () => import('../views/Home.vue'), - meta: { requiresAuth: true, hideNavBar: false } - }, - { - path: '/principle', - name: 'PrincipleDiagram', - component: () => import('../views/home-subpages/PrincipleDiagram.vue'), - meta: { requiresAuth: true, hideNavBar: false } - }, - { - path: '/sample', - name: 'SamplePreview', - component: () => import('../views/home-subpages/SamplePreview.vue'), - meta: { requiresAuth: true, hideNavBar: false } - }, - { - path: '/paper', - name: 'PaperSupport', - component: () => import('../views/home-subpages/PaperSupport.vue'), - meta: { requiresAuth: true, hideNavBar: false } - }, - { - path: '/general-protection', - name: 'GeneralProtection', - component: () => import('../views/GeneralProtection.vue'), - meta: { requiresAuth: true, hideNavBar: false } - }, - { - path: '/universal-mode', - name: 'UniversalMode', - component: () => import('../views/general-protect-subpages/UniversalMode.vue'), - meta: { requiresAuth: true, hideNavBar: false } - }, - { - path: '/quick-mode', - name: 'QuickMode', - component: () => import('../views/general-protect-subpages/QuickMode.vue'), - meta: { requiresAuth: true, hideNavBar: false } - }, - { - path: '/topic-protection', - name: 'TopicProtection', - component: () => import('../views/TopicProtection.vue'), - meta: { requiresAuth: true, hideNavBar: false } - }, - { - path: '/topic-protection/style-transfer', - name: 'AntiStyleTransfer', - component: () => import('../views/topic-protect-subpages/AntiStyleTransfer.vue'), - meta: { requiresAuth: true, hideNavBar: false } - }, - { - path: '/effect-validation', - name: 'EffectValidation', - component: () => import('../views/EffectValidation.vue'), - meta: { requiresAuth: true, hideNavBar: false } - }, - { - path: '/effect-validation/fine-tuning', - name: 'FineTuning', - component: () => import('../views/effect-validate-subpages/FineTuning.vue'), - meta: { requiresAuth: true, hideNavBar: false } - }, - { - path: '/effect-validation/metrics', - name: 'MetricsComparison', - component: () => import('../views/effect-validate-subpages/MetricsComparison.vue'), - meta: { requiresAuth: true, hideNavBar: false } - }, - { - path: '/effect-validation/heatmap', - name: 'HeatmapComparison', - component: () => import('../views/effect-validate-subpages/HeatmapComparison.vue'), - meta: { requiresAuth: true, hideNavBar: false } - }, - { - path: '/my-resources', - name: 'MyResources', - component: () => import('../views/MyResources.vue'), - meta: { requiresAuth: true, hideNavBar: false } - }, - { - path: '/my-resources/tasks', - name: 'MyTaskResources', - component: () => import('../views/my-resources-subpages/MyTaskResources.vue'), - meta: { requiresAuth: true, hideNavBar: false } - }, - { - path: '/my-resources/protected-images', - name: 'ProtectedImages', - component: () => import('../views/my-resources-subpages/ProtectedImages.vue'), - meta: { requiresAuth: true, hideNavBar: false } - }, - { - path: '/my-resources/validation-results', - name: 'ValidationResults', - component: () => import('../views/my-resources-subpages/ValidationResults.vue'), - meta: { requiresAuth: true, hideNavBar: false } - }, - { - path: '/account', - name: 'Account', - component: () => import('../views/AccountCenter.vue'), - meta: { requiresAuth: true, hideNavBar: false } - }, - { - path: '/account/edit-profile', - name: 'EditProfile', - component: () => import('../views/account-center-subpages/EditProfile.vue'), - meta: { requiresAuth: true, hideNavBar: false } - }, - { - path: '/account/change-password', - name: 'ChangePassword', - component: () => import('../views/account-center-subpages/ChangePassword.vue'), - meta: { requiresAuth: true, hideNavBar: false } - }, - { - path: '/account/admin-users', - name: 'AdminUserManage', - component: () => import('../views/account-center-subpages/AdminUserManage.vue'), - meta: { requiresAuth: true, hideNavBar: false } - }, - { - path: '/account/config', - name: 'UserConfig', - component: () => import('../views/account-center-subpages/UserConfig.vue'), - meta: { requiresAuth: true, hideNavBar: false } - }, - { - path: '/task-details', - name: 'TaskDetails', - component: () => import('../components/TaskDetails.vue'), - meta: { requiresAuth: true, hideNavBar: false } - } -] - const router = createRouter({ history: createWebHistory(), - routes + routes: [ + { + path: '/login', + name: 'Login', + component: () => import('../views/LoginView.vue') + }, + { + path: '/', + name: 'Main', + component: () => import('../views/MainFlow.vue'), + children: [ + // 子页面路由 - 按主页面分组 + { + path: 'home/PrincipleDiagram', + name: 'PrincipleDiagram', + component: () => import('../views/home/subpages/PrincipleDiagram.vue'), + meta: { parent: 'home' } + }, + { + path: 'home/SamplePreview', + name: 'SamplePreview', + component: () => import('../views/home/subpages/SamplePreview.vue'), + meta: { parent: 'home' } + }, + { + path: 'home/PaperSupport', + name: 'PaperSupport', + component: () => import('../views/home/subpages/PaperSupport.vue'), + meta: { parent: 'home' } + }, + { + path: 'page1/UniversalMode', + name: 'UniversalMode', + component: () => import('../views/Page1/subpages/UniversalMode.vue'), + meta: { parent: 'page1' } + }, + { + path: 'page1/QuickMode', + name: 'QuickMode', + component: () => import('../views/Page1/subpages/QuickMode.vue'), + meta: { parent: 'page1' } + }, + { + path: 'page2/:subpage', + name: 'Page2Sub', + component: () => import('../views/Page2/subpages/SubpageContainer.vue'), + meta: { parent: 'page2' } + }, + { + path: 'page3/:subpage', + name: 'Page3Sub', + component: () => import('../views/Page3/subpages/SubpageContainer.vue'), + meta: { parent: 'page3' } + }, + { + path: 'page4/:subpage', + name: 'Page4Sub', + component: () => import('../views/Page4/subpages/SubpageContainer.vue'), + meta: { parent: 'page4' } + }, + { + path: 'page5/:subpage', + name: 'Page5Sub', + component: () => import('../views/Page5/subpages/SubpageContainer.vue'), + meta: { parent: 'page5' } + } + ] + } + ] }) +export default router -router.beforeEach((to, from, next) => { - const token = localStorage.getItem('access_token') - - const requiresAuth = to. meta.requiresAuth !== false - - if (requiresAuth && !token) { - next('/login') - } else if (token && (to.path === '/login' || to.path === '/register')) { - next('/') - } else { - next() - } -}) - -export default router \ No newline at end of file diff --git a/src/frontend/src/views/AccountCenter.vue b/src/frontend/src/views/AccountCenter.vue deleted file mode 100644 index d600417..0000000 --- a/src/frontend/src/views/AccountCenter.vue +++ /dev/null @@ -1,510 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/frontend/src/views/EffectValidation.vue b/src/frontend/src/views/EffectValidation.vue deleted file mode 100644 index 29f5550..0000000 --- a/src/frontend/src/views/EffectValidation.vue +++ /dev/null @@ -1,131 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/frontend/src/views/GeneralProtection.vue b/src/frontend/src/views/GeneralProtection.vue deleted file mode 100644 index e833a19..0000000 --- a/src/frontend/src/views/GeneralProtection.vue +++ /dev/null @@ -1,98 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/frontend/src/views/Home.vue b/src/frontend/src/views/Home.vue deleted file mode 100644 index d0e95e7..0000000 --- a/src/frontend/src/views/Home.vue +++ /dev/null @@ -1,106 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/frontend/src/views/Login.vue b/src/frontend/src/views/Login.vue deleted file mode 100644 index 6615a83..0000000 --- a/src/frontend/src/views/Login.vue +++ /dev/null @@ -1,94 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/frontend/src/views/LoginView.vue b/src/frontend/src/views/LoginView.vue new file mode 100644 index 0000000..3b140cd --- /dev/null +++ b/src/frontend/src/views/LoginView.vue @@ -0,0 +1,113 @@ + + + + + \ No newline at end of file diff --git a/src/frontend/src/views/MainFlow.vue b/src/frontend/src/views/MainFlow.vue new file mode 100644 index 0000000..0814a21 --- /dev/null +++ b/src/frontend/src/views/MainFlow.vue @@ -0,0 +1,339 @@ + + + + + \ No newline at end of file diff --git a/src/frontend/src/views/MyResources.vue b/src/frontend/src/views/MyResources.vue deleted file mode 100644 index 8c49401..0000000 --- a/src/frontend/src/views/MyResources.vue +++ /dev/null @@ -1,67 +0,0 @@ - - - - - diff --git a/src/frontend/src/views/Page1/Page1.vue b/src/frontend/src/views/Page1/Page1.vue new file mode 100644 index 0000000..445f653 --- /dev/null +++ b/src/frontend/src/views/Page1/Page1.vue @@ -0,0 +1,263 @@ + + + + + \ No newline at end of file diff --git a/src/frontend/src/views/Page1/subpages/QuickMode.vue b/src/frontend/src/views/Page1/subpages/QuickMode.vue new file mode 100644 index 0000000..474f5bb --- /dev/null +++ b/src/frontend/src/views/Page1/subpages/QuickMode.vue @@ -0,0 +1,390 @@ + + + + + \ No newline at end of file diff --git a/src/frontend/src/views/Page1/subpages/UniversalMode.vue b/src/frontend/src/views/Page1/subpages/UniversalMode.vue new file mode 100644 index 0000000..d961f88 --- /dev/null +++ b/src/frontend/src/views/Page1/subpages/UniversalMode.vue @@ -0,0 +1,409 @@ + + + + + \ No newline at end of file diff --git a/src/frontend/src/views/Page2/Page2.vue b/src/frontend/src/views/Page2/Page2.vue new file mode 100644 index 0000000..f5143c6 --- /dev/null +++ b/src/frontend/src/views/Page2/Page2.vue @@ -0,0 +1,146 @@ + + + + + \ No newline at end of file diff --git a/src/frontend/src/views/Page2/subpages/SubpageContainer.vue b/src/frontend/src/views/Page2/subpages/SubpageContainer.vue new file mode 100644 index 0000000..9f81b16 --- /dev/null +++ b/src/frontend/src/views/Page2/subpages/SubpageContainer.vue @@ -0,0 +1,261 @@ + + + + + \ No newline at end of file diff --git a/src/frontend/src/views/Page3/Page3.vue b/src/frontend/src/views/Page3/Page3.vue new file mode 100644 index 0000000..a367ef1 --- /dev/null +++ b/src/frontend/src/views/Page3/Page3.vue @@ -0,0 +1,164 @@ + + + + + \ No newline at end of file diff --git a/src/frontend/src/views/Page3/subpages/SubpageContainer.vue b/src/frontend/src/views/Page3/subpages/SubpageContainer.vue new file mode 100644 index 0000000..2d81f19 --- /dev/null +++ b/src/frontend/src/views/Page3/subpages/SubpageContainer.vue @@ -0,0 +1,261 @@ + + + + + \ No newline at end of file diff --git a/src/frontend/src/views/Page4/Page4.vue b/src/frontend/src/views/Page4/Page4.vue new file mode 100644 index 0000000..3801fe5 --- /dev/null +++ b/src/frontend/src/views/Page4/Page4.vue @@ -0,0 +1,165 @@ + + + + + \ No newline at end of file diff --git a/src/frontend/src/views/Page4/subpages/SubpageContainer.vue b/src/frontend/src/views/Page4/subpages/SubpageContainer.vue new file mode 100644 index 0000000..4c13688 --- /dev/null +++ b/src/frontend/src/views/Page4/subpages/SubpageContainer.vue @@ -0,0 +1,243 @@ + + + + + \ No newline at end of file diff --git a/src/frontend/src/views/Page5/Page5.vue b/src/frontend/src/views/Page5/Page5.vue new file mode 100644 index 0000000..3c41b01 --- /dev/null +++ b/src/frontend/src/views/Page5/Page5.vue @@ -0,0 +1,212 @@ + + + + + \ No newline at end of file diff --git a/src/frontend/src/views/Page5/subpages/SubpageContainer.vue b/src/frontend/src/views/Page5/subpages/SubpageContainer.vue new file mode 100644 index 0000000..e9741c1 --- /dev/null +++ b/src/frontend/src/views/Page5/subpages/SubpageContainer.vue @@ -0,0 +1,197 @@ + + + + + \ No newline at end of file diff --git a/src/frontend/src/views/Register.vue b/src/frontend/src/views/Register.vue deleted file mode 100644 index 59e291d..0000000 --- a/src/frontend/src/views/Register.vue +++ /dev/null @@ -1,83 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/frontend/src/views/TopicProtection.vue b/src/frontend/src/views/TopicProtection.vue deleted file mode 100644 index 62ae747..0000000 --- a/src/frontend/src/views/TopicProtection.vue +++ /dev/null @@ -1,122 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/frontend/src/views/account-center-subpages/AccountCenterStyleSub.css b/src/frontend/src/views/account-center-subpages/AccountCenterStyleSub.css deleted file mode 100644 index 3ccb27e..0000000 --- a/src/frontend/src/views/account-center-subpages/AccountCenterStyleSub.css +++ /dev/null @@ -1,102 +0,0 @@ -/* CommonStyle_acc.css - 管理与表单类页面特有样式 */ - -.page-container { - background-color: #4cc4bc8a; /* 特有背景色 */ - justify-content: center; /* 上下左右居中 */ - align-items: center; -} - -/* 中央内容卡片 (Account特有,比通用的 form-container 小) */ -.central-card { - background: white; - border: 0.125rem solid #000; - width: 40rem; - max-width: 95%; - padding: 2rem 3rem; - box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.1); - display: flex; - flex-direction: column; - box-sizing: border-box; -} - -/* 表单内部结构 (Account特有) */ -.form-body { - display: flex; - flex-direction: column; - gap: 1rem; -} - -.form-item { - display: flex; - flex-direction: column; - gap: 0.4rem; -} - -.form-item label { - font-size: 0.95rem; - color: #555; - font-weight: 500; -} - -/* 底部按钮区域 (Account特有) */ -.form-actions { - margin-top: 1.5rem; - text-align: center; -} - -/* 主按钮 (Account特有,尺寸稍小) */ -.primary-btn { - padding: 0.6rem 2.5rem; - border: 1px solid #000; - background: #fff; - cursor: pointer; - font-size: 1rem; - transition: background 0.2s; -} -.primary-btn:hover { background: #f5f5f5; } - -/* 管理表格通用样式 */ -.toolbar { - margin-bottom: 1rem; - display: flex; - justify-content: space-between; - align-items: center; -} - -.search-box { display: flex; gap: 0.5rem; } - -.search-btn { - padding: 0.5rem 1rem; - border: 1px solid #333; - background: #333; - color: white; - cursor: pointer; - font-size: 0.9rem; -} -.search-btn:hover { background: #444; } - -.table-wrapper { flex: 1; overflow-y: auto; } - -.std-table { - width: 100%; - border-collapse: collapse; - font-size: 0.9rem; -} - -.std-table th, .std-table td { - border: 1px solid #eee; - padding: 0.5rem 0.75rem; - text-align: left; -} -.std-table thead { background: #f5f5f5; } - -.link-btn { - border: none; - background: none; - color: #1976d2; - cursor: pointer; - margin-right: 0.5rem; - padding: 0; - font-size: 0.9rem; -} -.link-btn:hover { text-decoration: underline; } \ No newline at end of file diff --git a/src/frontend/src/views/account-center-subpages/AdminUserManage.vue b/src/frontend/src/views/account-center-subpages/AdminUserManage.vue deleted file mode 100644 index f862f49..0000000 --- a/src/frontend/src/views/account-center-subpages/AdminUserManage.vue +++ /dev/null @@ -1,432 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/frontend/src/views/account-center-subpages/ChangePassword.vue b/src/frontend/src/views/account-center-subpages/ChangePassword.vue deleted file mode 100644 index ada8b2d..0000000 --- a/src/frontend/src/views/account-center-subpages/ChangePassword.vue +++ /dev/null @@ -1,100 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/frontend/src/views/account-center-subpages/EditProfile.vue b/src/frontend/src/views/account-center-subpages/EditProfile.vue deleted file mode 100644 index 0543350..0000000 --- a/src/frontend/src/views/account-center-subpages/EditProfile.vue +++ /dev/null @@ -1,52 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/frontend/src/views/account-center-subpages/UserConfig.vue b/src/frontend/src/views/account-center-subpages/UserConfig.vue deleted file mode 100644 index 9f3b4ec..0000000 --- a/src/frontend/src/views/account-center-subpages/UserConfig.vue +++ /dev/null @@ -1,152 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/frontend/src/views/effect-validate-subpages/EffectValidSub.css b/src/frontend/src/views/effect-validate-subpages/EffectValidSub.css deleted file mode 100644 index a4db8cb..0000000 --- a/src/frontend/src/views/effect-validate-subpages/EffectValidSub.css +++ /dev/null @@ -1,62 +0,0 @@ -/* CommonStyle_ev.css - 效果验证页面特有样式 */ - -.page-container { - background-color: #f0f4f8; /* 特有背景色 */ -} - -/* 模态框内部结构 (EV特有) */ -.modal-content { - background: white; - padding: 2rem; - border: 0.125rem solid #000; - border-radius: 0.5rem; - width: 30rem; - max-width: 90%; - display: flex; - flex-direction: column; - gap: 1.5rem; -} - -.resource-list { - max-height: 20rem; - overflow-y: auto; - border: 1px solid #eee; -} - -.resource-item { - display: flex; - align-items: center; - padding: 0.8rem; - border-bottom: 1px solid #eee; - cursor: pointer; -} -.resource-item:hover { background: #f9f9f9; } -.resource-item.selected { background: #eaf4ff; border-left: 4px solid #0056b3; } - -.res-icon { - width: 3rem; - height: 3rem; - background: #ddd; - display: flex; - justify-content: center; - align-items: center; - font-size: 0.8rem; - margin-right: 1rem; -} - -.res-info { flex: 1; } -.res-name { font-weight: bold; font-size: 1rem; } -.res-date { font-size: 0.8rem; color: #888; } - -.modal-actions { - display: flex; - justify-content: flex-end; - gap: 1rem; -} - -.cancel-btn, .confirm-btn { - padding: 0.5rem 1.5rem; - cursor: pointer; -} -.cancel-btn { background: white; border: 1px solid #ccc; } -.confirm-btn { background: #333; color: white; border: none; } \ No newline at end of file diff --git a/src/frontend/src/views/effect-validate-subpages/FineTuning.vue b/src/frontend/src/views/effect-validate-subpages/FineTuning.vue deleted file mode 100644 index d09caa8..0000000 --- a/src/frontend/src/views/effect-validate-subpages/FineTuning.vue +++ /dev/null @@ -1,223 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/frontend/src/views/effect-validate-subpages/HeatmapComparison.vue b/src/frontend/src/views/effect-validate-subpages/HeatmapComparison.vue deleted file mode 100644 index 51b1008..0000000 --- a/src/frontend/src/views/effect-validate-subpages/HeatmapComparison.vue +++ /dev/null @@ -1,158 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/frontend/src/views/effect-validate-subpages/MetricsComparison.vue b/src/frontend/src/views/effect-validate-subpages/MetricsComparison.vue deleted file mode 100644 index 7ed9d0e..0000000 --- a/src/frontend/src/views/effect-validate-subpages/MetricsComparison.vue +++ /dev/null @@ -1,181 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/frontend/src/views/general-protect-subpages/GeneralProtectSub.css b/src/frontend/src/views/general-protect-subpages/GeneralProtectSub.css deleted file mode 100644 index 43ecbff..0000000 --- a/src/frontend/src/views/general-protect-subpages/GeneralProtectSub.css +++ /dev/null @@ -1,18 +0,0 @@ -/* CommonStyle_gen.css - 通用防护页面特有样式 */ - -.page-container { - background-color: #f0f4f8; /* 特有背景色 */ -} - -/* 模式标题与介绍 (Gen特有) */ -.mode-header { - font-size: 1.5rem; - margin: 0; -} - -.mode-intro { - color: #666; - margin-top: -1rem; - border-bottom: 1px solid #eee; - padding-bottom: 1rem; -} \ No newline at end of file diff --git a/src/frontend/src/views/general-protect-subpages/QuickMode.vue b/src/frontend/src/views/general-protect-subpages/QuickMode.vue deleted file mode 100644 index 143c101..0000000 --- a/src/frontend/src/views/general-protect-subpages/QuickMode.vue +++ /dev/null @@ -1,118 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/frontend/src/views/general-protect-subpages/UniversalMode.vue b/src/frontend/src/views/general-protect-subpages/UniversalMode.vue deleted file mode 100644 index 6f69a02..0000000 --- a/src/frontend/src/views/general-protect-subpages/UniversalMode.vue +++ /dev/null @@ -1,164 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/frontend/src/views/home-subpages/HomeSub.css b/src/frontend/src/views/home-subpages/HomeSub.css deleted file mode 100644 index 3ef57a8..0000000 --- a/src/frontend/src/views/home-subpages/HomeSub.css +++ /dev/null @@ -1,109 +0,0 @@ -/* CommonStyle_home.css - 翻页书本类页面特有样式 */ - -.page-container { - background-color: #f5f5f5; /* 特有背景色 */ - flex-direction: column; -} - -/* 书本整体布局 */ -.book-layout { - display: flex; - height: 100%; - align-items: center; - justify-content: center; - width: 100%; - padding-top: 3rem; - box-sizing: border-box; -} - -/* 导航条 */ -.nav-side { - width: 4rem; - height: 100%; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - cursor: pointer; - color: #555; - background-color: rgba(200, 200, 200, 0.1); - user-select: none; - transition: background-color 0.3s, opacity 0.3s; - flex-shrink: 0; -} -.nav-side:hover:not(.disabled) { background-color: rgba(200, 200, 200, 0.3); } -.nav-side.disabled { opacity: 0.3; cursor: not-allowed; } - -.arrow { font-size: 2rem; font-weight: bold; } -.hint { font-size: 0.9rem; margin-top: 0.5rem; } - -/* 中间内容页 */ -.content-page { - width: 85%; - height: auto; - aspect-ratio: 16 / 9; - max-height: 75vh; - background-color: white; - border: 0.125rem solid #333; - padding: 2.5rem; - box-shadow: 0 0.25rem 0.5rem rgba(0,0,0,0.1); - display: flex; - flex-direction: column; - position: relative; - margin: 0; - box-sizing: border-box; -} - -.page-content { - flex: 1; - display: flex; - flex-direction: column; - align-items: center; - width: 100%; - overflow-y: auto; -} - -.placeholder-content { - margin-top: 1rem; - text-align: center; - width: 100%; - display: flex; - flex-direction: column; - align-items: center; -} - -.mock-image-box { - width: 80%; - height: 18rem; - background-color: #eee; - border: 1px dashed #999; - margin: 1.5rem auto; - display: flex; - align-items: center; - justify-content: center; - color: #666; - font-size: 1.2rem; -} - -/* 底部分页器 */ -.pagination { - display: flex; - justify-content: center; - align-items: center; - gap: 0.8rem; - padding-top: 1rem; - margin-top: auto; - border-top: 1px solid #eee; - width: 100%; -} - -.dot { - color: #ccc; - font-size: 1.5rem; - cursor: pointer; - line-height: 1; - transition: color 0.2s; -} -.dot:hover { color: #999; } -.dot.active { color: #333; } -.page-text { margin-left: 1rem; color: #666; font-size: 0.9rem; } \ No newline at end of file diff --git a/src/frontend/src/views/home-subpages/PaperSupport.vue b/src/frontend/src/views/home-subpages/PaperSupport.vue deleted file mode 100644 index ba764d5..0000000 --- a/src/frontend/src/views/home-subpages/PaperSupport.vue +++ /dev/null @@ -1,65 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/frontend/src/views/home-subpages/PrincipleDiagram.vue b/src/frontend/src/views/home-subpages/PrincipleDiagram.vue deleted file mode 100644 index 3552f59..0000000 --- a/src/frontend/src/views/home-subpages/PrincipleDiagram.vue +++ /dev/null @@ -1,266 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/frontend/src/views/home-subpages/SamplePreview.vue b/src/frontend/src/views/home-subpages/SamplePreview.vue deleted file mode 100644 index 9ff0e21..0000000 --- a/src/frontend/src/views/home-subpages/SamplePreview.vue +++ /dev/null @@ -1,212 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/frontend/src/views/home/HomePage.vue b/src/frontend/src/views/home/HomePage.vue new file mode 100644 index 0000000..8246509 --- /dev/null +++ b/src/frontend/src/views/home/HomePage.vue @@ -0,0 +1,120 @@ + + + + + \ No newline at end of file diff --git a/src/frontend/src/views/home/subpages/PaperSupport.vue b/src/frontend/src/views/home/subpages/PaperSupport.vue new file mode 100644 index 0000000..f7ab06e --- /dev/null +++ b/src/frontend/src/views/home/subpages/PaperSupport.vue @@ -0,0 +1,73 @@ + + + + + \ No newline at end of file diff --git a/src/frontend/src/views/home/subpages/PrincipleDiagram.vue b/src/frontend/src/views/home/subpages/PrincipleDiagram.vue new file mode 100644 index 0000000..74419a0 --- /dev/null +++ b/src/frontend/src/views/home/subpages/PrincipleDiagram.vue @@ -0,0 +1,73 @@ + + + + + \ No newline at end of file diff --git a/src/frontend/src/views/home/subpages/SamplePreview.vue b/src/frontend/src/views/home/subpages/SamplePreview.vue new file mode 100644 index 0000000..0cccd47 --- /dev/null +++ b/src/frontend/src/views/home/subpages/SamplePreview.vue @@ -0,0 +1,73 @@ + + + + + \ No newline at end of file diff --git a/src/frontend/src/views/my-resources-subpages/MyResourcesSub.css b/src/frontend/src/views/my-resources-subpages/MyResourcesSub.css deleted file mode 100644 index f532af4..0000000 --- a/src/frontend/src/views/my-resources-subpages/MyResourcesSub.css +++ /dev/null @@ -1,61 +0,0 @@ -/* CommonStyle_res.css - 资源列表类页面特有样式 */ - -.page-container { - background-color: #de743fa1; /* 特有背景色 */ - justify-content: center; - align-items: center; -} - -/* 中心宽卡片容器 (Res特有) */ -.resource-card { - background: white; - border: 0.125rem solid #000; - width: 62rem; - max-width: 92%; - padding: 2rem; - box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.1); - height: 30rem; - display: flex; - flex-direction: column; - box-sizing: border-box; -} - -/* 通用列表行样式 (Res特有) */ -.list-row { - display: grid; - grid-template-columns: 2fr 2fr 1fr; - align-items: center; - border: 1px solid #ddd; - padding: 1rem 1.5rem; - min-height: 6rem; - box-sizing: border-box; - background: #fff; - transition: background 0.2s; -} -.list-row:hover { background: #fafafa; } - -/* 列样式 */ -.info-col { display: flex; flex-direction: column; gap: 0.3rem; } -.info-title { font-weight: bold; font-size: 1rem; } -.info-meta { font-size: 0.9rem; color: #666; } - -.preview-col { - justify-self: center; - width: 8rem; - height: 5rem; - border: 1px dashed #aaa; - display: flex; - align-items: center; - justify-content: center; - font-size: 0.85rem; - color: #777; - background: #f9f9f9; -} - -.actions-col { - display: flex; - flex-direction: column; - gap: 0.5rem; - justify-content: center; - align-items: flex-end; -} \ No newline at end of file diff --git a/src/frontend/src/views/my-resources-subpages/MyTaskResources.vue b/src/frontend/src/views/my-resources-subpages/MyTaskResources.vue deleted file mode 100644 index 771bc99..0000000 --- a/src/frontend/src/views/my-resources-subpages/MyTaskResources.vue +++ /dev/null @@ -1,185 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/frontend/src/views/my-resources-subpages/ProtectedImages.vue b/src/frontend/src/views/my-resources-subpages/ProtectedImages.vue deleted file mode 100644 index ede9660..0000000 --- a/src/frontend/src/views/my-resources-subpages/ProtectedImages.vue +++ /dev/null @@ -1,59 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/frontend/src/views/my-resources-subpages/ValidationResults.vue b/src/frontend/src/views/my-resources-subpages/ValidationResults.vue deleted file mode 100644 index 7e6e863..0000000 --- a/src/frontend/src/views/my-resources-subpages/ValidationResults.vue +++ /dev/null @@ -1,59 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/frontend/src/views/topic-protect-subpages/AntiStyleTransfer.vue b/src/frontend/src/views/topic-protect-subpages/AntiStyleTransfer.vue deleted file mode 100644 index 7a3d658..0000000 --- a/src/frontend/src/views/topic-protect-subpages/AntiStyleTransfer.vue +++ /dev/null @@ -1,122 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/frontend/src/views/topic-protect-subpages/TopicProtectSub.css b/src/frontend/src/views/topic-protect-subpages/TopicProtectSub.css deleted file mode 100644 index 24bcdce..0000000 --- a/src/frontend/src/views/topic-protect-subpages/TopicProtectSub.css +++ /dev/null @@ -1,17 +0,0 @@ -/* CommonStyle_topic.css - 专题防护类页面特有样式 */ - -.page-container { - background-color: #fffaf0; /* 特有背景色 */ -} - -/* 只读字段 (Topic特有) */ -.read-only-field { - padding: 0.8rem; - border: 1px dashed #999; - background: #f0f0f0; - color: #555; - font-size: 1rem; - font-style: italic; - width: 100%; - box-sizing: border-box; -} \ No newline at end of file diff --git a/src/frontend/vite.config.js b/src/frontend/vite.config.js index 41606f9..f4cf720 100644 --- a/src/frontend/vite.config.js +++ b/src/frontend/vite.config.js @@ -1,22 +1,21 @@ +// vite.config.js import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' -import path from 'path' +import path from 'path' // 记得引入 path -// https://vitejs.dev/config/ export default defineConfig({ plugins: [vue()], resolve: { alias: { - '@': path.resolve(__dirname, './src') // 确保 @ 指向 src 目录,方便引用 + '@': path.resolve(__dirname, './src') // 确保 @ 指向 src } }, server: { - port: 5173, // 前端开发服务器端口(默认) + port: 5173, proxy: { - // 代理配置核心:匹配 /api 开头的请求 '/api': { - target: 'http://127.0.0.1:6001', // SSH 隧道映射的后端地址 - changeOrigin: true, // 必须开启,欺骗后端这是本地请求 + target: 'http://127.0.0.1:6001', // 你的后端地址 + changeOrigin: true, } } }