# 萌芽小店 · 前端 基于 **Vue 3 + Vite** 构建的数字商品销售平台前端,采用组件化模块架构。 ## 技术依赖 | 包 | 版本 | 用途 | |----|------|------| | vue | ^3.x | 核心框架 | | vite | ^5.x | 构建工具 | | vue-router | ^4.x | 路由管理 | | pinia | ^2.x | 状态管理 | | axios | ^1.6 | HTTP 请求 | | markdown-it | ^14 | Markdown 渲染 | ## 目录结构 ``` src/ ├── assets/ │ └── styles.css # 全局 CSS 变量与公共样式 ├── router/ │ └── index.js # 路由配置(含维护模式守卫) ├── modules/ │ ├── shared/ │ │ ├── api.js # 所有 API 请求封装 │ │ ├── auth.js # 认证状态(Pinia store) │ │ └── useWishlist.js # 收藏夹 Composable │ ├── store/ │ │ ├── StorePage.vue # 商品列表页 │ │ ├── ProductDetail.vue # 商品详情页 │ │ ├── CheckoutPage.vue # 结算页 │ │ └── components/ │ │ └── ProductCard.vue # 商品卡片组件 │ ├── admin/ │ │ ├── AdminPage.vue # 管理后台(编排层) │ │ └── components/ │ │ ├── AdminTokenRow.vue # 令牌输入 │ │ ├── AdminMaintenanceRow.vue # 维护模式开关 │ │ ├── AdminProductTable.vue # 商品列表表格 │ │ ├── AdminProductModal.vue # 商品编辑弹窗 │ │ ├── AdminOrderTable.vue # 订单记录表格 │ │ └── AdminChatPanel.vue # 用户聊天管理 │ ├── user/ │ │ └── MyOrdersPage.vue # 我的订单 │ ├── wishlist/ │ │ └── WishlistPage.vue # 收藏夹页面 │ ├── maintenance/ │ │ └── MaintenancePage.vue # 站点维护页面 │ └── chat/ │ └── ChatWidget.vue # 用户悬浮聊天窗口 └── App.vue # 根组件(全局布局 + 导航) ``` ## 路由列表 | 路径 | 组件 | 说明 | |------|------|------| | `/` | `StorePage` | 商品列表 | | `/product/:id` | `ProductDetail` | 商品详情 | | `/product/:id/checkout` | `CheckoutPage` | 结算页 | | `/my/orders` | `MyOrdersPage` | 我的订单(需登录)| | `/wishlist` | `WishlistPage` | 收藏夹(需登录)| | `/admin` | `AdminPage` | 管理后台(需令牌)| | `/maintenance` | `MaintenancePage` | 维护中页面 | ### 路由守卫 - **维护模式**:`beforeEach` 检查 `GET /api/site/maintenance`,若站点维护中则重定向到 `/maintenance`(管理员访问 `/admin` 时豁免) - 豁免路径:`/maintenance`、`/wishlist`、`/admin` ## 认证流程 使用 SproutGate OAuth 服务: 1. 未登录用户点击「萌芽账号登录」,跳转到 `https://auth.shumengya.top/login?callback=<当前页>` 2. 登录成功后回调携带 token,存入 localStorage 3. `authState`(reactive 对象)全局共享 `token`、`account`、`username`、`avatarUrl` 4. 所有需要认证的 API 请求在 `Authorization: Bearer ` 头部携带 token ## 主要功能模块 ### 商品列表(StorePage) - 视图模式(`viewMode`):全部 / 免费 / 新上架 / 最多购买 / 最多浏览 / 价格最高 / 价格最低 - 搜索:实时过滤商品名称 - 分页:桌面 20 条/页(4×5),手机 10 条/页(5×2) - 响应式布局:`window.innerWidth <= 900` 切换为双列 ### 结算页(CheckoutPage) - 展示商品信息与价格 - 数量输入,最大值受 `product.maxPerAccount` 限制 - 若商品开启 `showNote`:展示备注文本框 - 若商品开启 `showContact`:展示手机号和邮箱输入框 - 手动发货商品:展示蓝色提示条,确认后显示"等待发货中" - 自动发货商品:确认后展示卡密内容 ### 收藏夹(useWishlist Composable) ```js import { wishlistIds, wishlistCount, inWishlist, loadWishlist, toggleWishlist } from './useWishlist' ``` - 数据存储在后端,通过 API 同步 - `App.vue` 在登录状态变化时自动调用 `loadWishlist()` - 收藏状态通过 `wishlistSet`(computed Set)提供 O(1) 查找 ### 客服聊天(ChatWidget) - 仅已登录用户显示(右下角悬浮按钮) - 每 5 秒轮询新消息 - 客户端和服务端均限制每秒最多发送 1 条消息 ## 开发启动 ```bash npm install npm run dev # 开发服务器 :5173 npm run build # 生产构建 → dist/ npm run preview # 预览构建结果 ``` ### 环境变量 在项目根目录创建 `.env.local`: ```env VITE_API_BASE_URL=http://localhost:8080 ``` 生产部署时设置实际 API 地址。 ## 全局样式 `src/assets/styles.css` 定义了全局 CSS 变量: ```css :root { --accent: #91a8d0; /* 主题色 */ --accent-2: #b8c8e4; /* 渐变色 */ --text: #2c2c3a; /* 文字色 */ --muted: #8e8e9e; /* 次要文字 */ --line: rgba(0,0,0,0.08); /* 边框色 */ --radius: 8px; /* 圆角 */ } ``` 字体使用楷体(KaiTi / STKaiti),fallback 到系统衬线字体。 ## 构建与部署 ```bash npm run build ``` 产物在 `dist/` 目录,为静态文件,部署到 Nginx / CDN 时需配置: ```nginx location / { try_files $uri $uri/ /index.html; # SPA 路由支持 } location /api/ { proxy_pass http://localhost:8080; # 反向代理到后端 } ```