5.13 系统消息【代码实现完成,待登录态联调】

说明:系统消息按当前 Token 的 current_identity 隔离读取。当前身份为 fan 时查询 receiver_identity=fan 且 receiver_id=当前 tieup_user.id 的消息;当前身份为 artist 时查询 receiver_identity=artist 且 receiver_id=当前账号对应 tieup_artist.id 的消息。business_type 只表示用于筛选和未读统计的粗分类,具体通知场景由 title、content 展示;需要交互的消息由稳定的 source_type 和 payload 描述,客户端不得依赖标题文字判断操作类型。接收用户渠道的 welfare_display_enabled=2 时,business_type=benefit 的福利消息仍保留在本地消息表,但创建时即标记为已读且通知状态为跳过,不调用融云,也不会被补偿任务重发;福利业务和审核流程不受影响。

融云实时通知使用 SYSTEM 会话和自定义消息类型 Tieup:SysMsg,不使用 RC:TxtMsg、图片或视频等内置消息类型。iOS、Android 必须注册 Tieup:SysMsg;content.extra 是 JSON 字符串,需要再次反序列化。融云 SDK 外层 SYSTEM 会话的 targetId 是系统发送方融云用户 ID,不是业务群 ID;普通系统消息不提供群聊跳转上下文。

SYSTEM 离线通知的 pushContent 是“系统消息标题:系统消息正文”摘要,通知栏标题由 pushExt.title 明确指定为 tieup_system_message.title(最多 50 个字符,空值回退 Tieup),并固定提交 pushExt.forceShowPushContent=1;接收用户存在有效厂商渠道配置时,pushExt.pushConfigs 只附加渠道参数,不覆盖业务标题。小米渠道配置了 MI.templateId 后,服务端还会把相同的业务标题和正文摘要动态写入 MI.templateParam.title/content,因为启用小米模板后普通 pushExt.title 与 pushContent 对小米模板不生效。通知同时提交独立的 pushData JSON 字符串。iOS、Android 收到厂商离线推送后从通知载荷的 appData 取得该字符串并再次反序列化;Android 也可通过融云 PushNotificationMessage#getPushData() 获取。pushData.notificationType=system 后必须继续根据 sourceType 和 payload 跳转业务页面,不得根据通知标题、正文或 SDK 外层 targetId 判断。

融云原始消息内容示例:

{
  "objectName": "Tieup:SysMsg",
  "content": {
    "content": "福利可兑换:您已满足「示例艺人」的「签名照」兑换条件,可前往福利页面申请",
    "extra": "{\"message_id\":90001,\"business_type\":\"benefit\",\"message_category\":\"fan\",\"link_id\":30001,\"source_type\":\"benefit_redeemable\",\"source_no\":\"BF202607130001\",\"conversationType\":0,\"targetId\":\"\",\"channelId\":\"\",\"payload\":{\"artist_id\":20001,\"artist_name\":\"示例艺人\",\"benefit_title\":\"签名照\"}}"
  }
}

content.extra 反序列化结果:

{
  "message_id": 90001,
  "business_type": "benefit",
  "message_category": "fan",
  "link_id": 30001,
  "source_type": "benefit_redeemable",
  "source_no": "BF202607130001",
  "conversationType": 0,
  "targetId": "",
  "channelId": "",
  "payload": {
    "artist_id": 20001,
    "artist_name": "示例艺人",
    "benefit_title": "签名照"
  }
}

自定义系统消息字段:

字段 类型 说明
content.content string 推送展示文本,由标题和正文摘要组成
content.extra string JSON 字符串,反序列化后得到业务路由数据
message_id integer 本地系统消息 ID
business_type string 系统消息粗分类,用于列表筛选和未读统计;完整取值见 5.13.1 粗分类表
message_category string 消息分类:artist 或 fan
link_id integer/null 关联业务主记录 ID
source_type string 稳定的系统消息场景分类;完整取值、接收端和触发时机见 5.13.1 场景分类表
source_no string 业务来源编号
conversationType integer 普通系统消息固定为 0,表示没有群聊跳转上下文
targetId string 普通系统消息固定为空字符串
channelId string 普通系统消息固定为空字符串
payload object 对应系统消息的业务扩展数据

SYSTEM 离线通知 pushData 反序列化完整示例:

{
  "schemaVersion": 1,
  "notificationType": "system",
  "messageType": "system",
  "conversationType": 0,
  "messageId": 90001,
  "businessType": "benefit",
  "sourceType": "benefit_redeemable",
  "sourceNo": "BF202607130001",
  "linkId": 30001,
  "payload": {
    "artist_id": 20001,
    "artist_name": "示例艺人",
    "benefit_title": "签名照"
  }
}

SYSTEM pushData 字段:

字段 类型 说明
schemaVersion integer 跳转协议版本,当前固定为 1
notificationType string 固定为 system
messageType string 固定为 system,与聊天内容类型区分
conversationType integer 固定为 0,表示不直接使用融云群聊定位
messageId integer 本地系统消息 ID
businessType string 系统消息粗分类,取值与列表响应的 business_type 一致
sourceType string 稳定的系统消息场景分类,是系统消息页面跳转的主要判断字段;完整取值见 5.13.1 场景分类表
sourceNo string 业务来源编号
linkId integer/null 关联业务主记录 ID
payload object 业务跳转所需的最小扩展数据,不包含 Token、手机号等敏感信息

5.13.1 我的系统消息列表

