# 萌芽小店 · Mengyastore

一个前后端分离的轻量级数字商品商城，支持**卡密 / 固定内容**两种发货、扫码收款演示流程、邮件通知（直发或 RabbitMQ 队列）、聊天客服、收藏夹、管理端系统状态面板与 PWA 安装。

---

## 技术栈

### 前端 `mengyastore-frontend/`

| 分类 | 技术 | 说明 |
|------|------|------|
| 框架 | Vue 3 | Composition API + `<script setup>` |
| 构建 | Vite 5 + `@tailwindcss/vite` | 开发与生产打包 |
| 路由 | Vue Router 4 | History 模式 |
| 状态 | Pinia、本地 reactive | 收藏与认证等 |
| HTTP | Axios | `modules/shared/api.js` |
| Markdown | markdown-it | 商品描述 |
| PWA | vite-plugin-pwa | Service Worker、Manifest、更新提示 |
| 认证 | SproutGate OAuth | 回调 `AuthCallback.vue` |

**主要模块**

```
src/
  modules/
    admin/          # 管理后台（商品/订单/聊天/站点设置/系统状态）
    auth/           # OAuth 回调
    chat/           # 用户悬浮聊天
    maintenance/    # 维护页
    shared/         # api.js、auth、fulfillment.js、useWishlist、SplashScreen
    store/          # 商店、详情、结算（含真实收款码展示）
    user/           # 我的订单
    wishlist/       # 收藏夹
  assets/
    payment/        # 支付宝/微信收款图（打包进产物，供结算页演示）
    styles.css
  App.vue           # 顶栏；窄屏为汉堡菜单 + 下拉导航
  router/index.js   # 路由与维护模式守卫
```

---

### 后端 `mengyastore-backend-go/`

| 分类 | 技术 | 说明 |
|------|------|------|
| 语言 | Go 1.21+ | 单二进制部署 |
| Web | Gin | REST、CORS |
| ORM | GORM | MySQL，`Open` 时 AutoMigrate |
| 消息 | RabbitMQ（可选） | `internal/mq`，订单邮件可走队列；连接异常自动重连 |
| 缓存 | Redis（可选） | 配置项齐全，可用于扩展；管理端状态可探测 |
| 邮件 | `internal/email` | SMTP；与 MQ 二选一或降级 |
| 配置 | 环境变量 + `.env` | `internal/config`，见下文 |

**主要模块**

```
internal/
  auth/           # SproutGate 校验
  cache/          # Redis 等（按项目演进）
  config/         # Load()：APP_ENV、DB、Redis、RabbitMQ、HTTP 监听等
  database/       # db.go、models.go
  email/
  handlers/       # public、order、stats、wishlist、chat、admin_*、admin_status
  mq/             # AMQP 发布/消费、拓扑、重连
  models/
  storage/        # product、order、site、wishlist、chat（productstore 含 fulfillment）
cmd/migrate/      # 历史 JSON → MySQL 迁移
main.go           # 依赖注入、路由
```

**数据库表（要点）**

| 表 | 说明 |
|----|------|
| `products` | 含 `fulfillment_type`（`card`/`fixed`）、`fixed_content`、`delivery_mode`（订单侧自动/手动）等 |
| `product_codes` | 卡密行表；`fixed` 商品可不使用 |
| `orders` | `delivered_codes`、`notify_email`、`delivery_mode`、`status` |
| `site_settings` | 维护、SMTP、访问量等 KV |
| `wishlists` / `chat_messages` | 收藏与聊天 |

---

## 功能列表（摘要）

| 能力 | 前端 | 后端 |
|------|:----:|:----:|
| 商品浏览、详情、Markdown | ✅ | ✅ |
| **发货方式**：卡密（逐条库存）/ 固定内容（不限库存） | ✅ | ✅ |
| 结算页：应付金额、**本地上传收款码**、订单号一键复制 | ✅ | 订单仍返回 `qrCodeUrl` 作凭证 |
| 订单确认、我的订单 | ✅ | ✅ |
| SMTP 邮件；可选 **RabbitMQ** 排队发信 | — | ✅ |
| 管理端 **系统状态**（API/ MySQL/ Redis/ RabbitMQ） | ✅ | ✅ |
| 收藏夹、聊天、维护模式 | ✅ | ✅ |
| SproutGate 登录 | ✅ | ✅ |
| PWA | ✅ | — |
| **窄屏顶栏**（汉堡菜单） | ✅ | — |

---

## 快速开始

### 1. MySQL

创建库与用户后，**无需手写表结构**，后端首次连接会 `AutoMigrate`。

可参考 `mengyastore-backend-go/init.sql` 中的建库语句。

### 2. 后端配置

在 **`mengyastore-backend-go/`** 使用 **`.env`**（或环境变量）。常用项：

- `APP_ENV`：`development` / `production`（影响默认 DSN、RabbitMQ/Redis 默认地址等）
- `DATABASE_DSN`：MySQL 连接串
- `ADMIN_TOKEN`：管理端令牌
- `AUTH_API_URL`：SproutGate 网关
- `RABBITMQ_ENABLED`、`RABBITMQ_URL`（或密码拼装变量）
- `REDIS_ENABLED`、`REDIS_ADDR` 等（可选）
- `HTTP_LISTEN_ADDR`、`PUBLIC_API_BASE_URL`（系统状态展示用，可选）

```bash
cd mengyastore-backend-go
go run .    # 默认 :8080，见配置
```

### 3. 前端

```bash
cd mengyastore-frontend
npm install
npm run dev    # 默认 :5173
```

`.env.development` 中设置 `VITE_API_BASE_URL` 指向后端。

### 4. 管理后台

在站点 **Logo 上连续点击 5 次**，输入 `ADMIN_TOKEN`；或使用带 `?token=` 的 `/admin` 链接。

---

## 生产部署（Docker）

见 `mengyastore-backend-go/docker-compose.yml`：通过环境变量注入 `DATABASE_DSN`、`ADMIN_TOKEN`、`REDIS_*`、`RABBITMQ_*` 等，不要将真实密钥提交到 Git。

---

## 项目结构

```
mengyastore/
  mengyastore-frontend/     # Vue 3 + Vite 前端
  mengyastore-backend-go/   # Go + Gin 后端
  README.md                 # 本文件
```

---

## 工程亮点

- **两种发货**：卡密扣 `product_codes`；固定内容不扣库存，每笔订单复制 `fixed_content` 至 `delivered_codes`。
- **管理员鉴权**：`X-Admin-Token`（推荐）/ `Authorization` / `?token=`；`POST /api/admin/verify` 仅返回 `valid`。
- **MQ 韧性**：AMQP 504/断线后客户端会尝试重连并重启消费协程。
- **公开接口**：列表/详情不返回卡密与 `fixedContent`。
- **PWA**：离线缓存、启动屏、新版本 Toast。

---

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