# 保质期提醒小程序 - 开发任务清单 本文档按优先级和依赖关系拆分开发任务,便于团队协作和进度跟踪。 --- ## 🎯 Milestone 1: 数据库与基础架构(优先级:P0) ### Issue #1: 数据库表设计与初始化 **标签**: `database`, `P0` **预计工时**: 0.5天 **任务描述**: - [ ] 创建 `expiry_items` 表(物品表) - [ ] 创建 `expiry_user_settings` 表(用户设置表) - [ ] 添加必要的索引 - [ ] 编写 SQL 初始化脚本 `docs/sql/expiry.sql` **验收标准**: - 表结构符合 PRD 设计 - 索引覆盖常用查询场景 - 可通过脚本一键初始化 **SQL 脚本位置**: `/root/wx_service/docs/sql/expiry.sql` --- ### Issue #2: 创建 expiry 模块目录结构 **标签**: `backend`, `architecture`, `P0` **预计工时**: 0.5天 **任务描述**: - [ ] 创建 `internal/expiry` 目录 - [ ] 创建 `model.go` - 定义数据模型 - [ ] 创建 `repository.go` - 数据访问层 - [ ] 创建 `service.go` - 业务逻辑层 - [ ] 创建 `handler.go` - HTTP 处理器 - [ ] 在 `internal/routes/routes.go` 注册路由 **目录结构**: ``` internal/expiry/ ├── handler.go ├── service.go ├── model.go └── repository.go ``` **验收标准**: - 目录结构清晰,符合项目规范 - 路由注册成功,可通过 `/api/expiry/healthz` 测试 --- ## 🔧 Milestone 2: 后端核心接口(优先级:P0) ### Issue #3: 实现物品数据模型 **标签**: `backend`, `model`, `P0` **预计工时**: 0.5天 **依赖**: Issue #1, #2 **任务描述**: - [ ] 定义 `ExpiryItem` 结构体 - [ ] 定义 `ExpiryUserSettings` 结构体 - [ ] 实现 GORM 模型标签 - [ ] 实现 `CalculateDaysLeft()` 方法 - [ ] 实现 `CalculateStatus()` 方法 **核心逻辑**: ```go type ExpiryItem struct { ID uint `json:"id" gorm:"primaryKey"` UserID uint `json:"user_id"` MiniProgramID uint `json:"mini_program_id"` Name string `json:"name"` Category string `json:"category"` ProductionDate *time.Time `json:"production_date"` ExpiryDate time.Time `json:"expiry_date"` ShelfLifeDays *int `json:"shelf_life_days"` Quantity int `json:"quantity" gorm:"default:1"` Location string `json:"location"` Remark string `json:"remark"` Status string `json:"status" gorm:"default:'normal'"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` DeletedAt gorm.DeletedAt `json:"-" gorm:"index"` } // 计算剩余天数 func (item *ExpiryItem) CalculateDaysLeft() int { now := time.Now().Truncate(24 * time.Hour) expiry := item.ExpiryDate.Truncate(24 * time.Hour) return int(expiry.Sub(now).Hours() / 24) } // 计算状态 func (item *ExpiryItem) CalculateStatus() string { daysLeft := item.CalculateDaysLeft() if daysLeft < 0 { return "expired" } else if daysLeft <= 7 { return "expiring" } return "normal" } ``` **验收标准**: - 模型定义完整,字段类型正确 - 辅助方法逻辑正确 - 通过单元测试 --- ### Issue #4: 实现物品 Repository 层 **标签**: `backend`, `repository`, `P0` **预计工时**: 1天 **依赖**: Issue #3 **任务描述**: - [ ] `Create(item *ExpiryItem) error` - 创建物品 - [ ] `Update(item *ExpiryItem) error` - 更新物品 - [ ] `Delete(id, userID uint) error` - 删除物品(软删除) - [ ] `FindByID(id, userID uint) (*ExpiryItem, error)` - 查询单个物品 - [ ] `FindByUser(userID uint, filters map[string]interface{}, page, pageSize int) ([]ExpiryItem, int64, error)` - 查询用户物品列表 - [ ] `GetSummary(userID uint) (map[string]int, error)` - 获取统计汇总 - [ ] `UpdateStatus(id, userID uint, status string) error` - 更新状态 **验收标准**: - 所有方法实现完整 - 支持分页、筛选、排序 - 错误处理完善 --- ### Issue #5: 实现物品 Service 层 **标签**: `backend`, `service`, `P0` **预计工时**: 1天 **依赖**: Issue #4 **任务描述**: - [ ] `CreateItem(userID uint, req CreateItemRequest) (*ExpiryItem, error)` - 创建物品 - 验证必填字段 - 如果提供生产日期+保质期,自动计算过期日期 - 调用 Repository 创建 - [ ] `UpdateItem(id, userID uint, req UpdateItemRequest) (*ExpiryItem, error)` - 更新物品 - [ ] `DeleteItem(id, userID uint) error` - 删除物品 - [ ] `GetItem(id, userID uint) (*ExpiryItem, error)` - 获取单个物品 - [ ] `GetItems(userID uint, filters ItemFilters) (*ItemListResponse, error)` - 获取物品列表 - 支持状态筛选(all/expiring/expired/normal/used) - 支持分类筛选 - 支持排序(expiry_date/created_at) - 计算 days_left - [ ] `GetSummary(userID uint) (*SummaryResponse, error)` - 获取汇总统计 - [ ] `UpdateItemStatus(id, userID uint, status string) error` - 更新状态 **验收标准**: - 业务逻辑正确 - 参数验证完善 - 返回数据包含 days_left 计算结果 --- ### Issue #6: 实现物品 Handler 层 **标签**: `backend`, `handler`, `P0` **预计工时**: 1天 **依赖**: Issue #5 **任务描述**: - [ ] `GetSummary(c *gin.Context)` - GET /api/expiry/summary - [ ] `GetItems(c *gin.Context)` - GET /api/expiry/items - [ ] `CreateItem(c *gin.Context)` - POST /api/expiry/items - [ ] `UpdateItem(c *gin.Context)` - PUT /api/expiry/items/:id - [ ] `DeleteItem(c *gin.Context)` - DELETE /api/expiry/items/:id - [ ] `UpdateStatus(c *gin.Context)` - POST /api/expiry/items/:id/status **验收标准**: - 所有接口可通过 Postman/curl 测试 - 返回格式符合 API 文档 - 错误处理完善(400/401/404/500) --- ### Issue #7: 实现用户设置接口 **标签**: `backend`, `settings`, `P1` **预计工时**: 0.5天 **依赖**: Issue #2 **任务描述**: - [ ] Repository: `GetSettings(userID uint)`, `UpdateSettings(userID uint, remindDays []int)` - [ ] Service: 验证 remind_days 数组(最多5个,范围1-30) - [ ] Handler: `GetSettings(c *gin.Context)`, `UpdateSettings(c *gin.Context)` **验收标准**: - 默认返回 [7,3,1] - 更新后持久化到数据库 --- ## 📱 Milestone 3: 小程序前端开发(优先级:P0) ### Issue #8: 小程序项目初始化 **标签**: `frontend`, `setup`, `P0` **预计工时**: 0.5天 **任务描述**: - [ ] 创建小程序项目 - [ ] 配置 `app.json`(页面路由、TabBar) - [ ] 配置 `project.config.json` - [ ] 封装 API 请求工具(支持 JWT Token) - [ ] 实现登录逻辑(复用公共登录接口) **TabBar 配置**: ```json { "list": [ { "pagePath": "pages/expiry/home/home", "text": "首页", "iconPath": "images/home.png", "selectedIconPath": "images/home-active.png" }, { "pagePath": "pages/expiry/list/list", "text": "全部", "iconPath": "images/list.png", "selectedIconPath": "images/list-active.png" }, { "pagePath": "pages/expiry/profile/profile", "text": "我的", "iconPath": "images/profile.png", "selectedIconPath": "images/profile-active.png" } ] } ``` **验收标准**: - 小程序可正常运行 - 登录流程正常 - API 请求工具可用 --- ### Issue #9: 首页开发 **标签**: `frontend`, `home`, `P0` **预计工时**: 1.5天 **依赖**: Issue #6, #8 **任务描述**: - [ ] 统计卡片组件(总数/即将过期/已过期) - [ ] 即将过期物品列表 - [ ] 列表项组件(名称、分类图标、剩余天数、过期日期) - [ ] 浮动添加按钮 - [ ] 下拉刷新 - [ ] 空状态提示 **UI 要点**: - 剩余天数颜色:红色(已过期)、橙色(3天内)、黄色(7天内)、绿色(正常) - 分类图标:食品🍎、药品💊、化妆品💄、其他📦 **验收标准**: - 数据正确展示 - 交互流畅 - 空状态友好 --- ### Issue #10: 添加/编辑页开发 **标签**: `frontend`, `form`, `P0` **预计工时**: 1.5天 **依赖**: Issue #6, #8 **任务描述**: - [ ] 表单组件(名称、分类、日期、数量、位置、备注) - [ ] 日期选择器(生产日期、过期日期) - [ ] 分类选择器(食品/药品/化妆品/其他) - [ ] 自动计算过期日期(生产日期 + 保质期天数) - [ ] 表单验证 - [ ] 提交逻辑(新增/编辑) **交互逻辑**: - 如果填写生产日期 + 保质期天数,自动计算过期日期 - 过期日期必填 **验收标准**: - 表单验证完善 - 新增/编辑功能正常 - 自动计算逻辑正确 --- ### Issue #11: 全部物品页开发 **标签**: `frontend`, `list`, `P0` **预计工时**: 1.5天 **依赖**: Issue #6, #8 **任务描述**: - [ ] 状态筛选 Tabs(全部/即将过期/已过期/正常) - [ ] 分类筛选(全部/食品/药品/化妆品/其他) - [ ] 排序切换(按过期时间/按添加时间) - [ ] 物品列表(复用首页列表项组件) - [ ] 左滑操作(编辑/删除/标记已用) - [ ] 分页加载 **验收标准**: - 筛选和排序功能正常 - 左滑操作流畅 - 分页加载正常 --- ### Issue #12: 个人中心页开发 **标签**: `frontend`, `profile`, `P1` **预计工时**: 1天 **依赖**: Issue #7, #8 **任务描述**: - [ ] 用户信息展示(头像、昵称) - [ ] 数据统计(累计添加、已使用、已过期) - [ ] 提醒设置(提前天数) - [ ] 关于小程序 **验收标准**: - 用户信息正确展示 - 设置可保存 --- ## 🧪 Milestone 4: 测试与优化(优先级:P1) ### Issue #13: 后端单元测试 **标签**: `backend`, `test`, `P1` **预计工时**: 1天 **依赖**: Issue #3-#7 **任务描述**: - [ ] Model 层测试(CalculateDaysLeft, CalculateStatus) - [ ] Repository 层测试(使用 sqlmock) - [ ] Service 层测试(业务逻辑验证) - [ ] Handler 层测试(HTTP 请求测试) **验收标准**: - 测试覆盖率 > 80% - 所有测试通过 --- ### Issue #14: 接口集成测试 **标签**: `backend`, `test`, `P1` **预计工时**: 0.5天 **依赖**: Issue #6, #7 **任务描述**: - [ ] 编写 Postman Collection - [ ] 测试所有接口的正常流程 - [ ] 测试异常情况(参数错误、权限错误等) - [ ] 性能测试(并发请求) **验收标准**: - 所有接口测试通过 - 响应时间 < 200ms --- ### Issue #15: 小程序端测试 **标签**: `frontend`, `test`, `P1` **预计工时**: 1天 **依赖**: Issue #9-#12 **任务描述**: - [ ] 功能测试(所有页面和交互) - [ ] 兼容性测试(iOS/Android) - [ ] 边界情况测试(网络异常、数据为空等) - [ ] 性能测试(页面加载速度) **验收标准**: - 所有功能正常 - 无明显性能问题 --- ### Issue #16: 性能优化 **标签**: `optimization`, `P2` **预计工时**: 0.5天 **依赖**: Issue #14, #15 **任务描述**: - [ ] 后端:添加 Redis 缓存(summary 数据) - [ ] 后端:优化数据库查询(使用索引) - [ ] 前端:列表虚拟滚动(大数据量优化) - [ ] 前端:图片懒加载 **验收标准**: - 首页加载时间 < 500ms - 列表滚动流畅 --- ## 📦 Milestone 5: 部署上线(优先级:P0) ### Issue #17: 部署准备 **标签**: `deployment`, `P0` **预计工时**: 0.5天 **依赖**: Issue #13-#15 **任务描述**: - [ ] 更新 `.env.example` - [ ] 编写部署文档 - [ ] 配置 Docker Compose(如需要) - [ ] 配置 Nginx(如需要) **验收标准**: - 部署文档完整 - 可一键部署 --- ### Issue #18: 生产环境部署 **标签**: `deployment`, `P0` **预计工时**: 0.5天 **依赖**: Issue #17 **任务描述**: - [ ] 数据库初始化 - [ ] 后端服务部署 - [ ] 小程序提审上线 - [ ] 监控配置 **验收标准**: - 服务稳定运行 - 小程序审核通过 --- ## 📊 优先级说明 - **P0**: 必须完成(MVP 核心功能) - **P1**: 重要(优化和测试) - **P2**: 可选(性能优化) --- ## 🗓️ 预计时间线 | Milestone | 预计工时 | 建议时间 | |-----------|---------|---------| | M1: 数据库与基础架构 | 1天 | Day 1 | | M2: 后端核心接口 | 4.5天 | Day 2-5 | | M3: 小程序前端开发 | 5天 | Day 6-10 | | M4: 测试与优化 | 2.5天 | Day 11-12 | | M5: 部署上线 | 1天 | Day 13 | | **总计** | **14天** | **2周** | --- ## 📝 备注 1. 以上工时为单人开发预估,团队协作可并行开发 2. 建议先完成 M1+M2,再开始 M3,避免接口变更 3. 测试阶段(M4)可与开发阶段(M2+M3)并行进行 4. 每个 Issue 完成后需要 Code Review