GET /tieup/api/v1/me/system-messages

鉴权:需要 Authorization: Bearer <access_token>。

查询参数:

参数 类型 必填 说明
page integer 否 页码,默认 1
page_size integer 否 每页数量,默认 20,最大 100
business_type string 否 当前身份的粗分类;不传或传 all 表示全部,非法值或跨身份分类返回参数错误
read_status integer 否 阅读状态:1=未读,2=已读

type 与 business_type 返回相同的粗分类值,type_label 返回对应中文名称。粗分类仅用于列表筛选、未读统计和分栏展示;source_type 才是稳定的具体场景分类。查询参数中的 all 只表示不限制粗分类,不会出现在 type、business_type 或 type_label 响应字段中。

business_type 粗分类:

使用端 business_type type_label 分类说明 具体 source_type(场景)
粉丝端 subscription 订阅 订阅开通、续费、到期和自动续费状态 subscription_success(订阅成功)、subscription_renewed(续费成功)、subscription_expiring(订阅即将到期)、subscription_expired(订阅已到期)、subscription_canceled(订阅已取消)、subscription_auto_renew_closed(自动续费已关闭)、subscription_renew_failed(自动续费失败)
粉丝端 consume 消费 提问、追问、视频通话消费及退款结果 question_paid(提问支付成功)、follow_up_paid(追问支付成功)、video_call_paid(视频通话支付成功)、consume_refund(退款状态更新)
粉丝端 benefit 福利 福利可兑换、提交兑换和发放结果 benefit_redeemable(福利可兑换)、benefit_redemption_submitted(兑换申请已提交)、benefit_fulfilled(福利已发放);另有尚未接入触发入口的 benefit_outcome(福利状态更新)模板
粉丝端 call 通话 视频通话预约、提醒、完成和其他终态 video_call_booked(预约成功)、video_call_reminder(通话即将开始)、video_call_completed(通话已完成)、video_call_outcome(通话状态更新)
粉丝端 feedback 反馈 提问处理结果、客服反馈、入驻审核、内容审核和通话违规 question_answered(提问已回答)、question_rejected(提问已拒绝并退款)、customer_feedback_handled(反馈已处理)、customer_feedback_closed(反馈已关闭)、artist_application_approved(艺人入驻审核通过)、artist_application_rejected(艺人入驻审核未通过)、tieup_audit(内容审核通知)、video_call_violation(视频通话违规警告或中断)
粉丝端 system 系统 后台公告和经纪公司绑定邀请 admin_push(系统推送)、artist_agency_bind_invite(后台公告和经纪公司绑定邀请)
艺人端 income 收益 订阅、回答和视频通话收益 income_subscription(订阅收益产生)、income_question(回答收益产生)、income_video_call(视频通话收益产生)
艺人端 fan 粉丝 新粉丝关注 artist_followed(新粉丝关注)
艺人端 question 提问 收到粉丝提问或追问 question_received(收到新提问)、follow_up_received(收到新追问)
艺人端 call 通话 收到预约、开始提醒、完成和其他终态 video_call_received(收到新通话预约)、video_call_reminder(通话即将开始)、video_call_completed(通话已完成)、video_call_outcome(通话状态更新)
艺人端 benefit 福利 收到待发放的福利兑换申请 benefit_redemption_pending(收到待发放福利)
艺人端 feedback 反馈 客服反馈、内容审核和通话违规反馈 customer_feedback_handled(反馈已处理)、customer_feedback_closed(反馈已关闭)、tieup_audit(内容审核通知)、video_call_violation(视频通话违规警告或中断)
艺人端 system 系统 后台公告、经纪公司绑定邀请、实名认证更新提醒和提现结果 admin_push(系统推送)、artist_agency_bind_invite(后台公告和经纪公司绑定邀请)、identity_verification_required(实名认证更新提醒)、artist_withdraw_completed(提现到账成功)、artist_withdraw_failed(提现金额已退回)

注意:视频通话退款结果只向粉丝端写入 business_type=consume、source_type=consume_refund 的消息;艺人端只保留 source_type=video_call_outcome 的通话状态更新,避免同一爽约结果重复通知。其他关联艺人的退款业务仍按各自既有规则通知。

source_type 场景分类:

