docs: add expiry docs and sql script

This commit is contained in:
hello-dd-code
2026-03-04 16:31:30 +08:00
parent ff16ea09d2
commit fe9f64f51d
6 changed files with 2168 additions and 0 deletions
+396
View File
@@ -0,0 +1,396 @@
# 保质期提醒小程序 - API 文档
## 基础信息
**Base URL**: `/api/expiry`
**认证方式**: JWT Token(通过公共登录接口获取,参见 `docs/common/auth.md`
**请求头**:
```
Authorization: Bearer <token>
Content-Type: application/json
```
---
## 1. 物品管理
### 1.1 获取物品列表
**接口**: `GET /api/expiry/items`
**Query 参数**:
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| status | string | ❌ | 状态筛选:all/expiring/expired/normal/used |
| category | string | ❌ | 分类筛选:all/food/medicine/cosmetic/other |
| sort | string | ❌ | 排序方式:expiry_date/created_at,默认 expiry_date |
| page | int | ❌ | 页码,默认 1 |
| page_size | int | ❌ | 每页数量,默认 20,最大 100 |
**响应示例**:
```json
{
"code": 0,
"message": "success",
"data": {
"items": [
{
"id": 1,
"name": "牛奶",
"category": "food",
"production_date": "2026-02-01",
"expiry_date": "2026-03-10",
"shelf_life_days": 37,
"quantity": 2,
"location": "冰箱",
"remark": "",
"status": "normal",
"days_left": 6,
"created_at": "2026-03-01T10:00:00Z",
"updated_at": "2026-03-01T10:00:00Z"
}
],
"total": 15,
"page": 1,
"page_size": 20
}
}
```
**状态说明**:
- `normal`: 正常(距离过期 > 7天)
- `expiring`: 即将过期(0-7天)
- `expired`: 已过期(< 0天)
- `used`: 已使用
- `discarded`: 已丢弃
**days_left 计算**:
- 正数:距离过期还有 N 天
- 0:今天过期
- 负数:已过期 N 天
---
### 1.2 获取首页汇总
**接口**: `GET /api/expiry/summary`
**响应示例**:
```json
{
"code": 0,
"message": "success",
"data": {
"total_items": 15,
"expiring_soon": 3,
"expired": 2,
"normal": 10,
"used": 0,
"discarded": 0
}
}
```
**字段说明**:
- `total_items`: 当前有效物品总数(不含已使用/已丢弃)
- `expiring_soon`: 7天内即将过期的数量
- `expired`: 已过期的数量
- `normal`: 正常状态的数量
- `used`: 已使用的数量
- `discarded`: 已丢弃的数量
---
### 1.3 添加物品
**接口**: `POST /api/expiry/items`
**请求体**:
```json
{
"name": "牛奶",
"category": "food",
"production_date": "2026-02-01",
"expiry_date": "2026-03-10",
"shelf_life_days": 37,
"quantity": 2,
"location": "冰箱",
"remark": "伊利纯牛奶"
}
```
**字段说明**:
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| name | string | ✅ | 物品名称,最长 100 字符 |
| category | string | ✅ | 分类:food/medicine/cosmetic/other |
| production_date | string | ❌ | 生产日期,格式 YYYY-MM-DD |
| expiry_date | string | ✅ | 过期日期,格式 YYYY-MM-DD |
| shelf_life_days | int | ❌ | 保质期天数 |
| quantity | int | ❌ | 数量,默认 1 |
| location | string | ❌ | 存放位置,最长 50 字符 |
| remark | string | ❌ | 备注,最长 255 字符 |
**业务逻辑**:
1. 如果提供 `production_date``shelf_life_days`,后端会自动计算 `expiry_date`(如果未提供)
2. `expiry_date` 必填,或者 `production_date` + `shelf_life_days` 组合必填
3. 初始状态为 `normal`,后端根据 `expiry_date` 自动计算 `days_left`
**响应示例**:
```json
{
"code": 0,
"message": "添加成功",
"data": {
"id": 1,
"name": "牛奶",
"category": "food",
"production_date": "2026-02-01",
"expiry_date": "2026-03-10",
"shelf_life_days": 37,
"quantity": 2,
"location": "冰箱",
"remark": "伊利纯牛奶",
"status": "normal",
"days_left": 6,
"created_at": "2026-03-04T10:00:00Z",
"updated_at": "2026-03-04T10:00:00Z"
}
}
```
---
### 1.4 更新物品
**接口**: `PUT /api/expiry/items/:id`
**路径参数**:
- `id`: 物品 ID
**请求体**: 同添加物品
**响应示例**:
```json
{
"code": 0,
"message": "更新成功",
"data": {
"id": 1,
"name": "牛奶(已开封)",
...
}
}
```
---
### 1.5 删除物品
**接口**: `DELETE /api/expiry/items/:id`
**路径参数**:
- `id`: 物品 ID
**响应示例**:
```json
{
"code": 0,
"message": "删除成功"
}
```
**说明**: 使用软删除,数据不会真正删除
---
### 1.6 标记物品状态
**接口**: `POST /api/expiry/items/:id/status`
**路径参数**:
- `id`: 物品 ID
**请求体**:
```json
{
"status": "used"
}
```
**status 可选值**:
- `used`: 已使用
- `discarded`: 已丢弃
**响应示例**:
```json
{
"code": 0,
"message": "标记成功",
"data": {
"id": 1,
"status": "used",
"updated_at": "2026-03-04T10:00:00Z"
}
}
```
---
## 2. 用户设置
### 2.1 获取用户设置
**接口**: `GET /api/expiry/settings`
**响应示例**:
```json
{
"code": 0,
"message": "success",
"data": {
"remind_days": [7, 3, 1]
}
}
```
**说明**: 如果用户未设置,返回默认值 `[7, 3, 1]`
---
### 2.2 更新用户设置
**接口**: `POST /api/expiry/settings`
**请求体**:
```json
{
"remind_days": [10, 5, 2, 1]
}
```
**字段说明**:
- `remind_days`: 提醒天数数组,最多 5 个值,每个值范围 1-30
**响应示例**:
```json
{
"code": 0,
"message": "更新成功",
"data": {
"remind_days": [10, 5, 2, 1]
}
}
```
---
## 3. 错误码
| code | message | 说明 |
|------|---------|------|
| 0 | success | 成功 |
| 400 | 参数错误 | 请求参数不合法 |
| 401 | 未授权 | Token 无效或过期 |
| 404 | 资源不存在 | 物品不存在 |
| 500 | 服务器错误 | 内部错误 |
**错误响应示例**:
```json
{
"code": 400,
"message": "物品名称不能为空"
}
```
---
## 4. 前端集成示例
### 4.1 获取首页数据
```javascript
// 并行请求
Promise.all([
wx.request({ url: '/api/expiry/summary' }),
wx.request({ url: '/api/expiry/items?status=expiring&page_size=10' })
]).then(([summary, items]) => {
// 渲染首页
});
```
### 4.2 添加物品
```javascript
wx.request({
url: '/api/expiry/items',
method: 'POST',
data: {
name: '牛奶',
category: 'food',
expiry_date: '2026-03-10',
quantity: 2,
location: '冰箱'
},
success: (res) => {
if (res.data.code === 0) {
wx.showToast({ title: '添加成功' });
// 刷新列表
}
}
});
```
### 4.3 标记已使用
```javascript
wx.request({
url: `/api/expiry/items/${itemId}/status`,
method: 'POST',
data: { status: 'used' },
success: (res) => {
if (res.data.code === 0) {
wx.showToast({ title: '已标记' });
// 刷新列表
}
}
});
```
---
## 5. 性能建议
### 5.1 缓存策略
- **summary**: 进入首页时刷新,缓存 5 分钟
- **items 列表**: 下拉刷新时更新,支持分页加载
- **settings**: 登录后缓存,修改时更新
### 5.2 请求优化
- 首页使用并行请求 `summary` + `items`
- 列表滚动到底部时自动加载下一页
- 使用防抖避免频繁请求
---
## 6. 数据库索引建议
```sql
-- 用户 + 过期日期(最常用查询)
CREATE INDEX idx_user_expiry ON expiry_items(user_id, expiry_date);
-- 用户 + 分类
CREATE INDEX idx_user_category ON expiry_items(user_id, category);
-- 用户 + 状态
CREATE INDEX idx_user_status ON expiry_items(user_id, status);
-- 软删除
CREATE INDEX idx_deleted_at ON expiry_items(deleted_at);
```