# 萌芽小店(Mengyastore)面试经历要点 ## 1. 项目一句话 一个前后端分离的轻量级商城系统,支持商品浏览、下单与发货(自动/手动)、邮件通知、聊天客服、收藏夹,以及 PWA 安装与离线缓存。 ## 2. 技术栈(可直接复述) - 前端:Vue 3(Composition API)、Vite、Vue Router 4、Pinia、Axios、`markdown-it`(商品描述渲染)、PWA(`vite-plugin-pwa`) - 后端:Go 1.21+、Gin、GORM、MySQL、SMTP 邮件发送(net/smtp + TLS) - 部署:Docker / docker-compose(后端二进制容器化 + 挂载只读配置) - 认证:SproutGate OAuth(用户侧 Bearer token 校验);管理员使用 `adminToken`(`/api/admin/verify` + 请求头/查询参数校验) ## 3. 整体架构 - 前端:按功能拆分模块(`admin/` 管理后台、`store/` 商品/结账、`chat/` 客服、`wishlist/` 收藏、`maintenance/` 维护页),并在路由层做维护模式守卫。 - 后端:使用 `internal/handlers` 按业务拆路由与处理逻辑;使用 `internal/storage` 把数据访问封装成独立存储层;通过 `cmd/migrate` 做旧数据到 MySQL 的迁移/初始化。 - 数据库:以 `products / product_codes / orders / chat_messages / wishlists / site_settings` 等核心表承载业务状态与统计。 ## 4. 关键业务链路(面试重点) ### 4.1 商品浏览与下单 - 商品列表:`GET /api/products` - 记录浏览量:`POST /api/products/:id/view` - 下单(创建订单与支付流程):`POST /api/checkout` - 确认付款/触发发货:`POST /api/orders/:id/confirm` ### 4.2 自动发货 vs 手动发货 - 自动发货(`deliveryMode = "auto"`):在下单/确认流程中从 `product_codes` 取出卡密,写入订单 `delivered_codes`,订单完成后返回卡密内容,并更新销量统计。 - 手动发货(`deliveryMode = "manual"`):下单不提取卡密,确认后订单状态变为完成但不返回卡密;管理员在后台查看订单信息后进行发货相关操作。 ### 4.3 邮件通知(SMTP 可配置) - 由管理员在后台配置 SMTP:`GET/POST /api/admin/site/smtp` - 下单或状态变更时触发邮件通知(例如订单确认/发货相关通知)。 ### 4.4 聊天客服(HTTP 轮询) - 用户端拉取消息:`GET /api/chat/messages` - 用户端发送消息(有频率限制):`POST /api/chat/messages` - 管理员端会话管理: - 获取全部会话:`GET /api/admin/chat` - 获取指定用户会话:`GET /api/admin/chat/:account` - 管理员回复:`POST /api/admin/chat/:account` - 清除对话:`DELETE /api/admin/chat/:account` ### 4.5 维护模式与管理后台鉴权 - 维护模式:前端在路由守卫里调用 `GET /api/site/maintenance`,站点维护时重定向到 `/maintenance`(管理员可豁免)。 - 管理后台鉴权:`POST /api/admin/verify` 校验 token;后续管理员接口通过 `X-Admin-Token` 头部携带。 ## 5. PWA 体验亮点(可讲“工程化”) - 支持 `display: standalone` 的安装到桌面体验 - Service Worker:静态资源 `CacheFirst`,API 请求 `NetworkFirst`(API 有短时缓存策略) - 自动检测新版本并提示更新 - 启动动画与引导(SplashScreen 过渡体验) ## 6. 数据治理/防刷点(面试可用) - 针对购买并发/绕过:通过统计 `pending` 与 `completed` 等订单状态来限制每账户购买数量,减少并发下的超额风险。 - 对外接口与管理员接口分离:公开接口与需要登录/需要管理员 token 的接口分层,降低权限误用概率。 ## 7. 部署与环境配置(可讲“落地”) - 后端容器通过 `DATABASE_DSN` 环境变量覆盖配置文件里的 DSN - `config.json` 作为只读挂载到容器内,减少运行时误写配置的风险 - 端口映射示例:`28081:8080` ## 8. 面试常问我怎么回答(可直接拿来用) 1. 为什么不使用 WebSocket? - 该项目选择 HTTP 轮询实现客服,降低复杂度;在并发不极端的场景下更易落地、便于维护,并且配合频率限制即可控制滥用。 2. 自动发货如何保证数据一致? - 关键状态更新与卡密提取/写入集中在后端的“创建订单/确认订单”链路内,确保业务流程按接口语义串联执行(如订单完成状态与卡密归属同步)。 3. PWA 离线策略怎么选? - 静态资源走 `CacheFirst` 提升加载速度与离线能力;API 走 `NetworkFirst` 保持业务数据的新鲜度,必要时做短时缓存降抖。 ## 9. 你可以按自己的贡献再补一句(占位) - 个人在项目中主要负责:前端模块/接口封装/后端某模块实现(按实际替换) - 自己解决过的一个难点:例如“接口鉴权边界/订单发货逻辑/SMTP 配置联调/PWA 缓存策略”等(按实际替换)