接收端 business_type source_type 场景名称 触发时机或当前状态
粉丝端 subscription subscription_success 订阅成功 新订阅权益成功发放后;正文为“您已成功订阅「艺人名称」,有效期至YYYY-MM-DD HH:mm:ss”;现有超级群 Tieup:Subscribe 消息继续保留
粉丝端 subscription subscription_renewed 续费成功 续费权益成功发放后;正文为“您已成功续费「艺人名称」,有效期至YYYY-MM-DD HH:mm:ss”;现有超级群 Tieup:Subscribe 消息继续保留
粉丝端 subscription subscription_expiring 订阅即将到期 到达后台配置的提前通知天数后,每个订阅周期提醒一次;配置为 0 时关闭
粉丝端 subscription subscription_expired 订阅已到期 订阅生命周期任务或支付渠道状态处理将订阅推进为到期后
粉丝端 subscription subscription_canceled 订阅已取消 退款或撤销处理将订阅推进为取消后;正文为“您的订阅已取消,如有余额将原路退回。”
粉丝端 subscription subscription_auto_renew_closed 自动续费已关闭 Apple 自动续费关闭通知处理成功后,当前权益继续有效至原到期时间
粉丝端 subscription subscription_renew_failed 自动续费失败 Apple 自动续费失败通知处理成功后
粉丝端 consume question_paid 提问支付成功 提问记录创建和糖果扣减在事务中成功后
粉丝端 consume follow_up_paid 追问支付成功 追问记录创建和糖果扣减在事务中成功后
艺人端 question question_received 收到新提问 粉丝提问记录创建和糖果扣减成功后
艺人端 question follow_up_received 收到新追问 粉丝追问记录创建和糖果扣减成功后
粉丝端 feedback question_answered 提问已回答 艺人提交回答并完成业务状态更新后
粉丝端 feedback question_rejected 提问已拒绝并退款 艺人拒绝提问且糖果退款完成后
粉丝端、艺人端 feedback customer_feedback_handled 反馈已处理 后台回复粉丝或艺人反馈并将状态更新为 3=已处理 后;经纪公司和未知身份不通知
粉丝端、艺人端 feedback customer_feedback_closed 反馈已关闭 后台填写关闭原因并将粉丝或艺人反馈更新为 4=已关闭 后;经纪公司和未知身份不通知
粉丝端 consume video_call_paid 视频通话支付成功 视频通话订单扣减糖果成功后
粉丝端 call video_call_booked 预约成功 视频通话预约创建成功后
艺人端 call video_call_received 收到新通话预约 粉丝视频通话预约创建成功后
粉丝端、艺人端 call video_call_reminder 通话即将开始 到达后台配置的提前提醒分钟数;配置为 0 时关闭提醒
粉丝端、艺人端 call video_call_completed 通话已完成 视频通话正常完成并写入实际时长后
粉丝端、艺人端 call video_call_outcome 通话状态更新 爽约、取消、退款等通话终态确定后
粉丝端;非视频通话业务可按既有规则通知艺人端 consume consume_refund 退款状态更新 退款最终成功、失败或关闭后;处理中不发送最终结果消息。视频通话退款不向艺人端发送该消息,艺人端只保留通话状态更新
粉丝端 benefit benefit_redeemable 福利可兑换 上架福利首次满足兑换条件、仍有库存且尚未兑换时;正文为“您已满足「{偶像名字}」的「{福利名称}」兑换条件,可前往福利页面申请”;同一粉丝和福利只提醒一次
粉丝端 benefit benefit_redemption_submitted 兑换申请已提交 粉丝成功提交福利兑换申请后;正文为“您已提交「{偶像名字}」的「{福利名称}」兑换申请,请等待偶像发放”
艺人端 benefit benefit_redemption_pending 收到待发放福利 粉丝成功提交福利兑换申请后
粉丝端 benefit benefit_fulfilled 福利已发放 艺人完成福利发放并成功更新兑换状态后
未固定 benefit benefit_outcome 福利状态更新 代码已定义消息模板,但当前未发现业务调用入口;客户端不应假设该场景必然下发
艺人端 income income_subscription 订阅收益产生 订阅业务完成并成功创建收入记录后;正文为“「{粉丝昵称}」订阅了您,收入{金额}元。”,昵称为空时使用“粉丝”
艺人端 income income_question 回答收益产生 提问或追问回答业务完成并成功创建收入记录后;正文为“您回答了「{粉丝昵称}」,收入{艺人分成糖果}糖果”,昵称为空时使用“粉丝”
艺人端 income income_video_call 视频通话收益产生 视频通话业务完成并成功创建收入记录后;正文为“您和「{粉丝昵称}」通话完成,收入{艺人分成糖果}糖果”,昵称为空时使用“粉丝”
艺人端 fan artist_followed 新粉丝关注 粉丝从未关注变为关注后;正文为“「{粉丝昵称}」关注了您”;同一粉丝和艺人按最近成功写入时间滚动一小时限频
粉丝端 feedback artist_application_approved 艺人入驻审核通过 后台审核通过艺人入驻申请后,固定通知申请人的粉丝身份;正文为“您的入驻申请已通过,请联系星伴为您指导服务。”
粉丝端 feedback artist_application_rejected 艺人入驻审核未通过 后台驳回艺人入驻申请后,固定通知申请人的粉丝身份
粉丝端、艺人端 system admin_push 后台系统公告 后台创建系统推送批次后,按目标范围异步写入接收人的系统消息
粉丝端、艺人端 system artist_agency_bind_invite 经纪公司绑定邀请 经纪公司向未绑定公司的用户发起邀请后;正文为“「{经纪公司名称}」邀请您成为旗下艺人,请确认是否同意。”;无艺人档案时归粉丝端,已有艺人档案时归艺人端
艺人端 system identity_verification_required 实名认证更新提醒 身份证到期或同一身份证被其他账号重新认证成功后;payload.reason 区分原因
艺人端 system artist_withdraw_completed 提现到账成功 云账户回调或主动查单返回 status=1,提现和资金状态在同一事务内完成后
艺人端 system artist_withdraw_failed 提现金额已退回 云账户返回 status=2 支付失败或 status=9 银行卡退汇,且服务端确认已生成余额退回流水后
粉丝端、艺人端 feedback tieup_audit 内容审核通知 人工审核拒绝用户或艺人提交的内容后;接收端按内容提交方身份确定
粉丝端、艺人端 feedback video_call_violation 视频通话违规警告或中断 视频审核第一次违规发送警告,第二次违规结束通话;通过 payload.action 区分 video_call_moderation_warning 和 force_leave_video_call

