feat: major update - MySQL, chat, wishlist, PWA, admin overhaul

This commit is contained in:
2026-03-21 20:22:00 +08:00
committed by 树萌芽
parent 48fb818b8c
commit 84874707f5
71 changed files with 13457 additions and 2031 deletions

View File

@@ -0,0 +1,167 @@
# 萌芽小店 · 前端
基于 **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>` 头部携带 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 / STKaitifallback 到系统衬线字体。
## 构建与部署
```bash
npm run build
```
产物在 `dist/` 目录,为静态文件,部署到 Nginx / CDN 时需配置:
```nginx
location / {
try_files $uri $uri/ /index.html; # SPA 路由支持
}
location /api/ {
proxy_pass http://localhost:8080; # 反向代理到后端
}
```