RUA宠物 - 小程序端 API 接口文档
RUA宠物 - 小程序端 API 接口文档
基础地址:
http://www.ruapet.com/api统一响应格式:{ "code": 200, "message": "success", "data": ... }鉴权方式:登录接口在请求头中携带** **Authorization: Bearer {access_token}最后更新:2026-08-06
目录
一、通用说明
1.1 统一响应格式
{
"code": 200,
"message": "success",
"data": {}
}
| 字段 | 类型 | 说明 |
|---|---|---|
| code | int | 状态码:200=成功,400=参数错误,401=未登录,403=无权限,404=资源不存在,422=参数验证失败 |
| message | string | 提示信息 |
| data | object/array/null | 响应数据 |
1.2 鉴权
需登录的接口须在 HTTP Header 中传入:
Authorization: Bearer {access_token}
access_token 有效期 7200 秒(2小时),过期后请使用** **/api/login/refresh 刷新。
1.3 分页响应
分页接口统一格式:
{
"list": [],
"total": 100,
"page": 1,
"page_size": 10
}
二、公开接口(无需登录)
2.1 首页聚合数据
一次性返回首页所需全部模块数据,减少请求次数。
模块动态开关:后台 system_config 表** **
home.show_*配置项控制各模块显隐,home.hot_*_limit控制展示数量。模块关闭时,对应字段不返回。
GET /api/home/index
请求参数(Query)
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| page | int | 否 | 1 | 信息流页码 |
| pageSize | int | 否 | 10 | 信息流每页条数 |
响应示例
{
"code": 200,
"message": "success",
"data": {
"banners": [
{
"id": 1,
"title": "新用户专享",
"image_url": "https://cdn.ruapet.com/banner/01.jpg",
"link_type": "service",
"link_url": "/pages/service/detail?id=1"
}
],
"categories": [
{
"id": 1,
"name": "洗护美容",
"icon_url": "https://cdn.ruapet.com/icon/wash.png"
}
],
"hot_services": [
{
"id": 1,
"category_id": 1,
"name": "宠物SPA",
"description": "深层清洁护理",
"cover_url": "https://cdn.ruapet.com/service/spa.jpg",
"price": "198.00",
"original_price": "298.00",
"duration": 60
}
],
"hot_topics": [
{
"id": 1,
"name": "萌宠日常",
"cover_url": "https://cdn.ruapet.com/topic/daily.jpg",
"description": "分享你家毛孩子的日常",
"post_count": 256,
"view_count": 10240
}
],
"personalities": [
{
"id": 1,
"name": "粘人精",
"description": "喜欢时刻跟在主人身边",
"icon_url": "https://cdn.ruapet.com/personality/clingy.png"
}
],
"feed": {
"list": [
{
"id": 1,
"topic_id": 1,
"title": "今天带崽去公园",
"content": "天气真好...",
"content_type": 1,
"video_cover_url": "",
"city": "杭州",
"like_count": 32,
"comment_count": 8,
"favorite_count": 15,
"view_count": 320,
"create_time": "2026-07-30 10:30:00",
"user": {
"id": 1,
"nickname": "宠主小明",
"avatar_url": "https://cdn.ruapet.com/avatar/user1.jpg"
},
"images": [
{
"id": 1,
"post_id": 1,
"image_url": "https://cdn.ruapet.com/post/pic1.jpg",
"sort": 1
}
]
}
],
"total": 100
}
}
}
响应字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
| banners | array | 轮播图列表 |
| banners[].id | int | 轮播图ID |
| banners[].title | string | 标题 |
| banners[].image_url | string | 图片地址 |
| banners[].link_type | string | 跳转类型:service/service_category/external |
| banners[].link_url | string | 跳转地址 |
| categories | array | 服务分类列表 |
| categories[].id | int | 分类ID |
| categories[].name | string | 分类名称 |
| categories[].icon_url | string | 图标地址 |
| hot_services | array | 热门服务列表(最多6条) |
| hot_services[].id | int | 服务ID |
| hot_services[].category_id | int | 所属分类ID |
| hot_services[].name | string | 服务名称 |
| hot_services[].description | string | 服务简介 |
| hot_services[].cover_url | string | 封面图 |
| hot_services[].price | string | 售价 |
| hot_services[].original_price | string | 原价 |
| hot_services[].duration | int | 时长(分钟) |
| hot_topics | array | 热门话题列表(最多5条) |
| hot_topics[].id | int | 话题ID |
| hot_topics[].name | string | 话题名称 |
| hot_topics[].cover_url | string | 封面图 |
| hot_topics[].description | string | 话题简介 |
| hot_topics[].post_count | int | 帖子数 |
| hot_topics[].view_count | int | 浏览数 |
| personalities | array | 宠物性格标签列表 |
| personalities[].id | int | 标签ID |
| personalities[].name | string | 标签名称 |
| personalities[].description | string | 标签描述 |
| personalities[].icon_url | string | 图标地址 |
| feed | object | 社区信息流(带分页) |
| feed.list | array | 帖子列表,结构见公共-帖子信息 |
| feed.total | int | 帖子总数 |
2.2 服务分类列表
GET /api/service/category
请求参数
无
响应示例
{
"code": 200,
"message": "success",
"data": [
{ "id": 1, "name": "洗护美容", "icon_url": "https://cdn.ruapet.com/icon/wash.png" },
{ "id": 2, "name": "医疗健康", "icon_url": "https://cdn.ruapet.com/icon/medical.png" }
]
}
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int | 分类ID |
| name | string | 分类名称 |
| icon_url | string | 图标地址 |
2.3 服务项目列表
GET /api/service/list
请求参数(Query)
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| category_id | int | 否 | 0 | 分类ID,0=全部 |
| page | int | 否 | 1 | 页码 |
| pageSize | int | 否 | 20 | 每页条数 |
响应示例
{
"code": 200,
"message": "success",
"data": {
"list": [
{
"id": 1,
"category_id": 1,
"name": "宠物SPA",
"description": "深层清洁护理,让宠物享受舒适体验",
"cover_url": "https://cdn.ruapet.com/service/spa.jpg",
"price": "198.00",
"original_price": "298.00",
"duration": 60
}
],
"total": 50,
"page": 1,
"page_size": 20
}
}
响应字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
| list | array | 服务列表 |
| list[].id | int | 服务ID |
| list[].category_id | int | 所属分类ID |
| list[].name | string | 服务名称 |
| list[].description | string | 服务简介 |
| list[].cover_url | string | 封面图 |
| list[].price | string | 售价 |
| list[].original_price | string | 原价 |
| list[].duration | int | 时长(分钟) |
| total | int | 记录总数 |
| page | int | 当前页码 |
| page_size | int | 每页条数 |
2.4 服务详情
GET /api/service/:id
请求参数(路径)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | int | 是 | 服务ID |
响应示例
{
"code": 200,
"message": "success",
"data": {
"id": 1,
"category_id": 1,
"category_name": "洗护美容",
"name": "宠物SPA",
"description": "深层清洁护理,让宠物享受舒适体验",
"detail": "<p>服务详情HTML内容...</p>",
"cover_url": "https://cdn.ruapet.com/service/spa.jpg",
"images": "[\"https://cdn.ruapet.com/service/spa1.jpg\",\"https://cdn.ruapet.com/service/spa2.jpg\"]",
"price": "198.00",
"original_price": "298.00",
"duration": 60,
"sales_count": 128,
"create_time": "2026-07-01 10:00:00"
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int | 服务ID |
| category_id | int | 所属分类ID |
| category_name | string | 所属分类名称 |
| name | string | 服务名称 |
| description | string | 简介 |
| detail | string | 详情(HTML) |
| cover_url | string | 封面图 |
| images | string | 详情图列表(JSON数组) |
| price | string | 售价 |
| original_price | string | 原价 |
| duration | int | 时长(分钟) |
| sales_count | int | 销量 |
| create_time | string | 创建时间 |
2.5 话题列表
GET /api/community/topic
请求参数
无
响应示例
{
"code": 200,
"message": "success",
"data": [
{
"id": 1,
"name": "萌宠日常",
"cover_url": "https://cdn.ruapet.com/topic/daily.jpg",
"description": "分享你家毛孩子的日常",
"post_count": 256,
"view_count": 10240
},
{
"id": 2,
"name": "养宠经验",
"cover_url": "https://cdn.ruapet.com/topic/exp.jpg",
"description": "交流养宠心得与技巧",
"post_count": 189,
"view_count": 8760
}
]
}
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int | 话题ID |
| name | string | 话题名称 |
| cover_url | string | 封面图 |
| description | string | 话题简介 |
| post_count | int | 帖子数 |
| view_count | int | 浏览数 |
2.6 帖子列表
GET /api/community/post
请求参数(Query)
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| topic_id | int | 否 | 0 | 话题ID,0=全部 |
| page | int | 否 | 1 | 页码 |
| pageSize | int | 否 | 10 | 每页条数 |
响应示例
{
"code": 200,
"message": "success",
"data": {
"list": [
{
"id": 1,
"topic_id": 1,
"title": "今天带崽去公园",
"content": "天气真好,带狗子去公园撒欢...",
"content_type": 1,
"video_cover_url": "",
"city": "杭州",
"like_count": 32,
"comment_count": 8,
"favorite_count": 15,
"view_count": 320,
"create_time": "2026-07-30 10:30:00",
"user": {
"id": 1,
"nickname": "宠主小明",
"avatar_url": "https://cdn.ruapet.com/avatar/user1.jpg"
},
"images": [
{
"id": 1,
"post_id": 1,
"image_url": "https://cdn.ruapet.com/post/pic1.jpg",
"sort": 1
}
]
}
],
"total": 100,
"page": 1,
"page_size": 10
}
}
响应字段说明见** **附录-帖子信息。
2.7 帖子详情
GET /api/community/post/:id
请求参数(路径)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | int | 是 | 帖子ID |
响应示例
{
"code": 200,
"message": "success",
"data": {
"id": 1,
"user_id": 1,
"topic_id": 1,
"title": "今天带崽去公园",
"content": "天气真好,带狗子去公园撒欢,遇到了好多小伙伴...",
"content_type": 1,
"video_cover_url": "",
"city": "杭州",
"like_count": 32,
"comment_count": 8,
"favorite_count": 15,
"view_count": 320,
"create_time": "2026-07-30 10:30:00",
"user": {
"id": 1,
"nickname": "宠主小明",
"avatar_url": "https://cdn.ruapet.com/avatar/user1.jpg"
},
"images": [
{
"id": 1,
"post_id": 1,
"image_url": "https://cdn.ruapet.com/post/pic1.jpg",
"sort": 1
}
],
"topic": {
"id": 1,
"name": "萌宠日常"
}
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int | 帖子ID |
| user_id | int | 作者用户ID |
| topic_id | int | 话题ID |
| title | string | 标题 |
| content | string | 正文内容 |
| content_type | int | 内容类型:1=图文,2=视频 |
| video_cover_url | string | 视频封面(视频类型时有值) |
| city | string | 所在城市 |
| like_count | int | 点赞数 |
| comment_count | int | 评论数 |
| favorite_count | int | 收藏数 |
| view_count | int | 浏览数 |
| create_time | string | 发布时间 |
| user | object | 作者信息,见公共-用户简要信息 |
| images | array | 图片列表 |
| images[].id | int | 图片记录ID |
| images[].post_id | int | 所属帖子ID |
| images[].image_url | string | 图片地址 |
| images[].sort | int | 排序 |
| topic | object | 所属话题 |
2.8 性格标签列表
GET /api/personality
请求参数
无
响应示例
{
"code": 200,
"message": "success",
"data": [
{
"id": 1,
"name": "粘人精",
"description": "喜欢时刻跟在主人身边",
"icon_url": "https://cdn.ruapet.com/personality/clingy.png"
},
{
"id": 2,
"name": "社牛",
"description": "见谁都亲,社交达人",
"icon_url": "https://cdn.ruapet.com/personality/social.png"
}
]
}
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int | 标签ID |
| name | string | 标签名称 |
| description | string | 标签描述 |
| icon_url | string | 图标地址 |
2.9 微信登录
POST /api/login/wechat
请求参数(Body - JSON)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| code | string | 是 | 通过wx.login() 获取的登录凭证,长度32位 |
| phone_code | string | 否 | 通过<button open-type="getPhoneNumber"> 获取的手机号授权码(登录时同步获取手机号) |
| nickname | string | 否 | 用户微信昵称,首次登录时传入,最长32字符 |
| avatar_url | string | 否 | 用户微信头像URL,最长512字符 |
请求示例
{
"code": "0a3bCxXwE6YqeZ3nGZqFxAzQb1IYgxZ3",
"phone_code": "d7b8f9c0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8",
"nickname": "宠主小明",
"avatar_url": "https://thirdwx.qlogo.cn/mmopen/xxx/132"
}
响应示例 - 新用户
{
"code": 200,
"message": "登录成功",
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6...",
"expires_in": 7200,
"is_new_user": true,
"user_info": {
"id": 1,
"nickname": "宠主小明",
"avatar_url": "https://thirdwx.qlogo.cn/mmopen/xxx/132",
"gender": 0,
"real_name_status": 0,
"status": 1,
"create_time": "2026-07-30 12:00:00"
}
}
}
响应示例 - 老用户
{
"code": 200,
"message": "登录成功",
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6...",
"expires_in": 7200,
"is_new_user": false,
"user_info": {
"id": 1,
"nickname": "宠主小明",
"avatar_url": "https://thirdwx.qlogo.cn/mmopen/xxx/132",
"gender": 0,
"real_name_status": 0,
"status": 1,
"create_time": "2026-07-30 12:00:00"
}
}
}
响应字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
| access_token | string | 访问令牌,后续请求在 Header 中携带 |
| refresh_token | string | 刷新令牌,用于刷新 access_token(一次性使用) |
| expires_in | int | access_token 有效期,单位秒(7200秒 = 2小时) |
| is_new_user | bool | 是否新用户(true=需要走新用户引导流程) |
| user_info | object | 用户信息,结构见公共-用户简要信息 |
2.10 刷新Token
access_token 过期后调用此接口刷新,refresh_token 为一次性使用,刷新后旧 refresh_token 作废。
POST /api/login/refresh
请求参数(Body - JSON)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| refresh_token | string | 是 | 登录时获取的刷新令牌 |
请求示例
{
"refresh_token": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6..."
}
响应示例
{
"code": 200,
"message": "success",
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...(新)",
"refresh_token": "z9y8x7w6v5u4t3s2r1q0p9o8n7m6l5k4...(新)",
"expires_in": 7200,
"user_info": {
"id": 1,
"nickname": "宠主小明",
"avatar_url": "https://thirdwx.qlogo.cn/mmopen/xxx/132",
"gender": 0,
"real_name_status": 0,
"status": 1,
"create_time": "2026-07-30 12:00:00"
}
}
}
错误响应
| code | message | 说明 |
|---|---|---|
| 401 | refresh_token 无效或已过期 | 需重新走登录流程 |
| 403 | 账号已失效 | 用户已被禁用 |
2.11 单文件上传
支持图片(jpg/png/gif/webp/bmp)、视频(mp4/mov),最大 10MB。 未登录也可上传,user_id 记录为 0。 当前阶段:本地存储到
public/upload/目录。OSS 配置完成后自动切换,无需改动上传代码。
POST /api/upload
请求参数(multipart/form-data)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| file | File | 是 | 上传的文件,表单字段名file |
请求头(可选)
Authorization: Bearer {access_token}
携带 Token 时,上传记录会关联到对应用户;不携带时 user_id=0。
响应示例
{
"code": 200,
"message": "上传成功",
"data": {
"id": 1,
"url": "/upload/20260730/64b3a1c2d3e4f.jpg",
"file_name": "pet_photo.jpg",
"file_size": 204800,
"mime_type": "image/jpeg",
"width": 1080,
"height": 720
}
}
响应字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int | 文件记录ID,后续业务关联时使用 |
| url | string | 文件访问地址(本地相对路径或 OSS 完整 URL) |
| file_name | string | 原始文件名 |
| file_size | int | 文件大小(字节) |
| mime_type | string | MIME 类型 |
| width | int | 图片宽度(非图片时为 0) |
| height | int | 图片高度(非图片时为 0) |
2.12 多文件上传
单次最多上传 9 个文件,每个文件独立处理,部分失败不影响其他文件。
POST /api/upload/multi
请求参数(multipart/form-data)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| files | File[] | 是 | 文件数组,表单字段名files[],最多9个 |
响应示例
{
"code": 200,
"message": "上传完成",
"data": [
{
"id": 1,
"url": "/upload/20260730/64b3a1c2d3e4f.jpg",
"file_name": "photo1.jpg",
"file_size": 204800,
"mime_type": "image/jpeg",
"width": 1080,
"height": 720
},
{
"id": 2,
"url": "/upload/20260730/74b3a2d4e5f6g.jpg",
"file_name": "photo2.jpg",
"file_size": 153600,
"mime_type": "image/jpeg",
"width": 900,
"height": 600
}
]
}
单个文件上传失败时,该元素会包含** **
error字段说明失败原因,id为 0。
使用流程说明
小程序端调用 wx.chooseImage / wx.chooseMedia
→ 获取 tempFilePath
→ 调用 wx.uploadFile,url 指向 /api/upload
→ 后端返回 { id, url }
→ 前端将 id 存入业务表(如 user.avatar_file_id = 1)
→ 或通过 file_relation 表关联多个文件
2.13 品种字典列表
返回平台维护的宠物品种数据,前端按**
species分组展示选择弹窗,或传入 **species过滤。
GET /api/breed
请求参数(Query)
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| species | int | 否 | 0 | 物种:0=全部,1=猫,2=狗,3=其他 |
响应示例
{
"code": 200,
"message": "success",
"data": [
{ "id": 1, "species": 1, "name": "英短", "sort": 1 },
{ "id": 2, "species": 1, "name": "美短", "sort": 2 },
{ "id": 18, "species": 2, "name": "金毛", "sort": 1 },
{ "id": 19, "species": 2, "name": "柯基", "sort": 2 }
]
}
响应字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int | 品种ID |
| species | int | 物种:1=猫,2=狗,3=其他 |
| name | string | 品种名称 |
| sort | int | 排序序号 |
2.14 公益活动
公开接口:活动列表、详情、报名者列表。活动报名和取消需登录,见** **3.10。
活动列表
GET /api/activity
请求参数(Query)
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| page | int | 否 | 1 | 页码 |
| pageSize | int | 否 | 20 | 每页条数 |
| city | string | 否 | - | 城市筛选 |
| category | int | 否 | - | 分类:1=救助 2=领养日 3=义卖 4=环保 5=科普 6=其他 |
| status | int | 否 | - | 状态:1=进行中 2=已结束 |
响应示例
{
"code": 200,
"message": "success",
"data": {
"list": [{
"id": 1,
"title": "杭州流浪猫救助日",
"cover_url": "/upload/0701/activity_cover.jpg",
"category": 1,
"city": "杭州",
"location_name": "西湖文化广场",
"start_time": "2026-08-15 09:00:00",
"end_time": "2026-08-15 17:00:00",
"signup_end_time": "2026-08-14 12:00:00",
"max_participants": 50,
"current_participants": 38,
"is_free": 1,
"price": 0,
"organizer_name": "杭州宠物救助协会",
"status": 1,
"deadline_soon": true,
"is_full": false,
"view_count": 256,
"create_time": "2026-07-20 10:00:00"
}],
"total": 12,
"page": 1,
"page_size": 20
}
}
列表特有字段
| 字段 | 类型 | 说明 |
|---|---|---|
| deadline_soon | bool | 是否即将截止(报名截止<24h) |
| is_full | bool | 是否已满员 |
活动详情
GET /api/activity/:id
响应示例
{
"code": 200,
"message": "success",
"data": {
"id": 1,
"title": "杭州流浪猫救助日",
"description": "本次活动旨在救助杭州地区流浪猫,欢迎爱心人士参与...",
"cover_url": "/upload/0701/activity_cover.jpg",
"cover_file_id": 1,
"images": ["/upload/0701/act1.jpg", "/upload/0701/act2.jpg"],
"category": 1,
"city": "杭州",
"location_name": "西湖文化广场",
"address": "下城区西湖文化广场1号",
"latitude": "30.2741",
"longitude": "120.1616",
"start_time": "2026-08-15 09:00:00",
"end_time": "2026-08-15 17:00:00",
"signup_start_time": "2026-07-25 00:00:00",
"signup_end_time": "2026-08-14 12:00:00",
"max_participants": 50,
"current_participants": 38,
"organizer_name": "杭州宠物救助协会",
"contact_phone": "138****5678",
"is_free": 1,
"price": 0,
"status": 1,
"deadline_soon": true,
"is_full": false,
"remaining": 12,
"view_count": 256,
"create_time": "2026-07-20 10:00:00"
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
| remaining | int | 剩余名额,-1=不限 |
报名者列表
GET /api/activity/:id/signups?page=1&pageSize=30
响应示例
{
"code": 200,
"message": "success",
"data": {
"list": [{
"id": 1,
"pet_id": 0,
"name": "张三",
"remark": "带朋友一起",
"signup_count": 2,
"create_time": "2026-07-30 15:00:00",
"user": { "id": 1, "nickname": "宠主小明", "avatar_url": "/upload/avatar.jpg" }
}],
"total": 38,
"page": 1,
"page_size": 30
}
}
活动报名
POST /api/activity/:id/signup
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| name | string | 是 | 联系人姓名 |
| phone | string | 是 | 联系电话 |
| signup_count | int | 否 | 报名人数(含携带),默认1 |
| pet_id | int | 否 | 携带宠物ID |
| remark | string | 否 | 备注 |
响应示例
{
"code": 200,
"message": "报名成功",
"data": {
"signup_id": 1,
"current_participants": 39
}
}
错误响应
| code | message | 说明 |
|---|---|---|
| 400 | 您已报名此活动 | 重复报名 |
| 400 | 报名尚未开始 | 未到报名时间 |
| 400 | 报名已截止 | 超过报名截止时间 |
| 400 | 活动名额已满 | 满员 |
取消报名
DELETE /api/activity/signup/:id
请求参数: 路径传报名记录ID
响应示例
{ "code": 200, "message": "已取消报名", "data": { "activity_id": 1 } }
2.15 社区关注(公开)
查看任意用户的关注列表和粉丝列表,无需登录。 关注/取消关注需登录,见** **3.11。
查看用户关注列表
GET /api/user/:id/following?page=1&pageSize=20
响应示例
{
"code": 200,
"message": "success",
"data": {
"list": [
{
"id": 1002,
"nickname": "宠友小红",
"avatar_url": "/upload/avatar_1002.jpg",
"follow_time": "2026-07-25 10:00:00"
}
],
"total": 5,
"page": 1,
"page_size": 20
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
| follow_time | string | 关注时间 |
查看用户粉丝列表
GET /api/user/:id/followers?page=1&pageSize=20
响应示例
{
"code": 200,
"message": "success",
"data": {
"list": [
{
"id": 1003,
"nickname": "宠友小明",
"avatar_url": "/upload/avatar_1003.jpg",
"is_following": false,
"follow_time": "2026-07-26 15:00:00"
}
],
"total": 12,
"page": 1,
"page_size": 20
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
| is_following | bool | 当前登录用户是否已关注该粉丝(不登录或不关注时均为 false) |
关注流帖子("关注" Tab)
现有帖子列表接口加**
tab=following参数即可,需登录。 将现有GET /api/community/post?tab=following的 **community/post路由从公开组移到需登录组。 关注流逻辑:仅展示当前用户本人及其关注用户发布的帖子。
GET /api/community/post?tab=following&page=1&pageSize=10
响应格式同** **2.6 帖子列表。
2.16 地图寻宠(公开)
浏览寻宠/寻主发布列表,支持列表视图和地图视图切换。发布/管理需登录,见** **3.15。
2.16.1 列表视图
GET /api/lostpet?view=list&type=1&species=1&city=杭州&page=1&pageSize=20
请求参数(Query)
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| view | string | 否 | list | 视图模式: list=列表 map=地图(地图需传 lat/lng/radius) |
| type | int | 否 | - | 类型: 1=寻宠(找宠物) 2=寻主(找主人) |
| species | int | 否 | - | 物种: 1=猫 2=狗 3=其他 |
| city | string | 否 | - | 城市 |
| page | int | 否 | 1 | 页码 |
| pageSize | int | 否 | 20 | 每页条数 |
响应示例(列表视图)
{
"code": 200,
"message": "success",
"data": {
"list": [
{
"id": 1,
"type": 1,
"title": "急寻!三花猫走失",
"pet_name": "花花",
"species": 1,
"breed": "三花",
"gender": 2,
"age": "2岁",
"color": "黑白黄三色",
"description": "白色居多,背部有黑色和黄色斑块...",
"city": "杭州",
"district": "西湖区",
"location_name": "文三路附近",
"address": "文三路123号小区",
"latitude": 30.2741,
"longitude": 120.1551,
"lost_time": "2026-08-01 14:00:00",
"contact_phone": "138****1234",
"reward": "500.00",
"images": [
"https://cdn.ruapet.com/lostpet/pic1.jpg",
"https://cdn.ruapet.com/lostpet/pic2.jpg"
],
"view_count": 320,
"status": 1,
"create_time": "2026-08-01 15:30:00",
"user": {
"id": 1,
"nickname": "宠主小明",
"avatar_url": "https://cdn.ruapet.com/avatar/user1.jpg"
}
}
],
"total": 50,
"page": 1,
"page_size": 20
}
}
响应字段(列表项)
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int | 记录ID |
| type | int | 类型: 1=寻宠 2=寻主 |
| title | string | 标题 |
| pet_name | string | 宠物名称 |
| species | int | 物种: 0=未知 1=猫 2=狗 3=其他 |
| breed | string | 品种 |
| gender | int | 性别: 0=未知 1=公 2=母 |
| age | string | 年龄描述 |
| color | string | 毛色 |
| description | string | 详细描述/特征 |
| city | string | 所在城市 |
| district | string | 区/县 |
| location_name | string | 位置名称 |
| address | string | 详细地址 |
| latitude | float | 纬度 |
| longitude | float | 经度 |
| lost_time | string | 走失/发现时间 |
| contact_phone | string | 联系电话(脱敏) |
| reward | string | 悬赏金额 |
| images | array | 图片URL列表 |
| view_count | int | 浏览数 |
| status | int | 状态: 0=已下架 1=寻找中 2=已找到 |
| create_time | string | 发布时间 |
| user | object | 发布者信息,见用户简要信息 |
2.16.2 地图视图
GET /api/lostpet?view=map&lat=30.2741&lng=120.1551&radius=10&type=1&species=1
请求参数(Query)
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| view | string | 是 | - | 固定传map |
| lat | float | 是 | - | 中心纬度 |
| lng | float | 是 | - | 中心经度 |
| radius | int | 否 | 10 | 搜索半径(公里) |
| type | int | 否 | - | 类型筛选 |
| species | int | 否 | - | 物种筛选 |
| city | string | 否 | - | 城市筛选 |
响应示例(地图视图)
{
"code": 200,
"message": "success",
"data": {
"markers": [
{
"id": 1,
"type": 1,
"title": "急寻!三花猫走失",
"pet_name": "花花",
"species": 1,
"breed": "三花",
"city": "杭州",
"district": "西湖区",
"location_name": "文三路附近",
"latitude": 30.2741,
"longitude": 120.1551,
"lost_time": "2026-08-01 14:00:00",
"status": 1,
"create_time": "2026-08-01 15:30:00",
"distance": 0.52,
"user": {
"id": 1,
"nickname": "宠主小明",
"avatar_url": "https://cdn.ruapet.com/avatar/user1.jpg"
}
}
],
"center": { "lat": 30.2741, "lng": 120.1551 },
"radius": 10,
"total": 25
}
}
响应字段(marker)
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int | 记录ID |
| type | int | 类型: 1=寻宠 2=寻主 |
| title | string | 标题 |
| pet_name | string | 宠物名称 |
| species | int | 物种 |
| breed | string | 品种 |
| city | string | 城市 |
| district | string | 区/县 |
| location_name | string | 位置名称 |
| latitude | float | 纬度 |
| longitude | float | 经度 |
| lost_time | string | 走失/发现时间 |
| status | int | 状态 |
| create_time | string | 发布时间 |
| distance | float | 距离中心点的距离(公里) |
| user | object | 发布者简要信息 |
2.16.3 详情
GET /api/lostpet/:id
返回单条记录完整信息,字段同列表项,额外含完整** description 和 **address 字段。浏览数自动 +1。
2.17 宠物性格测试题库
获取性格测试题目,供前端渲染答题页。评分逻辑在服务端闭环,前端不感知得分权重。
GET /api/personality/questions
请求参数
无
响应示例
{
"code": 200,
"message": "success",
"data": {
"questions": [
{
"id": 1,
"question": "当家里来陌生人时,宠物通常会怎么做?",
"options": [
{ "text": "立刻躲到角落或主人身后" },
{ "text": "远远观望,观察一阵后可能会靠近" },
{ "text": "主动上前闻一闻,确认安全" },
{ "text": "大声叫唤或做出警告姿态" }
]
},
{
"id": 2,
"question": "宠物和主人的日常互动方式是?",
"options": [
{ "text": "时刻粘着主人,走哪跟哪" },
{ "text": "喜欢安静地陪在主人身边" },
{ "text": "爱答不理,有自己的一套" },
{ "text": "一会粘人一会高冷,看心情" }
]
}
],
"total_questions": 8
}
}
响应字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
| questions | array | 题目列表 |
| questions[].id | int | 题目ID |
| questions[].question | string | 问题内容 |
| questions[].options | array | 选项列表(仅含text,不含scores) |
| total_questions | int | 题目总数 |
三、需登录接口
以下接口须在 Header 中携带** **
Authorization: Bearer {access_token}。
3.1 获取用户信息
GET /api/user/info
请求参数
无(从 Token 解析用户ID)
请求头
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
响应示例
{
"code": 200,
"message": "success",
"data": {
"id": 1,
"nickname": "宠主小明",
"avatar_url": "https://cdn.ruapet.com/avatar/user1.jpg",
"phone": "138****1234",
"gender": 0,
"real_name_status": 0,
"status": 1,
"create_time": "2026-07-30 12:00:00"
}
}
响应字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int | 用户ID |
| nickname | string | 昵称 |
| avatar_url | string | 头像地址 |
| phone | string | 手机号(脱敏显示,中间4位替换为****) |
| gender | int | 性别:0=未知,1=男,2=女 |
| real_name_status | int | 实名认证状态:0=未认证,1=已认证,2=审核中,3=认证失败 |
| status | int | 账号状态:0=禁用,1=正常 |
| create_time | string | 注册时间 |
3.2 更新用户资料
PUT /api/user/profile
请求头
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
请求参数(Body - JSON)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| nickname | string | 否 | 昵称,最长32字符 |
| avatar_url | string | 否 | 头像URL,最长512字符 |
| avatar_file_id | int | 否 | 头像文件ID(通过上传接口获取) |
| gender | int | 否 | 性别:0=未知,1=男,2=女 |
请求示例
{
"nickname": "宠主小明Pro",
"gender": 1
}
响应示例
{
"code": 200,
"message": "资料更新成功",
"data": {
"id": 1,
"nickname": "宠主小明Pro",
"avatar_url": "https://cdn.ruapet.com/avatar/user1.jpg",
"gender": 1,
"real_name_status": 0,
"status": 1,
"create_time": "2026-07-30 12:00:00"
}
}
3.3 绑定手机号
用于未在登录时获取到手机号的用户后续绑定。
POST /api/user/bindPhone
请求头
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
请求参数(Body - JSON)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| phone_code | string | 是 | 通过<button open-type="getPhoneNumber"> 获取的手机号授权码 |
请求示例
{
"phone_code": "d7b8f9c0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8"
}
响应示例
{
"code": 200,
"message": "手机号绑定成功",
"data": {
"phone": "138****1234"
}
}
3.4 退出登录
使当前用户所有未过期的 refresh_token 失效。
POST /api/login/logout
请求头
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
请求参数
无
响应示例
{
"code": 200,
"message": "已退出登录",
"data": null
}
3.5 宠物管理
宠物档案 CRUD,所有操作仅限当前用户对自己名下的宠物进行。 支持多宠物管理、生日自动计算年龄。
3.5.1 宠物列表
GET /api/pet
请求头
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
请求参数
无(从 Token 解析用户ID,返回该用户所有正常状态宠物)
响应示例
{
"code": 200,
"message": "success",
"data": [
{
"id": 1,
"name": "旺财",
"species": 2,
"breed": "金毛",
"gender": 1,
"age": 2.5,
"weight": 25.00,
"avatar_url": "/upload/20260730/pet1.jpg",
"is_neutered": 1,
"vaccine_status": 1,
"birthday": "2024-01-15",
"create_time": "2026-07-20 10:00:00"
}
]
}
响应字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int | 宠物ID |
| name | string | 宠物昵称 |
| species | int | 物种:1=猫,2=狗,3=其他 |
| breed | string | 品种名称 |
| gender | int | 性别:0=未知,1=公,2=母 |
| age | float | 年龄(岁),根据生日自动计算 |
| weight | float | 体重(kg) |
| avatar_url | string | 宠物头像地址 |
| is_neutered | int | 是否绝育:0=否,1=是 |
| vaccine_status | int | 疫苗状态:0=未注射,1=已注射 |
| birthday | string | 出生日期 |
| create_time | string | 创建时间 |
3.5.2 宠物详情
GET /api/pet/:id
请求参数(路径)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | int | 是 | 宠物ID |
响应示例
{
"code": 200,
"message": "success",
"data": {
"id": 1,
"user_id": 1,
"name": "旺财",
"species": 2,
"breed": "金毛",
"gender": 1,
"birthday": "2024-01-15",
"age": 2.5,
"weight": 25.00,
"color": "金色",
"avatar_url": "/upload/20260730/pet1.jpg",
"avatar_file_id": 1,
"personality_id": 3,
"personality_name": "社牛",
"is_neutered": 1,
"vaccine_status": 1,
"description": "活泼好动的金毛,喜欢游泳",
"status": 1,
"create_time": "2026-07-20 10:00:00",
"update_time": "2026-07-25 14:30:00"
}
}
响应字段说明(在列表字段基础上增加)
| 字段 | 类型 | 说明 |
|---|---|---|
| user_id | int | 所属用户ID |
| color | string | 毛色 |
| avatar_file_id | int | 头像文件ID |
| personality_id | int | 性格标签ID |
| personality_name | string | 性格标签名称 |
| description | string | 宠物简介 |
| status | int | 状态:0=隐藏,1=正常 |
| update_time | string | 更新时间 |
3.5.3 新增宠物
POST /api/pet
请求参数(Body - JSON)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| name | string | 是 | 宠物昵称,2~12字符,中英文数字 |
| species | int | 是 | 物种:1=猫,2=狗,3=其他 |
| gender | int | 是 | 性别:1=公,2=母 |
| birthday | string | 是 | 出生日期,格式 YYYY-MM-DD,不可选择未来日期 |
| is_neutered | int | 是 | 是否绝育:0=否,1=是 |
| vaccine_status | int | 是 | 疫苗状态:0=未注射,1=已注射 |
| breed | string | 否 | 品种名称,最长32字符 |
| weight | float | 否 | 体重(kg),范围0~200 |
| color | string | 否 | 毛色,最长32字符 |
| personality_id | int | 否 | 性格标签ID |
| description | string | 否 | 宠物简介,最长500字 |
| avatar_url | string | 否 | 宠物头像URL |
| avatar_file_id | int | 否 | 头像文件ID(通过上传接口获取) |
请求示例
{
"name": "旺财",
"species": 2,
"breed": "金毛",
"gender": 1,
"birthday": "2024-01-15",
"weight": 25.00,
"color": "金色",
"is_neutered": 1,
"vaccine_status": 1,
"personality_id": 3,
"description": "活泼好动的金毛,喜欢游泳",
"avatar_file_id": 1
}
响应示例
{
"code": 200,
"message": "添加成功",
"data": {
"id": 1,
"name": "旺财",
"species": 2,
"breed": "金毛",
"gender": 1,
"birthday": "2024-01-15",
"age": 2.5,
"weight": 25.00,
"color": "金色",
"avatar_url": "/upload/20260730/pet1.jpg",
"avatar_file_id": 1,
"personality_id": 3,
"personality_name": "",
"is_neutered": 1,
"vaccine_status": 1,
"description": "活泼好动的金毛,喜欢游泳",
"status": 1,
"create_time": "2026-07-30 15:00:00",
"update_time": "2026-07-30 15:00:00"
}
}
3.5.4 编辑宠物
PUT /api/pet/:id
请求参数(路径)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | int | 是 | 宠物ID |
请求参数(Body - JSON)
全部字段可选,传入哪些就更新哪些;birthday 变更时会自动重新计算 age。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| name | string | 否 | 同新增 |
| species | int | 否 | 同新增 |
| gender | int | 否 | 同新增 |
| birthday | string | 否 | 同新增 |
| is_neutered | int | 否 | 同新增 |
| vaccine_status | int | 否 | 同新增 |
| breed | string | 否 | 同新增 |
| weight | float | 否 | 同新增 |
| color | string | 否 | 同新增 |
| personality_id | int | 否 | 同新增 |
| description | string | 否 | 同新增 |
| avatar_url | string | 否 | 同新增 |
| avatar_file_id | int | 否 | 同新增 |
请求示例
{
"name": "旺财Pro",
"weight": 28.00
}
响应示例
同** 3.5.3 新增宠物,message 为 **"编辑成功"。
3.5.5 删除宠物
软删除,数据保留不永久移除,关联的历史记录保持关联。
DELETE /api/pet/:id
请求参数(路径)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | int | 是 | 宠物ID |
响应示例
{
"code": 200,
"message": "删除成功",
"data": null
}
错误响应
| code | message | 说明 |
|---|---|---|
| 404 | 宠物不存在或已删除 | 宠物不属于当前用户或不存在 |
3.6 社区帖子互动
发布、删除、点赞、评论全套互动接口,均需登录。 浏览类接口(列表/详情/评论列表)为公开接口,见** **2.5~2.7。
3.6.1 发布帖子
至少上传 1 张图片,标题和正文选填。
POST /api/community/post
请求参数(Body - JSON)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| images | array | 是 | 图片数组,至少1张,最多9张 |
| images[].image_url | string | 是 | 图片URL(通过上传接口获取) |
| images[].file_id | int | 否 | 图片文件ID |
| title | string | 否 | 标题,最长30字符 |
| content | string | 否 | 正文,最长1000字符 |
| topic_id | int | 否 | 话题ID,0=不关联话题 |
| city | string | 否 | 所在城市 |
| location_name | string | 否 | 位置名称 |
| content_type | int | 否 | 内容类型:1=图文(默认),2=视频 |
请求示例
{
"images": [
{ "image_url": "/upload/20260730/pet1.jpg", "file_id": 1 },
{ "image_url": "/upload/20260730/pet2.jpg", "file_id": 2 }
],
"title": "今天带崽去公园",
"content": "天气真好,带狗子去公园撒欢,遇到了好多小伙伴...",
"topic_id": 1,
"city": "杭州",
"location_name": "西湖区龙井路"
}
响应示例
{
"code": 200,
"message": "发布成功",
"data": {
"id": 1
}
}
3.6.2 删除帖子
仅允许删除自己发布的帖子(软删除)。
DELETE /api/community/post/:id
请求参数(路径)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | int | 是 | 帖子ID |
响应示例
{
"code": 200,
"message": "删除成功",
"data": null
}
错误响应
| code | message | 说明 |
|---|---|---|
| 404 | 帖子不存在或无权操作 | 帖子不属于当前用户 |
3.6.3 点赞/取消点赞
Toggle 模式:点击点赞,再次点击取消点赞。同一用户对同一帖子最多点赞1次。
POST /api/community/post/:id/like
请求参数(路径)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | int | 是 | 帖子ID |
请求参数(Body)
无
响应示例
{
"code": 200,
"message": "success",
"data": {
"liked": true,
"like_count": 33
}
}
响应字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
| liked | bool | 当前点赞状态:true=已点赞,false=已取消 |
| like_count | int | 帖子最新点赞总数 |
3.6.4 发表评论
支持一级评论和子回复。
parent_id=0为一级评论;parent_id>0为回复某条评论。
POST /api/community/post/:id/comment
请求参数(路径)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | int | 是 | 帖子ID |
请求参数(Body - JSON)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| content | string | 是 | 评论内容,最长1000字符 |
| parent_id | int | 否 | 父评论ID,0=一级评论,>0=子回复 |
| reply_user_id | int | 否 | 被回复的用户ID(回复子评论时传入) |
请求示例 - 一级评论
{
"content": "好可爱的金毛!"
}
请求示例 - 回复评论
{
"content": "谢谢!",
"parent_id": 5,
"reply_user_id": 2
}
响应示例
{
"code": 200,
"message": "评论成功",
"data": {
"id": 8,
"content": "好可爱的金毛!",
"create_time": "2026-07-30 16:30:00"
}
}
3.6.5 评论列表
公开接口,无需登录。返回一级评论分页列表,每个一级评论包含最多若干条子回复。
GET /api/community/post/:id/comment
请求参数(路径)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | int | 是 | 帖子ID |
请求参数(Query)
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| page | int | 否 | 1 | 页码 |
| pageSize | int | 否 | 20 | 每页条数 |
响应示例
{
"code": 200,
"message": "success",
"data": {
"list": [
{
"id": 8,
"post_id": 1,
"parent_id": 0,
"content": "好可爱的金毛!",
"like_count": 2,
"create_time": "2026-07-30 16:30:00",
"user": {
"id": 2,
"nickname": "宠友小红",
"avatar_url": "/upload/avatar2.jpg"
},
"children": [
{
"id": 9,
"post_id": 1,
"parent_id": 8,
"content": "谢谢!",
"like_count": 0,
"create_time": "2026-07-30 16:35:00",
"user": {
"id": 1,
"nickname": "宠主小明",
"avatar_url": "/upload/avatar1.jpg"
},
"reply_user": {
"id": 2,
"nickname": "宠友小红"
}
}
]
}
],
"total": 15,
"page": 1,
"page_size": 20
}
}
响应字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
| list[].id | int | 评论ID |
| list[].post_id | int | 帖子ID |
| list[].parent_id | int | 父评论ID,0=一级 |
| list[].content | string | 评论内容 |
| list[].like_count | int | 评论点赞数 |
| list[].create_time | string | 评论时间 |
| list[].user | object | 评论人信息 |
| list[].children[].id | int | 子回复ID |
| list[].children[].reply_user | object | 被回复的用户信息(仅回复时有) |
3.7 消息通知
系统通知 + 互动消息(点赞/评论/关注),均需登录。
3.7.1 消息列表
GET /api/message/list
请求参数(Query)
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| type | int | 否 | 0 | 消息类型:0=全部,1=系统通知,2=互动消息 |
| page | int | 否 | 1 | 页码 |
| pageSize | int | 否 | 20 | 每页条数 |
响应示例
{
"code": 200,
"message": "success",
"data": {
"list": [
{
"id": 1,
"message_type": 2,
"title": "你的帖子收到了新的点赞",
"content": "宠友小红点赞了你的帖子",
"extra": { "post_id": 1 },
"is_read": 0,
"create_time": "2026-07-30 15:30:00",
"from_user": { "id": 2, "nickname": "宠友小红", "avatar_url": "/upload/avatar.jpg" }
},
{
"id": 2,
"message_type": 1,
"title": "系统公告",
"content": "RUA宠物小程序1.0版本正式上线啦!",
"extra": null,
"is_read": 1,
"create_time": "2026-07-29 10:00:00",
"from_user": { "id": 0, "nickname": "系统", "avatar_url": "" }
}
],
"total": 25,
"page": 1,
"page_size": 20
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
| message_type | int | 1=系统通知,2=互动消息 |
| is_read | int | 0=未读,1=已读 |
| extra | object | 扩展数据(如关联的帖子ID) |
| from_user | object | 发送者(系统消息时 id=0) |
3.7.2 未读消息数(红点)
GET /api/message/unread
响应示例
{
"code": 200,
"message": "success",
"data": {
"system": 3,
"interact": 5,
"private": 2,
"total": 10
}
}
3.7.3 标记单条已读
PUT /api/message/read/:id
请求参数: 无 Body,路径传消息ID
3.7.4 全部已读
PUT /api/message/readAll
请求参数(Body - JSON)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| type | int | 否 | 0=全部已读,1=系统,2=互动 |
响应示例
{ "code": 200, "message": "已全部标为已读", "data": { "count": 5 } }
3.8 私信聊天
一对一私信,自动创建会话,消息列表自动标记已读。
3.8.1 会话列表
GET /api/conversation/list
响应示例
{
"code": 200,
"message": "success",
"data": [
{
"id": 1,
"target_user": { "id": 2, "nickname": "宠友小红", "avatar_url": "/upload/avatar.jpg" },
"last_message": "你好,我想领养你的猫",
"last_message_time": "2026-07-30 16:30:00",
"unread_count": 2,
"create_time": "2026-07-25 10:00:00"
}
]
}
3.8.2 私信消息列表
GET /api/conversation/:id/messages?page=1&pageSize=30
说明: 读取后自动将该会话内所有未读消息标为已读。
响应示例
{
"code": 200,
"message": "success",
"data": {
"list": [
{
"id": 101,
"from_user_id": 1,
"to_user_id": 2,
"content": "你好",
"is_read": 1,
"create_time": "2026-07-30 16:28:00"
},
{
"id": 102,
"from_user_id": 2,
"to_user_id": 1,
"content": "你好,我想领养你的猫",
"is_read": 1,
"create_time": "2026-07-30 16:29:00"
}
],
"total": 5,
"page": 1,
"page_size": 30
}
}
消息按时间正序排列(较早的在上,最新的在底部)。
3.8.3 发送私信
自动查找或创建会话,写入消息并更新会话的最后一条消息。
POST /api/conversation/send
请求参数(Body - JSON)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| to_user_id | int | 是 | 接收者用户ID |
| content | string | 是 | 消息内容,最长1000字 |
请求示例
{
"to_user_id": 2,
"content": "你好,我想了解一下领养详情"
}
响应示例
{
"code": 200,
"message": "发送成功",
"data": {
"id": 103,
"content": "你好,我想了解一下领养详情",
"conversation_id": 1,
"create_time": "2026-07-30 17:00:00"
}
}
3.8.4 标记会话已读
PUT /api/conversation/:id/read
请求参数: 无 Body,路径传会话ID
3.9 四大服务发布
领养、上门喂养、寄养、宠物配对四大 UGC 服务的发布和列表接口。 列表和详情为公开接口,发布和删除需登录。
3.9.1 领养 - 列表
GET /api/adoption
请求参数(Query)
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| page | int | 否 | 1 | 页码 |
| pageSize | int | 否 | 20 | 每页条数 |
| city | string | 否 | - | 城市筛选 |
| species | int | 否 | - | 物种:1=猫,2=狗 |
| is_free | int | 否 | - | 是否无偿:0=收费,1=无偿 |
响应示例
{
"code": 200,
"message": "success",
"data": {
"list": [{
"id": 1,
"title": "无偿领养3个月小橘猫",
"pet_name": "小橘",
"species": 1,
"breed": "橘猫",
"gender": 1,
"age": 0.3,
"city": "杭州",
"is_free": 1,
"price": 0,
"images": ["/upload/0701/cat1.jpg"],
"status": 1,
"create_time": "2026-07-30 10:00:00",
"user": { "id": 1, "nickname": "宠主小明", "avatar_url": "/upload/avatar.jpg" }
}],
"total": 20,
"page": 1,
"page_size": 20
}
}
3.9.2 领养 - 详情
GET /api/adoption/:id
响应示例(在列表字段基础上增加)
{
"code": 200,
"message": "success",
"data": {
"id": 1,
"pet_id": 0,
"title": "无偿领养3个月小橘猫",
"pet_name": "小橘",
"species": 1,
"breed": "橘猫",
"gender": 1,
"age": 0.3,
"description": "会自己用猫砂盆,性格温顺粘人",
"city": "杭州",
"location_name": "余杭区未来科技城",
"is_free": 1,
"price": 0,
"contact_phone": "138****1234",
"images": ["/upload/0701/cat1.jpg", "/upload/0701/cat2.jpg"],
"view_count": 128,
"status": 1,
"create_time": "2026-07-30 10:00:00",
"user": { "id": 1, "nickname": "宠主小明", "avatar_url": "/upload/avatar.jpg" }
}
}
3.9.3 领养 - 发布
POST /api/adoption
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| title | string | 是 | 标题,最长100字 |
| pet_name | string | 否 | 宠物名称 |
| species | int | 否 | 物种,默认2(狗) |
| breed | string | 否 | 品种 |
| gender | int | 否 | 性别:0=未知,1=公,2=母 |
| age | float | 否 | 年龄(岁) |
| description | string | 否 | 描述/领养要求 |
| city | string | 否 | 城市 |
| location_name | string | 否 | 位置名称 |
| is_free | int | 否 | 是否无偿:1=无偿(默认),0=收费 |
| price | float | 否 | 费用 |
| contact_phone | string | 否 | 联系电话 |
| images | array | 否 | 图片URL数组 |
| pet_id | int | 否 | 关联宠物档案ID |
响应示例
{ "code": 200, "message": "发布成功", "data": { "id": 1 } }
3.9.4 领养 - 删除
DELETE /api/adoption/:id
仅允许删除本人发布的内容。
3.9.5 上门喂养 - 列表
GET /api/feeding
请求参数(Query)
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| page | int | 否 | 1 | 页码 |
| pageSize | int | 否 | 20 | 每页条数 |
| city | string | 否 | - | 地址模糊搜索 |
响应示例
{
"code": 200,
"message": "success",
"data": {
"list": [{
"id": 1,
"title": "出差一周求人上门喂猫",
"description": "两只猫每天需要喂食换水铲屎",
"service_address": "杭州西湖区",
"location_name": "龙井路88号",
"services": ["喂食","换水","铲屎","陪玩"],
"commission": 200,
"start_date": "2026-08-01",
"end_date": "2026-08-07",
"start_time": "08:00",
"end_time": "20:00",
"images": ["/upload/0701/feed1.jpg"],
"status": 1,
"create_time": "2026-07-30 10:00:00",
"user": { "id": 1, "nickname": "宠主小明", "avatar_url": "/upload/avatar.jpg" }
}],
"total": 1,
"page": 1,
"page_size": 20
}
}
3.9.6 上门喂养 - 详情 / 发布 / 删除
- 详情:** **
GET /api/feeding/:id— 返回全字段 + 发布者信息 - 发布:** **
POST /api/feeding— 见下方参数 - 删除:** **
DELETE /api/feeding/:id
发布参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| title | string | 是 | 标题 |
| service_address | string | 是 | 服务地址 |
| services | array | 是 | 服务内容,如["喂食","换水"] |
| start_date | string | 是 | 开始日期 YYYY-MM-DD |
| end_date | string | 是 | 结束日期 YYYY-MM-DD |
| start_time | string | 是 | 开始时间 HH:mm |
| end_time | string | 是 | 结束时间 HH:mm |
| commission | float | 否 | 服务佣金 |
| pet_id | int | 否 | 关联宠物档案ID |
| location_name | string | 否 | 位置名称 |
| description | string | 否 | 详细描述 |
| images | array | 否 | 图片URL数组 |
3.9.7 寄养 - 列表
GET /api/boarding
请求参数(Query)
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| page | int | 否 | 1 | 页码 |
| pageSize | int | 否 | 20 | 每页条数 |
| city | string | 否 | - | 城市筛选 |
| species | int | 否 | - | 物种筛选 |
3.9.8 寄养 - 详情 / 发布 / 删除
- 详情:** **
GET /api/boarding/:id - 发布:** **
POST /api/boarding - 删除:** **
DELETE /api/boarding/:id
发布参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| title | string | 是 | 标题 |
| board_address | string | 是 | 寄养地址 |
| start_date | string | 是 | 开始日期 YYYY-MM-DD |
| end_date | string | 是 | 结束日期 YYYY-MM-DD |
| species | int | 否 | 物种 |
| breed | string | 否 | 品种 |
| pet_count | int | 否 | 宠物数量 |
| city | string | 否 | 城市 |
| price | float | 否 | 费用/天 |
| pet_id | int | 否 | 关联宠物档案ID |
| description | string | 否 | 描述 |
| images | array | 否 | 图片URL数组 |
寄养天数**
days由接口根据start_date和 **end_date自动计算。
3.9.9 宠物配对 - 列表
GET /api/matching
请求参数(Query)
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| page | int | 否 | 1 | 页码 |
| pageSize | int | 否 | 20 | 每页条数 |
| city | string | 否 | - | 城市筛选 |
| species | int | 否 | - | 物种筛选 |
| breed | string | 否 | - | 品种筛选 |
响应示例
{
"code": 200,
"message": "success",
"data": {
"list": [{
"id": 1,
"pet_name": "旺财",
"species": 2,
"breed": "金毛",
"gender": 1,
"age": 2.5,
"city": "杭州",
"breed_require": "金毛",
"images": ["/upload/0701/dog1.jpg"],
"status": 1,
"create_time": "2026-07-30 10:00:00",
"user": { "id": 1, "nickname": "宠主小明", "avatar_url": "/upload/avatar.jpg" }
}],
"total": 1,
"page": 1,
"page_size": 20
}
}
3.9.10 宠物配对 - 详情 / 发布 / 删除
- 详情:** **
GET /api/matching/:id - 发布:** **
POST /api/matching - 删除:** **
DELETE /api/matching/:id
发布参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| pet_name | string | 否 | 宠物名称 |
| species | int | 否 | 物种 |
| breed | string | 否 | 品种 |
| gender | int | 否 | 性别 |
| age | float | 否 | 年龄 |
| breed_require | string | 否 | 期望配种品种 |
| city | string | 否 | 城市 |
| location_name | string | 否 | 位置名称 |
| pet_id | int | 否 | 关联宠物档案ID |
| description | string | 否 | 描述 |
| images | array | 否 | 图片URL数组 |
3.10 公益活动报名
活动列表、详情、报名者列表为公开接口,见** **2.14。 报名字段校验 + 重复报名/名额/时间窗口检验 + 已取消用户可重新报名。
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /api/activity/:id/signup |
报名活动 |
| DELETE | /api/activity/signup/:id |
取消报名 |
报名业务规则
- 同一用户同一活动只能有一条有效报名(唯一约束),取消后可以再次报名
- 报名窗口:
signup_start_time~** **signup_end_time,过期或未开始均拒绝 - 名额检查:
max_participants > 0时,current_participants >= max_participants拒绝 - 报名人数**
signup_count作用:报名成功后 **current_participants += signup_count,取消时相应扣减 - 已取消(status=0)的记录再次调用报名接口时自动恢复
3.11 社区关注(需登录)
关注/取消关注为 Toggle 模式。关注时自动推送互动消息。
关注用户
POST /api/follow/:id
请求参数: 路径传被关注用户ID,无需 Body
响应示例(首次关注/恢复关注)
{ "code": 200, "message": "已关注", "data": { "followed": true } }
响应示例(取消关注)
{ "code": 200, "message": "已取消关注", "data": { "followed": false } }
错误响应
| code | message | 说明 |
|---|---|---|
| 422 | 不能关注自己 | user_id == follow_user_id |
取消关注
DELETE /api/follow/:id
仅当** **
status=1(已关注)时有效,已取消的记录返回 404。
响应示例
{ "code": 200, "message": "已取消关注", "data": { "followed": false } }
我的关注列表
GET /api/user/following?page=1&pageSize=20
响应格式同** **2.15 查看用户关注列表。
我的粉丝列表
GET /api/user/followers?page=1&pageSize=20
响应格式同** 2.15 查看用户粉丝列表,含 **
is_following互关标识。
关注流帖子
见** 2.15 关注流帖子,路由 **
GET /api/community/post?tab=following。
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /api/follow/:id |
Toggle 关注 |
| DELETE | /api/follow/:id |
取消关注 |
| GET | /api/user/following |
我的关注 |
| GET | /api/user/followers |
我的粉丝 |
3.12 收货地址管理
用户收货地址 CRUD,支持设为默认地址。每个用户可有多个地址,设默认时会自动取消其他默认。
3.12.1 地址列表
GET /api/address
响应示例
{
"code": 200,
"message": "success",
"data": [
{
"id": 1,
"contact_name": "张三",
"contact_phone": "138****1234",
"province": "浙江省",
"city": "杭州市",
"district": "西湖区",
"detail": "文三路 123 号",
"is_default": 1,
"create_time": "2026-07-30 10:00:00"
},
{
"id": 2,
"contact_name": "李四",
"contact_phone": "139****5678",
"province": "浙江省",
"city": "杭州市",
"district": "余杭区",
"detail": "未来科技城 xxx",
"is_default": 0,
"create_time": "2026-07-28 15:30:00"
}
]
}
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int | 地址ID |
| contact_name | string | 联系人姓名 |
| contact_phone | string | 联系电话(脱敏) |
| province | string | 省份 |
| city | string | 城市 |
| district | string | 区/县 |
| detail | string | 详细地址 |
| is_default | int | 是否默认: 0=否 1=是 |
| create_time | string | 创建时间 |
3.12.2 地址详情
GET /api/address/:id
响应说明
返回单条地址完整信息,字段同列表项。
3.12.3 新增地址
POST /api/address
请求参数(Body JSON)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| contact_name | string | 是 | 联系人姓名 |
| contact_phone | string | 是 | 联系电话 |
| province | string | 否 | 省份 |
| city | string | 否 | 城市 |
| district | string | 否 | 区/县 |
| detail | string | 是 | 详细地址 |
| is_default | int | 否 | 是否默认: 0=否 1=是,默认0 |
响应示例
{
"code": 200,
"message": "地址已添加",
"data": {
"id": 3,
"contact_name": "王五",
"contact_phone": "137****9999",
"province": "浙江省",
"city": "宁波市",
"district": "海曙区",
"detail": "天一广场 xxx",
"is_default": 0,
"create_time": "2026-08-01 09:00:00"
}
}
3.12.4 编辑地址
PUT /api/address/:id
请求参数(Body JSON)
所有字段均为可选,传什么改什么。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| contact_name | string | 否 | 联系人姓名 |
| contact_phone | string | 否 | 联系电话 |
| province | string | 否 | 省份 |
| city | string | 否 | 城市 |
| district | string | 否 | 区/县 |
| detail | string | 否 | 详细地址 |
| is_default | int | 否 | 是否设为默认,设1时自动取消其他默认 |
3.12.5 删除地址
DELETE /api/address/:id
软删除,不做物理删除。
3.12.6 设为默认地址
PUT /api/address/:id/default
设为默认地址,同时自动取消其他地址的默认状态。
接口汇总
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/address |
地址列表 |
| GET | /api/address/:id |
地址详情 |
| POST | /api/address |
新增地址 |
| PUT | /api/address/:id |
编辑地址 |
| DELETE | /api/address/:id |
删除地址 |
| PUT | /api/address/:id/default |
设为默认 |
3.13 我的动态列表
查看当前用户发布的所有社区帖子,含已下架/审核失败/已删除。公开帖子列表接口只返回审核通过的,这里返回全量。
GET /api/user/posts
请求参数(Query)
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| status | int | 否 | - | 帖子状态: 0=隐藏 1=正常,不传=全部 |
| audit_status | int | 否 | - | 审核状态: 0=待审核 1=通过 2=拒绝,不传=全部 |
| page | int | 否 | 1 | 页码 |
| pageSize | int | 否 | 10 | 每页条数 |
响应示例
{
"code": 200,
"message": "success",
"data": {
"list": [
{
"id": 1,
"topic_id": 1,
"topic_name": "萌宠日常",
"title": "今天带崽去公园",
"content": "天气真好...",
"content_type": 1,
"video_cover_url": "",
"city": "杭州",
"status": 1,
"audit_status": 1,
"like_count": 32,
"comment_count": 8,
"favorite_count": 15,
"view_count": 320,
"is_deleted": 0,
"create_time": "2026-07-30 10:30:00",
"images": [
{ "id": 1, "post_id": 1, "image_url": "https://cdn.ruapet.com/post/pic1.jpg", "sort": 1 }
]
}
],
"total": 25,
"page": 1,
"page_size": 10
}
}
响应字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int | 帖子ID |
| topic_id | int | 话题ID |
| topic_name | string | 话题名称 |
| title | string | 标题 |
| content | string | 正文 |
| content_type | int | 内容类型: 1=图文 2=视频 |
| video_cover_url | string | 视频封面 |
| city | string | 所在城市 |
| status | int | 帖子状态: 0=隐藏 1=正常 |
| audit_status | int | 审核状态: 0=待审核 1=已通过 2=已拒绝 |
| like_count | int | 点赞数 |
| comment_count | int | 评论数 |
| favorite_count | int | 收藏数 |
| view_count | int | 浏览数 |
| is_deleted | int | 是否已删除: 0=否 1=是 |
| create_time | string | 发布时间 |
| images | array | 帖子图片列表 |
3.14 我的发布管理
聚合展示当前用户在四大服务(领养/喂养/寄养/配对)和公益活动中发布的全部内容,支持按类型和状态筛选。
GET /api/user/publish
请求参数(Query)
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| type | string | 否 | - | 发布类型: adoption\ |
| status | int | 否 | - | 状态筛选(按各表status字段),不传=全部 |
| page | int | 否 | 1 | 页码 |
| pageSize | int | 否 | 10 | 每页条数 |
响应示例
{
"code": 200,
"message": "success",
"data": {
"list": [
{
"id": 1,
"title": "三个月英短求领养",
"pet_name": "小橘",
"species": 1,
"breed": "英短",
"gender": 1,
"age": 0.25,
"city": "杭州",
"status": 1,
"view_count": 128,
"create_time": "2026-07-30 10:00:00",
"update_time": "2026-07-30 10:00:00",
"publish_type": "adoption"
},
{
"id": 2,
"title": "周末义卖活动",
"category": 3,
"city": "杭州",
"start_time": "2026-08-15 09:00:00",
"end_time": "2026-08-15 17:00:00",
"current_participants": 15,
"max_participants": 50,
"status": 1,
"view_count": 320,
"create_time": "2026-07-28 14:00:00",
"update_time": "2026-07-28 14:00:00",
"publish_type": "activity"
}
],
"total": 10,
"page": 1,
"page_size": 10
}
}
响应字段说明
所有条目统一包含** **publish_type 字段区分来源,各类型特有字段如下:
| publish_type | 特有字段 | 说明 |
|---|---|---|
| adoption | title, pet_name, species, breed, gender, age | 领养发布 |
| feeding | title | 喂养需求 |
| boarding | title | 寄养需求 |
| matching | pet_name, species, breed, gender, age | 配对发布 |
| activity | title, category, start_time, end_time, current_participants, max_participants | 公益活动 |
通用字段
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int | 记录ID |
| publish_type | string | 发布类型标识 |
| city | string | 城市 |
| status | int | 状态(各类型含义不同) |
| view_count | int | 浏览数 |
| create_time | string | 发布时间 |
| update_time | string | 更新时间 |
3.15 地图寻宠发布管理
发布寻宠/寻主信息,管理自己的发布记录。浏览接口见** **2.16。
3.15.1 发布
POST /api/lostpet
请求参数(Body JSON)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| type | int | 是 | 类型: 1=寻宠(找宠物) 2=寻主(找主人) |
| title | string | 是 | 标题 |
| pet_name | string | 否 | 宠物名称 |
| species | int | 否 | 物种: 0=未知 1=猫 2=狗 3=其他 |
| breed | string | 否 | 品种 |
| gender | int | 否 | 性别: 0=未知 1=公 2=母 |
| age | string | 否 | 年龄描述 |
| color | string | 否 | 毛色 |
| description | string | 否 | 详细描述/特征 |
| city | string | 是 | 城市 |
| district | string | 否 | 区/县 |
| location_name | string | 否 | 位置名称 |
| address | string | 否 | 详细地址 |
| latitude | float | 是 | 纬度 |
| longitude | float | 是 | 经度 |
| lost_time | string | 否 | 走失/发现时间 |
| contact_phone | string | 否 | 联系电话 |
| reward | number | 否 | 悬赏金额(元) |
| images | array | 否 | 图片URL列表 |
注意: 发布后** **status 默认为1(寻找中),audit_status 默认为1(审核通过),立即在列表和地图中可见。
响应示例
{
"code": 200,
"message": "发布成功",
"data": {
"id": 3,
"type": 1,
"title": "急寻!三花猫走失",
"pet_name": "花花",
"species": 1,
"status": 1,
"create_time": "2026-08-03 10:00:00"
}
}
3.15.2 更新发布
PUT /api/lostpet/:id
请求参数(Body JSON)
所有字段均为可选,传什么改什么。可更新字段同发布接口。
3.15.3 删除发布
DELETE /api/lostpet/:id
软删除,仅发布者本人可操作。
3.15.4 关闭(标记已找到)
PUT /api/lostpet/:id/close
将状态从"寻找中"改为"已找到/已关闭"。仅发布者本人可操作,已关闭的记录不可重复关闭。
接口汇总
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/lostpet?view=list |
列表视图(公开) |
| GET | /api/lostpet?view=map&lat=&lng=&radius= |
地图视图(公开) |
| GET | /api/lostpet/:id |
详情(公开) |
| POST | /api/lostpet |
发布(需登录) |
| PUT | /api/lostpet/:id |
更新(需登录) |
| DELETE | /api/lostpet/:id |
删除(需登录) |
| PUT | /api/lostpet/:id/close |
关闭(需登录) |
3.16 宠物性格测试
提交答题自动计算性格得分,生成报告并更新宠物性格标签。
3.16.1 提交答题
POST /api/personality/submit
请求参数(Body JSON)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| pet_id | int | 是 | 宠物ID |
| answers | array | 是 | 答题记录 |
answers 数组元素结构
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| question_id | int | 是 | 题目ID(对应题库中的id) |
| option_index | int | 是 | 选项索引(0开始,对应options数组下标) |
请求示例
{
"pet_id": 1,
"answers": [
{ "question_id": 1, "option_index": 2 },
{ "question_id": 2, "option_index": 0 },
{ "question_id": 3, "option_index": 1 },
{ "question_id": 4, "option_index": 1 },
{ "question_id": 5, "option_index": 0 },
{ "question_id": 6, "option_index": 3 },
{ "question_id": 7, "option_index": 2 },
{ "question_id": 8, "option_index": 1 }
]
}
响应示例
{
"code": 200,
"message": "测试完成",
"data": {
"result_id": 1,
"personality": {
"id": 4,
"name": "猫界黑帮老大",
"description": "霸气侧漏,有强烈的领地意识",
"icon_url": "https://cdn.ruapet.com/personality/boss.png"
},
"top_scores": [
{ "rank": 1, "personality_id": 4, "name": "猫界黑帮老大", "score": 14 },
{ "rank": 2, "personality_id": 9, "name": "小钢炮", "score": 11 },
{ "rank": 3, "personality_id": 10, "name": "街头教父", "score": 9 },
{ "rank": 4, "personality_id": 7, "name": "二傻子·情绪版", "score": 6 },
{ "rank": 5, "personality_id": 5, "name": "永动机小疯子", "score": 5 }
]
}
}
响应字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
| result_id | int | 测试结果记录ID |
| personality | object | 匹配的性格(得分最高的性格) |
| personality.id | int | 性格ID |
| personality.name | string | 性格名称 |
| personality.description | string | 性格描述 |
| personality.icon_url | string | 性格图标 |
| top_scores | array | 得分排行(前5名) |
| top_scores[].rank | int | 排名 |
| top_scores[].personality_id | int | 性格ID |
| top_scores[].name | string | 性格名称 |
| top_scores[].score | int | 得分 |
注意: 提交后会自动更新该宠物的** **personality_id 字段为匹配到的性格ID。
3.16.2 查看测试报告
GET /api/personality/result/:petId
请求参数(路径)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| petId | int | 是 | 宠物ID |
响应示例
{
"code": 200,
"message": "success",
"data": {
"result_id": 1,
"pet_id": 1,
"personality": {
"id": 4,
"name": "猫界黑帮老大",
"description": "霸气侧漏,有强烈的领地意识",
"icon_url": "https://cdn.ruapet.com/personality/boss.png"
},
"top_scores": [
{ "rank": 1, "personality_id": 4, "name": "猫界黑帮老大", "score": 14 },
{ "rank": 2, "personality_id": 9, "name": "小钢炮", "score": 11 }
],
"create_time": "2026-08-03 10:00:00"
}
}
返回该宠物最近一次测试的完整报告。若无记录返回404。
接口汇总
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/personality |
性格标签列表(公开) |
| GET | /api/personality/questions |
测试题库(公开) |
| POST | /api/personality/submit |
提交答题(需登录) |
| GET | /api/personality/result/:petId |
查看报告(需登录) |
3.17 服务预约下单
用户选择平台服务项目、指定宠物、预约日期时间并下单。支付后商家确认 → 开始服务 → 完成。
3.17.1 我的订单列表
GET /api/order?order_status=&page=1&pageSize=20
请求参数(Query)
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| order_status | int | 否 | - | 订单状态筛选:0=待支付 1=待确认 2=已确认 3=服务中 4=已完成 5=已取消 6=已退款 |
| page | int | 否 | 1 | 页码 |
| pageSize | int | 否 | 20 | 每页条数 |
响应示例
{
"code": 200,
"message": "success",
"data": {
"list": [
{
"id": 1,
"order_no": "SO202608031530000123",
"service_item_id": 5,
"service_name": "宠物SPA",
"pet_id": 3,
"pet_name": "团团",
"appoint_date": "2026-08-10",
"appoint_time": "14:00-15:00",
"pet_count": 1,
"amount": "198.00",
"pay_amount": "198.00",
"pay_status": 0,
"order_status": 0,
"remark": "猫咪比较怕生,请温柔操作",
"cancel_reason": "",
"create_time": "2026-08-03 15:30:00"
}
],
"total": 5,
"page": 1,
"page_size": 20
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
| order_no | string | 订单编号(SO开头) |
| service_item_id | int | 服务项目ID |
| service_name | string | 服务名称 |
| pet_name | string | 宠物名 |
| appoint_date | string | 预约日期 |
| appoint_time | string | 预约时间段 |
| pet_count | int | 宠物数量 |
| amount/pay_amount | string | 金额/实付 |
| pay_status | int | 0=待支付 1=已支付 2=已退款 |
| order_status | int | 见状态对照表 |
订单状态对照表
| 值 | 状态 | 说明 |
|---|---|---|
| 0 | 待支付 | 刚下单,等待付款 |
| 1 | 待确认 | 已支付,等待商家确认 |
| 2 | 已确认 | 商家已确认预约 |
| 3 | 服务中 | 服务已开始 |
| 4 | 已完成 | 服务完成,可评价 |
| 5 | 已取消 | 用户主动取消(仅待支付状态) |
| 6 | 已退款 | 商家操作退款 |
3.17.2 订单详情
GET /api/order/:id
响应比列表多返回:service(服务详情对象,含category_id/name/description/cover_url/price/duration)、pay_time、finish_time、transaction_id。
3.17.3 创建订单
POST /api/order
请求参数(Body - JSON)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| service_item_id | int | 是 | 服务项目ID(service_item表) |
| pet_id | int | 否 | 宠物ID |
| appoint_date | string | 是 | 预约日期(YYYY-MM-DD,不能早于今天) |
| appoint_time | string | 否 | 预约时间段(如 09:00-10:00) |
| pet_count | int | 否 | 宠物数量,默认1 |
| remark | string | 否 | 备注 |
请求示例
{
"service_item_id": 5,
"pet_id": 3,
"appoint_date": "2026-08-10",
"appoint_time": "14:00-15:00",
"pet_count": 1,
"remark": "猫咪比较怕生"
}
下单后订单号自动生成(SO + YmdHis + 4位随机),金额 = 服务单价 × 数量。
3.17.4 支付订单
POST /api/order/:id/pay
当前为模拟支付接口,直接标记为已支付。后续对接微信支付后替换。
支付成功后:pay_status → 1(已支付)、order_status → 1(待确认)、记录** pay_time + **transaction_id。
3.17.5 取消订单
PUT /api/order/:id/cancel
仅** **待支付 状态可取消,取消后状态变为 5(已取消)。
接口汇总
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/order |
我的订单列表 |
| GET | /api/order/:id |
订单详情 |
| POST | /api/order |
创建订单 |
| POST | /api/order/:id/pay |
支付(模拟) |
| PUT | /api/order/:id/cancel |
取消订单 |
3.18 社区收藏
Toggle 收藏/取消收藏帖子,查看收藏列表。
3.18.1 收藏/取消收藏
POST /api/community/post/:id/favorite
请求参数(路径)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | int | 是 | 帖子ID |
响应示例
{
"code": 200,
"message": "success",
"data": {
"favorited": true,
"favorite_count": 16
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
| favorited | bool | 当前状态:true=已收藏 false=已取消 |
| favorite_count | int | 帖子当前总收藏数 |
说明: Toggle 模式,已收藏则取消、未收藏则收藏。收藏/取消时自动更新帖子** **favorite_count。
3.18.2 我的收藏列表
GET /api/user/favorites?page=1&pageSize=10
请求参数(Query)
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| page | int | 否 | 1 | 页码 |
| pageSize | int | 否 | 10 | 每页条数 |
响应示例
{
"code": 200,
"message": "success",
"data": {
"list": [
{
"id": 1,
"topic_id": 1,
"title": "今天带崽去公园",
"content": "天气真好...",
"content_type": 1,
"video_cover_url": "",
"city": "杭州",
"like_count": 32,
"comment_count": 8,
"favorite_count": 16,
"view_count": 320,
"create_time": "2026-07-30 10:30:00",
"user": {
"id": 1,
"nickname": "宠主小明",
"avatar_url": "https://cdn.ruapet.com/avatar/user1.jpg"
},
"images": [
{
"id": 1,
"post_id": 1,
"image_url": "https://cdn.ruapet.com/post/pic1.jpg",
"sort": 1
}
]
}
],
"total": 15,
"page": 1,
"page_size": 10
}
}
按收藏时间倒序排列。已下架/审核不通过的帖子自动从列表中移除。
接口汇总
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /api/community/post/:id/favorite |
收藏/取消(需登录) |
| GET | /api/user/favorites |
我的收藏列表(需登录) |
3.19 服务评价
用户对已完成的服务订单进行评分和文字评价。一个订单只能评价一次。支持匿名评价。
3.19.1 服务评价列表(公开)
GET /api/service/:serviceItemId/comments?page=1&pageSize=20
响应示例
{
"code": 200,
"message": "success",
"data": {
"list": [
{
"id": 1,
"user_id": 1001,
"order_id": 5,
"rating": 5,
"content": "服务非常好,宠物SPA后毛毛特别顺滑,工作人员也很耐心",
"images": ["/upload/review/img1.jpg"],
"is_anonymous": 0,
"user_nickname": "宠主小明",
"user_avatar": "/upload/avatar.jpg",
"create_time": "2026-08-03 16:00:00"
}
],
"total": 12,
"page": 1,
"page_size": 20
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
| rating | int | 评分 1-5 |
| images | array | 评价图片列表 |
| is_anonymous | int | 是否匿名:0=否 1=是 |
| user_nickname | string | 匿名评价时显示"匿名用户" |
| user_avatar | string | 匿名评价时为空 |
3.19.2 评分统计(公开)
GET /api/service/:serviceItemId/rating
响应示例
{
"code": 200,
"message": "success",
"data": {
"count": 12,
"avg_rating": 4.6,
"distribution": { "1": 0, "2": 0, "3": 2, "4": 3, "5": 7 }
}
}
3.19.3 提交评价(需登录)
POST /api/comment
Body: { "order_id": 5, "rating": 5, "content": "服务很好", "service_item_id": 3, "is_anonymous": 0, "images": ["/upload/review/img1.jpg"] }
请求参数(Body - JSON)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| order_id | int | 是 | 订单ID |
| rating | int | 否 | 评分 1-5,默认5 |
| content | string | 是 | 评价内容(最长1000字) |
| service_item_id | int | 否 | 服务项目ID,不传则自动从订单获取 |
| is_anonymous | int | 否 | 是否匿名,默认0 |
| images | array | 否 | 评价图片URL列表 |
约束:
- 仅已完成订单可评价
- 一个订单只能评价一次(防重)
- 提交后自动更新**
service_item表的avg_rating+ **comment_count
接口汇总
| 方法 | 路径 | 鉴权 | 说明 |
|---|---|---|---|
| GET | /api/service/:id/comments |
公开 | 服务评价列表 |
| GET | /api/service/:id/rating |
公开 | 评分统计 |
| POST | /api/comment |
需登录 | 提交评价 |
3.20 宠物健康记录
记录宠物的疫苗、驱虫、体检、患病、用药等健康事件。支持到期提醒。
3.20.1 记录类型枚举
GET /api/health/types
响应示例
{
"code": 200,
"message": "success",
"data": [
{ "id": 1, "name": "疫苗" },
{ "id": 2, "name": "驱虫" },
{ "id": 3, "name": "体检" },
{ "id": 4, "name": "患病" },
{ "id": 5, "name": "用药" },
{ "id": 6, "name": "其他" }
]
}
3.20.2 健康记录列表
GET /api/health/:petId?record_type=&page=1&pageSize=20
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| record_type | int | 否 | 0=全部 | 记录类型筛选:1-6 |
| page | int | 否 | 1 | 页码 |
| pageSize | int | 否 | 20 | 每页条数 |
响应示例
{
"code": 200,
"message": "success",
"data": {
"list": [
{
"id": 1,
"pet_id": 3,
"record_type": 1,
"record_type_cn": "疫苗",
"record_name": "狂犬疫苗",
"record_date": "2026-06-15",
"next_date": "2027-06-15",
"hospital": "宠爱动物医院",
"doctor": "张医生",
"remark": "注射后观察30分钟",
"certificate_url": "/upload/health/vaccine_cert.jpg",
"create_time": "2026-06-15 10:00:00"
}
],
"total": 5,
"page": 1,
"page_size": 20
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
| record_type | int | 1=疫苗 2=驱虫 3=体检 4=患病 5=用药 6=其他 |
| record_type_cn | string | 类型中文名 |
| next_date | string\ | null |
| certificate_url | string | 证明文件/单据图片 |
3.20.3 记录详情
GET /api/health/detail/:id
3.20.4 创建健康记录
POST /api/health
Body: { "pet_id": 3, "record_type": 1, "record_name": "狂犬疫苗", "record_date": "2026-06-15", "next_date": "2027-06-15", "hospital": "宠爱动物医院" }
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| pet_id | int | 是 | 宠物ID |
| record_type | int | 是 | 记录类型 1-6 |
| record_name | string | 是 | 记录名称 |
| record_date | string | 是 | 记录日期 YYYY-MM-DD |
| next_date | string | 否 | 下次日期 |
| hospital | string | 否 | 医院/诊所名称 |
| doctor | string | 否 | 医生姓名 |
| remark | string | 否 | 备注 |
| certificate_url | string | 否 | 证明文件URL |
3.20.5 更新/删除
PUT /api/health/:id — 更新记录(白名单字段)
DELETE /api/health/:id — 删除记录(软删除)
3.20.6 到期提醒
GET /api/health/:petId/reminders
返回该宠物** **未来7天内 需要处理的记录(next_date 在今天~7天后之间),按日期升序排列。
响应示例
{
"code": 200,
"message": "success",
"data": [
{
"id": 5,
"pet_id": 3,
"record_type": 2,
"record_type_cn": "驱虫",
"record_name": "体内驱虫",
"record_date": "2026-05-01",
"next_date": "2026-08-08",
"hospital": "宠爱动物医院",
"days_left": 3
}
]
}
| 字段 | 说明 |
|---|---|
| days_left | 剩余天数(截止日倒计时) |
接口汇总
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/health/types |
记录类型枚举 |
| GET | /api/health/:petId |
健康记录列表 |
| GET | /api/health/detail/:id |
记录详情 |
| POST | /api/health |
创建记录 |
| PUT | /api/health/:id |
更新记录 |
| DELETE | /api/health/:id |
删除记录 |
| GET | /api/health/:petId/reminders |
到期提醒 |
3.21 系统通知
后台运营向C端用户推送系统通知。支持全员推送和指定用户推送。通知有3种状态:草稿 → 已发布 → 已撤回。
3.21.1 通知列表
GET /api/notification?page=1&pageSize=20
自动过滤:仅返回当前用户可见的已发布通知。全员通知直接可见,指定用户通知仅在当前用户在目标列表中时返回。
响应示例
{
"code": 200,
"message": "success",
"data": {
"list": [
{
"id": 1,
"title": "系统维护通知",
"content": "平台将于8月10日进行升级维护...",
"is_top": 1,
"publish_time": "2026-08-03 14:00:00"
}
],
"total": 5,
"page": 1,
"page_size": 20
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
| is_top | int | 是否置顶:0=否 1=是 |
| publish_time | string | 发布时间 |
3.21.2 通知详情
GET /api/notification/:id
含** **target_type 权限校验:指定用户通知若非目标用户则返回 404。
接口汇总
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/notification |
我的通知列表 |
| GET | /api/notification/:id |
通知详情 |
3.22 会员体系
用户会员等级、成长值、升级进度查询。成长值来源:消费(1元=1)、评价(+5)、发布帖子(+3)、签到(+2)、系统调整。
3.22.1 我的会员信息
GET /api/member/info
返回用户当前会员等级、折扣、成长值、升级进度及下一级信息。
响应示例
{
"code": 200,
"message": "success",
"data": {
"id": 1,
"user_id": 1,
"level_id": 2,
"growth_value": 1200,
"total_growth_value": 1500,
"create_time": "2026-07-01 10:00:00",
"update_time": "2026-08-05 14:30:00",
"level": {
"id": 2,
"name": "银牌会员",
"level": 2,
"icon_url": "https://...",
"discount": 0.95,
"description": "享95折优惠"
},
"next_level": {
"id": 3,
"name": "金牌会员",
"level": 3,
"min_growth": 5000,
"discount": 0.90,
"description": "享9折优惠,专属客服"
},
"progress": {
"current": 1200,
"need": 5000,
"percent": 24.0
}
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
| level | object | 当前等级信息(名称、折扣等) |
| level.discount | float | 当前等级折扣(1.00=无折扣) |
| next_level | object | 下一级信息,已是最高级时为 null |
| progress | object | 升级进度,已满级时为 null |
| progress.percent | float | 进度百分比 |
3.22.2 成长值记录
GET /api/member/growthLogs?page=1&pageSize=20
按时间倒序返回成长值变更记录。
响应示例
{
"code": 200,
"message": "success",
"data": {
"list": [
{
"id": 52,
"change_type": 1,
"change_type_cn": "消费",
"change_value": 100,
"before_value": 1100,
"after_value": 1200,
"remark": "订单 SO20260805... 消费100元",
"related_id": 10,
"create_time": "2026-08-05 14:30:00"
}
],
"total": 52,
"page": 1,
"page_size": 20
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
| change_type | int | 变更类型:1=消费 2=评价 3=发布帖子 4=签到 5=系统调整 |
| change_type_cn | string | 变更类型中文 |
| change_value | int | 变更值(正数增加,负数减少) |
| before_value | int | 变更前成长值 |
| after_value | int | 变更后成长值 |
| related_id | int | 关联业务ID(如订单ID) |
接口汇总
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/member/info |
我的会员信息 |
| GET | /api/member/growthLogs |
成长值记录 |
附录:公共数据结构
用户简要信息
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int | 用户ID |
| nickname | string | 昵称 |
| avatar_url | string | 头像地址 |
| gender | int | 性别:0=未知,1=男,2=女 |
| real_name_status | int | 实名认证状态:0=未认证,1=已认证,2=审核中,3=认证失败 |
| status | int | 账号状态:0=禁用,1=正常 |
| create_time | string | 注册时间 |
帖子信息
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int | 帖子ID |
| topic_id | int | 话题ID |
| title | string | 标题 |
| content | string | 正文内容 |
| content_type | int | 内容类型:1=图文,2=视频 |
| video_cover_url | string | 视频封面图 |
| city | string | 所在城市 |
| like_count | int | 点赞数 |
| comment_count | int | 评论数 |
| favorite_count | int | 收藏数 |
| view_count | int | 浏览数 |
| create_time | string | 发布时间 |
| user | object | 作者信息,见用户简要信息 |
| images | array | 图片列表 |
帖子图片
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int | 图片记录ID |
| post_id | int | 所属帖子ID |
| image_url | string | 图片地址 |
| sort | int | 排序序号 |
附录:WebSocket 实时推送协议
服务地址:**
ws://www.ruapet.com:9502(生产环境使用wss://) **服务端口: 9502(WebSocket 客户端连接)、9501(内部推送,无需关心)
服务启动
# ====== Linux 启动 ======
# 调试模式(前台运行,Ctrl+C 停止)
cd rua_server
php think rua:worker start
# 守护进程模式(后台运行)
php think rua:worker start -d
# 查看运行状态
php think rua:worker status
# 查看当前连接数
php think rua:worker connections
# 平滑重启(不中断现有连接)
php think rua:worker reload
# 优雅停止(等待连接完成后关闭)
php think rua:worker stop -g
# 立即停止
php think rua:worker stop
# 重启
php think rua:worker restart -d
# ====== Windows 启动 ======
php think rua:worker # 前台运行,Ctrl+C 停止
# ====== 生产环境(supervisor 守护) ======
# /etc/supervisor/conf.d/rua-worker.conf
[program:rua-worker]
command=php /www/wwwroot/ruapet/rua_server/think rua:worker start
directory=/www/wwwroot/ruapet/rua_server
autostart=true
autorestart=true
user=www
numprocs=1
stdout_logfile=/www/wwwroot/ruapet/rua_server/runtime/log/worker.log
# Supervisor 重载
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start rua-worker
连接与认证
小程序端需先建立 WebSocket 连接,然后发送 JWT token 进行身份认证:
// 1. 小程序连接
wx.connectSocket({ url: 'wss://www.ruapet.com:9502' })
// 2. 连接成功后发送 token
{ "type": "auth", "token": "{{access_token}}" }
// 3. 认证成功返回
{ "type": "auth_ok", "user_id": 1 }
// 3b. 认证失败返回
{ "type": "auth_fail", "msg": "token无效" }
心跳保活
// 客户端每 30 秒发送
{ "type": "ping" }
// 服务端响应
{ "type": "pong", "time": 1691234567 }
推送消息类型
1. 新私信消息** **new_private_message
当有人给当前用户发送私信时,实时推送:
{
"type": "new_private_message",
"data": {
"conversation_id": 1,
"from_user_id": 2,
"content": "你好呀",
"message_id": 100,
"create_time": "2026-08-06 15:30:00"
}
}
小程序处理:
- 判断当前是否在会话列表页 → 刷新会话列表 + 更新未读红点
- 判断当前是否在该会话详情页 → 追加消息到聊天列表
- 否则 → 仅更新底部"消息"Tab 未读红点
2. 新互动消息** **new_interact
当有人点赞/评论/关注时,实时推送:
{
"type": "new_interact",
"data": {
"action": "like",
"post_id": 10,
"from_user_id": 3,
"from_user": "小明",
"content": "你的帖子收到了新的点赞"
}
}
action 取值:** like(点赞)| comment(评论)| reply(回复评论)| **follow(关注)
小程序处理:
- 更新"消息"Tab 的未读红点数字
- 如当前在消息列表页 → 刷新列表
小程序前端对接清单(需前端完成)
| # | 任务 | 说明 |
|---|---|---|
| 1 | 建立 WebSocket 连接 | 在App.onLaunch() 中调用 wx.connectSocket({ url: 'wss://www.ruapet.com:9502' }) |
| 2 | 发送认证 | onSocketOpen 回调中发送 { type: 'auth', token: getStorageSync('access_token') } |
| 3 | Token 刷新后重连 | access_token 更换后,重新发送 auth 消息(无需断开连接) |
| 4 | 心跳保活 | 每 30 秒发送{ type: 'ping' },超时无 pong 回复则重连 |
| 5 | 断线重连 | onSocketClose / onSocketError 中 3 秒后自动重连(指数退避,最多 5 次) |
| 6 | 消息分发 | onSocketMessage 中根据 type 分发到对应页面处理逻辑 |
| 7 | App 切后台 | onHide 中不关闭连接,onShow 中判断连接状态,断线则重连 |
| 8 | 未读红点 | 收到推送时更新全局未读数(配合/api/message/unread 接口同步) |
注意事项
- WebSocket 仅推送通知,不传输完整消息体。用户点击后仍通过 HTTP 接口获取详细数据
- 用户离线期间的未读消息,仍通过** **
/api/message/unreadHTTP 接口获取 - Worker 进程不写数据库,推送失败不影响消息的持久化存储
- 生产环境需配置 Nginx 反向代理 WebSocket(9502 端口),并启用 WSS(SSL)
更新日志
| 日期 | 版本 | 说明 |
|---|---|---|
| 2026-07-30 | v1.0 | 初始版本,包含首页聚合、服务、社区、登录、用户等模块接口 |
| 2026-07-30 | v1.1 | 新增单文件/多文件上传接口,支持本地存储+OSS双模式自动切换 |
| 2026-07-30 | v1.2 | 新增宠物档案 CRUD 全套接口(列表/详情/新增/编辑/删除)+ 品种字典接口 |
| 2026-07-30 | v1.3 | 新增社区互动全套接口(发布/删除帖子、点赞/取消、发表评论、评论列表) |
| 2026-07-30 | v1.4 | 新增四大服务接口(领养/喂养/寄养/配对,各含列表+详情+发布+删除) |
| 2026-07-30 | v1.5 | 新增消息通知(系统+互动列表/未读数/已读)+ 私信聊天(会话列表/收发/已读) |
| 2026-07-30 | v1.6 | 新增公益活动接口(列表/详情/报名者/报名/取消报名,含报名窗口+名额校验) |
| 2026-07-30 | v2.1 | 新增社区关注功能(Toggle关注/关注列表/粉丝列表/关注流帖子+关注通知联动) |
| 2026-08-03 | v2.2 | 新增我的页面聚合模块:收货地址CRUD(6接口)、我的动态列表(含已下架)、我的发布管理(四大服务+活动聚合) |
| 2026-08-03 | v2.3 | 新增地图找宠模块:寻宠/寻主发布、Haversine半径搜索地图点位、列表/地图双视图切换 |
| 2026-08-03 | v2.4 | 新增宠物性格测试模块:题库配置(8题预置)、答题评分引擎、性格报告生成+宠物性格自动更新 |
| 2026-08-03 | v2.5 | 新增社区收藏功能:Toggle收藏/取消+favorite_count同步、我的收藏列表(含帖子详情、用户、图片) |
| 2026-08-03 | v3.4 | 服务预约下单模块:C端下单/列表/详情/支付/取消(5接口)、后台订单管理(全量列表+状态流转:确认→开始→完成→退款)、订单号自动生成、状态机校验 |
| 2026-08-03 | v3.5 | 服务评价模块:C端公开浏览评价列表+评分统计(含各星级分布)、C端提交评价(匿名+TTS+防重校验+自动回写service_item评分)、后台评价列表+隐藏/显示切换 |
| 2026-08-03 | v3.6 | 宠物健康记录模块:6种记录类型CRUD(疫苗/驱虫/体检/患病/用药/其他)、类型枚举接口、到期提醒(未来7天next_date)、宠物归属校验、软删除 |
| 2026-08-03 | v3.7 | 系统通知推送模块:后台创建/编辑/发布/撤回/删除通知(草稿→发布→撤回状态机),C端列表+详情(全员推送+指定用户推送+内存分页+权限校验) |
| 2026-08-05 | v3.8 | 会员体系模块:后台等级字典CRUD+用户会员列表/详情+手动加减成长值(自动升降级检测),C端会员信息(含等级/折扣/升级进度)+成长值记录分页查询 |
| 2026-08-06 | v3.9 | WebSocket 实时推送:引入 Workerman,私信/点赞/评论/关注实时推送至小程序客户端(端口 9502)。新增 WebSocket 协议文档,标注小程序前端 8 项对接任务。清理 conversation.unread_count 冗余字段 |