以上 36 个值是当前代码定义或当前写入入口使用的系统消息场景契约。客户端应使用 source_type 与 payload 共同决定页面跳转和交互;标题、正文和 tag_label 仅用于展示,不是稳定的业务判断字段。历史数据库中可能存在迁移前旧值,不作为当前接口支持枚举。

订阅成功和续费成功消息的正文使用消息生成时的艺人名称,不再展示订阅档位名称;艺名为空时依次回退艺人账号昵称和“偶像”。该规则仅影响新生成的系统消息,不回填或改写历史消息;现有 payload.artist_id、payload.plan_name 等路由载荷保持不变。

回答和视频通话收益通知中的糖果数量按本次业务原始消费糖果乘以收入记录的 share_ratio 快照计算,不读取修改后的后台配置;结果向下保留最多两位小数并移除末尾零。例如原始消费 10 糖果、艺人分成 70% 时展示 7糖果,原始消费 1 糖果时展示 0.7糖果。该展示口径只影响新生成的系统消息正文,不改变收入记录中的人民币折现、分账、可提现余额和艺人汇总接口既有统计口径。

所有业务系统消息先写入 tieup_system_message,再投递异步队列调用融云。队列或融云失败不回滚订阅、扣款、福利、通话等业务结果;服务端每分钟扫描 notify_status in (0,2) 且未超过最大尝试次数的消息重新投递。notify_status=1 只表示融云服务端已成功接收发送请求,厂商通知是否最终展示仍受客户端注册、厂商配置和用户系统通知权限影响。

响应字段:

字段 类型 说明
items[].id integer 系统消息 ID
items[].title string 消息标题,例如订阅成功、续费成功、提问已支付、追问已支付、福利可兑换、兑换申请已提交
items[].content string 消息内容
items[].created_at string/null 消息创建时间
items[].type string 系统消息粗分类,等同 tieup_system_message.business_type;完整取值见本节粗分类表
items[].business_type string 系统消息粗分类,与 type 完全相同;用于筛选、未读统计和分栏展示
items[].type_label string 消息类型展示文案
items[].message_category string 消息分类:artist=艺人消息,fan=粉丝消息
items[].tag_label string 右侧标签文案
items[].read_status integer 阅读状态:1=未读,2=已读
items[].read_at string/null 阅读时间
items[].link_id integer/null 关联业务主记录 ID,用于 APP 跳转或业务处理
items[].source_type string 稳定的系统消息场景分类;完整取值、接收端和触发时机见本节场景分类表
items[].source_no string 业务来源编号
items[].payload object 业务扩展数据;具体字段由 source_type 决定,不包含敏感明文
pagination.page integer 当前页码
pagination.page_size integer 每页数量
pagination.total integer 总条数
pagination.next_cursor string/null 游标分页预留字段,当前返回 null

当 items[].source_type=identity_verification_required 时,消息只写入艺人端并固定归入 business_type=system。身份证到期正文为“您的身份证已过期,提现功能已被暂停,请立即更新”;实名被其他账号顶替正文为“您的实名认证已被其他账号更新,提现功能已被暂停,请立即重新认证”。

字段 类型 说明
items[].payload.reason string identity_expired=身份证超过到期日;identity_reassigned=同一身份证被其他账号重新认证成功
items[].payload.action_required boolean 固定为 true
items[].payload.priority string 固定为 urgent
items[].payload.next_action string 固定为 identity_verification,客户端进入实名认证更新流程

实名认证更新提醒完整消息项示例:

{
  "id": 90005,
  "title": "实名认证更新提醒",
  "content": "您的身份证已过期,提现功能已被暂停,请立即更新",
  "created_at": "2026-08-14 06:25:00",
  "type": "system",
  "business_type": "system",
  "type_label": "系统",
  "message_category": "artist",
  "tag_label": "官方",
  "read_status": 1,
  "read_at": null,
  "link_id": null,
  "source_type": "identity_verification_required",
  "source_no": "UIE-88",
  "payload": {
    "reason": "identity_expired",
    "action_required": true,
    "priority": "urgent",
    "next_action": "identity_verification"
  }
}

SYSTEM 离线推送展示参数完整示例:

{
  "pushContent": "福利可兑换:您已满足「示例艺人」的「签名照」兑换条件,可前往福利页面申请",
  "pushExt": {
    "title": "福利可兑换",
    "forceShowPushContent": 1,
    "pushConfigs": [
      {
        "MI": {
          "channelId": "tieup-system",
          "templateId": "小米审核通过的模板ID",
          "templateParam": {
            "title": "福利可兑换",
            "content": "福利可兑换:您已满足「示例艺人」的「签名照」兑换条件,可前往福利页面申请"
          }
        }
      },
      {
        "OPPO": {
          "channelId": "system",
          "category": "IM",
          "notify_level": 2
        }
      }
    ]
  }
}

pushConfigs 仅在接收用户所属启用渠道存在合法厂商配置时出现;无有效配置时仍保留 title 和 forceShowPushContent,但不发送空数组。MI.templateId 必须在小米推送运营平台创建并审核,模板必须定义 title、content 两个变量;后台只配置模板 ID,templateParam 由服务端按每条消息动态生成。未录入模板 ID 时不发送空 templateParam,小米继续使用融云控制台 AppKey 默认模板,因此仅部署代码不能替代模板审核和渠道录入。

