From 9d2c59212790b4315742eba2cd73901f3e9417b4 Mon Sep 17 00:00:00 2001 From: "fengchuanhn@gmail.com" Date: Fri, 15 May 2026 19:08:03 +0800 Subject: [PATCH] homevue --- src/components/AppSidebar.vue | 72 +++ src/components/dashboard/DashboardCard.vue | 48 ++ src/components/dashboard/StepBadge.vue | 9 + src/layouts/MainLayout.vue | 12 + src/main.js | 24 + src/router/index.js | 63 ++- src/styles/main.css | 251 +++++++++++ src/views/HomeView.vue | 484 +++++++++++++++++++-- src/views/PlaceholderView.vue | 14 + 9 files changed, 946 insertions(+), 31 deletions(-) create mode 100644 src/components/AppSidebar.vue create mode 100644 src/components/dashboard/DashboardCard.vue create mode 100644 src/components/dashboard/StepBadge.vue create mode 100644 src/layouts/MainLayout.vue create mode 100644 src/views/PlaceholderView.vue diff --git a/src/components/AppSidebar.vue b/src/components/AppSidebar.vue new file mode 100644 index 0000000..508b17d --- /dev/null +++ b/src/components/AppSidebar.vue @@ -0,0 +1,72 @@ + + + diff --git a/src/components/dashboard/DashboardCard.vue b/src/components/dashboard/DashboardCard.vue new file mode 100644 index 0000000..b998b8e --- /dev/null +++ b/src/components/dashboard/DashboardCard.vue @@ -0,0 +1,48 @@ + + + diff --git a/src/components/dashboard/StepBadge.vue b/src/components/dashboard/StepBadge.vue new file mode 100644 index 0000000..4fca5ad --- /dev/null +++ b/src/components/dashboard/StepBadge.vue @@ -0,0 +1,9 @@ + + + diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue new file mode 100644 index 0000000..760f425 --- /dev/null +++ b/src/layouts/MainLayout.vue @@ -0,0 +1,12 @@ + + + diff --git a/src/main.js b/src/main.js index 2087559..e6b1896 100644 --- a/src/main.js +++ b/src/main.js @@ -7,7 +7,19 @@ import InputText from "primevue/inputtext"; import Password from "primevue/password"; import Message from "primevue/message"; import Card from "primevue/card"; +import Select from "primevue/select"; +import Textarea from "primevue/textarea"; +import InputNumber from "primevue/inputnumber"; +import Slider from "primevue/slider"; +import Checkbox from "primevue/checkbox"; +import SelectButton from "primevue/selectbutton"; +import Tabs from "primevue/tabs"; +import TabList from "primevue/tablist"; +import Tab from "primevue/tab"; +import TabPanels from "primevue/tabpanels"; +import TabPanel from "primevue/tabpanel"; +import DashboardCard from "./components/dashboard/DashboardCard.vue"; import App from "./App.vue"; import router from "./router"; import "./styles/main.css"; @@ -31,5 +43,17 @@ app.component("InputText", InputText); app.component("Password", Password); app.component("Message", Message); app.component("Card", Card); +app.component("Select", Select); +app.component("Textarea", Textarea); +app.component("InputNumber", InputNumber); +app.component("Slider", Slider); +app.component("Checkbox", Checkbox); +app.component("SelectButton", SelectButton); +app.component("Tabs", Tabs); +app.component("TabList", TabList); +app.component("Tab", Tab); +app.component("TabPanels", TabPanels); +app.component("TabPanel", TabPanel); +app.component("DashboardCard", DashboardCard); app.mount("#app"); diff --git a/src/router/index.js b/src/router/index.js index b9e7bd5..fb3782a 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,12 +1,68 @@ import { createRouter, createWebHistory } from "vue-router"; import { useAuthStore } from "../stores/auth"; +const placeholder = () => import("../views/PlaceholderView.vue"); + const routes = [ { path: "/", - name: "home", - component: () => import("../views/HomeView.vue"), + component: () => import("../layouts/MainLayout.vue"), meta: { requiresAuth: true }, + children: [ + { + path: "", + name: "home", + component: () => import("../views/HomeView.vue"), + }, + { + path: "avatar", + name: "avatar", + component: placeholder, + meta: { title: "形象" }, + }, + { + path: "material", + name: "material", + component: placeholder, + meta: { title: "素材" }, + }, + { + path: "voice", + name: "voice", + component: placeholder, + meta: { title: "声音" }, + }, + { + path: "compose", + name: "compose", + component: placeholder, + meta: { title: "合成" }, + }, + { + path: "extract", + name: "extract", + component: placeholder, + meta: { title: "提取" }, + }, + { + path: "design", + name: "design", + component: placeholder, + meta: { title: "设计" }, + }, + { + path: "model", + name: "model", + component: placeholder, + meta: { title: "模型" }, + }, + { + path: "help", + name: "help", + component: placeholder, + meta: { title: "帮助" }, + }, + ], }, { path: "/login", @@ -31,8 +87,9 @@ const router = createRouter({ router.beforeEach((to) => { const auth = useAuthStore(); + const requiresAuth = to.matched.some((record) => record.meta.requiresAuth); - if (to.meta.requiresAuth && !auth.isAuthenticated) { + if (requiresAuth && !auth.isAuthenticated) { return { name: "login" }; } diff --git a/src/styles/main.css b/src/styles/main.css index 44d7d60..33d218d 100644 --- a/src/styles/main.css +++ b/src/styles/main.css @@ -102,3 +102,254 @@ body { .auth-link:hover { color: var(--color-accent-cyan); } + +.sidebar-nav { + display: flex; + flex-direction: column; + align-items: center; + width: 72px; + flex-shrink: 0; + padding: 12px 0; + gap: 4px; + background: #0a0c14; + border-right: 1px solid rgba(255, 255, 255, 0.06); +} + +.sidebar-item { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + width: 56px; + min-height: 56px; + padding: 8px 4px; + gap: 6px; + border-radius: 10px; + color: #94a3b8; + text-decoration: none; + transition: + color 0.2s, + background 0.2s, + box-shadow 0.2s; +} + +.sidebar-item:hover { + color: #e2e8f0; + background: rgba(255, 255, 255, 0.04); +} + +.sidebar-item--active { + color: #e2e8f0; + border: 1px solid rgba(0, 229, 255, 0.45); + background: rgba(0, 229, 255, 0.06); + box-shadow: 0 0 12px rgba(0, 229, 255, 0.08); +} + +.sidebar-icon { + display: flex; + align-items: center; + justify-content: center; + width: 24px; + height: 24px; +} + +.sidebar-icon svg { + width: 22px; + height: 22px; +} + +.sidebar-label { + font-size: 12px; + line-height: 1.2; + white-space: nowrap; +} + +.main-content { + background: + radial-gradient(ellipse 60% 40% at 50% 0%, rgba(0, 229, 255, 0.06), transparent), + var(--color-bg-base); +} + +/* 首页工作台 */ +.custom-scrollbar { + scrollbar-width: thin; + scrollbar-color: rgba(0, 229, 255, 0.25) transparent; +} + +.custom-scrollbar::-webkit-scrollbar { + width: 6px; + height: 6px; +} + +.custom-scrollbar::-webkit-scrollbar-thumb { + background: rgba(0, 229, 255, 0.2); + border-radius: 3px; +} + +.dashboard-page { + height: 100%; + overflow-y: auto; + background: #0a0a0a; +} + +.dashboard-grid { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 6px; + padding: 6px; + min-height: 100%; +} + +.dashboard-col { + display: flex; + flex-direction: column; + gap: 6px; + min-width: 0; +} + +.dashboard-card { + background: #141414; + border: 1px solid #333; + border-radius: 12px; + overflow: hidden; + transition: box-shadow 0.25s, border-color 0.25s; +} + +.dashboard-card:hover { + border-color: rgba(0, 229, 255, 0.2); + box-shadow: 0 0 16px rgba(0, 229, 255, 0.06); +} + +.dashboard-card--grow { + flex: 1; + display: flex; + flex-direction: column; + min-height: 0; +} + +.dashboard-card--grow .dashboard-card-body { + flex: 1; + min-height: 0; +} + +.dashboard-card-header { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; + padding: 12px; + border-bottom: 1px solid #333; + user-select: none; +} + +.dashboard-card-title { + font-size: 15px; + font-weight: 600; + color: #e2e8f0; +} + +.dashboard-card-body { + padding: 12px; +} + +.dashboard-chevron { + width: 16px; + height: 16px; + color: var(--color-accent-cyan-dim); + transition: transform 0.25s; +} + +.dashboard-chevron--open { + transform: rotate(180deg); +} + +.step-badge { + display: inline-flex; + align-items: center; + justify-content: center; + width: 20px; + height: 20px; + border-radius: 9999px; + font-size: 11px; + font-weight: 700; + color: #fff; + background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%); + flex-shrink: 0; +} + +.dashboard-field-label { + font-size: 13px; + font-weight: 500; + color: #e2e8f0; + margin-bottom: 4px; +} + +.dashboard-field-label--muted { + color: #94a3b8; + font-weight: 400; +} + +.dashboard-muted { + font-size: 13px; + color: #64748b; +} + +.dashboard-preview-box { + background: #1a1a1a; + border: 1px solid #333; + border-radius: 8px; + padding: 12px; +} + +.dashboard-aspect-video { + aspect-ratio: 16 / 9; + background: rgba(255, 255, 255, 0.04); + border-radius: 8px; + display: flex; + align-items: center; + justify-content: center; +} + +.dashboard-platform-row { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; + padding: 8px; + border-radius: 8px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid rgba(255, 255, 255, 0.05); +} + +.dashboard-platform-row:hover { + background: rgba(255, 255, 255, 0.08); +} + +.dashboard-one-click { + width: 100%; + padding: 12px; + border-radius: 10px; + border: 1px solid rgba(0, 229, 255, 0.35); + background: linear-gradient( + 135deg, + rgba(0, 229, 255, 0.12) 0%, + rgba(99, 102, 241, 0.15) 100% + ); + color: #e2e8f0; + font-size: 14px; + font-weight: 600; + cursor: pointer; + transition: box-shadow 0.2s, border-color 0.2s; +} + +.dashboard-one-click:hover { + border-color: rgba(0, 229, 255, 0.55); + box-shadow: 0 0 20px rgba(0, 229, 255, 0.15); +} + +.dashboard-textarea-mono :deep(textarea) { + font-family: var(--font-mono); + font-size: 14px; + line-height: 1.6; + min-height: 200px; +} diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue index 7efe93c..5b2d0fa 100644 --- a/src/views/HomeView.vue +++ b/src/views/HomeView.vue @@ -1,37 +1,465 @@