Files
2026-03-04 16:31:30 +08:00

397 lines
7.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 保质期提醒小程序 - 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);
```