当 items[].source_type=artist_withdraw_completed 或 artist_withdraw_failed 时,消息只写入艺人端并固定归入 business_type=system。系统消息与提现状态、余额流水在同一数据库事务内写入,事务提交后异步投递融云;回调和主动查单重复执行时按提现单、艺人和消息场景幂等。只通知新发生的终态,不补发上线前已有终态记录。审核拒绝、15/-1 取消或批次撤销、下单失败但资金仍冻结均不使用这两个场景。

字段 类型 说明
items[].payload.withdraw_id integer 提现记录 ID,与 items[].link_id 相同
items[].payload.withdraw_no string 提现单号,与 items[].source_no 相同
items[].payload.withdraw_status integer 提现终态:5=已完成,6=打款失败
items[].payload.withdraw_status_label string 提现状态中文说明:已完成 或 出款失败
items[].payload.funds_status integer 资金状态:2=已完成,3=已退回
items[].payload.funds_status_label string 资金状态中文说明:已完成 或 已退回
items[].payload.withdraw_amount string 申请提现金额,单位元,固定两位小数
items[].payload.actual_amount string 仅成功消息返回;实际到账金额,单位元,固定两位小数
items[].payload.tax_amount string 仅成功消息返回;实际税费,单位元,固定两位小数
items[].payload.paid_at string/null 仅成功消息返回;云账户支付完成时间
items[].payload.returned_amount string 仅失败消息返回;实际退回可提现余额的金额,单位元,固定两位小数
items[].payload.failure_type string 仅失败消息返回;payment_failed=支付失败,bank_return=银行卡退汇
items[].payload.action_required boolean 固定为 false
items[].payload.priority string 固定为 normal

提现到账成功完整消息项示例:

{
  "id": 90006,
  "title": "提现到账成功",
  "content": "您的提现已打款成功,实际到账金额为94.50元,请注意查收。",
  "created_at": "2026-08-14 12:30:01",
  "type": "system",
  "business_type": "system",
  "type_label": "系统",
  "message_category": "artist",
  "tag_label": "提现",
  "read_status": 1,
  "read_at": null,
  "link_id": 101,
  "source_type": "artist_withdraw_completed",
  "source_no": "AW202608140001",
  "payload": {
    "withdraw_id": 101,
    "withdraw_no": "AW202608140001",
    "withdraw_status": 5,
    "withdraw_status_label": "已完成",
    "funds_status": 2,
    "funds_status_label": "已完成",
    "withdraw_amount": "100.00",
    "actual_amount": "94.50",
    "tax_amount": "5.50",
    "paid_at": "2026-08-14 12:30:00",
    "action_required": false,
    "priority": "normal"
  }
}

提现支付失败并退回余额的完整消息项示例:

{
  "id": 90007,
  "title": "提现金额已退回",
  "content": "您的提现打款未成功,100.00元已退回可提现余额,请前往提现记录查看。",
  "created_at": "2026-08-14 13:00:01",
  "type": "system",
  "business_type": "system",
  "type_label": "系统",
  "message_category": "artist",
  "tag_label": "提现",
  "read_status": 1,
  "read_at": null,
  "link_id": 102,
  "source_type": "artist_withdraw_failed",
  "source_no": "AW202608140002",
  "payload": {
    "withdraw_id": 102,
    "withdraw_no": "AW202608140002",
    "withdraw_status": 6,
    "withdraw_status_label": "出款失败",
    "funds_status": 3,
    "funds_status_label": "已退回",
    "withdraw_amount": "100.00",
    "returned_amount": "100.00",
    "failure_type": "payment_failed",
    "action_required": false,
    "priority": "normal"
  }
}

当 items[].source_type=customer_feedback_handled 或 customer_feedback_closed 时,link_id 为 tieup_feedback.id,source_no 固定为 feedback:{feedback_id}。粉丝反馈归属粉丝端,艺人反馈归属提交时的艺人端;客户端点击消息后必须按 payload.action=view_feedback_detail 和 payload.feedback_id 打开“我的反馈”详情。消息正文取实际回复或关闭原因的前 30 个字符,超过时追加 ...,完整内容以反馈详情接口的 handle_result 为准。

字段 类型 说明
items[].payload.feedback_id integer 反馈 ID,与 items[].link_id 相同
items[].payload.feedback_type integer 反馈类型:1=功能建议,2=问题反馈,3=内容反馈,4=投诉,5=其他,6=举报
items[].payload.handle_status integer 通知产生后的终态:3=已处理,4=已关闭
items[].payload.action string 固定为 view_feedback_detail,表示打开当前身份的反馈详情

回复并处理后的完整消息项示例:

{
  "id": 90003,
  "title": "反馈处理通知",
  "content": "您反馈的登录问题已经处理完成,请重新登录后查看,如仍有问题请...",
  "created_at": "2026-08-04 15:30:00",
  "type": "feedback",
  "business_type": "feedback",
  "type_label": "反馈",
  "message_category": "fan",
  "tag_label": "反馈",
  "read_status": 1,
  "read_at": null,
  "link_id": 88,
  "source_type": "customer_feedback_handled",
  "source_no": "feedback:88",
  "payload": {
    "feedback_id": 88,
    "feedback_type": 2,
    "handle_status": 3,
    "action": "view_feedback_detail"
  }
}

关闭反馈后的完整消息项示例:

