docs: add expiry docs and sql script
This commit is contained in:
@@ -0,0 +1,393 @@
|
||||
# 保质期提醒小程序 - 产品需求文档 (PRD)
|
||||
|
||||
## 1. 产品概述
|
||||
|
||||
### 1.1 产品定位
|
||||
一款家庭物品保质期管理小程序,帮助用户记录食品、药品、化妆品等物品的保质期,提供临期提醒,减少浪费。
|
||||
|
||||
### 1.2 核心价值
|
||||
- **快速记录**:扫码/手动添加物品保质期
|
||||
- **智能提醒**:临期自动提醒,避免过期浪费
|
||||
- **分类管理**:按类别查看,一目了然
|
||||
- **统计分析**:了解消费习惯,优化采购
|
||||
|
||||
### 1.3 目标用户
|
||||
- 家庭主妇/主夫
|
||||
- 注重健康的年轻人
|
||||
- 有囤货习惯的用户
|
||||
|
||||
---
|
||||
|
||||
## 2. MVP 功能范围
|
||||
|
||||
### 2.1 核心功能(必做)
|
||||
|
||||
#### ✅ 物品管理
|
||||
- 添加物品(名称、分类、生产日期、保质期天数)
|
||||
- 编辑物品
|
||||
- 删除物品
|
||||
- 标记已使用/已丢弃
|
||||
|
||||
#### ✅ 提醒系统
|
||||
- 临期提醒(提前 7 天、3 天、1 天)
|
||||
- 已过期标记
|
||||
- 首页展示即将过期物品列表
|
||||
|
||||
#### ✅ 分类查看
|
||||
- 预设分类:食品、药品、化妆品、其他
|
||||
- 按分类筛选
|
||||
- 按过期时间排序
|
||||
|
||||
#### ✅ 基础统计
|
||||
- 当前物品总数
|
||||
- 即将过期数量(7天内)
|
||||
- 已过期数量
|
||||
|
||||
### 2.2 暂不实现(后续迭代)
|
||||
|
||||
- ❌ 拍照识别生产日期
|
||||
- ❌ 家庭成员共享
|
||||
- ❌ 购物清单联动
|
||||
- ❌ 消费习惯分析
|
||||
- ❌ 推送通知(小程序订阅消息)
|
||||
|
||||
---
|
||||
|
||||
## 3. 页面结构
|
||||
|
||||
### 3.1 首页 (home)
|
||||
|
||||
**核心目标**:快速查看即将过期物品
|
||||
|
||||
| 元素 | 说明 | 数据来源 |
|
||||
|------|------|----------|
|
||||
| 统计卡片 | 总数/即将过期/已过期 | `GET /expiry/summary` |
|
||||
| 即将过期列表 | 7天内过期的物品 | `GET /expiry/items?status=expiring` |
|
||||
| 快速添加按钮 | 浮动按钮 | 跳转添加页 |
|
||||
| 分类筛选 | 全部/食品/药品/化妆品/其他 | 前端筛选 |
|
||||
|
||||
**列表项展示**:
|
||||
- 物品名称
|
||||
- 分类图标
|
||||
- 剩余天数(红色:已过期,橙色:3天内,黄色:7天内)
|
||||
- 过期日期
|
||||
|
||||
### 3.2 添加/编辑页 (add_edit_item)
|
||||
|
||||
**表单字段**:
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
|------|------|------|------|
|
||||
| name | string | ✅ | 物品名称 |
|
||||
| category | enum | ✅ | 分类:food/medicine/cosmetic/other |
|
||||
| production_date | date | ❌ | 生产日期 |
|
||||
| expiry_date | date | ✅ | 过期日期 |
|
||||
| shelf_life_days | int | ❌ | 保质期天数(与过期日期二选一) |
|
||||
| quantity | int | ❌ | 数量(默认1) |
|
||||
| location | string | ❌ | 存放位置(冰箱/柜子等) |
|
||||
| remark | string | ❌ | 备注 |
|
||||
|
||||
**交互逻辑**:
|
||||
- 如果填写生产日期 + 保质期天数,自动计算过期日期
|
||||
- 如果直接填写过期日期,则不需要生产日期
|
||||
|
||||
### 3.3 全部物品页 (all_items)
|
||||
|
||||
**核心目标**:查看所有物品,支持筛选和排序
|
||||
|
||||
| 功能 | 说明 |
|
||||
|------|------|
|
||||
| 状态筛选 | 全部/即将过期/已过期/正常 |
|
||||
| 分类筛选 | 全部/食品/药品/化妆品/其他 |
|
||||
| 排序方式 | 按过期时间/按添加时间 |
|
||||
| 列表展示 | 同首页列表项 |
|
||||
| 左滑操作 | 编辑/删除/标记已用 |
|
||||
|
||||
### 3.4 个人中心 (profile)
|
||||
|
||||
**功能**:
|
||||
- 用户信息(头像、昵称)
|
||||
- 提醒设置(提前天数:7/3/1天)
|
||||
- 数据统计(累计添加、已使用、已过期)
|
||||
- 关于小程序
|
||||
|
||||
---
|
||||
|
||||
## 4. 数据模型
|
||||
|
||||
### 4.1 物品表 (expiry_items)
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| id | bigint | 主键 |
|
||||
| user_id | bigint | 用户ID(关联 users 表) |
|
||||
| mini_program_id | bigint | 小程序ID |
|
||||
| name | varchar(100) | 物品名称 |
|
||||
| category | varchar(20) | 分类:food/medicine/cosmetic/other |
|
||||
| production_date | date | 生产日期(可选) |
|
||||
| expiry_date | date | 过期日期 |
|
||||
| shelf_life_days | int | 保质期天数(可选) |
|
||||
| quantity | int | 数量(默认1) |
|
||||
| location | varchar(50) | 存放位置(可选) |
|
||||
| remark | varchar(255) | 备注(可选) |
|
||||
| status | varchar(20) | 状态:normal/used/expired/discarded |
|
||||
| created_at | timestamp | 创建时间 |
|
||||
| updated_at | timestamp | 更新时间 |
|
||||
| deleted_at | timestamp | 软删除 |
|
||||
|
||||
**索引**:
|
||||
- `idx_user_expiry` (user_id, expiry_date)
|
||||
- `idx_user_category` (user_id, category)
|
||||
- `idx_user_status` (user_id, status)
|
||||
|
||||
### 4.2 用户设置表 (expiry_user_settings)
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| id | bigint | 主键 |
|
||||
| user_id | bigint | 用户ID(唯一) |
|
||||
| remind_days | json | 提醒天数数组 [7,3,1] |
|
||||
| created_at | timestamp | 创建时间 |
|
||||
| updated_at | timestamp | 更新时间 |
|
||||
|
||||
---
|
||||
|
||||
## 5. API 设计
|
||||
|
||||
### 5.1 物品管理
|
||||
|
||||
#### 获取物品列表
|
||||
```
|
||||
GET /api/expiry/items
|
||||
Query:
|
||||
- status: string (expiring/expired/normal/used/all)
|
||||
- category: string (food/medicine/cosmetic/other/all)
|
||||
- sort: string (expiry_date/created_at)
|
||||
- page: int
|
||||
- page_size: int
|
||||
|
||||
Response:
|
||||
{
|
||||
"code": 0,
|
||||
"data": {
|
||||
"items": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "牛奶",
|
||||
"category": "food",
|
||||
"expiry_date": "2026-03-10",
|
||||
"days_left": 6,
|
||||
"status": "normal",
|
||||
"quantity": 2,
|
||||
"location": "冰箱"
|
||||
}
|
||||
],
|
||||
"total": 10,
|
||||
"page": 1,
|
||||
"page_size": 20
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 获取首页汇总
|
||||
```
|
||||
GET /api/expiry/summary
|
||||
|
||||
Response:
|
||||
{
|
||||
"code": 0,
|
||||
"data": {
|
||||
"total_items": 15,
|
||||
"expiring_soon": 3, // 7天内
|
||||
"expired": 2,
|
||||
"normal": 10
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 添加物品
|
||||
```
|
||||
POST /api/expiry/items
|
||||
Body:
|
||||
{
|
||||
"name": "牛奶",
|
||||
"category": "food",
|
||||
"production_date": "2026-02-01", // 可选
|
||||
"expiry_date": "2026-03-10", // 必填
|
||||
"shelf_life_days": 37, // 可选
|
||||
"quantity": 2,
|
||||
"location": "冰箱",
|
||||
"remark": ""
|
||||
}
|
||||
|
||||
Response:
|
||||
{
|
||||
"code": 0,
|
||||
"data": {
|
||||
"id": 1,
|
||||
"name": "牛奶",
|
||||
...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 更新物品
|
||||
```
|
||||
PUT /api/expiry/items/:id
|
||||
Body: 同添加物品
|
||||
|
||||
Response:
|
||||
{
|
||||
"code": 0,
|
||||
"data": { ... }
|
||||
}
|
||||
```
|
||||
|
||||
#### 删除物品
|
||||
```
|
||||
DELETE /api/expiry/items/:id
|
||||
|
||||
Response:
|
||||
{
|
||||
"code": 0,
|
||||
"message": "删除成功"
|
||||
}
|
||||
```
|
||||
|
||||
#### 标记物品状态
|
||||
```
|
||||
POST /api/expiry/items/:id/status
|
||||
Body:
|
||||
{
|
||||
"status": "used" // used/discarded
|
||||
}
|
||||
|
||||
Response:
|
||||
{
|
||||
"code": 0,
|
||||
"message": "标记成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 5.2 用户设置
|
||||
|
||||
#### 获取设置
|
||||
```
|
||||
GET /api/expiry/settings
|
||||
|
||||
Response:
|
||||
{
|
||||
"code": 0,
|
||||
"data": {
|
||||
"remind_days": [7, 3, 1]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 更新设置
|
||||
```
|
||||
POST /api/expiry/settings
|
||||
Body:
|
||||
{
|
||||
"remind_days": [7, 3, 1]
|
||||
}
|
||||
|
||||
Response:
|
||||
{
|
||||
"code": 0,
|
||||
"message": "更新成功"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 用户流程
|
||||
|
||||
### 6.1 新用户流程
|
||||
|
||||
```
|
||||
启动小程序
|
||||
↓
|
||||
微信登录 (wx.login)
|
||||
↓
|
||||
进入首页(空状态)
|
||||
↓
|
||||
点击"添加物品"
|
||||
↓
|
||||
填写表单
|
||||
↓
|
||||
提交成功 → 返回首页
|
||||
```
|
||||
|
||||
### 6.2 日常使用流程
|
||||
|
||||
```
|
||||
打开首页
|
||||
↓
|
||||
查看即将过期物品
|
||||
↓
|
||||
[需要添加新物品]
|
||||
↓
|
||||
点击浮动按钮
|
||||
↓
|
||||
填写表单 → 提交
|
||||
↓
|
||||
[物品已使用]
|
||||
↓
|
||||
左滑 → 标记已用
|
||||
↓
|
||||
[查看所有物品]
|
||||
↓
|
||||
切换到"全部"Tab
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 技术实现要点
|
||||
|
||||
### 7.1 过期状态计算
|
||||
|
||||
**后端统一计算**:
|
||||
- `days_left = expiry_date - today`
|
||||
- `status`:
|
||||
- `days_left < 0`: expired
|
||||
- `0 <= days_left <= 7`: expiring
|
||||
- `days_left > 7`: normal
|
||||
|
||||
### 7.2 提醒逻辑(MVP 暂不实现推送)
|
||||
|
||||
**前端展示提醒**:
|
||||
- 首页红点:有即将过期物品时显示
|
||||
- 列表颜色标记:
|
||||
- 红色:已过期
|
||||
- 橙色:3天内
|
||||
- 黄色:7天内
|
||||
- 绿色:正常
|
||||
|
||||
### 7.3 性能优化
|
||||
|
||||
**缓存策略**:
|
||||
- summary 数据:进入首页时刷新
|
||||
- items 列表:按页加载,支持下拉刷新
|
||||
|
||||
**索引优化**:
|
||||
- 按 user_id + expiry_date 查询(最常用)
|
||||
- 按 user_id + category 筛选
|
||||
|
||||
---
|
||||
|
||||
## 8. 待扩展功能(后续版本)
|
||||
|
||||
### V2.0
|
||||
- [ ] 拍照识别生产日期和保质期
|
||||
- [ ] 小程序订阅消息推送
|
||||
- [ ] 常用物品模板(快速添加)
|
||||
|
||||
### V3.0
|
||||
- [ ] 家庭成员共享
|
||||
- [ ] 购物清单联动
|
||||
- [ ] 消费习惯分析
|
||||
|
||||
### V4.0
|
||||
- [ ] 社区分享(保质期知识)
|
||||
- [ ] 积分系统(减少浪费奖励)
|
||||
Reference in New Issue
Block a user