logo
0
0
WeChat Login

Baby Care Log Backend

运行

# Windows PowerShell ./mvnw spring-boot:run

服务默认地址:http://localhost:8080/api

主要接口

  • 健康检查: GET /api/health
  • 用户认证:
    • POST /api/auth/register - 用户注册
    • POST /api/auth/login - 用户登录
    • POST /api/auth/logout - 用户登出
    • GET /api/auth/me - 获取用户信息
    • PUT /api/auth/profile - 更新用户个人信息
  • 记录创建:
    • POST /api/records/feeding
    • POST /api/records/diaper
    • POST /api/records/sleep
    • POST /api/records/cry
  • 按日期聚合查询:POST /api/records/by-date
  • 时光轴(合并排序):POST /api/timeline/by-date
  • 统计概览:POST /api/stats/overview
  • 趋势分析:POST /api/stats/trends
  • 验证码:GET /api/auth/captcha/image
  • 家庭管理:
    • POST /api/family/create - 创建家庭
    • GET /api/family/{id} - 获取家庭信息
    • POST /api/family/{id}/settings - 更新家庭设置
    • POST /api/family/{familyId}/baby - 新增/更新宝宝档案
    • GET /api/family/{familyId}/babies - 查询家庭下的所有宝宝
    • DELETE /api/family/{familyId}/baby/{babyId} - 删除宝宝
    • POST /api/family/{familyId}/invite - 发送家庭邀请
    • POST /api/family/invite/{inviteCode}/accept - 接受家庭邀请
    • GET /api/family/{familyId}/members - 查询家庭成员
    • DELETE /api/family/{familyId}/members/{memberId} - 移除家庭成员
  • 媒体管理:
    • POST /api/media/upload - 上传媒体文件
    • GET /api/media/list - 查询媒体列表
    • DELETE /api/media/{id} - 删除媒体文件

示例请求

  • 喂奶记录(配方奶):
{ "babyId": 1, "feedingType": "FORMULA", "formulaMl": 150 }
  • 按日期查询:
{ "babyId": 1, "date": "2025-10-03" }

用户认证接口

  • 获取图形验证码
    • 方法/路径:GET /api/auth/captcha/image
    • 说明:获取图形验证码,用于登录和注册时的验证
    • 成功响应:200
{ "success": true, "image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...", "token": "captcha_token_123456789", "expires": 300 }
  • 用户注册
    • 方法/路径:POST /api/auth/register
    • 请求体:
{ "account": "13800138000", "password": "password123", "nickname": "爸爸", "captcha": "A3B7", "captchaToken": "captcha_token_123456789" }
  • 成功响应:200
{ "token": "jwt_token_string", "user": { "id": 1, "familyId": 1, "role": "PARENT", "nickname": "爸爸" } }
  • 错误响应:

    • 验证码错误:{"error": "验证码错误或已过期,请重新获取", "errorType": "CAPTCHA_INVALID"}
    • 账号已存在:{"error": "账号已存在", "errorType": "REGISTER_FAILED"}
  • 用户登录

    • 方法/路径:POST /api/auth/login
    • 请求体:
{ "account": "13800138000", "password": "password123", "captcha": "A3B7", "captchaToken": "captcha_token_123456789" }
  • 成功响应:200(同注册接口)

  • 错误响应:

    • 验证码错误:{"error": "验证码错误或已过期,请重新获取", "errorType": "CAPTCHA_INVALID"}
    • 账号密码错误:{"error": "账号或密码错误", "errorType": "LOGIN_FAILED"}
  • 用户登出

    • 方法/路径:POST /api/auth/logout
    • 认证:需要 Authorization: Bearer <token>
    • 成功响应:200
{ "message": "登出成功" }
  • 获取用户信息
    • 方法/路径:GET /api/auth/me
    • 认证:需要 Authorization: Bearer <token>
    • 成功响应:200
{ "user": { "id": 1, "familyId": 1, "role": "PARENT", "nickname": "爸爸", "account": "13800138000" }, "family": { "id": 1, "name": "张家的家庭", "babies": [ { "id": 1, "nickname": "宝宝", "birthday": "2023-01-01", "gender": "M", "avatarUrl": "https://example.com/avatar.jpg" } ] } }
  • 更新用户个人信息
    • 方法/路径:PUT /api/user/profile
    • 认证:需要 Authorization: Bearer <token>
    • 请求体:
{ "nickname": "新昵称" }
  • 成功响应:200
{ "user": { "id": 1, "familyId": 1, "role": "PARENT", "nickname": "新昵称", "account": "13800138000" } }
  • 错误响应:401(未授权)、400(昵称为空)、404(用户不存在)