{
  "id": 90004,
  "title": "反馈关闭通知",
  "content": "该问题缺少必要的设备信息,本次反馈已关闭",
  "created_at": "2026-08-04 15:35:00",
  "type": "feedback",
  "business_type": "feedback",
  "type_label": "反馈",
  "message_category": "artist",
  "tag_label": "反馈",
  "read_status": 1,
  "read_at": null,
  "link_id": 89,
  "source_type": "customer_feedback_closed",
  "source_no": "feedback:89",
  "payload": {
    "feedback_id": 89,
    "feedback_type": 4,
    "handle_status": 4,
    "action": "view_feedback_detail"
  }
}

当 items[].source_type=artist_agency_bind_invite 时,items[].payload 包含以下字段。邀请状态从邀请主记录实时读取,不使用消息创建时的状态快照,因此用户同意、拒绝或邀请过期后,再次查询列表和详情均返回最新状态。

字段 类型 说明
items[].payload.invite_no string 经纪公司绑定邀请编号,与 items[].source_no 相同
items[].payload.agency_company_id integer 发起邀请的经纪公司 ID
items[].payload.agency_company_name string 发起邀请时的经纪公司名称快照
items[].payload.target_user_id integer 被邀请 APP 用户 ID
items[].payload.target_artist_id integer/null 被邀请艺人档案 ID;普通用户尚未创建艺人档案时为空
items[].payload.target_identity string 邀请消息接收身份:fan=粉丝端,artist=艺人端
items[].payload.action_required boolean 是否仍需用户处理;仅 invite_status=pending 时为 true,其他状态为 false
items[].payload.priority string 操作优先级;待处理时为 urgent,其他状态为 normal
items[].payload.invite_status string 邀请状态:pending=待处理、accepted=已同意、rejected=已拒绝、expired=已过期、cancelled=已取消

经纪公司绑定邀请完整消息项示例(待处理状态):

{
  "id": 90001,
  "title": "经纪公司绑定邀请",
  "content": "「星河娱乐」邀请您成为旗下艺人,请确认是否同意。",
  "created_at": "2026-07-15 10:00:00",
  "type": "system",
  "business_type": "system",
  "type_label": "系统",
  "message_category": "artist",
  "tag_label": "艺人",
  "read_status": 1,
  "read_at": null,
  "link_id": 70001,
  "source_type": "artist_agency_bind_invite",
  "source_no": "ABI202607150001",
  "payload": {
    "invite_no": "ABI202607150001",
    "agency_company_id": 1001,
    "agency_company_name": "星河娱乐",
    "target_user_id": 10001,
    "target_artist_id": 20001,
    "target_identity": "artist",
    "action_required": true,
    "priority": "urgent",
    "invite_status": "pending"
  }
}

艺人入驻审核结果消息使用 link_id = tieup_artist_application.id,点击后统一跳转入驻申请详情。客户端必须按 source_type 和 payload.application_id 路由,不得根据标题文字判断审核结果。完整消息项示例:

{
  "id": 90002,
  "title": "艺人入驻审核未通过",
  "content": "您的艺人入驻申请未通过审核:资料不完整,请补充相关经历",
  "created_at": "2026-07-27 16:30:00",
  "type": "feedback",
  "business_type": "feedback",
  "type_label": "反馈",
  "message_category": "fan",
  "tag_label": "反馈",
  "read_status": 1,
  "read_at": null,
  "link_id": 88,
  "source_type": "artist_application_rejected",
  "source_no": "application:88",
  "payload": {
    "application_id": 88,
    "application_status": 3,
    "artist_type": null,
    "artist_id": null,
    "agency_company_id": null,
    "audit_remark": "资料不完整,请补充相关经历",
    "action_required": false,
    "priority": "normal"
  }
}

响应示例:

{
  "code": 200,
  "message": "成功",
  "data": {
    "items": [
      {
        "id": 90001,
        "title": "经纪公司绑定邀请",
        "content": "「星河娱乐」邀请您成为旗下艺人,请确认是否同意。",
        "created_at": "2026-07-15 10:00:00",
        "type": "system",
        "business_type": "system",
        "type_label": "系统",
        "message_category": "artist",
        "tag_label": "艺人",
        "read_status": 1,
        "read_at": null,
        "link_id": 70001,
        "source_type": "artist_agency_bind_invite",
        "source_no": "ABI202607150001",
        "payload": {
          "invite_no": "ABI202607150001",
          "agency_company_id": 1001,
          "agency_company_name": "星河娱乐",
          "target_user_id": 10001,
          "target_artist_id": 20001,
          "target_identity": "artist",
          "action_required": true,
          "priority": "urgent",
          "invite_status": "pending"
        }
      }
    ],
    "pagination": {
      "page": 1,
      "page_size": 20,
      "total": 1,
      "next_cursor": null
    }
  }
}

5.13.2 我的系统消息详情

GET /tieup/api/v1/me/system-messages/90001

鉴权:需要 Authorization: Bearer <access_token>。

路径参数:

参数 类型 必填 说明
message_id integer 是 系统消息 ID

响应字段:同 5.13.1 items[] 单条结构。

响应示例:

