2. 需求分析与设计:功能模块划分、数据库E-R图与接口规范
好,咱们进入第二章。说实话,很多新手做项目,上来就撸代码,结果写到一半发现逻辑打架,接口对不上。我个人的习惯是,先花半天时间把需求理清楚,把模块画出来。这就像盖房子,图纸没画好就砌砖,后面肯定得返工。
这一章,我会带你走完三个关键步骤:功能模块划分、数据库E-R图设计、接口文档规范。你想想看,这三件事做扎实了,后面的开发就是「填表格」的体力活了。
2.1 功能模块划分
一个小程序电商系统,核心就五个模块:用户、商品、购物车、订单、支付。嗯,这里要注意,千万别把「支付」和「订单」混在一起,它们是两个独立的东西。
2.1.1 用户模块
用户模块不只是登录注册。我记得有一次做项目,只做了手机号登录,结果用户反馈说「我想换个头像都找不到入口」。所以,用户模块至少包含:
- 注册与登录:微信授权登录 + 手机号绑定
- 个人信息管理:头像、昵称、收货地址
- 账户安全:密码修改、退出登录
2.1.2 商品模块
商品模块是门面。说白了,用户第一眼看到的就是商品列表。我建议把商品模块拆成:
- 商品分类:一级分类、二级分类(比如「女装」→「连衣裙」)
- 商品详情:标题、价格、库存、规格(颜色、尺寸)、轮播图
- 搜索与筛选:按价格排序、按销量排序、按分类筛选
2.1.3 购物车模块
购物车看似简单,其实坑不少。用户可能加购10件商品,但只结算3件。所以购物车需要:
- 商品列表:展示加购的商品,支持勾选/取消
- 数量修改:加号、减号,实时计算小计
- 库存校验:结算时检查库存是否充足
2.1.4 订单模块
订单模块是核心中的核心。我习惯把订单状态画成一条线:
- 待支付:用户提交订单,但还没付钱
- 已支付:支付成功,等待商家发货
- 已发货:商家发货,用户等待收货
- 已完成:用户确认收货
- 已取消:用户主动取消或超时未支付
每个状态都要有对应的操作按钮,比如「取消订单」、「查看物流」、「确认收货」。
2.1.5 支付模块
支付模块其实是一个「桥梁」。它连接了前端、后端和微信支付服务器。流程大概是:
- 前端发起支付请求
- 后端生成预支付订单,返回支付参数
- 前端调起微信支付
- 支付成功后,微信异步通知后端
这里有个关键点:支付结果以后端通知为准。前端显示的支付成功可能是假的,必须等后端收到微信的回调才算数。
2.2 数据库E-R图设计
E-R图,说白了就是「实体-关系图」。你想想看,用户和订单是什么关系?一个用户可以有多个订单,这就是一对多。商品和分类呢?一个分类下有多个商品,也是一对多。
我直接给你列出核心表的设计思路:
2.2.1 用户表(user)
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | int | 主键,自增 |
| openid | varchar(64) | 微信唯一标识 |
| nickname | varchar(32) | 昵称 |
| avatar | varchar(255) | 头像URL |
| phone | varchar(11) | 手机号 |
| created_at | datetime | 注册时间 |
2.2.2 商品表(product)
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | int | 主键 |
| category_id | int | 分类ID,外键 |
| title | varchar(100) | 商品标题 |
| price | decimal(10,2) | 价格 |
| stock | int | 库存数量 |
| image | varchar(255) | 主图 |
| status | tinyint | 状态:1上架,0下架 |
2.2.3 订单表(order)
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | int | 主键 |
| user_id | int | 用户ID |
| order_no | varchar(32) | 订单号(唯一) |
| total_price | decimal(10,2) | 总金额 |
| status | tinyint | 0待支付,1已支付,2已发货,3已完成,4已取消 |
| created_at | datetime | 下单时间 |
2.2.4 订单商品表(order_item)
为什么要有这张表?因为一个订单可能包含多个商品。比如你买了「T恤」和「裤子」,它们会出现在同一个订单里。这张表就是用来记录订单和商品的对应关系。
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | int | 主键 |
| order_id | int | 订单ID |
| product_id | int | 商品ID |
| quantity | int | 购买数量 |
| price | decimal(10,2) | 购买时的单价 |
用户 1 : N 订单
订单 1 : N 订单商品
商品 1 : N 订单商品
商品 N : 1 分类
2.3 接口文档规范(RESTful API)
接口文档是前后端沟通的「合同」。我见过太多因为接口定义不清导致的撕逼。前端说「你返回的字段名不对」,后端说「你传的参数格式错了」。所以,规范很重要。
2.3.1 RESTful 风格
说白了,RESTful 就是用 HTTP 方法来表示操作:
- GET:获取资源(比如获取商品列表)
- POST:创建资源(比如创建订单)
- PUT:更新资源(比如修改收货地址)
- DELETE:删除资源(比如删除购物车商品)
2.3.2 接口命名规范
我习惯用名词复数形式,比如:
GET /api/products— 获取商品列表GET /api/products/:id— 获取单个商品详情POST /api/orders— 创建订单PUT /api/users/:id/address— 更新用户地址
注意,不要用动词,比如 /api/getProducts 这种写法是不推荐的。
2.3.3 统一返回格式
所有接口返回统一的结构,前端才好统一处理。我常用的格式是:
{
"code": 200,
"message": "success",
"data": {
// 具体数据
}
}
错误时:
{
"code": 400,
"message": "参数错误:商品ID不能为空",
"data": null
}
2.3.4 接口示例
我挑几个核心接口给你看看:
1. 获取商品列表
GET /api/products?category_id=1&page=1&size=10
响应:
{
"code": 200,
"data": {
"list": [
{
"id": 1,
"title": "纯棉T恤",
"price": 59.90,
"image": "https://xxx.com/t-shirt.jpg"
}
],
"total": 100,
"page": 1,
"size": 10
}
}
2. 创建订单
POST /api/orders
请求体:
{
"items": [
{"product_id": 1, "quantity": 2},
{"product_id": 2, "quantity": 1}
],
"address_id": 5
}
响应:
{
"code": 200,
"data": {
"order_id": 123,
"order_no": "20250315123456",
"total_price": 179.70,
"status": 0
}
}
3. 发起支付
POST /api/pay
请求体:
{
"order_id": 123
}
响应:
{
"code": 200,
"data": {
"pay_params": {
"appId": "wx...",
"timeStamp": "1710000000",
"nonceStr": "random",
"package": "prepay_id=wx...",
"signType": "MD5",
"paySign": "signature"
}
}
}
2.4 本章小结
好,这一章的内容就这些。你想想看,我们做了三件事:
- 把系统拆成了5个模块,每个模块的职责清清楚楚
- 画出了核心表的结构和关系,数据库设计心里有底
- 定好了接口规范,前后端开发不会打架
下一章,我们会开始搭建开发环境,真正动手写代码。嗯,到时候你会觉得,前面这些设计工作,真的太值了。