+
+
-
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main.js b/src/main.js
index efadd61..08a9279 100644
--- a/src/main.js
+++ b/src/main.js
@@ -1,16 +1,37 @@
import { createApp } from 'vue'
-import { createPinia } from 'pinia'
-import Antd from 'ant-design-vue'
import './style.css'
import App from './App.vue'
-// 注册路由
import router from './router'
+import { createPinia } from 'pinia'
+import AOS from 'aos'
+import 'aos/dist/aos.css'
const app = createApp(App)
+const pinia = createPinia()
-
-// 注册Ant Design组件
-app.use(createPinia())
+app.use(pinia)
app.use(router)
-app.use(Antd)
-app.mount('#app')
+
+// 挂载应用
+const mountedApp = app.mount('#app')
+
+// 初始化主题系统
+import { useThemeStore } from './stores/theme'
+const themeStore = useThemeStore()
+themeStore.initTheme()
+
+// 初始化AOS动画
+AOS.init({
+ duration: 800,
+ easing: 'ease-out-cubic',
+ once: true,
+ offset: 100,
+ delay: 0,
+})
+
+// 监听主题变化,重新初始化AOS
+themeStore.$subscribe(() => {
+ setTimeout(() => {
+ AOS.refresh()
+ }, 100)
+})
\ No newline at end of file
diff --git a/src/router/index.js b/src/router/index.js
index add6aa0..500755a 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -43,6 +43,11 @@ const routes = [
path: 'contact',
name: 'Contact',
component: () => import('@/views/contact/index.vue')
+ },
+ {
+ path: 'careers',
+ name: 'Careers',
+ component: () => import('@/views/careers/index.vue')
}
]
},
diff --git a/src/stores/theme.js b/src/stores/theme.js
new file mode 100644
index 0000000..d0adda4
--- /dev/null
+++ b/src/stores/theme.js
@@ -0,0 +1,293 @@
+import { defineStore } from 'pinia'
+import { ref, computed } from 'vue'
+
+// 内存中存储主题设置
+let memoryTheme = null
+
+// 安全地检测系统颜色偏好
+const getSystemPreference = () => {
+ try {
+ if (typeof window === 'undefined' || !window.matchMedia) {
+ return false
+ }
+ return window.matchMedia('(prefers-color-scheme: dark)').matches
+ } catch (e) {
+ console.error('无法检测系统颜色偏好:', e)
+ return false
+ }
+}
+
+// 安全地访问localStorage
+const safeLocalStorage = {
+ get: (key) => {
+ try {
+ if (typeof localStorage === 'undefined') {
+ return null
+ }
+ return localStorage.getItem(key)
+ } catch (e) {
+ console.error('无法读取localStorage:', e)
+ return null
+ }
+ },
+ set: (key, value) => {
+ try {
+ if (typeof localStorage === 'undefined') {
+ return false
+ }
+ localStorage.setItem(key, value)
+ return true
+ } catch (e) {
+ console.error('无法写入localStorage:', e)
+ return false
+ }
+ },
+ remove: (key) => {
+ try {
+ if (typeof localStorage === 'undefined') {
+ return false
+ }
+ localStorage.removeItem(key)
+ return true
+ } catch (e) {
+ console.error('无法删除localStorage:', e)
+ return false
+ }
+ }
+}
+
+export const useThemeStore = defineStore('theme', () => {
+ // 检查系统偏好
+ const prefersDark = getSystemPreference()
+
+ // 尝试从localStorage读取主题设置
+ try {
+ if (memoryTheme === null) {
+ const storedTheme = safeLocalStorage.get('theme')
+ if (storedTheme) {
+ memoryTheme = storedTheme
+ }
+ }
+ } catch (e) {
+ console.error('初始化主题时出错:', e)
+ }
+
+ // 主题状态 - 优先使用内存中的设置,如果没有则跟随系统
+ const isDark = ref(
+ memoryTheme === 'dark' ||
+ (memoryTheme === null && prefersDark)
+ )
+
+ // 计算属性
+ const theme = computed(() => isDark.value ? 'dark' : 'light')
+
+ // 主题配置
+ const themeConfig = computed(() => ({
+ dark: {
+ // 深色渐变背景 - 更加丰富的色彩过渡
+ background: 'linear-gradient(135deg, #0f172a 0%, #1e293b 20%, #312e81 50%, #4c1d95 70%, #1e1b4b 100%)',
+ surface: 'rgba(30, 41, 59, 0.8)',
+ surfaceHover: 'rgba(51, 65, 85, 0.9)',
+ card: 'rgba(255, 255, 255, 0.05)',
+ cardHover: 'rgba(255, 255, 255, 0.1)',
+ border: 'rgba(255, 255, 255, 0.1)',
+ borderHover: 'rgba(99, 102, 241, 0.4)',
+ text: {
+ primary: '#f8fafc',
+ secondary: '#cbd5e1',
+ muted: '#94a3b8'
+ },
+ glass: {
+ background: 'rgba(15, 23, 42, 0.7)',
+ border: 'rgba(255, 255, 255, 0.1)',
+ blur: '20px'
+ },
+ gradient: {
+ primary: 'linear-gradient(135deg, #2563eb 0%, #7c3aed 100%)',
+ secondary: 'linear-gradient(135deg, #06b6d4 0%, #3b82f6 100%)',
+ accent: 'linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%)',
+ success: 'linear-gradient(135deg, #10b981 0%, #059669 100%)',
+ warning: 'linear-gradient(135deg, #f59e0b 0%, #d97706 100%)',
+ error: 'linear-gradient(135deg, #ef4444 0%, #b91c1c 100%)',
+ info: 'linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%)',
+ purple: 'linear-gradient(135deg, #8b5cf6 0%, #6d28d9 100%)',
+ pink: 'linear-gradient(135deg, #ec4899 0%, #be185d 100%)',
+ orange: 'linear-gradient(135deg, #f97316 0%, #c2410c 100%)',
+ teal: 'linear-gradient(135deg, #14b8a6 0%, #0d9488 100%)'
+ },
+ // 强调色
+ accent: {
+ blue: 'rgba(59, 130, 246, 0.15)',
+ purple: 'rgba(139, 92, 246, 0.15)',
+ pink: 'rgba(236, 72, 153, 0.15)',
+ green: 'rgba(16, 185, 129, 0.15)',
+ orange: 'rgba(249, 115, 22, 0.15)',
+ teal: 'rgba(20, 184, 166, 0.15)'
+ }
+ },
+ light: {
+ // 亮色渐变背景 - 更加丰富的色彩过渡
+ background: 'linear-gradient(135deg, #f8fafc 0%, #e2e8f0 20%, #ddd6fe 50%, #fbcfe8 70%, #e2e8f0 100%)',
+ surface: 'rgba(248, 250, 252, 0.9)',
+ surfaceHover: 'rgba(241, 245, 249, 0.95)',
+ card: 'rgba(255, 255, 255, 0.8)',
+ cardHover: 'rgba(255, 255, 255, 0.95)',
+ border: 'rgba(203, 213, 225, 0.3)',
+ borderHover: 'rgba(99, 102, 241, 0.4)',
+ text: {
+ primary: '#1e293b',
+ secondary: '#475569',
+ muted: '#64748b'
+ },
+ glass: {
+ background: 'rgba(255, 255, 255, 0.7)',
+ border: 'rgba(203, 213, 225, 0.3)',
+ blur: '20px'
+ },
+ gradient: {
+ primary: 'linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%)',
+ secondary: 'linear-gradient(135deg, #06b6d4 0%, #3b82f6 100%)',
+ accent: 'linear-gradient(135deg, #f59e0b 0%, #ef4444 100%)',
+ success: 'linear-gradient(135deg, #10b981 0%, #059669 100%)',
+ warning: 'linear-gradient(135deg, #f59e0b 0%, #d97706 100%)',
+ error: 'linear-gradient(135deg, #ef4444 0%, #b91c1c 100%)',
+ info: 'linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%)',
+ purple: 'linear-gradient(135deg, #8b5cf6 0%, #6d28d9 100%)',
+ pink: 'linear-gradient(135deg, #ec4899 0%, #be185d 100%)',
+ orange: 'linear-gradient(135deg, #f97316 0%, #c2410c 100%)',
+ teal: 'linear-gradient(135deg, #14b8a6 0%, #0d9488 100%)'
+ },
+ // 强调色
+ accent: {
+ blue: 'rgba(59, 130, 246, 0.15)',
+ purple: 'rgba(139, 92, 246, 0.15)',
+ pink: 'rgba(236, 72, 153, 0.15)',
+ green: 'rgba(16, 185, 129, 0.15)',
+ orange: 'rgba(249, 115, 22, 0.15)',
+ teal: 'rgba(20, 184, 166, 0.15)'
+ }
+ }
+ }))
+
+ // 当前主题配置
+ const currentTheme = computed(() => themeConfig.value[theme.value])
+
+ // 切换主题
+ const toggleTheme = () => {
+ isDark.value = !isDark.value
+ const newTheme = theme.value
+ memoryTheme = newTheme
+ safeLocalStorage.set('theme', newTheme)
+ updateDocumentTheme()
+ }
+
+ // 设置主题
+ const setTheme = (newTheme) => {
+ if (newTheme === 'system') {
+ // 跟随系统
+ const prefersDark = getSystemPreference()
+ isDark.value = prefersDark
+ memoryTheme = null
+ safeLocalStorage.remove('theme') // 删除本地存储,表示跟随系统
+ } else {
+ // 明确设置为亮色或暗色
+ isDark.value = newTheme === 'dark'
+ memoryTheme = newTheme
+ safeLocalStorage.set('theme', newTheme)
+ }
+ updateDocumentTheme()
+ }
+
+ // 更新文档主题
+ const updateDocumentTheme = () => {
+ // 确保在浏览器环境中运行
+ if (typeof document === 'undefined') {
+ return
+ }
+
+ try {
+ const root = document.documentElement
+ const config = currentTheme.value
+
+ // 设置CSS变量
+ root.style.setProperty('--theme-background', config.background)
+ root.style.setProperty('--theme-surface', config.surface)
+ root.style.setProperty('--theme-surface-hover', config.surfaceHover)
+ root.style.setProperty('--theme-card', config.card)
+ root.style.setProperty('--theme-card-hover', config.cardHover)
+ root.style.setProperty('--theme-border', config.border)
+ root.style.setProperty('--theme-border-hover', config.borderHover)
+ root.style.setProperty('--theme-text-primary', config.text.primary)
+ root.style.setProperty('--theme-text-secondary', config.text.secondary)
+ root.style.setProperty('--theme-text-muted', config.text.muted)
+ root.style.setProperty('--theme-glass-bg', config.glass.background)
+ root.style.setProperty('--theme-glass-border', config.glass.border)
+ root.style.setProperty('--theme-glass-blur', config.glass.blur)
+ root.style.setProperty('--theme-gradient-primary', config.gradient.primary)
+ root.style.setProperty('--theme-gradient-secondary', config.gradient.secondary)
+ root.style.setProperty('--theme-gradient-accent', config.gradient.accent)
+
+ // 设置主题类
+ if (isDark.value) {
+ root.classList.add('dark')
+ root.classList.remove('light')
+ } else {
+ root.classList.add('light')
+ root.classList.remove('dark')
+ }
+ } catch (e) {
+ console.error('更新文档主题时出错:', e)
+ }
+ }
+
+ // 初始化主题
+ const initTheme = () => {
+ updateDocumentTheme()
+
+ // 确保在浏览器环境中运行
+ if (typeof window === 'undefined') {
+ return
+ }
+
+ // 监听系统主题变化
+ try {
+ if (window.matchMedia) {
+ const colorSchemeQuery = window.matchMedia('(prefers-color-scheme: dark)')
+
+ // 添加主题变化监听器
+ const handleThemeChange = (e) => {
+ // 只有当用户没有明确设置主题时才跟随系统
+ if (memoryTheme === null) {
+ isDark.value = e.matches
+ updateDocumentTheme()
+ }
+ }
+
+ // 添加监听器
+ if (colorSchemeQuery.addEventListener) {
+ colorSchemeQuery.addEventListener('change', handleThemeChange)
+ } else if (colorSchemeQuery.addListener) {
+ // Safari 和 IE 支持
+ colorSchemeQuery.addListener(handleThemeChange)
+ }
+ }
+ } catch (e) {
+ console.error('监听系统主题变化时出错:', e)
+ }
+ }
+
+ // 检查当前是否为系统主题
+ const isSystemTheme = computed(() => {
+ return memoryTheme === null
+ })
+
+ return {
+ isDark,
+ theme,
+ currentTheme,
+ toggleTheme,
+ setTheme,
+ initTheme,
+ isSystemTheme
+ }
+})
\ No newline at end of file
diff --git a/src/stores/user.js b/src/stores/user.js
index 5987aad..955b506 100644
--- a/src/stores/user.js
+++ b/src/stores/user.js
@@ -1,87 +1,83 @@
import { defineStore } from 'pinia'
-import { ref, computed } from 'vue'
-import {loginApi, registerApi} from "@/api/request/user.js";
-import {message, notification} from "ant-design-vue";
-export const useUserStore = defineStore('user', () => {
- const user = ref(JSON.parse(localStorage.getItem('user') || 'null'))
- const modal = ref(localStorage.getItem('authModal') || 'false')
-
- // 添加初始化状态校验
- const initUser = () => {
- const userData = localStorage.getItem('user')
- if (!userData) return null
- try {
- return JSON.parse(userData)
- } catch {
+export const useUserStore = defineStore('user', {
+ state: () => ({
+ user: null,
+ token: null,
+ isLoggedIn: false
+ }),
+
+ getters: {
+ userInfo: (state) => state.user,
+ isAuthenticated: (state) => state.isLoggedIn && !!state.token,
+ userRole: (state) => state.user?.role || 'guest'
+ },
+
+ actions: {
+ // 设置用户信息
+ setUser(userData) {
+ this.user = userData
+ this.token = userData.token
+ this.isLoggedIn = true
+
+ // 保存到localStorage
+ if (userData.token) {
+ localStorage.setItem('token', userData.token)
+ }
+ localStorage.setItem('user', JSON.stringify(userData))
+ },
+
+ // 登出
+ logout() {
+ this.user = null
+ this.token = null
+ this.isLoggedIn = false
+
+ // 清除localStorage
localStorage.removeItem('user')
localStorage.removeItem('token')
- return null
+ localStorage.removeItem('remember_user')
+ },
+
+ // 从localStorage恢复用户状态
+ restoreUser() {
+ try {
+ const token = localStorage.getItem('token')
+ const userStr = localStorage.getItem('user')
+
+ if (token && userStr) {
+ const user = JSON.parse(userStr)
+ this.user = user
+ this.token = token
+ this.isLoggedIn = true
+ return true
+ }
+ } catch (error) {
+ console.error('恢复用户状态失败:', error)
+ this.logout()
+ }
+ return false
+ },
+
+ // 更新用户信息
+ updateUser(userData) {
+ if (this.user) {
+ this.user = { ...this.user, ...userData }
+ localStorage.setItem('user', JSON.stringify(this.user))
+ }
+ },
+
+ // 检查是否有权限
+ hasPermission(permission) {
+ if (!this.user) return false
+
+ // 管理员拥有所有权限
+ if (this.user.role === 'admin' || this.user.role === 'super_admin') {
+ return true
+ }
+
+ // 其他权限检查逻辑
+ return this.user.permissions?.includes(permission) || false
}
}
-
- const isAuthenticated = computed(() => !!user.value?.nick_name)
-
- function login(credentials, functionName) {
- console.log(functionName, 'sssssssssssss')
- loginApi({
- account: credentials.username,
- password: credentials.password,
- remember: credentials.remember,
- }).then((res) => {
- const userData = {
- nick_name: res.nick_name,
- role_name: res.role_name,
- role_value: res.role_value,
- }
- user.value = userData;
- localStorage.setItem('user', JSON.stringify(userData))
- localStorage.setItem('token', res.token)
- notification.success({
- message: '登录成功',
- description: `欢迎回来${res.nick_name}`,
- })
- functionName()
- })
- }
- function register(credentials, functionName) {
- registerApi({
- account: credentials.username,
- password: credentials.password,
- email: credentials.email,
- code: credentials.code,
- }).then((res) => {
- const userData = {
- nick_name: res.nick_name,
- role_name: res.role_name,
- role_value: res.role_value,
- }
- user.value = userData;
- localStorage.setItem('user', JSON.stringify(userData))
- localStorage.setItem('token', res.token)
- message.success('注册成功')
- functionName()
- })
- }
-
- function logout() {
- user.value = null
- localStorage.removeItem('user')
- localStorage.removeItem('token')
- }
-
- function setModal(value) {
- modal.value = modal.value === 'false' ? 'true' : 'false';
- localStorage.setItem('authModal', value)
- }
-
- return {
- modal,
- user,
- isAuthenticated,
- setModal,
- login,
- register,
- logout
- }
})
\ No newline at end of file
diff --git a/src/style.css b/src/style.css
index a461c50..6ef4a68 100644
--- a/src/style.css
+++ b/src/style.css
@@ -1 +1,548 @@
-@import "tailwindcss";
\ No newline at end of file
+@import 'tailwindcss';
+
+/* 全局CSS变量 - 将由主题系统动态更新 */
+:root {
+ /* 主题颜色 */
+ --theme-background: linear-gradient(135deg, #0f172a 0%, #1e293b 25%, #334155 50%, #1e293b 75%, #0f172a 100%);
+ --theme-surface: rgba(30, 41, 59, 0.8);
+ --theme-surface-hover: rgba(51, 65, 85, 0.9);
+ --theme-card: rgba(255, 255, 255, 0.05);
+ --theme-card-hover: rgba(255, 255, 255, 0.1);
+ --theme-border: rgba(255, 255, 255, 0.1);
+ --theme-border-hover: rgba(59, 130, 246, 0.3);
+ --theme-text-primary: #f8fafc;
+ --theme-text-secondary: #cbd5e1;
+ --theme-text-muted: #94a3b8;
+ --theme-glass-bg: rgba(15, 23, 42, 0.7);
+ --theme-glass-border: rgba(255, 255, 255, 0.1);
+ --theme-glass-blur: 20px;
+ --theme-gradient-primary: linear-gradient(135deg, #2563eb 0%, #7c3aed 100%);
+ --theme-gradient-secondary: linear-gradient(135deg, #06b6d4 0%, #3b82f6 100%);
+ --theme-gradient-accent: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
+
+ /* 动画变量 */
+ --animation-duration-fast: 200ms;
+ --animation-duration-normal: 300ms;
+ --animation-duration-slow: 500ms;
+ --animation-easing: cubic-bezier(0.4, 0, 0.2, 1);
+ --animation-easing-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55);
+}
+
+/* 基础样式重置 */
+* {
+ box-sizing: border-box;
+}
+
+html {
+ scroll-behavior: smooth;
+}
+
+body {
+ margin: 0;
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+ background: var(--theme-background);
+ color: var(--theme-text-primary);
+ line-height: 1.6;
+ overflow-x: hidden;
+ transition: all var(--animation-duration-normal) var(--animation-easing);
+}
+
+/* 滚动条样式 */
+::-webkit-scrollbar {
+ width: 8px;
+ height: 8px;
+}
+
+::-webkit-scrollbar-track {
+ background: var(--theme-surface);
+ border-radius: 4px;
+}
+
+::-webkit-scrollbar-thumb {
+ background: var(--theme-gradient-primary);
+ border-radius: 4px;
+ transition: all var(--animation-duration-normal) var(--animation-easing);
+}
+
+::-webkit-scrollbar-thumb:hover {
+ background: var(--theme-gradient-secondary);
+}
+
+/* 选择文本样式 */
+::selection {
+ background: rgba(59, 130, 246, 0.3);
+ color: var(--theme-text-primary);
+}
+
+/* 主题工具类 */
+.theme-bg {
+ background: var(--theme-background);
+}
+
+.theme-surface {
+ background: var(--theme-surface);
+}
+
+.theme-card {
+ background: var(--theme-card);
+ border: 1px solid var(--theme-border);
+ transition: all var(--animation-duration-normal) var(--animation-easing);
+}
+
+.theme-card:hover {
+ background: var(--theme-card-hover);
+ border-color: var(--theme-border-hover);
+ transform: translateY(-2px);
+}
+
+.theme-glass {
+ background: var(--theme-glass-bg);
+ backdrop-filter: blur(var(--theme-glass-blur));
+ border: 1px solid var(--theme-glass-border);
+}
+
+.theme-text-primary {
+ color: var(--theme-text-primary);
+}
+
+.theme-text-secondary {
+ color: var(--theme-text-secondary);
+}
+
+.theme-text-muted {
+ color: var(--theme-text-muted);
+}
+
+.theme-gradient-primary {
+ background: var(--theme-gradient-primary);
+}
+
+.theme-gradient-secondary {
+ background: var(--theme-gradient-secondary);
+}
+
+.theme-gradient-accent {
+ background: var(--theme-gradient-accent);
+}
+
+/* 按钮组件 */
+.btn {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 0.75rem 1.5rem;
+ font-size: 0.875rem;
+ font-weight: 500;
+ border-radius: 0.75rem;
+ border: none;
+ cursor: pointer;
+ transition: all var(--animation-duration-normal) var(--animation-easing);
+ text-decoration: none;
+ position: relative;
+ overflow: hidden;
+}
+
+.btn:before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: -100%;
+ width: 100%;
+ height: 100%;
+ background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
+ transition: left 0.5s;
+}
+
+.btn:hover:before {
+ left: 100%;
+}
+
+.btn-primary {
+ color: white;
+ background: var(--theme-gradient-primary);
+ box-shadow: 0 4px 14px 0 rgba(59, 130, 246, 0.3);
+}
+
+.btn-primary:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 6px 20px 0 rgba(59, 130, 246, 0.4);
+}
+
+.btn-secondary {
+ color: var(--theme-text-primary);
+ background: var(--theme-surface);
+ border: 1px solid var(--theme-border);
+}
+
+.btn-secondary:hover {
+ background: var(--theme-surface-hover);
+ border-color: var(--theme-border-hover);
+ transform: translateY(-2px);
+}
+
+.btn-glass {
+ color: var(--theme-text-primary);
+ background: var(--theme-glass-bg);
+ backdrop-filter: blur(var(--theme-glass-blur));
+ border: 1px solid var(--theme-glass-border);
+}
+
+.btn-glass:hover {
+ background: var(--theme-card-hover);
+ transform: translateY(-2px);
+}
+
+/* 卡片组件 */
+.card {
+ border-radius: 1rem;
+ padding: 1.5rem;
+ transition: all var(--animation-duration-normal) var(--animation-easing);
+ position: relative;
+ overflow: hidden;
+}
+
+.card-glass {
+ background: var(--theme-glass-bg);
+ backdrop-filter: blur(var(--theme-glass-blur));
+ border: 1px solid var(--theme-glass-border);
+}
+
+.card-hover:hover {
+ transform: translateY(-4px);
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
+}
+
+/* 输入框组件 */
+.input {
+ width: 100%;
+ padding: 0.75rem 1rem;
+ font-size: 0.875rem;
+ background: var(--theme-surface);
+ border: 1px solid var(--theme-border);
+ border-radius: 0.5rem;
+ color: var(--theme-text-primary);
+ transition: all var(--animation-duration-normal) var(--animation-easing);
+}
+
+.input:focus {
+ outline: none;
+ border-color: #3b82f6;
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
+}
+
+.input::placeholder {
+ color: var(--theme-text-muted);
+}
+
+/* 动画类 */
+.fade-enter-active,
+.fade-leave-active {
+ transition: all var(--animation-duration-normal) var(--animation-easing);
+}
+
+.fade-enter-from,
+.fade-leave-to {
+ opacity: 0;
+ transform: translateY(10px);
+}
+
+.slide-up-enter-active,
+.slide-up-leave-active {
+ transition: all var(--animation-duration-normal) var(--animation-easing);
+}
+
+.slide-up-enter-from,
+.slide-up-leave-to {
+ opacity: 0;
+ transform: translateY(20px);
+}
+
+.scale-enter-active,
+.scale-leave-active {
+ transition: all var(--animation-duration-normal) var(--animation-easing);
+}
+
+.scale-enter-from,
+.scale-leave-to {
+ opacity: 0;
+ transform: scale(0.9);
+}
+
+/* 加载动画 */
+.loading-spinner {
+ display: inline-block;
+ width: 20px;
+ height: 20px;
+ border: 3px solid var(--theme-border);
+ border-radius: 50%;
+ border-top-color: #3b82f6;
+ animation: spin 1s ease-in-out infinite;
+}
+
+@keyframes spin {
+ to { transform: rotate(360deg); }
+}
+
+/* 脉冲动画 */
+.pulse-glow {
+ animation: pulse-glow 2s ease-in-out infinite alternate;
+}
+
+@keyframes pulse-glow {
+ 0% {
+ box-shadow: 0 0 20px rgba(59, 130, 246, 0.3);
+ }
+ 100% {
+ box-shadow: 0 0 40px rgba(59, 130, 246, 0.6);
+ }
+}
+
+/* 浮动动画 */
+.float {
+ animation: float 3s ease-in-out infinite;
+}
+
+@keyframes float {
+ 0%, 100% { transform: translateY(0px); }
+ 50% { transform: translateY(-10px); }
+}
+
+/* 闪烁动画 */
+.twinkle {
+ animation: twinkle 2s ease-in-out infinite alternate;
+}
+
+@keyframes twinkle {
+ 0% { opacity: 0.3; transform: scale(1); }
+ 100% { opacity: 1; transform: scale(1.2); }
+}
+
+/* 响应式工具类 */
+.container {
+ width: 100%;
+ margin-left: auto;
+ margin-right: auto;
+ padding-left: 1rem;
+ padding-right: 1rem;
+}
+
+@media (min-width: 640px) {
+ .container { max-width: 640px; }
+}
+
+@media (min-width: 768px) {
+ .container { max-width: 768px; }
+}
+
+@media (min-width: 1024px) {
+ .container { max-width: 1024px; }
+}
+
+@media (min-width: 1280px) {
+ .container { max-width: 1280px; }
+}
+
+@media (min-width: 1536px) {
+ .container { max-width: 1536px; }
+}
+
+/* 主题切换按钮 */
+.theme-toggle {
+ position: relative;
+ width: 3rem;
+ height: 1.5rem;
+ background: var(--theme-surface);
+ border: 1px solid var(--theme-border);
+ border-radius: 0.75rem;
+ cursor: pointer;
+ transition: all var(--animation-duration-normal) var(--animation-easing);
+}
+
+.theme-toggle:hover {
+ background: var(--theme-surface-hover);
+}
+
+.theme-toggle-thumb {
+ position: absolute;
+ top: 2px;
+ left: 2px;
+ width: 1.25rem;
+ height: 1.25rem;
+ background: var(--theme-gradient-primary);
+ border-radius: 50%;
+ transition: all var(--animation-duration-normal) var(--animation-easing);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: white;
+ font-size: 0.75rem;
+}
+
+.theme-toggle.dark .theme-toggle-thumb {
+ transform: translateX(1.5rem);
+}
+
+/* 错误和成功状态 */
+.error-state {
+ color: #ef4444;
+ background: rgba(239, 68, 68, 0.1);
+ border: 1px solid rgba(239, 68, 68, 0.2);
+ border-radius: 0.5rem;
+ padding: 0.75rem;
+}
+
+.success-state {
+ color: #10b981;
+ background: rgba(16, 185, 129, 0.1);
+ border: 1px solid rgba(16, 185, 129, 0.2);
+ border-radius: 0.5rem;
+ padding: 0.75rem;
+}
+
+.warning-state {
+ color: #f59e0b;
+ background: rgba(245, 158, 11, 0.1);
+ border: 1px solid rgba(245, 158, 11, 0.2);
+ border-radius: 0.5rem;
+ padding: 0.75rem;
+}
+
+/* 工具提示 */
+.tooltip {
+ position: relative;
+}
+
+.tooltip::after {
+ content: attr(data-tooltip);
+ position: absolute;
+ bottom: 100%;
+ left: 50%;
+ transform: translateX(-50%);
+ background: var(--theme-surface);
+ color: var(--theme-text-primary);
+ padding: 0.5rem;
+ border-radius: 0.25rem;
+ font-size: 0.875rem;
+ white-space: nowrap;
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity var(--animation-duration-normal) var(--animation-easing);
+ border: 1px solid var(--theme-border);
+ z-index: 1000;
+}
+
+.tooltip:hover::after {
+ opacity: 1;
+}
+
+/* 响应式文本 */
+.text-responsive {
+ font-size: clamp(1rem, 2.5vw, 1.5rem);
+}
+
+.text-responsive-lg {
+ font-size: clamp(1.5rem, 4vw, 3rem);
+}
+
+.text-responsive-xl {
+ font-size: clamp(2rem, 6vw, 5rem);
+}
+
+/* 渐变文本 */
+.gradient-text {
+ background: var(--theme-gradient-primary);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+}
+
+/* 页面过渡 */
+.page-enter-active,
+.page-leave-active {
+ transition: all var(--animation-duration-slow) var(--animation-easing);
+}
+
+.page-enter-from {
+ opacity: 0;
+ transform: translateX(30px);
+}
+
+.page-leave-to {
+ opacity: 0;
+ transform: translateX(-30px);
+}
+
+/* 列表过渡 */
+.list-enter-active,
+.list-leave-active {
+ transition: all var(--animation-duration-normal) var(--animation-easing);
+}
+
+.list-enter-from,
+.list-leave-to {
+ opacity: 0;
+ transform: translateY(20px);
+}
+
+.list-move {
+ transition: transform var(--animation-duration-normal) var(--animation-easing);
+}
+
+/* 亮色主题特定样式 */
+.light {
+ --shadow-color: rgba(0, 0, 0, 0.1);
+}
+
+.light .card-glass {
+ box-shadow: 0 8px 32px var(--shadow-color);
+}
+
+.light .btn-primary {
+ box-shadow: 0 4px 14px 0 rgba(59, 130, 246, 0.25);
+}
+
+/* 暗色主题特定样式 */
+.dark {
+ --shadow-color: rgba(0, 0, 0, 0.3);
+}
+
+.dark .card-glass {
+ box-shadow: 0 8px 32px var(--shadow-color);
+}
+
+.dark .btn-primary {
+ box-shadow: 0 4px 14px 0 rgba(59, 130, 246, 0.4);
+}
+
+/* 无障碍支持 */
+@media (prefers-reduced-motion: reduce) {
+ *,
+ *::before,
+ *::after {
+ animation-duration: 0.01ms !important;
+ animation-iteration-count: 1 !important;
+ transition-duration: 0.01ms !important;
+ }
+}
+
+/* 高对比度模式 */
+@media (prefers-contrast: high) {
+ :root {
+ --theme-border: rgba(255, 255, 255, 0.3);
+ --theme-text-muted: rgba(255, 255, 255, 0.8);
+ }
+}
+
+/* 打印样式 */
+@media print {
+ body {
+ background: white !important;
+ color: black !important;
+ }
+
+ .btn,
+ .theme-toggle,
+ .modal-overlay {
+ display: none !important;
+ }
+}
diff --git a/src/views/about/index.vue b/src/views/about/index.vue
index cf9f917..d634aa2 100644
--- a/src/views/about/index.vue
+++ b/src/views/about/index.vue
@@ -1,302 +1,354 @@
-
-
-
-
-
-
关于我们
-
- 我们致力于为客户提供最优质的产品和服务,以创新驱动发展,以质量赢得信任
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 关于我们
+
+
+
+ 致力于打造最前沿的科技资讯平台,为用户提供高质量的技术内容和深度洞察
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
公司简介
-
-
- 我们公司成立于2010年,是一家专注于技术创新和产品研发的现代化企业。
- 经过十多年的发展,我们已经成为行业内的领军企业之一。
+
+
+
+
+
+
+
我们的使命
+
+ 在这个快速发展的数字时代,我们致力于成为技术创新与知识分享的桥梁。通过提供最新的科技资讯、深度的技术分析和实用的开发指南,我们帮助开发者和技术爱好者保持在技术前沿。
-
- 公司秉承"创新、品质、服务、共赢"的经营理念,始终坚持以客户需求为导向,
- 以技术创新为驱动,为客户提供高品质的产品和专业的服务。
-
-
- 我们拥有一支专业的技术团队和完善的服务体系,能够为客户提供从产品设计、
- 开发到售后服务的全方位解决方案。
+
+ 我们相信,优质的内容能够启发创新,推动技术进步,让每个人都能在数字化浪潮中找到自己的位置。
-
-
-
-
+
+
+
-
-
-
-
-
+
-
-
-
+
+
-
企业文化
-
- 我们的企业文化体现在每一个细节中,指导着我们的行为和决策
-
+
核心价值
+
我们坚持的原则和价值观
-
-
-
-
-
-
创新
-
持续创新,引领行业发展
-
-
-
-
-
-
品质
-
严格把控,追求卓越品质
-
-
-
-
-
-
服务
-
用心服务,超越客户期望
-
-
-
-
-
-
共赢
-
合作共赢,共创美好未来
-
-
-
-
-
-
-
-
-
核心团队
-
- 我们拥有一支经验丰富、专业素质过硬的核心团队
-
-
-
-
-
-
{{ member.name }}
-
{{ member.position }}
-
{{ member.description }}
+
+
+
+
{{ value.title }}
+
{{ value.description }}
-
-
+
-
-
-
+
+
-
发展历程
-
- 回顾我们的发展历程,每一步都见证着我们的成长与进步
-
+
核心团队
+
经验丰富的专业团队
+
+
+
+
+
{{ member.name }}
+
{{ member.position }}
+
{{ member.description }}
+
+
+
+
+
+
+
+
-
+
+
+
-
-
-
-
{{ milestone.year }}
-
{{ milestone.title }}
-
{{ milestone.description }}
+
+
+
+
+
+ {{ milestone.year }}
+
+
{{ milestone.title }}
+
+
{{ milestone.description }}
-
+
+
+
+
+
-
-
+
-
-
-
-
加入我们
-
- 如果您对我们的事业感兴趣,欢迎加入我们的团队,一起创造美好的未来
-
-
- 联系我们
-
-
-
-
+
+
+
+
加入我们的旅程
+
+ 如果您对我们的使命感兴趣,或者想要与我们合作,我们很乐意听到您的声音
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/admin/ArticleForm.vue b/src/views/admin/ArticleForm.vue
index 0ef8853..30add8c 100644
--- a/src/views/admin/ArticleForm.vue
+++ b/src/views/admin/ArticleForm.vue
@@ -27,7 +27,7 @@