hyapp-server/docs/flutter对接/用户举报Flutter对接.md
2026-05-29 19:56:14 +08:00

7.7 KiB
Raw Blame History

用户举报 Flutter 对接

本文描述 Flutter App 对接用户举报和房间举报的 HTTP 契约。通用文件上传接口用于上传举报图片并拿到 URL提交举报接口只接收 JSON。

基础地址

本地开发地址:

http://127.0.0.1:13000

线上环境使用当前 App 配置里的 gateway base URL。下面所有路径都拼在 gateway base URL 后。

请求头

Header 必填 示例 说明
Authorization Bearer <access_token> 登录 access token举报发起人只从 token 读取Flutter 不传举报发起人 ID。
X-App-Code lalu App 编码;登录态接口最终以 token 内的 app_code 为准。
Content-Type 提交举报必填 application/json 提交举报使用 JSON。
Content-Type 上传图片必填 multipart/form-data 上传举报图片使用 multipart。

统一响应 envelope

{
  "code": "OK",
  "message": "ok",
  "request_id": "req_abc",
  "data": {}
}

Flutter 只在 code == "OK" 时读取 data。失败时记录 request_id,用于后端排查。

调用顺序

1. 用户在举报弹窗选择举报类型。
2. 如有举报图,逐张调用 POST /api/v1/files/upload收集每次返回的 data.url。
3. 调用 POST /api/v1/reports 提交举报。
4. 提交成功后关闭弹窗,并用 data.report_id 写本地日志。

上传举报图片

上传接口只负责把文件写入对象存储并返回 URL不创建举报单。

POST /api/v1/files/upload
Authorization: Bearer <access_token>
X-App-Code: lalu
Content-Type: multipart/form-data

file=<binary>

请求字段:

字段 必填 类型 说明
file multipart file 单文件最大 20MB。多图逐张上传Flutter 把每张图返回的 data.url 放进提交举报接口的 image_urls

成功响应:

{
  "code": "OK",
  "message": "ok",
  "request_id": "req_upload_report_image",
  "data": {
    "url": "https://cdn.example.com/app/files/10001/20260529/file_xxx.jpg",
    "object_key": "app/files/10001/20260529/file_xxx.jpg",
    "content_type": "image/jpeg",
    "size_bytes": 345678
  }
}

Flutter 提交举报时只需要使用 data.url

提交举报

POST /api/v1/reports
Authorization: Bearer <access_token>
X-App-Code: lalu
Content-Type: application/json

{
  "user_id": "10002",
  "report_type": "pornography",
  "reason": "用户在房间内发布违规内容",
  "image_urls": [
    "https://cdn.example.com/app/files/10001/20260529/file_xxx.jpg"
  ]
}

举报房间示例:

POST /api/v1/reports
Authorization: Bearer <access_token>
X-App-Code: lalu
Content-Type: application/json

{
  "room_id": "lalu_abc123",
  "report_type": "fraud",
  "reason": "房间引导线下交易",
  "image_urls": []
}

请求字段:

字段 必填 类型 说明
user_id 条件必填 string 被举报用户 ID。和 room_id 二选一,只能传一个。
room_id 条件必填 string 被举报房间 ID。和 user_id 二选一,只能传一个。
report_type string 举报类型,取值见下方枚举。
reason string 举报理由Flutter 可允许用户不填。
image_urls string[] 举报图 URL 数组;无图可传 [] 或不传。

目标校验规则:

场景 结果
只传 user_id 举报用户。
只传 room_id 举报房间。
user_idroom_id 都不传 400 INVALID_ARGUMENT
user_idroom_id 同时传 400 INVALID_ARGUMENTFlutter 需要拆成一次明确的用户举报或房间举报。

举报发起人不在请求体里传。gateway 必须从 Authorization 对应的 access token 读取当前登录用户,避免客户端伪造举报发起人。

举报类型

UI 文案 report_type
Politics politics
Pornography pornography
Graphic Violence graphic_violence
Verbal Abuse verbal_abuse
Fraud fraud
Illegal Content illegal_content
Minors minors
In-Person Transactions in_person_transactions
Other other

返回体模拟数据

举报用户成功:

{
  "code": "OK",
  "message": "ok",
  "request_id": "req_report_user",
  "data": {
    "report_id": "rpt_10001_1778000000000",
    "target_type": "user",
    "user_id": "10002",
    "room_id": "",
    "report_type": "pornography",
    "status": "submitted",
    "created_at_ms": 1778000000000
  }
}

举报房间成功:

{
  "code": "OK",
  "message": "ok",
  "request_id": "req_report_room",
  "data": {
    "report_id": "rpt_10001_1778000001000",
    "target_type": "room",
    "user_id": "",
    "room_id": "lalu_abc123",
    "report_type": "fraud",
    "status": "submitted",
    "created_at_ms": 1778000001000
  }
}

字段说明:

字段 类型 说明
report_id string 举报单 IDFlutter 可用于本地日志和客服排查。
target_type string userroom,由服务端按本次传入目标生成。
user_id string 被举报用户 ID房间举报返回空字符串。
room_id string 被举报房间 ID用户举报返回空字符串。
report_type string 本次提交的举报类型。
status string 首次提交固定返回 submitted
created_at_ms int64 举报创建时间Unix epoch milliseconds。

错误处理

失败返回仍使用统一 envelope

{
  "code": "INVALID_ARGUMENT",
  "message": "invalid argument",
  "request_id": "req_abc"
}
HTTP 状态码 code Flutter 处理
400 INVALID_JSON JSON 格式错误,检查本地序列化逻辑。
400 INVALID_ARGUMENT user_id/room_id 二选一不满足、report_type 非法、图片 URL 格式非法或字段超长。
401 UNAUTHORIZED token 缺失、无效、过期或会话失效,重新登录。
403 PROFILE_REQUIRED 用户资料未完成,跳转资料补全流程。
404 NOT_FOUND 被举报用户不存在,刷新页面状态。
502 UPSTREAM_ERROR 内部服务暂不可用,可提示稍后重试。

Flutter 数据模型建议

class SubmitReportRequest {
  SubmitReportRequest({
    this.userId,
    this.roomId,
    required this.reportType,
    this.reason,
    this.imageUrls = const [],
  });

  final String? userId;
  final String? roomId;
  final String reportType;
  final String? reason;
  final List<String> imageUrls;

  Map<String, dynamic> toJson() => {
        if (userId != null && userId!.isNotEmpty) 'user_id': userId,
        if (roomId != null && roomId!.isNotEmpty) 'room_id': roomId,
        'report_type': reportType,
        if (reason != null && reason!.trim().isNotEmpty) 'reason': reason!.trim(),
        if (imageUrls.isNotEmpty) 'image_urls': imageUrls,
      };
}

提交前本地校验:

void validateReportTarget({String? userId, String? roomId}) {
  final hasUser = userId != null && userId.trim().isNotEmpty;
  final hasRoom = roomId != null && roomId.trim().isNotEmpty;
  if (hasUser == hasRoom) {
    throw ArgumentError('user_id and room_id must be exactly one');
  }
}

实现边界

  • Flutter 不传举报发起人 ID服务端只认 token 中的当前用户。
  • user_id 表示被举报用户,不是举报发起人。
  • room_id 表示被举报房间,不要求同时传房间内某个用户。
  • user_idroom_id 必须二选一,不能同时提交一个混合举报。
  • 举报图片先上传再提交 URL提交举报接口不接收 multipart 文件。
  • message 不作为业务分支依据Flutter 只按 code 和 HTTP 状态处理。