# 萌芽小店 · Mengyastore

一个前后端分离的轻量级商城，支持自动/手动发货、邮件通知、聊天客服、收藏夹与 PWA 安装。

---

## 技术栈

### 前端 `mengyastore-frontend/`

| 分类 | 技术 | 版本 | 说明 |
|------|------|------|------|
| 框架 | Vue 3 | ^3.4 | Composition API + `<script setup>` |
| 构建工具 | Vite 5 | ^5.2 | 开发服务器 / 生产打包 |
| 路由 | Vue Router 4 | ^4.3 | Hash / History 模式 |
| 状态管理 | Pinia 2 | ^2.1 | 全局 auth 状态 |
| HTTP 客户端 | Axios | ^1.6 | API 请求封装 |
| Markdown 渲染 | markdown-it | ^14.1 | 商品描述富文本 |
| PWA | vite-plugin-pwa | ^1.2 | Service Worker + Web Manifest |
| PWA 图标生成 | @vite-pwa/assets-generator | ^1.0 | 从 logo 自动生成各尺寸 PNG |
| 认证 | SproutGate OAuth | — | 第三方账号系统，redirect 回调 |
| 样式 | 原生 CSS + Scoped | — | CSS 变量、Flexbox、Grid、媒体查询 |

**主要模块**

```
src/
  modules/
    admin/          # 管理员后台（商品/订单/聊天/站点设置）
    auth/           # OAuth 回调处理
    chat/           # 用户端悬浮聊天窗口
    maintenance/    # 维护模式页面
    shared/         # api.js / auth.js / SplashScreen.vue / useWishlist.js
    store/          # 商品列表、详情、结账
    user/           # 我的订单
    wishlist/       # 收藏夹
  assets/styles.css # 全局样式变量
  router/index.js   # 路由定义 + 全局导航守卫
  main.js           # 应用入口
```

**PWA 特性**

- `display: standalone` 独立窗口模式，可添加到主屏
- Service Worker：静态资源 `CacheFirst`，API 请求 `NetworkFirst`（5 分钟缓存）
- 自动检测新版本，底部 toast 提示更新
- 启动画面（SplashScreen.vue）：渐变背景 + Logo 浮动 + 扩散环 + 绿色圆点加载动画

---

### 后端 `mengyastore-backend/`

| 分类 | 技术 | 版本 | 说明 |
|------|------|------|------|
| 语言 | Go | 1.21+ | 静态编译，单二进制部署 |
| Web 框架 | Gin | ^1.9 | HTTP 路由、中间件、JSON 绑定 |
| ORM | GORM | ^1.25 | MySQL 数据库操作 |
| MySQL 驱动 | go-sql-driver/mysql | ^1.9 | GORM MySQL 方言 |
| CORS | gin-contrib/cors | — | 跨域请求支持 |
| UUID | google/uuid | — | 订单 ID 生成 |
| 邮件 | net/smtp + crypto/tls | 标准库 | SMTP 邮件通知，支持 SSL/TLS（端口 465） |
| 认证 | SproutGate OAuth | — | `/api/auth/verify` Token 验证 |
| 数据库 | MySQL 8.x | — | 生产：192.168.1.100:3306，测试：10.1.1.100:3306 |
| 容器化 | Docker + docker-compose | — | 镜像构建与部署 |

**主要模块**

```
internal/
  auth/         # SproutGate OAuth 客户端
  config/       # config.json 读写（adminToken、DSN 等）
  database/     # GORM 初始化 (db.go) + 表结构定义 (models.go)
  email/        # SMTP 邮件发送服务
  handlers/     # HTTP 处理器（按功能拆分文件）
    admin.go          # 通用管理员接口
    admin_chat.go     # 聊天管理
    admin_orders.go   # 订单管理（查看/确认/删除/分页）
    admin_product.go  # 商品 CRUD
    admin_site.go     # 站点设置（维护模式、SMTP 配置）
    chat.go           # 用户聊天消息读写
    order.go          # 下单 / 自动发货 / 邮件通知
    stats.go          # 访问统计
    wishlist.go       # 收藏夹
  models/       # 业务模型（Product、Order、Chat 等）
  storage/      # 数据库 CRUD 封装（每类资源一个文件）
cmd/
  migrate/main.go  # 数据库 Schema 初始化 / 迁移脚本
main.go             # 路由注册 + 依赖注入入口
```

**数据库表**

| 表名 | 主要字段 |
|------|---------|
| `products` | id, name, description, price, discount_price, cover_url, screenshot_urls, tags, codes（卡密）, delivery_mode, require_login, max_per_account, total_sold, view_count, active, created_at |
| `product_codes` | id, product_id, code（卡密条目） |
| `orders` | id, product_id, product_name, user_account, user_name, quantity, status, delivery_mode, delivered_codes, note, contact_phone, contact_email, notify_email, created_at |
| `chat_messages` | id, account_id, account_name, content, sent_at, from_admin |
| `wishlists` | id, account, product_id |
| `site_settings` | key, value（KV 存储：maintenance、SMTP 配置等） |

