# 保质期提醒小程序 - 开发文档 ## 项目概述 保质期提醒小程序是一款帮助用户管理家庭物品保质期的工具,支持食品、药品、化妆品等多种物品的记录和提醒。 --- ## 文档索引 - **[PRD.md](./PRD.md)** - 产品需求文档(功能范围、页面设计、数据模型) - **[API.md](./API.md)** - 接口文档(完整的 API 定义和示例) - **[DEVELOPMENT.md](./DEVELOPMENT.md)** - 开发指南(技术实现细节) - **[ISSUES.md](./ISSUES.md)** - 开发任务清单(按优先级拆分的 Issues) --- ## 快速开始 ### 1. 数据库初始化 ```sql -- 创建物品表 CREATE TABLE expiry_items ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, user_id BIGINT UNSIGNED NOT NULL, mini_program_id BIGINT UNSIGNED NOT NULL, name VARCHAR(100) NOT NULL, category VARCHAR(20) NOT NULL, production_date DATE, expiry_date DATE NOT NULL, shelf_life_days INT, quantity INT DEFAULT 1, location VARCHAR(50), remark VARCHAR(255), status VARCHAR(20) DEFAULT 'normal', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, deleted_at TIMESTAMP NULL, INDEX idx_user_expiry (user_id, expiry_date), INDEX idx_user_category (user_id, category), INDEX idx_user_status (user_id, status), INDEX idx_deleted_at (deleted_at) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 创建用户设置表 CREATE TABLE expiry_user_settings ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, user_id BIGINT UNSIGNED NOT NULL UNIQUE, remind_days JSON DEFAULT '[7,3,1]', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ``` ### 2. 后端开发 参考现有模块结构(如 `internal/smoke`),创建 `internal/expiry` 目录: ``` internal/expiry/ ├── handler.go # HTTP 处理器 ├── service.go # 业务逻辑 ├── model.go # 数据模型 └── repository.go # 数据访问层 ``` ### 3. 路由注册 在 `internal/routes/routes.go` 中注册路由: ```go expiry := r.Group("/api/expiry") expiry.Use(middleware.AuthMiddleware()) { expiry.GET("/summary", expiryHandler.GetSummary) expiry.GET("/items", expiryHandler.GetItems) expiry.POST("/items", expiryHandler.CreateItem) expiry.PUT("/items/:id", expiryHandler.UpdateItem) expiry.DELETE("/items/:id", expiryHandler.DeleteItem) expiry.POST("/items/:id/status", expiryHandler.UpdateStatus) expiry.GET("/settings", expiryHandler.GetSettings) expiry.POST("/settings", expiryHandler.UpdateSettings) } ``` ### 4. 小程序端开发 参考 API 文档进行前端开发,主要页面: - `pages/expiry/home` - 首页 - `pages/expiry/add` - 添加/编辑物品 - `pages/expiry/list` - 全部物品列表 - `pages/expiry/profile` - 个人中心 --- ## MVP 功能清单 ### Phase 1: 核心功能(2-3天) - [x] 数据库表设计 - [ ] 后端 API 实现 - [ ] 物品 CRUD - [ ] 汇总统计 - [ ] 用户设置 - [ ] 前端页面开发 - [ ] 首页(列表 + 统计) - [ ] 添加/编辑页 - [ ] 全部物品页 ### Phase 2: 优化完善(1-2天) - [ ] 状态计算逻辑优化 - [ ] 列表分页加载 - [ ] 左滑操作 - [ ] 空状态提示 - [ ] 错误处理 ### Phase 3: 测试上线(1天) - [ ] 单元测试 - [ ] 接口测试 - [ ] 小程序端测试 - [ ] 部署上线 --- ## 技术栈 **后端**: - Go 1.23+ - Gin Web Framework - GORM (MySQL) - JWT 认证 **前端**: - 微信小程序原生开发 - WeUI 组件库(可选) **数据库**: - MySQL 8.0+ --- ## 开发规范 ### 1. 代码风格 遵循项目现有代码风格: - Go: 使用 `gofmt` 格式化 - 变量命名:驼峰命名法 - 错误处理:统一使用 `common.ErrorResponse` ### 2. 提交规范 ``` feat: 添加物品管理接口 fix: 修复过期日期计算错误 docs: 更新 API 文档 test: 添加物品服务单元测试 ``` ### 3. 分支管理 - `main`: 生产环境 - `develop`: 开发环境 - `feature/expiry-*`: 功能分支 --- ## 测试数据 ### 测试物品 ```json [ { "name": "伊利纯牛奶", "category": "food", "expiry_date": "2026-03-10", "quantity": 6, "location": "冰箱" }, { "name": "感冒灵颗粒", "category": "medicine", "expiry_date": "2027-12-31", "quantity": 1, "location": "药箱" }, { "name": "雅诗兰黛面霜", "category": "cosmetic", "production_date": "2025-06-01", "shelf_life_days": 1095, "quantity": 1, "location": "梳妆台" } ] ``` --- ## 常见问题 ### Q1: 如何计算过期状态? 后端统一计算 `days_left = expiry_date - today`,前端根据 `days_left` 显示颜色: - `< 0`: 红色(已过期) - `0-3`: 橙色(即将过期) - `4-7`: 黄色(临期) - `> 7`: 绿色(正常) ### Q2: 如何处理时区问题? 统一使用 UTC 时间存储,前端根据用户时区显示。 ### Q3: 软删除如何实现? 使用 GORM 的 `deleted_at` 字段,查询时自动过滤已删除数据。 --- ## 联系方式 如有问题,请查看: - [Issues](./ISSUES.md) - 开发任务和问题追踪 - [API 文档](./API.md) - 接口详细说明 - [PRD](./PRD.md) - 产品需求细节