{
  "code": 200,
  "message": "成功",
  "data": {
    "id": 90001,
    "title": "经纪公司绑定邀请",
    "content": "「星河娱乐」邀请您成为旗下艺人,请确认是否同意。",
    "created_at": "2026-07-15 10:00:00",
    "type": "system",
    "business_type": "system",
    "type_label": "系统",
    "message_category": "fan",
    "tag_label": "艺人",
    "read_status": 2,
    "read_at": "2026-07-15 10:30:00",
    "link_id": 70001,
    "source_type": "artist_agency_bind_invite",
    "source_no": "ABI202607150001",
    "payload": {
      "invite_no": "ABI202607150001",
      "agency_company_id": 1001,
      "agency_company_name": "星河娱乐",
      "target_user_id": 10001,
      "target_artist_id": null,
      "target_identity": "fan",
      "action_required": false,
      "priority": "normal",
      "invite_status": "rejected"
    }
  }
}

5.13.3 批量标记系统消息已读

PATCH /tieup/api/v1/me/system-messages/read

鉴权:需要 Authorization: Bearer <access_token>。

请求体二选一。按单一分类将当前分类全部标记已读:

{
  "type": "subscription"
}

按系统消息 ID 将指定的一条或多条消息标记已读:

{
  "sys_message_ids": [90001, 90002]
}

请求参数:

参数 类型 必填 说明
type string 条件必填 当前身份的单一系统消息粗分类;枚举与 5.13.1 列表接口的 business_type 一致,不支持 all;与 sys_message_ids 必须且只能传一个
sys_message_ids array 条件必填 系统消息 ID 数组,最少 1 条、最多 100 条,ID 不允许重复;与 type 必须且只能传一个
sys_message_ids[] integer 条件必填 正整数系统消息 ID

粉丝端支持 subscription、consume、benefit、call、feedback、system;艺人端支持 income、fan、question、call、benefit、feedback、system。空值、all、非法值或当前身份不支持的分类均返回 422。

业务规则:

  • type 模式只更新当前 Token 身份、当前接收人下该粗分类的全部未读系统消息。
  • sys_message_ids 模式只更新当前 Token 身份、当前接收人拥有且 ID 命中的未读系统消息;不存在、属于其他用户或其他身份、已经已读的 ID 不更新,也不计入 read_count。
  • 两种模式都使用单次批量更新并保持幂等;重复提交时已读消息不会再次计数。

响应字段:

字段 类型 说明
read_count integer 本次实际从未读更新为已读的系统消息数量;重复提交时不会重复计数

响应示例:

{
  "code": 200,
  "message": "成功",
  "data": {
    "read_count": 2
  }
}

5.13.4 我的系统消息未读数

GET /tieup/api/v1/me/system-messages/unread-count

鉴权:需要 Authorization: Bearer <access_token>。

粉丝端响应字段固定为 all_count、subscription_count、consume_count、benefit_count、call_count、feedback_count、system_count、fan_message_unread_count、pending_count;艺人端固定为 all_count、income_count、fan_count、question_count、call_count、benefit_count、feedback_count、system_count、pending_count。所有计数字段均为非负整数。all_count 仅表示当前身份全部未读系统消息数,其他系统消息字段是对应粗分类未读数;fan_message_unread_count 和 pending_count 均不计入 all_count。

pending_count 为福利待发放数量:艺人端统计当前艺人全部历史福利兑换记录中 tieup_benefit_redemption.status = 1 的记录,福利下架或删除后仍计入;粉丝端当前无艺人待办,固定返回 0。

粉丝聊天未读统计口径:fan_message_unread_count 汇总当前粉丝历史订阅过的所有艺人发送的未读聊天消息。艺人定向消息必须发送成功、未撤回、接收粉丝为当前用户且尚未读;艺人普通群发消息必须发送成功、未撤回,且当前粉丝没有 MySQL 已读回执或 Redis 实时已读记录。两类消息的发送时间都必须落在当前粉丝对同一艺人的任一订阅有效区间内,已过期订阅不会抹去有效期内仍未读的历史消息;订阅断档期间、粉丝发给艺人、发送失败、已撤回或已被当前粉丝身份删除的消息均不统计。渠道关闭艺人群发已读能力时,与粉丝聊天列表保持一致,只统计艺人定向未读消息,不统计普通群发。

粉丝端完整响应示例:

{
  "code": 200,
  "message": "成功",
  "data": {
    "all_count": 12,
    "subscription_count": 3,
    "consume_count": 2,
    "benefit_count": 2,
    "call_count": 2,
    "feedback_count": 1,
    "system_count": 2,
    "fan_message_unread_count": 8,
    "pending_count": 0
  }
}

响应字段:

字段 类型 返回身份 说明
data.all_count integer 粉丝、艺人 当前身份未读系统消息总数,不包含 fan_message_unread_count
data.subscription_count integer 粉丝 订阅类未读系统消息数
data.consume_count integer 粉丝 消费类未读系统消息数
data.income_count integer 艺人 收益类未读系统消息数
data.fan_count integer 艺人 粉丝类未读系统消息数
data.question_count integer 艺人 提问类未读系统消息数
data.call_count integer 粉丝、艺人 通话类未读系统消息数
data.benefit_count integer 粉丝、艺人 福利类未读系统消息数
data.feedback_count integer 粉丝、艺人 反馈类未读系统消息数
data.system_count integer 粉丝、艺人 系统类未读系统消息数
data.fan_message_unread_count integer 仅粉丝 当前粉丝订阅艺人的未读聊天消息总数,统计口径见本节说明;艺人身份不返回
data.pending_count integer 粉丝、艺人 待发放福利数量;艺人统计兑换状态 status=1 的全部历史福利兑换记录,粉丝端固定为 0;不计入 all_count

艺人端完整响应示例:

{
  "code": 200,
  "message": "成功",
  "data": {
    "all_count": 14,
    "income_count": 3,
    "fan_count": 2,
    "question_count": 2,
    "call_count": 2,
    "benefit_count": 1,
    "feedback_count": 1,
    "system_count": 3,
    "pending_count": 2
  }
}

5.13.5 粉丝系统消息摘要

GET /tieup/api/v1/me/system-messages/summary

鉴权:需要 Authorization: Bearer <access_token>,且当前 Token 的 current_identity 必须为 fan。艺人身份调用返回 403,接口不会跨身份读取同一账号的粉丝消息。接口不接收查询参数或请求体。

统计口径:仅统计 receiver_identity=fan 且 receiver_id=当前 tieup_user.id 的系统消息。unread_count 统计 read_status=1 的消息,total_count 统计包括已读和未读在内的全部消息,latest_message_at 取全部消息中最大的 created_at,不受阅读状态影响。

完整响应示例:

{
  "code": 200,
  "message": "成功",
  "data": {
    "unread_count": 3,
    "total_count": 12,
    "latest_message_at": "2026-07-20 15:30:00"
  }
}

响应字段:

字段 类型 说明
code integer 业务状态码,成功为 200
message string 响应说明,成功为 成功
data object 粉丝系统消息摘要
data.unread_count integer 当前粉丝未读系统消息数量
data.total_count integer 当前粉丝系统消息历史总数,包括已读和未读
data.latest_message_at string/null 最后一条系统消息的创建时间,格式为 Y-m-d H:i:s;无消息时为 null

无系统消息时完整响应示例:

{
  "code": 200,
  "message": "成功",
  "data": {
    "unread_count": 0,
    "total_count": 0,
    "latest_message_at": null
  }
}

5.13.6 同意经纪公司绑定邀请

PATCH /tieup/api/v1/me/agency-bind-invites/ABI202607150001/accept

鉴权:需要 Authorization: Bearer <access_token>,粉丝和艺人身份均可调用。请求体为空,服务端按邀请的 target_user_id 校验当前账号;同一结果重复提交幂等返回当前状态。

路径参数:

参数 类型 必填 说明
invite_no string 是 经纪公司绑定邀请编号

响应字段:

字段 类型 说明
invite_no string 邀请编号
agency_company_id integer 邀请经纪公司 ID
artist_created boolean 本次同意操作是否自动创建了艺人档案
artist_id integer/null 艺人档案 ID;拒绝普通用户邀请时可能为空
invite_status string 邀请状态:pending、accepted、rejected、expired、cancelled
handled_at string/null 邀请处理时间

完整响应示例:

{
  "code": 200,
  "message": "成功",
  "data": {
    "invite_no": "ABI202607150001",
    "agency_company_id": 1001,
    "artist_created": true,
    "artist_id": 20001,
    "invite_status": "accepted",
    "handled_at": "2026-07-15 10:30:00"
  }
}

5.13.7 拒绝经纪公司绑定邀请

PATCH /tieup/api/v1/me/agency-bind-invites/ABI202607150001/reject

鉴权、权限与幂等规则同 5.13.6。拒绝只更新邀请状态,不建立经纪公司绑定。

路径参数和响应字段同 5.13.6。

完整响应示例:

{
  "code": 200,
  "message": "成功",
  "data": {
    "invite_no": "ABI202607150001",
    "agency_company_id": 1001,
    "artist_created": false,
    "artist_id": null,
    "invite_status": "rejected",
    "handled_at": "2026-07-15 10:30:00"
  }
}

经纪公司绑定邀请消息通过 business_type=system 归入系统分类,通过 source_type=artist_agency_bind_invite 区分交互场景。普通用户在邀请创建时收到粉丝端消息,已有艺人收到艺人端消息;消息归属创建后不迁移。服务端动态返回 payload.action_required、payload.priority、payload.invite_status、payload.target_identity 和公司信息,客户端不得根据标题判断操作类型;其中 payload.invite_status 是同意、拒绝及其他终态的唯一状态字段,不在消息项顶层重复返回。

普通用户同意邀请后,服务端直接创建经纪公司艺人档案并绑定邀请公司,无需平台审核;艺名取粉丝昵称,头像由前端使用默认展示,手机号取当前账号手机号。响应中的 artist_created=true 表示本次自动建档,当前粉丝 Token 仍可继续使用,需要进入艺人端时调用现有身份切换接口获取艺人身份 Token。已有艺人同意时 artist_created=false,只更新经纪公司绑定。

业务规则:

  • 列表、详情、已读和未读数都只作用于当前 Token 的 current_identity,不会混合粉丝端和艺人端消息。
  • 当前身份为 artist 时,服务端会校验当前账号 tieup_user.is_idol = 1 且存在 tieup_artist 档案,否则返回无权限错误。
  • 详情和已读接口都限制只能操作当前身份自己的消息,不能跨用户或跨身份读取、标记。
  • 已读接口幂等:重复提交同一批消息不会报错,已读消息不会重复计入 read_count。
  • type 与 business_type 均返回粗分类,APP 可优先展示 type_label;具体通知场景使用标题和正文展示。
  • 同一用户只能有一条待处理绑定邀请;已拒绝、已过期或已取消后允许重新邀请,已经绑定经纪公司的艺人禁止再次邀请。

测试状态:已完成代码实现和 PHP 语法检查,待登录态和真实系统消息数据联调。