---

## 功能列表

| 功能 | 前端 | 后端 |
|------|------|------|
| 商品浏览（分页：桌面 4×5 / 手机 5×2） | ✅ | ✅ |
| 商品详情 + Markdown 描述 | ✅ | ✅ |
| 下单（自动/手动发货） | ✅ | ✅ |
| 订单邮件通知（SMTP 可配置） | ✅ | ✅ |
| 用户收藏夹 | ✅ | ✅ |
| 我的订单 | ✅ | ✅ |
| SproutGate 账号登录 | ✅ | ✅ |
| 用户聊天客服（HTTP 轮询） | ✅ | ✅ |
| 维护模式 | ✅ | ✅ |
| 管理后台 - 商品 CRUD | ✅ | ✅ |
| 管理后台 - 订单查看/确认/删除/分页 | ✅ | ✅ |
| 管理后台 - 聊天消息管理 | ✅ | ✅ |
| 管理后台 - SMTP 邮件配置（含启用/关闭开关） | ✅ | ✅ |
| 管理后台 - 站点设置（维护模式） | ✅ | ✅ |
| 访问统计 & 订单统计 | ✅ | ✅ |
| PWA 安装 + 离线缓存 | ✅ | — |
| 移动端响应式 | ✅ | — |

---

## 快速开始（从零部署）

### 1. 准备 MySQL 数据库

> **表结构无需手动创建**，后端启动时 GORM 会自动 `AutoMigrate`。  
> 只需创建数据库和用户：

```bash
mysql -u root -p < mengyastore-backend/init.sql
```

或手动执行：

```sql
CREATE DATABASE IF NOT EXISTS `mengyastore` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER IF NOT EXISTS 'mengyastore'@'%' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON `mengyastore`.* TO 'mengyastore'@'%';
FLUSH PRIVILEGES;
```

### 2. 配置后端

在 `mengyastore-backend/` 目录创建 `config.json`：

```json
{
  "adminToken": "your_admin_token_here",
  "databaseDsn": "mengyastore:your_password@tcp(127.0.0.1:3306)/mengyastore?charset=utf8mb4&parseTime=True&loc=Local"
}
```

也可以用环境变量覆盖（优先级更高）：

```bash
export DATABASE_DSN="mengyastore:your_password@tcp(127.0.0.1:3306)/mengyastore?charset=utf8mb4&parseTime=True&loc=Local"
```

### 3. 启动后端

```bash
cd mengyastore-backend
go run .           # http://localhost:8080
# 首次启动会自动创建全部表结构
```

### 4. 启动前端

```bash
cd mengyastore-frontend
npm install
npm run dev        # http://localhost:5173
```

### 5. 访问管理后台

在网站 Logo 上快速点击 **5 次**，输入 `config.json` 中的 `adminToken` 进入管理后台。

> **安全说明**：后端采用 `POST /api/admin/verify` 接口验证令牌，只返回 `{"valid": true/false}`，不会将令牌明文传输到前端。

---

## 生产部署（Docker）

```bash
cd mengyastore-backend

# 1. 创建 config.json（同上）
# 2. 修改 docker-compose.yml 中的 DATABASE_DSN 指向生产数据库
# 3. 启动
docker-compose up -d
```

`docker-compose.yml` 配置说明：

| 配置项 | 说明 |
|--------|------|
| `DATABASE_DSN` | 生产 MySQL 连接串（覆盖 config.json） |
| `./config.json:/app/config.json:ro` | 只读挂载配置文件 |

---

## 本地开发

```bash
# 前端热重载
cd mengyastore-frontend
npm install
npm run dev        # http://localhost:5173

# 后端热重载（需安装 air）
cd mengyastore-backend
go run .
```

**构建前端**

```bash
cd mengyastore-frontend
npm run build      # 输出到 dist/
```

**构建后端二进制**

```bash
cd mengyastore-backend
go build -o mengyastore-backend .
./mengyastore-backend
```

---

## 项目结构

```
mengyastore/
  mengyastore-frontend/   # Vue 3 + Vite 前端
  mengyastore-backend/    # Go + Gin 后端
  API_DOCS.md             # API 接口文档
  README.md               # 本文件
```

---

---

## 工程亮点

- **安全**：管理员令牌通过 `POST /api/admin/verify` 服务端验证，令牌不在网络中明文传输
- **防刷**：购买数量限制同时统计 `pending` 和 `completed` 状态，防止并发绕过
- **兼容**：管理员鉴权支持 `X-Admin-Token` 请求头（Spring Security 标准）/ `Authorization` / `?token` 三种方式
- **PWA**：Service Worker 离线缓存 + 启动动画 + 自动更新提示
- **可移植**：API 设计对齐 Spring Boot 风格，便于后端语言迁移

---

© 2025 – 2026 萌芽小店 · Powered by Vue 3 + Go + MySQL
