5.4 KiB
5.4 KiB
萌芽小店 · 前端
基于 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 服务:
- 未登录用户点击「萌芽账号登录」,跳转到
https://auth.shumengya.top/login?callback=<当前页> - 登录成功后回调携带 token,存入 localStorage
authState(reactive 对象)全局共享token、account、username、avatarUrl- 所有需要认证的 API 请求在
Authorization: Bearer <token>头部携带 token
主要功能模块
商品列表(StorePage)
- 视图模式(
viewMode):全部 / 免费 / 新上架 / 最多购买 / 最多浏览 / 价格最高 / 价格最低 - 搜索:实时过滤商品名称
- 分页:桌面 20 条/页(4×5),手机 10 条/页(5×2)
- 响应式布局:
window.innerWidth <= 900切换为双列
结算页(CheckoutPage)
- 展示商品信息与价格
- 数量输入,最大值受
product.maxPerAccount限制 - 若商品开启
showNote:展示备注文本框 - 若商品开启
showContact:展示手机号和邮箱输入框 - 手动发货商品:展示蓝色提示条,确认后显示"等待发货中"
- 自动发货商品:确认后展示卡密内容
收藏夹(useWishlist Composable)
import { wishlistIds, wishlistCount, inWishlist, loadWishlist, toggleWishlist } from './useWishlist'
- 数据存储在后端,通过 API 同步
App.vue在登录状态变化时自动调用loadWishlist()- 收藏状态通过
wishlistSet(computed Set)提供 O(1) 查找
客服聊天(ChatWidget)
- 仅已登录用户显示(右下角悬浮按钮)
- 每 5 秒轮询新消息
- 客户端和服务端均限制每秒最多发送 1 条消息
开发启动
npm install
npm run dev # 开发服务器 :5173
npm run build # 生产构建 → dist/
npm run preview # 预览构建结果
环境变量
在项目根目录创建 .env.local:
VITE_API_BASE_URL=http://localhost:8080
生产部署时设置实际 API 地址。
全局样式
src/assets/styles.css 定义了全局 CSS 变量:
:root {
--accent: #91a8d0; /* 主题色 */
--accent-2: #b8c8e4; /* 渐变色 */
--text: #2c2c3a; /* 文字色 */
--muted: #8e8e9e; /* 次要文字 */
--line: rgba(0,0,0,0.08); /* 边框色 */
--radius: 8px; /* 圆角 */
}
字体使用楷体(KaiTi / STKaiti),fallback 到系统衬线字体。
构建与部署
npm run build
产物在 dist/ 目录,为静态文件,部署到 Nginx / CDN 时需配置:
location / {
try_files $uri $uri/ /index.html; # SPA 路由支持
}
location /api/ {
proxy_pass http://localhost:8080; # 反向代理到后端
}