数据库

  • 使用 MySQL 5.7,默认连接:jdbc:mysql://106.12.220.77:12606/babycare?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC
  • 用户名/密码:root/di&@Hv^23(可在 application.yml 修改)
  • 数据库模式:create-drop(开发环境,每次启动会重新创建表)

说明

  • 使用 Spring Boot 2.7.x, Java 8, MySQL 5.7
  • 首次启动会注入少量演示数据(SampleDataLoader
  • 支持JWT认证,token有效期7天
  • 密码使用BCrypt加密存储
  • 支持CORS跨域访问

完整接口说明

通用说明

  • 基础路径:/api
  • 请求与响应均使用 application/json
  • 时间字段使用 ISO-8601(UTC),例如:2025-10-03T10:30:00Z
  • 认证:使用JWT token认证,格式为 Authorization: Bearer <token>
  • 数据隔离:用户只能访问自己家庭的数据,所有babyId都会验证权限

健康检查

  • 方法/路径:GET /api/health
  • 响应 200 示例:
{ "status": "UP", "service": "baby-care-log-backend" }

用户认证接口

  1. 用户注册
  • 方法/路径:POST /api/auth/register
  • 请求体:
{ "account": "13800138000", "password": "password123", "nickname": "爸爸" }
  • 响应 200 示例:
{ "token": "jwt_token_string", "user": { "id": 1, "familyId": 1, "role": "PARENT", "nickname": "爸爸" } }
  1. 用户登录
  • 方法/路径:POST /api/auth/login
  • 请求体:
{ "account": "13800138000", "password": "password123" }
  • 响应:同注册接口

记录创建接口

  1. 新增喂奶记录
  • 方法/路径:POST /api/records/feeding
  • 认证:需要 Authorization: Bearer <token>
  • 请求体:
{ "babyId": 1, "eventTime": "2025-10-03T10:30:00Z", "feedingType": "FORMULA", "leftMinutes": 10, "rightMinutes": 12, "formulaMl": 150, "note": "上午加餐" }
  • 说明:feedingType 可选 BREAST_MILKFORMULA;母乳时使用 leftMinutes/rightMinutes,配方奶使用 formulaMlbabyId 必须属于当前用户的家庭。
  • 成功响应:200,返回创建后的完整对象
  1. 新增尿布记录
  • 方法/路径:POST /api/records/diaper
  • 认证:需要 Authorization: Bearer <token>
  • 请求体:
{ "babyId": 1, "eventTime": "2025-10-03T09:20:00Z", "diaperType": "WET", "note": "清尿" }
  • 说明:diaperType 可选 WET, DIRTY, MIXEDbabyId 必须属于当前用户的家庭。
  • 成功响应:200,返回创建后的完整对象
  1. 新增睡眠记录
  • 方法/路径:POST /api/records/sleep
  • 认证:需要 Authorization: Bearer <token>
  • 请求体:
{ "babyId": 1, "sleepStart": "2025-10-03T01:00:00Z", "sleepEnd": "2025-10-03T02:15:00Z", "note": "夜醒一次" }
  • 说明:sleepEnd 可为空(表示仍在睡眠中)。服务会将 sleepStart 同步写入事件时间。babyId 必须属于当前用户的家庭。
  • 成功响应:200,返回创建后的完整对象
  1. 新增哭闹记录
  • 方法/路径:POST /api/records/cry
  • 认证:需要 Authorization: Bearer <token>
  • 请求体:
{ "babyId": 1, "startTime": "2025-10-03T03:00:00Z", "endTime": "2025-10-03T03:05:00Z", "reasons": ["HUNGRY"], "sootheWays": ["FEED"], "note": "吃完好了" }
  • 说明:reasons 可选 HUNGRY,SLEEPY,DIAPER,COMFORT,STOMACH,TOO_HOT,TOO_COLD,OTHERsootheWays 可选 FEED,HUG,CHANGE_DIAPER,PACIFIER,PLAY,OTHERbabyId 必须属于当前用户的家庭。
  • 成功响应:200,返回创建后的完整对象

记录编辑接口

  1. 更新喂奶记录
  • 方法/路径:PUT /api/records/feeding/{id}
  • 认证:需要 Authorization: Bearer <token>
  • 请求体:与创建接口相同,但需要包含记录ID
{ "babyId": 1, "eventTime": "2025-10-03T10:30:00Z", "feedingType": "FORMULA", "formulaMl": 200, "note": "更新后的备注" }
  • 说明:只能编辑自己家庭宝宝的记录,记录ID必须属于当前用户的家庭
  • 成功响应:200,返回更新后的完整对象
  • 错误响应:403(无权访问此记录),404(记录不存在)
  1. 更新尿布记录
  • 方法/路径:PUT /api/records/diaper/{id}
  • 认证:需要 Authorization: Bearer <token>
  • 请求体:与创建接口相同
{ "babyId": 1, "eventTime": "2025-10-03T09:20:00Z", "diaperType": "MIXED", "note": "更新后的备注" }
  • 成功响应:200,返回更新后的完整对象
  1. 更新睡眠记录
  • 方法/路径:PUT /api/records/sleep/{id}
  • 认证:需要 Authorization: Bearer <token>
  • 请求体:与创建接口相同
{ "babyId": 1, "sleepStart": "2025-10-03T01:00:00Z", "sleepEnd": "2025-10-03T02:15:00Z", "note": "更新后的备注" }
  • 成功响应:200,返回更新后的完整对象
  1. 更新哭闹记录
  • 方法/路径:PUT /api/records/cry/{id}
  • 认证:需要 Authorization: Bearer <token>
  • 请求体:与创建接口相同
{ "babyId": 1, "startTime": "2025-10-03T03:00:00Z", "endTime": "2025-10-03T03:05:00Z", "reasons": ["HUNGRY"], "sootheWays": ["FEED"], "note": "更新后的备注" }
  • 成功响应:200,返回更新后的完整对象

记录删除接口

  1. 删除喂奶记录
  • 方法/路径:DELETE /api/records/feeding/{id}
  • 认证:需要 Authorization: Bearer <token>
  • 成功响应:200,返回删除成功消息
{ "success": true, "message": "Feeding record deleted successfully" }
  1. 删除尿布记录
  • 方法/路径:DELETE /api/records/diaper/{id}
  • 认证:需要 Authorization: Bearer <token>
  • 成功响应:200,返回删除成功消息
  1. 删除睡眠记录
  • 方法/路径:DELETE /api/records/sleep/{id}
  • 认证:需要 Authorization: Bearer <token>
  • 成功响应:200,返回删除成功消息
  1. 删除哭闹记录
  • 方法/路径:DELETE /api/records/cry/{id}
  • 认证:需要 Authorization: Bearer <token>
  • 成功响应:200,返回删除成功消息

记录编辑删除通用错误处理

  • 401:未授权(token无效或过期)
  • 403:禁止访问(无权操作此记录)
  • 404:记录不存在
  • 400:请求数据格式错误

AI智能对话接口

  1. 流式AI对话
  • 方法/路径:POST /api/ai/chat/stream
  • 认证:需要 Authorization: Bearer <token>
  • 请求体:
{ "userInput": "为什么宝宝不饿也没拉粑粑总是哭" }
  • 响应:Server-Sent Events (SSE) 流式响应
  • 事件格式:
event: message data: {"content":"三个月","isFinish":false,"chatId":1} event: message data: {"content":"大的宝宝不饿也没拉粑粑却总是","isFinish":false,"chatId":1} event: message data: {"content":"哭,可能有以下一些原因。","isFinish":true,"chatId":1}
  • 说明:
    • 系统自动组合宝宝信息和今日动态数据
    • 记录用户输入和完整AI回答用于展示
    • 宝宝信息包括:姓名、性别、年龄、今日喂奶/尿布/睡眠/哭闹记录
    • 用户参数直接使用当前登录用户的account值(手机号或邮箱)
  1. 获取对话历史
  • 方法/路径:GET /api/ai/chat/history?page=0&size=10
  • 认证:需要 Authorization: Bearer <token>
  • 参数:
    • page: 页码(从0开始,默认0)
    • size: 每页大小(默认10)
  • 响应:
{ "chats": [ { "id": 1, "babyInfo": "宝宝信息:小明,男,出生日期:2024-10-03,当前年龄:3个月\n今日动态:\n- 喂奶记录:5次,配方奶300ml,母乳120分钟\n- 尿布记录:8次(湿5次,脏3次)\n- 睡眠记录:3次,总睡眠480分钟\n- 哭闹记录:2次,总哭闹15分钟", "userInput": "为什么宝宝不饿也没拉粑粑总是哭", "aiResponse": "三个月大的宝宝不饿也没拉粑粑却总是哭,可能有以下一些原因...", "createdAt": "2025-01-03T10:30:00Z" } ], "totalElements": 25, "totalPages": 3, "currentPage": 0, "size": 10 }
  1. 根据宝宝信息搜索对话
  • 方法/路径:GET /api/ai/chat/search?babyInfo=三个月
  • 认证:需要 Authorization: Bearer <token>
  • 参数:
    • babyInfo: 宝宝信息关键词
  • 响应:返回匹配的对话记录列表
  1. 获取对话详情
  • 方法/路径:GET /api/ai/chat/{chatId}
  • 认证:需要 Authorization: Bearer <token>
  • 响应:返回完整的对话记录(包括AI回答)
  1. 删除对话记录
  • 方法/路径:DELETE /api/ai/chat/{chatId}
  • 认证:需要 Authorization: Bearer <token>
  • 响应:
{ "success": true, "message": "对话记录删除成功" }

AI对话错误处理

  • 401:未授权(token无效或过期)
  • 400:请求参数错误(userInput为空)
  • 500:AI服务调用失败

按日期聚合查询(分类型返回)

  • 方法/路径:POST /api/records/by-date
  • 认证:需要 Authorization: Bearer <token>
  • 请求体:
{ "babyId": 1, "date": "2025-10-03" }
  • 说明:babyId 必须属于当前用户的家庭
  • 响应 200 示例(字段简化展示):
{ "feedings": [ { "id": 10, "eventTime": "2025-10-03T10:30:00Z", "feedingType": "FORMULA", "formulaMl": 150 } ], "diapers": [ { "id": 11, "eventTime": "2025-10-03T09:20:00Z", "diaperType": "WET" } ], "sleeps": [ { "id": 12, "eventTime": "2025-10-03T01:00:00Z", "sleepStart": "2025-10-03T01:00:00Z", "sleepEnd": "2025-10-03T02:15:00Z" } ], "cries": [ { "id": 13, "eventTime": "2025-10-03T03:00:00Z", "startTime": "2025-10-03T03:00:00Z", "endTime": "2025-10-03T03:05:00Z" } ] }

时光轴(跨类型合并排序)

  • 方法/路径:POST /api/timeline/by-date
  • 认证:需要 Authorization: Bearer <token>
  • 请求体:同上 records/by-date
  • 响应 200 示例(按 eventTime 倒序,type 指示类型):
[ { "type": "FEEDING", "eventTime": "2025-10-03T10:30:00Z", "data": { "id": 10, "feedingType": "FORMULA", "formulaMl": 150 } }, { "type": "DIAPER", "eventTime": "2025-10-03T09:20:00Z", "data": { "id": 11, "diaperType": "WET" } }, { "type": "CRY", "eventTime": "2025-10-03T03:00:00Z", "data": { "id": 13, "startTime": "2025-10-03T03:00:00Z" } }, { "type": "SLEEP", "eventTime": "2025-10-03T01:00:00Z", "data": { "id": 12, "sleepStart": "2025-10-03T01:00:00Z" } } ]

统计概览

  • 方法/路径:POST /api/stats/overview
  • 认证:需要 Authorization: Bearer <token>
  • 请求体:
{ "babyId": 1, "startDate": "2025-10-01", "endDate": "2025-10-07" }
  • 说明:babyId 必须属于当前用户的家庭
  • 响应 200 示例:
{ "totalFormulaMl": 900, "totalBreastMinutes": 120, "totalSleepMinutes": 380 }

趋势分析

  • 方法/路径:POST /api/stats/trends
  • 认证:需要 Authorization: Bearer <token>
  • 请求体:
{ "babyId": 1, "startDate": "2025-10-01", "endDate": "2025-10-07", "type": "WEEKLY" }
  • 说明:babyId 必须属于当前用户的家庭,type 支持 WEEKLY(周趋势)和 MONTHLY(月趋势)
  • 响应 200 示例:
{ "period": "2025-10-01 to 2025-10-07", "dailyStats": [ { "date": "2025-10-01", "feedings": { "count": 6, "totalFormulaMl": 450, "totalBreastMinutes": 60 }, "diapers": { "count": 8, "wetCount": 5, "dirtyCount": 3 }, "sleeps": { "count": 3, "totalMinutes": 480 }, "cries": { "count": 4, "totalMinutes": 20 } }, { "date": "2025-10-02", "feedings": { "count": 7, "totalFormulaMl": 500, "totalBreastMinutes": 80 }, "diapers": { "count": 9, "wetCount": 6, "dirtyCount": 3 }, "sleeps": { "count": 4, "totalMinutes": 520 }, "cries": { "count": 3, "totalMinutes": 15 } } ], "averages": { "dailyFeedings": 6.5, "dailyFormulaMl": 475, "dailyBreastMinutes": 70, "dailyDiapers": 8.5, "dailySleepMinutes": 500, "dailyCryMinutes": 17.5 } }

状态码与错误

  • 200:成功
  • 400:请求体验证失败(字段缺失/类型不符等)
  • 401:未授权(token无效或过期)
  • 403:禁止访问(无权访问此资源)
  • 500:服务器内部错误

家庭管理接口

  • 创建家庭
    • 方法/路径:POST /api/family/create
    • 认证:需要 Authorization: Bearer <token>
    • 请求体:
{ "name": "我的家庭" }
  • 成功响应:200
{ "success": true, "message": "家庭创建成功", "family": { "id": 1, "name": "我的家庭", "babies": [] } }
  • 错误响应:401(未授权)、400(家庭名称为空)

  • 删除宝宝

    • 方法/路径:DELETE /api/family/{familyId}/baby/{babyId}
    • 认证:需要 Authorization: Bearer <token>
    • 说明:只能删除自己家庭的宝宝
    • 成功响应:204 No Content
    • 错误响应:401(未授权)、403(无权访问)、404(宝宝不存在)
  • 发送家庭邀请

    • 方法/路径:POST /api/family/{familyId}/invite
    • 认证:需要 Authorization: Bearer <token>
    • 请求体:
{ "email": "family@example.com", "role": "PARENT", "message": "邀请您加入我们的家庭" }
  • 成功响应:200
{ "inviteCode": "abc123def456", "expiresAt": "2025-10-10T10:30:00Z" }
  • 错误响应:401(未授权)、403(无权访问)、409(邀请已存在)

  • 接受家庭邀请

    • 方法/路径:POST /api/family/invite/{inviteCode}/accept
    • 认证:需要 Authorization: Bearer <token>
    • 请求体:
{ "accept": true }
  • 成功响应:200
{ "success": true, "message": "成功加入家庭", "user": { "id": 1, "familyId": 1, "role": "PARENT", "nickname": "用户" }, "family": { "id": 1, "name": "张家的家庭", "babies": [ { "id": 1, "nickname": "宝宝", "birthday": "2023-01-01", "gender": "M", "avatarUrl": "https://example.com/avatar.jpg" } ] } }
  • 错误响应:401(未授权)、410(邀请已过期或已处理)

  • 查询家庭成员

    • 方法/路径:GET /api/family/{familyId}/members
    • 认证:需要 Authorization: Bearer <token>
    • 成功响应:200
[ { "id": 1, "nickname": "爸爸", "role": "PARENT", "account": "dad@example.com", "joinedAt": "2025-01-15T08:30:00Z" } ]
  • 移除家庭成员
    • 方法/路径:DELETE /api/family/{familyId}/members/{memberId}
    • 认证:需要 Authorization: Bearer <token>
    • 说明:只能移除自己家庭的成员,不能移除自己
    • 成功响应:204 No Content
    • 错误响应:401(未授权)、403(无权访问)、400(不能移除自己)、405(暂不支持)

美好时刻(媒体)接口

  • 上传媒体
    • 方法/路径:POST /api/media/upload
    • 认证:需要 Authorization: Bearer <token>
    • Content-Type:multipart/form-data
    • 表单字段:
      • babyId:数字,必填(必须属于当前用户的家庭)
      • file:文件,必填(图片/视频,遵循后端上传大小限制)
      • description:字符串,选填
    • 成功响应:200,返回 MediaAsset 对象(包含 id/objectKey/contentType/description/createdAt
  • 查询媒体列表
    • 方法/路径:GET /api/media/list?babyId=1
    • 认证:需要 Authorization: Bearer <token>
    • 说明:只能查询自己家庭宝宝的媒体
    • 成功响应:200,按创建时间倒序的 MediaAsset[]
  • 删除媒体
    • 方法/路径:DELETE /api/media/{id}
    • 认证:需要 Authorization: Bearer <token>
    • 说明:只能删除自己家庭宝宝的媒体
    • 成功响应:204

MinIO 使用说明

  • 已在 application.yml 配置:minio.endpoint/accessKey/secretKey/bucket
  • 对象键 objectKey 示例:baby-1/550e8400-e29b-41d4-a716-446655440000
  • 前端展示图片的两种方式:
    1. 预签名 URL(推荐):后台生成时效性链接(可后续新增接口 /api/media/presign?objectKey=...
    2. 公共桶直链:{endpoint}/{bucket}/{objectKey}(需桶策略允许匿名读)

家庭与设置接口

  • 获取家庭信息
    • 方法/路径:GET /api/family/{id}
    • 认证:需要 Authorization: Bearer <token>
    • 说明:只能访问自己的家庭信息
    • 成功响应:200,返回 Family(已屏蔽成员列表的序列化)
  • 更新家庭通知设置
    • 方法/路径:POST /api/family/{id}/settings
    • 认证:需要 Authorization: Bearer <token>
    • 请求体示例:
{ "notifyFeeding": true, "notifySleep": false, "notifyDiaper": true }
  • 成功响应:200,返回 FamilySetting
  • 新增/更新宝宝档案(家庭下)
    • 方法/路径:POST /api/family/{familyId}/baby
    • 认证:需要 Authorization: Bearer <token>
    • 说明:只能在自己的家庭下创建/更新宝宝
    • 请求体示例(新增时可不传 id):
{ "id": 1, "nickname": "小月亮", "birthday": "2025-05-01", "gender": "F", "avatarUrl": "https://example.com/avatar.jpg" }
  • 成功响应:200,返回 Baby
  • 查询家庭下的所有宝宝
    • 方法/路径:GET /api/family/{familyId}/babies
    • 认证:需要 Authorization: Bearer <token>
    • 说明:只能查询自己家庭的宝宝
    • 成功响应:200,返回 Baby[] 数组
    • 响应示例:
[ { "id": 1, "nickname": "小月亮", "birthday": "2025-05-01", "gender": "F", "avatarUrl": "https://example.com/avatar.jpg", "createdAt": "2025-01-15T08:30:00Z" }, { "id": 2, "nickname": "小太阳", "birthday": "2025-03-15", "gender": "M", "avatarUrl": null, "createdAt": "2025-01-16T10:20:00Z" } ]

注意事项(后端)

  • 为避免懒加载序列化问题,实体返回已加入必要的 @JsonIgnoreProperties@JsonIgnore;若需更严格控制返回数据,请改用 DTO。
  • 若数据库尚未创建,配置了 createDatabaseIfNotExist=true 会自动建库;无建库权限时请手动执行 CREATE DATABASE babycare DEFAULT CHARSET utf8mb4;
  • 所有需要认证的接口都需要在请求头中包含 Authorization: Bearer <token>
  • 用户只能访问自己家庭的数据,所有 babyId 都会验证权限。
  • JWT token 有效期为7天,过期后需要重新登录。
  • 密码使用 BCrypt 加密存储。
  • 开发环境使用 create-drop 模式,每次启动会重新创建数据库表。
  • 生产环境建议使用 updatevalidate 模式。
  • 所有API路径都使用 /api 前缀,与 context-path 配置保持一致。

About

宝宝护理日记后端

Language
Java99.7%
Dockerfile0.3%