146 lines
4.0 KiB
Markdown
146 lines
4.0 KiB
Markdown
发消息
|
||
前端调:
|
||
POST /api/chat/send
|
||
Authorization: Bearer <token>
|
||
Content-Type: application/json
|
||
请求体最常用就是:
|
||
{
|
||
"message": "给我发图片",
|
||
"image": null,
|
||
"useWebSocket": false
|
||
}
|
||
如果是“用户发自己的图片给 AI 看”,先上传图片,再把这些字段带进来:
|
||
{
|
||
"message": "你看看这张图",
|
||
"imageId": "...",
|
||
"imageThumbUrl": "...",
|
||
"imageMediumUrl": "...",
|
||
"imageOriginalUrl": "...",
|
||
"imageWidth": 1080,
|
||
"imageHeight": 720,
|
||
"useWebSocket": false
|
||
}
|
||
返回给前端,重点只看这几个字段:
|
||
{
|
||
"reply": "回复文本",
|
||
"audioUrl": "",
|
||
"messageId": "uuid",
|
||
"isGuest": true,
|
||
"timestamp": 1782281463683,
|
||
"image": {
|
||
"type": "elio_schedule",
|
||
"url": "https://..."
|
||
},
|
||
"lockDetail": {
|
||
"locked": true,
|
||
"showContent": false,
|
||
"showUpgrade": true,
|
||
"reason": "image_paywall",
|
||
"hint": "嗯,你想看我……那就给你看一张。这是我06月15日的照片,你喜欢吗?",
|
||
"detail": {
|
||
"image": {
|
||
"type": "elio_schedule",
|
||
"url": "https://..."
|
||
}
|
||
}
|
||
}
|
||
}
|
||
前端规则很简单:
|
||
lockDetail.showContent=true:正常展示 reply、image.url、audioUrl
|
||
lockDetail.showContent=false:不要展示真实内容,改成会员引导卡
|
||
lockDetail.showUpgrade=true:显示开会员入口
|
||
也就是说,后端会正常生成内容,前端只靠 lockDetail 决定“显示还是锁住”。
|
||
历史消息
|
||
前端调:
|
||
GET /api/chat/history?limit=50&offset=0
|
||
Authorization: Bearer <token>
|
||
返回结构:
|
||
{
|
||
"messages": [
|
||
{
|
||
"role": "user",
|
||
"type": "text",
|
||
"content": "给我发图片",
|
||
"id": "uuid",
|
||
"created_at": "2026-06-24T06:13:27.000Z",
|
||
"audioUrl": null,
|
||
"image": { "type": null, "url": null },
|
||
"lockDetail": {
|
||
"locked": false,
|
||
"showContent": true,
|
||
"showUpgrade": false,
|
||
"reason": null,
|
||
"hint": null,
|
||
"detail": null
|
||
}
|
||
},
|
||
{
|
||
"role": "assistant",
|
||
"type": "text",
|
||
"content": "嗯,你想看我……那就给你看一张。这是我06月15日的照片,你喜欢吗?",
|
||
"id": "uuid",
|
||
"created_at": "2026-06-24T06:13:27.000Z",
|
||
"audioUrl": null,
|
||
"image": {
|
||
"type": "elio_schedule",
|
||
"url": "https://..."
|
||
},
|
||
"lockDetail": {
|
||
"locked": true,
|
||
"showContent": false,
|
||
"showUpgrade": true,
|
||
"reason": "image_paywall",
|
||
"hint": "嗯,你想看我……那就给你看一张。这是我06月15日的照片,你喜欢吗?",
|
||
"detail": {
|
||
"image": {
|
||
"type": "elio_schedule",
|
||
"url": "https://..."
|
||
}
|
||
}
|
||
}
|
||
}
|
||
],
|
||
"total": 2,
|
||
"limit": 50,
|
||
"offset": 0,
|
||
"isVip": false
|
||
}
|
||
历史列表也完全按同一套 lockDetail 渲染,不要自己猜 VIP 逻辑。
|
||
看图片
|
||
图片消息统一看这两个位置:
|
||
message.image.url
|
||
如果被锁,message.lockDetail.detail.image.url
|
||
前端建议处理:
|
||
先看 lockDetail.showContent
|
||
如果 true,直接展示 image.url
|
||
如果 false,不要展示真实图,只显示“图片已锁定”的会员引导卡
|
||
也就是:
|
||
后端会返回真实图片
|
||
非 VIP 前端不展示
|
||
VIP 或解锁后前端正常展示
|
||
|
||
私密图片 / 私密消息
|
||
现在前端不用区分很多旧字段,只看 lockDetail.reason:
|
||
image_paywall:图片锁
|
||
private_message:私密消息锁
|
||
voice_message:语音锁
|
||
daily_limit:免费消息额度用完
|
||
其中“私密图片”本质上也是同一套路子:
|
||
后端正常产出内容
|
||
前端收到 lockDetail.showContent=false
|
||
前端不展示真实内容
|
||
前端展示会员引导
|
||
如果是 private_message,通常读:
|
||
content / reply:后端可能仍会返回
|
||
但前端必须以 lockDetail.showContent 为准
|
||
不要因为拿到了文本就直接渲染
|
||
|
||
前端最简对接结论
|
||
你们只需要统一渲染这几个字段:
|
||
文本:content 或 reply
|
||
图片:image.url
|
||
语音:audioUrl
|
||
是否展示:lockDetail.showContent
|
||
是否引导会员:lockDetail.showUpgrade
|
||
锁类型:lockDetail.reason
|
||
引导文案:lockDetail.hint |