diff --git a/README.md b/README.md index 1511959..f299ecf 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,56 @@ -# Vue 3 + Vite +# 项目展示平台 -This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 ` - diff --git a/src/assets/logo-admin.png b/src/assets/logo-admin.png new file mode 100644 index 0000000..5384de1 Binary files /dev/null and b/src/assets/logo-admin.png differ diff --git a/src/assets/logo.png b/src/assets/logo.png new file mode 100644 index 0000000..9ca1df8 Binary files /dev/null and b/src/assets/logo.png differ diff --git a/src/assets/nl-logo.png b/src/assets/nl-logo.png new file mode 100644 index 0000000..9a93c2e Binary files /dev/null and b/src/assets/nl-logo.png differ diff --git a/src/components/common/AuthModal.vue b/src/components/common/AuthModal.vue new file mode 100644 index 0000000..9ec957e --- /dev/null +++ b/src/components/common/AuthModal.vue @@ -0,0 +1,96 @@ + + + + + \ No newline at end of file diff --git a/src/layouts/AdminLayout.vue b/src/layouts/AdminLayout.vue new file mode 100644 index 0000000..f628431 --- /dev/null +++ b/src/layouts/AdminLayout.vue @@ -0,0 +1,65 @@ + + + + + \ No newline at end of file diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue new file mode 100644 index 0000000..676c425 --- /dev/null +++ b/src/layouts/MainLayout.vue @@ -0,0 +1,160 @@ + + + + + \ No newline at end of file diff --git a/src/main.js b/src/main.js index 2425c0f..56cbbd2 100644 --- a/src/main.js +++ b/src/main.js @@ -1,5 +1,24 @@ import { createApp } from 'vue' +import { createPinia } from 'pinia' +import Antd from 'ant-design-vue' +import AOS from 'aos' +import 'aos/dist/aos.css' import './style.css' import App from './App.vue' +// 注册路由 +import router from './router' -createApp(App).mount('#app') +const app = createApp(App) + +// 初始化AOS动画 +AOS.init({ + duration: 600, + offset: 120, + easing: 'ease-out-quad' +}) + +// 注册Ant Design组件 +app.use(createPinia()) +app.use(router) +app.use(Antd) +app.mount('#app') diff --git a/src/router/index.js b/src/router/index.js new file mode 100644 index 0000000..9a8a17f --- /dev/null +++ b/src/router/index.js @@ -0,0 +1,70 @@ +import { createRouter, createWebHistory } from 'vue-router' +import { useUserStore } from '@/stores/user' +import MainLayout from '@/layouts/MainLayout.vue' +import AdminLayout from '@/layouts/AdminLayout.vue' + +// 在路由配置中添加个人中心路由 +const routes = [ + { + path: '/', + component: MainLayout, + children: [ + { path: '', name: 'Home', component: () => import('@/views/frontend/Home.vue') }, + { path: '/projects', name: 'Projects', component: () => import('@/views/frontend/Projects.vue') }, + { path: '/project/:id', name: 'ProjectDetail', component: () => import('@/views/frontend/Detail.vue') }, + // 确保所有前台路由在此注册 + { path: '/about', name: 'About', component: () => import('@/views/frontend/About.vue') }, + { path: '/services', name: 'Services', component: () => import('@/views/frontend/Services.vue') }, + { + path: '/about', + name: 'About', + component: () => import('@/views/frontend/About.vue') + }, + { + path: '/services', + name: 'Services', + component: () => import('@/views/frontend/Services.vue') + }, + { + path: '/personal', + name: 'Personal', + component: () => import('@/views/frontend/Personal.vue'), + meta: { requiresAuth: true } + }, + ] + }, + { + path: '/admin', + component: AdminLayout, + meta: { requiresAuth: true }, + children: [ + { path: '', redirect: '/admin/dashboard' }, + { path: 'dashboard', name: 'Dashboard', component: () => import('@/views/admin/Dashboard.vue') }, + { path: 'projects', name: 'ProjectManage', component: () => import('@/views/admin/ProjectsCRUD.vue') } + ] + }, +] + +const router = createRouter({ + history: createWebHistory(), + routes, + scrollBehavior(to, from, savedPosition) { + return savedPosition || { top: 0 } + } +}) + +router.beforeEach((to, from) => { + const userStore = useUserStore() + if (to.meta.requiresAuth && !userStore.user) { + return { name: 'Login', query: { redirect: to.fullPath } } + } +}) + +export default router + +router.beforeEach((to, from) => { + const userStore = useUserStore() + if (to.meta.requiresAuth && !userStore.user) { + return { name: 'Login', query: { redirect: to.fullPath } } + } +}) \ No newline at end of file diff --git a/src/stores/user.js b/src/stores/user.js new file mode 100644 index 0000000..7505211 --- /dev/null +++ b/src/stores/user.js @@ -0,0 +1,54 @@ +import { defineStore } from 'pinia' +import { ref, computed } from 'vue' + +export const useUserStore = defineStore('user', () => { + const user = ref(JSON.parse(localStorage.getItem('user') || 'null')) + + // 添加初始化状态校验 + const initUser = () => { + const userData = localStorage.getItem('user') + if (!userData) return null + try { + return JSON.parse(userData) + } catch { + localStorage.removeItem('user') + localStorage.removeItem('token') + return null + } + } + + const isAuthenticated = computed(() => !!user.value?.token) + + function login(credentials) { + return new Promise((resolve, reject) => { + setTimeout(() => { + if (credentials.username === 'admin' && credentials.password === 'admin123') { + const userData = { + username: credentials.username, + role: 'admin', + token: 'mock_token_' + Math.random().toString(36).slice(2) + } + localStorage.setItem('user', JSON.stringify(userData)) + user.value = userData // 添加响应式状态更新 + localStorage.setItem('token', userData.token) + resolve() + } else { + reject(new Error('用户名或密码错误')) + } + }, 500) + }) + } + + function logout() { + user.value = null + localStorage.removeItem('user') + localStorage.removeItem('token') + } + + return { + user, + isAuthenticated, + login, + logout + } +}) \ No newline at end of file diff --git a/src/style.css b/src/style.css index a461c50..f1d8c73 100644 --- a/src/style.css +++ b/src/style.css @@ -1 +1 @@ -@import "tailwindcss"; \ No newline at end of file +@import "tailwindcss"; diff --git a/src/views/admin/Dashboard.vue b/src/views/admin/Dashboard.vue new file mode 100644 index 0000000..0de85ee --- /dev/null +++ b/src/views/admin/Dashboard.vue @@ -0,0 +1,58 @@ + + + + + \ No newline at end of file diff --git a/src/views/admin/Login.vue b/src/views/admin/Login.vue new file mode 100644 index 0000000..70714cb --- /dev/null +++ b/src/views/admin/Login.vue @@ -0,0 +1,96 @@ + + + + + \ No newline at end of file diff --git a/src/views/admin/ProjectsCRUD.vue b/src/views/admin/ProjectsCRUD.vue new file mode 100644 index 0000000..80b2861 --- /dev/null +++ b/src/views/admin/ProjectsCRUD.vue @@ -0,0 +1,116 @@ + + + + + \ No newline at end of file diff --git a/src/views/frontend/About.vue b/src/views/frontend/About.vue new file mode 100644 index 0000000..eaed55a --- /dev/null +++ b/src/views/frontend/About.vue @@ -0,0 +1,31 @@ + + + \ No newline at end of file diff --git a/src/views/frontend/Detail.vue b/src/views/frontend/Detail.vue new file mode 100644 index 0000000..62d77d2 --- /dev/null +++ b/src/views/frontend/Detail.vue @@ -0,0 +1,106 @@ + + +