三松礼品库技术栈说明
一、项目概述
本项目是一个前后端分离的 Monorepo 工程,为海外礼品产品提供检索、筛选、详情浏览与批量导出 ZIP 的能力。
- 前端:React 18 单页应用(SPA),负责界面渲染与用户交互
- 后端:Spring Boot 3.4 REST API,负责业务逻辑、数据持久化、ZIP 生成
- 数据库:PostgreSQL(开发期用 H2 兼容模式零安装)
- 部署:Nginx 托管前端静态资源并反向代理后端,systemd 守护后端服务
d:\AAAAA\AAA-sans\
├── client/ # React 18 前端
├── server/ # Spring Boot 后端
├── deploy/ # 部署配置(Nginx / systemd / 构建脚本)
├── docs/ # 项目文档(本文件所在)
├── guidelines/
├── pnpm-workspace.yaml # Monorepo 工作区声明
└── README.md
整体架构
┌──────────┐ HTTP ┌──────────┐ /api/ ┌──────────────────┐ JDBC ┌──────────────┐
│ 浏览器 │ ───────────▶ │ Nginx │ ───────────▶ │ Spring Boot │ ────────▶ │ PostgreSQL │
│ │ │ :80 │ │ :8080 (/api) │ │ │
└──────────┘ └────┬─────┘ └────────┬─────────┘ └──────────────┘
│ │
│ 静态资源 │ Flyway
▼ ▼
client/dist/ 建表 + 22 条种子数据
- 开发期:Vite dev server (5173) 通过
server.proxy 把 /api 转发到后端 8080
- 生产期:Nginx 把
/api/ 反代到后端 8080,其余路径回退到 index.html(SPA 路由)
二、前端技术栈(client/)
2.1 核心框架
| 技术 |
版本 |
用途 |
| React |
18.3.1 |
UI 框架 |
| React DOM |
18.3.1 |
DOM 渲染 |
| TypeScript |
— |
类型系统 |
| Vite |
6.3.5 |
开发服务器 + 生产构建 |
| React Router |
7.13.0 |
客户端路由 |
2.2 样式与 UI
| 技术 |
版本 |
用途 |
| Tailwind CSS |
4.1.12 |
原子化 CSS(通过 @tailwindcss/vite 插件集成) |
| MUI(@mui/material + @mui/icons-material) |
7.3.5 |
Material 组件库 |
| @emotion/react / @emotion/styled |
11.14.x |
MUI 的样式引擎 |
| Radix UI |
1.x |
无障碍无头组件(dialog、dropdown、tabs、checkbox 等 20+ 组件) |
| lucide-react |
0.487.0 |
图标库 |
| class-variance-authority + clsx + tailwind-merge |
— |
条件 className 工具 |
| tw-animate-css |
1.3.8 |
Tailwind 动画工具类 |
2.3 功能库
| 技术 |
版本 |
用途 |
| react-hook-form |
7.55.0 |
表单状态与校验 |
| Recharts |
2.15.2 |
数据图表 |
| motion(framer-motion) |
12.23.24 |
动画 |
| react-responsive-masonry |
2.7.1 |
产品瀑布流布局 |
| react-dnd + react-dnd-html5-backend |
16.0.1 |
拖拽交互 |
| embla-carousel-react |
8.6.0 |
轮播 |
| react-slick |
0.31.0 |
滑块 |
| react-resizable-panels |
2.1.7 |
可调尺寸面板 |
| react-day-picker |
8.10.1 |
日期选择 |
| date-fns |
3.6.0 |
日期处理 |
| sonner |
2.0.3 |
Toast 通知 |
| vaul |
1.1.2 |
Drawer 组件 |
| cmdk |
1.1.1 |
命令面板 |
| input-otp |
1.4.2 |
OTP 输入 |
| canvas-confetti |
1.9.4 |
彩纸动画(导出成功庆祝) |
| next-themes |
0.4.6 |
主题切换 |
| react-popper + @popperjs/core |
2.3.0 / 2.11.8 |
定位浮层 |
2.4 开发依赖
| 技术 |
版本 |
用途 |
| @vitejs/plugin-react |
4.7.0 |
Vite 的 React 支持(Fast Refresh) |
| @types/react / @types/react-dom |
18.3.x |
TypeScript 类型定义 |
2.5 前端脚本
{
"dev": "vite",
"build": "vite build",
"preview": "vite preview --port 4173",
"typecheck": "tsc --noEmit"
}
三、后端技术栈(server/)
3.1 核心框架
| 技术 |
版本 |
用途 |
| Spring Boot |
3.4.5 |
应用框架(parent POM) |
| Java |
21 |
编程语言 / JDK |
| Maven |
— |
构建工具 |
3.2 Spring 模块
| 依赖 |
用途 |
| spring-boot-starter-web |
REST API(内置 Tomcat、Jackson) |
| spring-boot-starter-data-jpa |
ORM(Hibernate 实现) |
| spring-boot-starter-validation |
@Valid 参数校验 |
| spring-boot-starter-test |
单元/集成测试 |
3.3 数据持久化
| 技术 |
版本 |
用途 |
| Flyway(flyway-core + flyway-database-postgresql) |
— |
数据库版本迁移(V1__init_schema.sql、V2__seed_products.sql 等) |
| PostgreSQL Driver |
— |
生产数据库驱动(runtime) |
| H2 Database |
— |
开发期数据库(runtime,PostgreSQL 兼容模式) |
| Hibernate |
— |
JPA 实现,ddl-auto=validate(禁止自动建表,全由 Flyway 管理) |
| HikariCP |
— |
连接池(Spring Boot 默认) |
3.4 工具库
| 技术 |
版本 |
用途 |
| Apache Commons Compress |
1.27.1 |
导出 ZIP 打包(产品图片 + metadata.json) |
| Lombok |
— |
减少样板代码(@Data、@RequiredArgsConstructor 等) |
3.5 后端包结构
com.singsong
├── config/ # CorsConfig、AsyncConfig(导出任务线程池)
├── controller/ # ProductController、ExportController
├── service/ # ProductService、SimilarityService、ExportTaskRunner
├── repository/ # JPA Repository
├── entity/ # JPA 实体
├── dto/ # 请求/响应 DTO
├── mapper/ # Entity ↔ DTO 映射
├── export/ # ImageDownloader、ZipPackager、MetadataWriter
└── exception/ # 全局异常处理
四、数据库
| 场景 |
数据库 |
说明 |
| 开发期 |
H2 文件库 |
server/data/singsong.*,PostgreSQL 兼容模式,零安装 |
| 生产期 |
PostgreSQL 15+ |
通过 application-prod.yml + 环境变量 DB_HOST/DB_USER/DB_PASSWORD 配置 |
主要表
| 表 |
说明 |
| products |
产品主表(22 条种子数据) |
| product_images |
产品图片(1:N) |
| product_tags |
产品标签(1:1,series/season/function/material) |
| product_visual_tags |
视觉标签(1:N,如"南瓜""枫叶") |
| export_records |
导出任务记录 |
| export_record_products |
导出-产品关联(M:N) |
| users |
Mock 用户(暂不鉴权) |
五、工程与部署
| 类别 |
技术 / 工具 |
| 仓库结构 |
Monorepo(pnpm-workspace.yaml 声明 packages: [client]) |
| 前端包管理 |
pnpm / npm |
| 后端包管理 |
Maven |
| 前端部署 |
Nginx 托管 client/dist/ 静态资源 |
| 后端部署 |
systemd 守护 singsong-server.jar |
| 反向代理 |
Nginx /api/ → http://127.0.0.1:8080(保留 /api 前缀匹配后端 context-path=/api) |
| 异步任务 |
Spring @Async + ThreadPool(core=2/max=4/queue=50)执行导出任务 |
| 文件下载 |
FileSystemResource 流式输出 ZIP,中文文件名用 RFC 5987 编码 |
部署产物
| 产物 |
构建命令 |
部署位置 |
| 后端 jar |
cd server && mvn clean package -DskipTests |
/opt/singsong/server/singsong-server.jar |
| 前端静态资源 |
cd client && npm run build |
/opt/singsong/client-dist/ |
一键构建脚本:deploy/build.sh / deploy/build.ps1
六、环境依赖汇总
本地开发 / 构建所需环境:
| 工具 |
最低版本 |
验证命令 |
| JDK |
21(推荐 Amazon Corretto 21) |
java -version |
| Maven |
3.9+ |
mvn -v |
| Node.js |
20+ |
node -v |
| npm / pnpm |
npm 10+ / pnpm 9+ |
npm -v |
| PostgreSQL(可选) |
15+ |
仅生产/集成测试需要,开发用 H2 |
| Nginx(可选) |
1.20+ |
仅生产部署需要 |
七、关键技术决策说明
开发用 H2,生产用 PostgreSQL:开发期零安装(数据落文件),通过 MODE=PostgreSQL 兼容模式确保 SQL 语法与生产一致;ddl-auto=validate 禁止 JPA 自动建表,schema 完全由 Flyway 管理,避免环境差异。
同源 /api + Vite proxy / Nginx 反代:开发与生产前端代码无差异,免 CORS 配置;后端通过 server.servlet.context-path=/api 接收前缀。
数据规模小(22 条)采用内存过滤:ProductService.search 一次性加载全部产品到内存做过滤/排序/分页,语义与原前端 mock 完全对齐;后续数据量增长可改为 JPA Specification + LIMIT/OFFSET。
导出 ZIP 异步生成:POST /exports 立即返回 taskId,@Async 后台拉图打包,前端轮询 GET /exports/{taskId}/status 获取进度,完成后 GET /exports/{id}/download 下载。
认证暂用 Mock 用户:当前 users 表只插一条 设计师小王,不鉴权;后续可加 Spring Security + JWT。
八、相关文档