#!/bin/bash # 云酒馆 Vue 3 前台应用快速创建脚本 echo "🚀 开始创建 web-app-vue 项目..." # 检查是否已存在 if [ -d "web-app-vue" ]; then echo "❌ web-app-vue 目录已存在,请先删除或重命名" exit 1 fi # 创建 Vue 项目 echo "📦 创建 Vue 3 + TypeScript 项目..." npm create vite@latest web-app-vue -- --template vue-ts # 进入项目目录 cd web-app-vue echo "📚 安装依赖..." npm install # 安装 Element Plus echo "🎨 安装 Element Plus..." npm install element-plus # 安装路由和状态管理 echo "🛣️ 安装 Vue Router 和 Pinia..." npm install vue-router@4 pinia # 安装 HTTP 客户端 echo "🌐 安装 Axios..." npm install axios # 安装工具库 echo "🔧 安装工具库..." npm install @vueuse/core # 安装开发依赖 echo "🛠️ 安装开发依赖..." npm install -D sass npm install -D unplugin-vue-components unplugin-auto-import # 创建目录结构 echo "📂 创建项目目录结构..." mkdir -p src/api mkdir -p src/assets/styles mkdir -p src/components/common mkdir -p src/components/chat mkdir -p src/components/character mkdir -p src/components/settings mkdir -p src/composables mkdir -p src/layouts mkdir -p src/router mkdir -p src/stores mkdir -p src/types mkdir -p src/utils mkdir -p src/views/auth mkdir -p src/views/home mkdir -p src/views/character mkdir -p src/views/chat mkdir -p src/views/settings mkdir -p src/views/user # 创建环境配置文件 echo "⚙️ 创建环境配置..." cat > .env.development << 'EOF' # 开发环境配置 VITE_API_BASE_URL=http://localhost:8888 VITE_WS_URL=ws://localhost:8888 EOF cat > .env.production << 'EOF' # 生产环境配置 VITE_API_BASE_URL=https://your-domain.com VITE_WS_URL=wss://your-domain.com EOF # 创建 Vite 配置 echo "⚙️ 配置 Vite..." cat > vite.config.ts << 'EOF' import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import { resolve } from 'path' import AutoImport from 'unplugin-auto-import/vite' import Components from 'unplugin-vue-components/vite' import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' export default defineConfig({ plugins: [ vue(), AutoImport({ resolvers: [ElementPlusResolver()], imports: ['vue', 'vue-router', 'pinia'], dts: 'src/auto-imports.d.ts', }), Components({ resolvers: [ElementPlusResolver()], dts: 'src/components.d.ts', }), ], resolve: { alias: { '@': resolve(__dirname, 'src'), }, }, server: { port: 3000, proxy: { '/app': { target: 'http://localhost:8888', changeOrigin: true, }, '/api': { target: 'http://localhost:8888', changeOrigin: true, }, }, }, build: { outDir: 'dist', sourcemap: false, rollupOptions: { output: { manualChunks: { 'element-plus': ['element-plus'], 'vue-vendor': ['vue', 'vue-router', 'pinia'], }, }, }, }, }) EOF # 创建 TypeScript 配置 echo "⚙️ 配置 TypeScript..." cat > tsconfig.json << 'EOF' { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "preserve", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, /* Path mapping */ "baseUrl": ".", "paths": { "@/*": ["src/*"] } }, "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"], "references": [{ "path": "./tsconfig.node.json" }] } EOF # 创建基础文件 echo "📝 创建基础文件..." # 创建 main.ts cat > src/main.ts << 'EOF' import { createApp } from 'vue' import { createPinia } from 'pinia' import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' import 'element-plus/theme-chalk/dark/css-vars.css' import router from './router' import App from './App.vue' import './assets/styles/index.scss' const app = createApp(App) const pinia = createPinia() app.use(pinia) app.use(router) app.use(ElementPlus) app.mount('#app') EOF # 创建路由配置 cat > src/router/index.ts << 'EOF' import { createRouter, createWebHistory } from 'vue-router' import type { RouteRecordRaw } from 'vue-router' const routes: RouteRecordRaw[] = [ { path: '/auth', name: 'Auth', component: () => import('@/layouts/AuthLayout.vue'), children: [ { path: 'login', name: 'Login', component: () => import('@/views/auth/Login.vue'), }, { path: 'register', name: 'Register', component: () => import('@/views/auth/Register.vue'), }, ], }, { path: '/', component: () => import('@/layouts/DefaultLayout.vue'), children: [ { path: '', name: 'Home', component: () => import('@/views/home/Index.vue'), }, { path: 'characters', name: 'Characters', component: () => import('@/views/character/List.vue'), }, { path: 'chat', name: 'Chat', component: () => import('@/views/chat/Index.vue'), }, { path: 'settings', name: 'Settings', component: () => import('@/views/settings/Index.vue'), }, ], }, ] const router = createRouter({ history: createWebHistory(), routes, }) // 路由守卫 router.beforeEach((to, from, next) => { const token = localStorage.getItem('st_access_token') if (!token && !to.path.startsWith('/auth')) { next('/auth/login') } else if (token && to.path.startsWith('/auth')) { next('/') } else { next() } }) export default router EOF # 创建全局样式 cat > src/assets/styles/index.scss << 'EOF' /* 全局样式 */ * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Segoe UI', 'Noto Sans', -apple-system, BlinkMacSystemFont, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } #app { width: 100%; height: 100vh; } /* 自定义滚动条 */ ::-webkit-scrollbar { width: 8px; height: 8px; } ::-webkit-scrollbar-track { background: var(--el-fill-color-light); } ::-webkit-scrollbar-thumb { background: var(--el-border-color-darker); border-radius: 4px; } ::-webkit-scrollbar-thumb:hover { background: var(--el-border-color-dark); } EOF # 创建 README cat > README.md << 'EOF' # 云酒馆前台应用 (Vue 3) ## 技术栈 - Vue 3 + TypeScript - Vite 5 - Element Plus - Vue Router 4 - Pinia - Axios ## 开发 ```bash # 安装依赖 npm install # 启动开发服务器 npm run dev # 构建生产版本 npm run build # 预览生产构建 npm run preview ``` ## 访问地址 - 开发环境: http://localhost:3000 - API 代理: http://localhost:8888 ## 项目结构 详见 `/docs/Vue重构方案.md` EOF echo "✅ 项目创建完成!" echo "" echo "📖 下一步:" echo " cd web-app-vue" echo " npm run dev" echo "" echo "🌐 访问地址:" echo " http://localhost:3000" echo "" echo "📚 详细文档:" echo " 请查看 docs/Vue重构方案.md"