From feece3366df772bb3f0d4191becfc20768501d5d Mon Sep 17 00:00:00 2001 From: cheng Date: Wed, 17 Sep 2025 10:07:34 +0800 Subject: [PATCH] =?utf8?q?=E5=8D=8F=E8=AE=AE=E6=96=87=E6=A1=A3=E6=9B=B4?= =?utf8?q?=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- ...45\345\217\243\346\226\207\346\241\243.md" | 1297 ++++++++++++++--- 1 file changed, 1116 insertions(+), 181 deletions(-) diff --git "a/code/sdk/zhihui/leiniao/\350\256\276\345\244\207API\346\216\245\345\217\243\346\226\207\346\241\243.md" "b/code/sdk/zhihui/leiniao/\350\256\276\345\244\207API\346\216\245\345\217\243\346\226\207\346\241\243.md" index b3a7ed109..9f3f74e54 100644 --- "a/code/sdk/zhihui/leiniao/\350\256\276\345\244\207API\346\216\245\345\217\243\346\226\207\346\241\243.md" +++ "b/code/sdk/zhihui/leiniao/\350\256\276\345\244\207API\346\216\245\345\217\243\346\226\207\346\241\243.md" @@ -216,12 +216,68 @@ data: {"errorCode":null,"message":null,"data":{"audioUrl":"https://example.com/a } ``` +**失败响应(设备信息异常)**: +```json +{ + "errorCode": "DEVICE_NOT_FOUND", + "message": "设备信息异常", + "data": { + "audioUrl": "https://file-virtual-person.api-cn.leiniao.com/ambybox/audio/device_notfound.mp3", + "textContent": "设备信息异常,请稍后重试。", + "intention": null + } +} +``` + +**失败响应(对话体力不足)**: +```json +{ + "errorCode": "INSUFFICIENT_STAMINA", + "message": "对话体力不足", + "data": { + "audioUrl": "https://file-virtual-person.api-cn.leiniao.com/ambybox/audio/insuffient_stamina.mp3", + "textContent": "对话体力不足,请前往小程序充值体力。", + "intention": null + } +} +``` + +**失败响应(音频输入无效)**: +```json +{ + "errorCode": "INVALID_AUDIO_INPUT", + "message": "音频输入无效", + "data": { + "audioUrl": "https://file-virtual-person.api-cn.leiniao.com/ambybox/audio/invalid_audio_input.mp3", + "textContent": "抱歉,我无法识别语音内容,请再说一次吧", + "intention": null + } +} +``` + +**失败响应(模型服务异常)**: +```json +{ + "errorCode": "MODEL_ERROR", + "message": "模型服务异常", + "data": { + "audioUrl": "https://file-virtual-person.api-cn.leiniao.com/ambybox/audio/model_error.mp3", + "textContent": "模型服务异常,请稍后重试。", + "intention": null + } +} +``` + **失败响应(服务异常)**: ```json { "errorCode": "SERVER_ERROR", "message": "服务器内部错误", - "data": null + "data": { + "audioUrl": "https://file-virtual-person.api-cn.leiniao.com/ambybox/audio/server_error.mp3", + "textContent": "服务器异常,请稍后重试。", + "intention": null + } } ``` @@ -233,10 +289,29 @@ data: {"errorCode":null,"message":null,"data":{"audioUrl":"https://example.com/a | intention | String | 用户意图识别结果,通常在第一个片段中返回,可能的值:StartSleepMode(哄我睡觉)等 | ### 错误码 -| 错误码 | 描述 | +| 错误码 | 描述 | |--------|------| -| AUTH_FAILURE | 认证失败(设备ID为空或Token无效) | -| SERVER_ERROR | 服务器内部错误 | +| AUTH_FAILURE | token认证失败 | +| DEVICE_NOT_FOUND | 设备信息异常 | +| INSUFFICIENT_STAMINA | 对话体力不足 | +| MODEL_NOT_FOUND | 模型信息不存在 | +| VOICE_NOT_FOUND | 音色信息不存在 | +| INVALID_AUDIO_INPUT | 音频输入无效 | +| MODEL_ERROR | 模型服务异常 | +| SERVER_ERROR | 服务器内部错误 | + +### 错误响应说明 +当流式语音对话接口发生错误时,会返回包含错误码、描述信息、文本内容和对应音频URL的响应。设备端应该: +1. 检查响应中的errorCode字段 +2. 如果errorCode不为null,表示发生了错误 +3. 播放data字段中的audioUrl音频文件,向用户说明错误情况 +4. 根据错误类型进行相应的处理: + - **DEVICE_NOT_FOUND**: 设备信息异常,建议重新获取设备Token + - **INSUFFICIENT_STAMINA**: 用户对话体力不足,引导用户前往小程序充值 + - **MODEL_NOT_FOUND/VOICE_NOT_FOUND**: 配置信息缺失,建议重新获取角色配置 + - **INVALID_AUDIO_INPUT**: 语音识别失败,提示用户重新录音 + - **MODEL_ERROR**: 模型服务异常,建议稍后重试 + - **SERVER_ERROR**: 服务器内部错误,建议稍后重试 ### SSE协议说明 - 接口使用SSE(Server-Sent Events)协议进行流式响应 @@ -369,12 +444,59 @@ data: {"errorCode":null,"message":null,"data":{"storyTheme":"童话故事","stor } ``` +**错误响应(音频输入无效)**: +```json +{ + "errorCode": "INVALID_AUDIO_INPUT", + "message": "音频输入无效", + "data": { + "storyTheme": "", + "storyContent": "抱歉,我无法识别语音内容,请再说一次吧", + "storyAudioUrl": "https://file-virtual-person.api-cn.leiniao.com/ambybox/audio/invalid_audio_input.mp3", + "storyDuration": 0 + } +} +``` + +**错误响应(设备信息异常)**: +```json +{ + "errorCode": "DEVICE_NOT_FOUND", + "message": "设备信息异常", + "data": { + "storyTheme": "", + "storyContent": "设备信息异常,请稍后重试。", + "storyAudioUrl": "https://file-virtual-person.api-cn.leiniao.com/ambybox/audio/device_notfound.mp3", + "storyDuration": 0 + } +} +``` + +**错误响应(模型服务异常)**: +```json +{ + "errorCode": "MODEL_ERROR", + "message": "模型服务异常", + "data": { + "storyTheme": "", + "storyContent": "模型服务异常,请稍后重试。", + "storyAudioUrl": "https://file-virtual-person.api-cn.leiniao.com/ambybox/audio/model_error.mp3", + "storyDuration": 0 + } +} +``` + **错误响应(故事生成失败)**: ```json { "errorCode": "SERVER_ERROR", - "message": "故事生成失败", - "data": null + "message": "服务器内部错误", + "data": { + "storyTheme": "", + "storyContent": "服务器异常,请稍后重试。", + "storyAudioUrl": "https://file-virtual-person.api-cn.leiniao.com/ambybox/audio/server_error.mp3", + "storyDuration": 0 + } } ``` @@ -384,14 +506,30 @@ data: {"errorCode":null,"message":null,"data":{"storyTheme":"童话故事","stor | storyTheme | String | 故事主题 | | storyContent | String | 故事片段文本内容 | | storyAudioUrl | String | 故事片段音频文件URL | -| storyDuration | Integer | 故事片段时长(秒),流式响应中通常为null | +| storyDuration | Integer | 故事片段时长(秒) | #### 错误码 | 错误码 | 描述 | |--------|------| -| AUTH_FAILURE | 认证失败(设备ID为空或Token无效) | +| AUTH_FAILURE | Token无效 | +| INVALID_AUDIO_INPUT | 音频输入无效 | +| DEVICE_NOT_FOUND | 设备信息异常 | +| MODEL_NOT_FOUND | 模型信息不存在 | +| MODEL_ERROR | 模型服务异常 | | SERVER_ERROR | 服务器内部错误 | +#### 错误响应说明 +当智能选择故事接口发生错误时,会返回包含错误码、描述信息、文本内容和对应音频URL的响应。设备端应该: +1. 检查响应中的errorCode字段 +2. 如果errorCode不为null,表示发生了错误 +3. 播放data字段中的storyAudioUrl音频文件,向用户说明错误情况 +4. 根据错误类型进行相应的处理: + - **INVALID_AUDIO_INPUT**: 语音识别失败,提示用户重新录音表达故事偏好 + - **DEVICE_NOT_FOUND**: 设备信息异常,建议重新获取设备Token + - **MODEL_NOT_FOUND**: 故事生成模型配置缺失,建议重新获取配置或联系技术支持 + - **MODEL_ERROR**: 故事生成服务异常,建议稍后重试 + - **SERVER_ERROR**: 服务器内部错误,建议稍后重试 + #### SSE协议说明 - 接口使用SSE(Server-Sent Events)协议进行流式响应 - 每个故事片段作为一个独立的SSE事件发送 @@ -406,7 +544,7 @@ data: {"errorCode":null,"message":null,"data":{"storyTheme":"童话故事","stor - 客户端可以边接收边播放,实现流式播放体验 - 故事生成完成后,SSE连接会自动关闭 -### 3.2 随机故事 +### 3.2 随机播放故事 #### 接口描述 随机故事接口。系统会随机生成一个故事并流式返回给用户。该接口使用SSE(Server-Sent Events)协议进行流式响应,需要设备Token认证。 @@ -462,12 +600,59 @@ data: {"errorCode":null,"message":null,"data":{"storyTheme":"冒险故事","stor } ``` +**错误响应(设备信息异常)**: +```json +{ + "errorCode": "DEVICE_NOT_FOUND", + "message": "设备信息异常", + "data": { + "storyTheme": "", + "storyContent": "设备信息异常,请稍后重试。", + "storyAudioUrl": "https://file-virtual-person.api-cn.leiniao.com/ambybox/audio/device_notfound.mp3", + "storyDuration": 0 + } +} +``` + +**错误响应(模型信息不存在)**: +```json +{ + "errorCode": "MODEL_NOT_FOUND", + "message": "模型信息不存在", + "data": { + "storyTheme": "", + "storyContent": "设备模型信息异常,请稍后重试。", + "storyAudioUrl": "https://file-virtual-person.api-cn.leiniao.com/ambybox/audio/model_notfound.mp3", + "storyDuration": 0 + } +} +``` + +**错误响应(模型服务异常)**: +```json +{ + "errorCode": "MODEL_ERROR", + "message": "模型服务异常", + "data": { + "storyTheme": "", + "storyContent": "模型服务异常,请稍后重试。", + "storyAudioUrl": "https://file-virtual-person.api-cn.leiniao.com/ambybox/audio/model_error.mp3", + "storyDuration": 0 + } +} +``` + **错误响应(故事生成失败)**: ```json { "errorCode": "SERVER_ERROR", - "message": "故事生成失败", - "data": null + "message": "服务器内部错误", + "data": { + "storyTheme": "", + "storyContent": "服务器异常,请稍后重试。", + "storyAudioUrl": "https://file-virtual-person.api-cn.leiniao.com/ambybox/audio/server_error.mp3", + "storyDuration": 0 + } } ``` @@ -477,13 +662,27 @@ data: {"errorCode":null,"message":null,"data":{"storyTheme":"冒险故事","stor | storyTheme | String | 故事主题 | | storyContent | String | 故事片段文本内容 | | storyAudioUrl | String | 故事片段音频文件URL | -| storyDuration | Integer | 故事片段时长(秒),流式响应中通常为null | +| storyDuration | Integer | 故事片段时长(秒) | #### 错误码 -| 错误码 | 描述 | +| 错误码 | 描述 | |--------|------| -| AUTH_FAILURE | 认证失败(设备ID为空或Token无效) | -| SERVER_ERROR | 服务器内部错误 | +| AUTH_FAILURE | Token无效 | +| DEVICE_NOT_FOUND | 设备信息异常 | +| MODEL_NOT_FOUND | 模型信息不存在 | +| MODEL_ERROR | 模型服务异常 | +| SERVER_ERROR | 服务器内部错误 | + +#### 错误响应说明 +当随机故事接口发生错误时,会返回包含错误码、描述信息、文本内容和对应音频URL的响应。设备端应该: +1. 检查响应中的errorCode字段 +2. 如果errorCode不为null,表示发生了错误 +3. 播放data字段中的storyAudioUrl音频文件,向用户说明错误情况 +4. 根据错误类型进行相应的处理: + - **DEVICE_NOT_FOUND**: 设备信息异常,建议重新获取设备Token + - **MODEL_NOT_FOUND**: 故事生成模型配置缺失,建议重新获取配置或联系技术支持 + - **MODEL_ERROR**: 故事生成服务异常,建议稍后重试 + - **SERVER_ERROR**: 服务器内部错误,建议稍后重试 #### SSE协议说明 - 接口使用SSE(Server-Sent Events)协议进行流式响应 @@ -714,22 +913,13 @@ sequenceDiagram "characterId": "char_001", "characterName": "小艾", "characterAvatar": { - "hairColor": "orange", - "eyesColor": "blue", - "hairStyle": "long-hair", + "hairColor": "blue", + "eyesColor": "green", + "hairStyle": "side-parted-comma", + "eyesShape": "calm-eyes", "screenImage": "https://example.com/avatar.jpg", "screenImageAsEmoji": false - }, - "emotionEmojis": [ - { - "emotion": "happy", - "emojiUrl": "https://example.com/emoji/happy.png" - }, - { - "emotion": "sad", - "emojiUrl": "https://example.com/emoji/sad.png" - } - ] + } } } ``` @@ -749,24 +939,18 @@ sequenceDiagram | characterId | String | 角色ID | | characterName | String | 角色名称 | | characterAvatar | Object | 角色形象配置 | -| emotionEmojis | Array | 角色表情数组 | **characterAvatar字段说明**: | 字段名 | 类型 | 描述 | 可选值 | |--------|------|------|--------| -| hairColor | String | 发色 | orange, red, purple, green, blue, black | -| eyesColor | String | 瞳色 | orange, red, purple, green, blue, yellow | -| hairStyle | String | 发型 | side-parted, slicked-back, long-hair | +| eyesShape | String | 眼型 | calm-eyes, round-eyes, upturned-eyes | +| hairColor | String | 发色 | light-brown, dark-brown, black, white, gray, blue, purple, gold | +| eyesColor | String | 瞳色 | red, yellow, blue, green, purple, brown, purple-orange-gradient, blue-pink-gradient, yellow-green-gradient | +| hairStyle | String | 发型 | side-parted-comma, m-shaped-bangs, diagonal-bangs, center-parted-bangs, straight-bangs, side-parted-texture | | screenImage | String | 屏保图片URL | | | screenImageAsEmoji | Boolean | 屏保图片是否作为对话表情 | 默认false | -**emotionEmoji字段说明**: - -| 字段名 | 类型 | 描述 | -|--------|------|------| -| emotion | String | 心情名称 | -| emojiUrl | String | 表情URL | #### 错误码 | 错误码 | 描述 | @@ -948,7 +1132,7 @@ sequenceDiagram | updateId | Integer | 升级任务ID | | sourceVersion | String | 源版本号 | | targetVersion | String | 目标版本号 | -| updateType | Integer | 升级类型,1:强制升级,0:可选升级 | +| updateType | Integer | 升级类型,0:紧急修复,1:重要更新,2:普通更新 | | packageId | Integer | 升级包ID | | packageUrl | String | 升级包下载URL | | packageMd5 | String | 升级包MD5校验值 | @@ -996,7 +1180,23 @@ sequenceDiagram end %% 业务消息推送示例 - par 角色切换 + par 语音对话分片传输 + Device->>Device: 用户语音输入 + Device->>Device: 音频数据分片(8KB) + loop 分片传输 + Device->>Server: WebSocket发送
{"command": "VoiceChatRequest", "data": {"audioBase64": "...", "chatId": "...", "finished": false}} + end + Device->>Server: WebSocket发送
{"command": "VoiceChatRequest", "data": {"finished": true}} + + Server->>Server: 重组音频数据 + Server->>Server: 语音识别和处理 + loop 流式响应 + Server->>Device: WebSocket推送
{"command": "VoiceChatResponse", "data": {"chatId": "...", "finished": false, "data": {...}}} + Device->>Device: 播放响应音频片段 + end + Server->>Device: WebSocket推送
{"command": "VoiceChatResponse", "data": {"finished": true}} + + and 角色切换 MiniProgram->>Server: 用户在小程序切换角色 Server->>Device: WebSocket推送
{"command": "CharacterChange", "data": {...}} Device->>Device: 应用新角色配置 @@ -1081,145 +1281,118 @@ WebSocket连接需要设备Token认证,有以下两种方式传递Token: -### 客户端心跳消息 -**客户端发送心跳**: -``` -ping -``` -**服务器响应心跳**: -``` -pong -``` +### 客户端业务消息 -### 服务端业务消息 +客户端可以通过WebSocket连接发送业务消息给服务端,目前支持心跳、语音对话分片传输、语音选择故事和随机故事请求。 -服务端通过WebSocket连接推送业务消息给设备端,消息采用JSON格式,消息结构如下: +#### 心跳请求 (Ping) +**命令描述**:客户端发送心跳请求,保持WebSocket连接活跃 +**协议说明**: +- 建议每30秒发送一次心跳请求 +- 服务端收到心跳请求后会立即响应Pong消息 +- 心跳机制用于检测连接状态和保持连接活跃 +**消息格式**: ```json { "deviceId": "设备ID", "timestamp": 1640995200, - "messageId": "消息ID,用于设备去重防重放", - "command": "命令名称", - "data": { - // 具体的消息数据,根据不同命令名称而变化 - } + "messageId": "消息ID", + "command": "Ping", + "data": null } ``` -#### 消息结构说明 -| 字段名 | 类型 | 描述 | -|--------|------|------| -| deviceId | String | 设备唯一标识符 | -| timestamp | Long | 时间戳,单位:秒 | -| messageId | String | 消息ID,用于设备去重防重放 | -| command | String | 命令名称,见下方支持的命令列表 | -| data | Object | 消息体,不同命令对应不同的数据结构 | - -支持的命令名称如下: - -#### 1. 角色切换 (CharacterChange) -**命令描述**:通知设备切换到指定角色 **消息示例**: ```json { "deviceId": "DEVICE_001", "timestamp": 1640995200, - "messageId": "msg_001", - "command": "CharacterChange", - "data": { - "characterId": "char_001", - "characterName": "小艾", - "characterAvatar": { - "hairColor": "orange", - "eyesColor": "blue", - "hairStyle": "long-hair", - "screenImage": "https://example.com/avatar.jpg", - "screenImageAsEmoji": false - }, - "emotionEmojis": [ - { - "emotion": "happy", - "emojiUrl": "https://example.com/emoji/happy.png" - }, - { - "emotion": "sad", - "emojiUrl": "https://example.com/emoji/sad.png" - } - ] - } + "messageId": "ping_001", + "command": "Ping", + "data": null } ``` -**data字段说明**: - -| 字段名 | 类型 | 描述 | -|--------|------|------| -| characterId | String | 角色ID | -| characterName | String | 角色名称 | -| characterAvatar | Object | 角色形象配置 | -| emotionEmojis | Array | 角色表情数组 | - -**characterAvatar字段说明**: +**服务端响应**: +服务端收到心跳请求后,会立即通过WebSocket推送Pong响应: -| 字段名 | 类型 | 描述 | 可选值 | -|--------|------|------|--------| -| hairColor | String | 发色 | orange, red, purple, green, blue, black | -| eyesColor | String | 瞳色 | orange, red, purple, green, blue, yellow | -| hairStyle | String | 发型 | side-parted, slicked-back, long-hair | -| screenImage | String | 屏保图片URL | | -| screenImageAsEmoji | Boolean | 屏保图片是否作为对话表情 | 默认false | +```json +{ + "deviceId": "DEVICE_001", + "timestamp": 1640995201, + "messageId": "pong_001", + "command": "Pong", + "data": null +} +``` -**emotionEmoji字段说明**: +**协议说明**: +- 客户端发送Ping消息后应等待服务端的Pong响应 +- 如果长时间未收到Pong响应,说明连接可能异常,建议重新连接 +- 心跳间隔建议设置为30秒,过于频繁会增加服务器负载 -| 字段名 | 类型 | 描述 | -|--------|------|------| -| emotion | String | 心情名称 | -| emojiUrl | String | 表情图片URL | +#### 语音对话分片传输 (VoiceChatRequest) +**命令描述**:客户端发送语音对话请求,支持大音频文件的分片传输 +**协议说明**: +- 大于8KB的音频数据应分片传输 +- 每个分片应包含相同的`chatId`用于服务端重组,建议使用UUIDv4算法生成 +- 最后一个分片应设置`finished=true`,否则设置为`finished=false` -#### 2. 角色配置更改 (CharacterConfigChange) -**命令描述**:更新当前角色的配置信息 -**消息示例**: +**消息格式**: ```json { - "deviceId": "DEVICE_001", + "deviceId": "设备ID", "timestamp": 1640995200, - "messageId": "msg_002", - "command": "CharacterConfigChange", + "messageId": "消息ID", + "command": "VoiceChatRequest", "data": { - "characterId": "char_001", - "characterName": "小艾", - "characterAvatar": { - "hairColor": "blue", - "eyesColor": "green", - "hairStyle": "side-parted", - "screenImage": "https://example.com/new_avatar.jpg", - "screenImageAsEmoji": true - }, - "emotionEmojis": [ - { - "emotion": "excited", - "emojiUrl": "https://example.com/emoji/excited.png" - } - ] + "audioBase64": "音频数据Base64编码(分片)", + "chatId": "对话ID,用于标识本次对话", + "finished": false } } ``` -**data字段说明**:与角色切换命令相同 - -#### 3. 哄睡模式开始 (SleepModeStart) -**命令描述**:通知设备启动哄睡模式 -**消息示例**: +**分片传输示例**: ```json +// 第一个分片 { "deviceId": "DEVICE_001", "timestamp": 1640995200, + "messageId": "msg_001", + "command": "VoiceChatRequest", + "data": { + "audioBase64": "UklGRiQAAABXQVZFZm10IBAAAAABAAEA...", + "chatId": "chat_12345", + "finished": false + } +} + +// 第二个分片 +{ + "deviceId": "DEVICE_001", + "timestamp": 1640995201, + "messageId": "msg_002", + "command": "VoiceChatRequest", + "data": { + "audioBase64": "AAEAAQABAAEAAQABAAEAAQABAAEAAQAB...", + "chatId": "chat_12345", + "finished": false + } +} + +// 最后一个分片 +{ + "deviceId": "DEVICE_001", + "timestamp": 1640995202, "messageId": "msg_003", - "command": "SleepModeStart", + "command": "VoiceChatRequest", "data": { - "storyTheme": "爱情故事" + "audioBase64": "BAAEAAQABAAEAAQABAAEAAQABAAEAAAA...", + "chatId": "chat_12345", + "finished": true } } ``` @@ -1228,48 +1401,84 @@ pong | 字段名 | 类型 | 描述 | |--------|------|------| -| storyTheme | String | 故事主题 | +| audioBase64 | String | 音频数据Base64编码,单个分片不超过8KB原始数据 | +| chatId | String | 对话ID,用于标识本次对话,建议使用UUID | +| finished | Boolean | 是否为最后一个分片,true表示传输完成 | -设备收到此命令后,使用推送的主题调用randomStory接口,播放故事。 +**分片传输规则**: +1. 原始音频数据按8KB分片 +2. 每个分片转换为Base64编码后发送 +3. 所有分片使用相同的chatId +4. 只有最后一个分片设置finished=true +**服务端响应**: +服务端收到完整音频后,会通过WebSocket推送VoiceChatResponse消息: -#### 4. 哄睡模式结束 (SleepModeEnd) -**命令描述**:通知设备结束哄睡模式 -**消息示例**: ```json { "deviceId": "DEVICE_001", - "timestamp": 1640995200, - "messageId": "msg_004", - "command": "SleepModeEnd", - "data": {} + "timestamp": 1640995203, + "messageId": "msg_004", + "command": "VoiceChatResponse", + "data": { + "chatId": "chat_12345", + "finished": false, + "data": { + "textContent": "你好,我听到了你的话", + "audioUrl": "https://example.com/response_audio.mp3" + } + } } ``` -**data字段说明**:无特殊字段 - -设备收到改命令后,需要停止播放故事。 - - -#### 6. 哄睡模式故事内容 - -设备收到`SleepModeStart` 命令后,需要调用`/v1/story/randomStory`接口获取故事内容。 - +#### 语音选择故事请求 (ChooseStoryRequest) +**命令描述**:客户端发送语音选择故事请求,用户通过语音表达故事偏好,系统根据语音内容选择相应故事 +**协议说明**: +- 支持音频数据分片传输,大于8KB的音频数据应分片传输 +- 每个分片应包含相同的`chatId`用于服务端重组,建议使用UUIDv4算法生成 +- 最后一个分片应设置`finished=true`,否则设置为`finished=false` +- 服务端会通过WebSocket推送ChooseStoryResponse消息流式返回故事内容 +**消息格式**: +```json +{ + "deviceId": "设备ID", + "timestamp": 1640995200, + "messageId": "消息ID", + "command": "ChooseStoryRequest", + "data": { + "audioBase64": "音频数据Base64编码(分片)", + "chatId": "对话ID,用于标识本次故事请求", + "finished": false + } +} +``` -#### 7. 设备绑定 (DeviceBind) -**命令描述**:通知设备已被用户绑定 -**消息示例**: +**分片传输示例**: ```json +// 第一个分片 { "deviceId": "DEVICE_001", "timestamp": 1640995200, - "messageId": "msg_007", - "command": "DeviceBind", + "messageId": "story_001", + "command": "ChooseStoryRequest", "data": { - "userId": "user_001", - "userName": "张三", - "bindTime": 1640995200 + "audioBase64": "UklGRiQAAABXQVZFZm10IBAAAAABAAEA...", + "chatId": "story_12345", + "finished": false + } +} + +// 最后一个分片 +{ + "deviceId": "DEVICE_001", + "timestamp": 1640995202, + "messageId": "story_002", + "command": "ChooseStoryRequest", + "data": { + "audioBase64": "BAAEAAQABAAEAAQABAAEAAQABAAEAAAA...", + "chatId": "story_12345", + "finished": true } } ``` @@ -1278,13 +1487,435 @@ pong | 字段名 | 类型 | 描述 | |--------|------|------| -| userId | String | 用户ID | -| userName | String | 用户名称 | -| bindTime | Long | 绑定时间戳,单位:秒 | +| audioBase64 | String | 音频数据Base64编码,单个分片不超过8KB原始数据 | +| chatId | String | 对话ID,用于标识本次故事请求,建议使用UUID | +| finished | Boolean | 是否为最后一个分片,true表示传输完成 | + +**服务端响应**: +服务端收到完整音频后,会通过WebSocket推送ChooseStoryResponse消息流式返回故事内容: -#### 8. 设备解绑 (DeviceUnbind) -**命令描述**:通知设备已被用户解绑 -**消息示例**: +```json +{ + "deviceId": "DEVICE_001", + "timestamp": 1640995203, + "messageId": "story_response_001", + "command": "ChooseStoryResponse", + "data": { + "chatId": "story_12345", + "finished": false, + "data": { + "storyTheme": "童话故事", + "storyContent": "从前有一个可爱的小女孩", + "storyAudioUrl": "https://example.com/story/audio/chunk_001.mp3", + "storyDuration": null + }, + "errorCode": null + } +} +``` + +#### 随机故事请求 (RandomStoryRequest) +**命令描述**:客户端发送随机故事请求,系统会根据指定主题(可选)生成随机故事 +**协议说明**: +- 无需音频数据,仅通过文本参数指定故事主题 +- 故事主题为可选参数,不指定时系统会随机选择主题 +- 服务端会通过WebSocket推送RandomStoryResponse消息流式返回故事内容 + +**消息格式**: +```json +{ + "deviceId": "设备ID", + "timestamp": 1640995200, + "messageId": "消息ID", + "command": "RandomStoryRequest", + "data": { + "chatId": "对话ID,用于标识本次故事请求", + "storyTheme": "故事主题(可选)" + } +} +``` + +**消息示例**: +```json +{ + "deviceId": "DEVICE_001", + "timestamp": 1640995200, + "messageId": "random_story_001", + "command": "RandomStoryRequest", + "data": { + "chatId": "random_story_12345", + "storyTheme": "冒险" + } +} +``` + +**data字段说明**: + +| 字段名 | 类型 | 描述 | +|--------|------|------| +| chatId | String | 对话ID,用于标识本次故事请求,建议使用UUID | +| storyTheme | String | 故事主题,可选参数。如"童话"、"冒险"、"科幻"等,不指定时系统随机选择 | + +**服务端响应**: +服务端收到随机故事请求后,会通过WebSocket推送RandomStoryResponse消息流式返回故事内容: + +```json +{ + "deviceId": "DEVICE_001", + "timestamp": 1640995201, + "messageId": "random_story_response_001", + "command": "RandomStoryResponse", + "data": { + "chatId": "random_story_12345", + "finished": false, + "data": { + "storyTheme": "冒险故事", + "storyContent": "在一个阳光明媚的早晨", + "storyAudioUrl": "https://example.com/story/audio/chunk_001.mp3", + "storyDuration": null + }, + "errorCode": null + } +} +``` + +### 服务端业务消息 + +服务端通过WebSocket连接推送业务消息给设备端,消息采用JSON格式,消息结构如下: + +```json +{ + "deviceId": "设备ID", + "timestamp": 1640995200, + "messageId": "消息ID,用于设备去重防重放", + "command": "命令名称", + "data": { + // 具体的消息数据,根据不同命令名称而变化 + } +} +``` + +#### 消息结构说明 +| 字段名 | 类型 | 描述 | +|--------|------|------| +| deviceId | String | 设备唯一标识符 | +| timestamp | Long | 时间戳,单位:秒 | +| messageId | String | 消息ID,用于设备去重防重放 | +| command | String | 命令名称,见下方支持的命令列表 | +| data | Object | 消息体,不同命令对应不同的数据结构 | + +支持的命令名称如下: + +#### 1. 心跳响应 (Pong) +**命令描述**:服务端响应客户端的心跳请求 +**消息示例**: +```json +{ + "deviceId": "DEVICE_001", + "timestamp": 1640995201, + "messageId": "pong_001", + "command": "Pong", + "data": null +} +``` + +**data字段说明**:无数据字段 + +#### 2. 语音对话响应 (VoiceChatResponse) +**命令描述**:服务端推送语音对话响应,流式返回对话结果 +**消息示例**: +```json +{ + "deviceId": "DEVICE_001", + "timestamp": 1640995203, + "messageId": "chat_response_001", + "command": "VoiceChatResponse", + "data": { + "chatId": "chat_12345", + "finished": false, + "data": { + "textContent": "你好,我听到了你的话", + "audioUrl": "https://example.com/response_audio.mp3", + "intention": null + }, + "errorCode": null + } +} +``` + +**data字段说明**: + +| 字段名 | 类型 | 描述 | +|--------|------|------| +| chatId | String | 对话ID,与客户端请求中的chatId对应 | +| finished | Boolean | 是否为最后一个响应片段 | +| data | Object | 响应数据,包含文本内容、音频URL等 | +| errorCode | String | 错误码,正常情况下为null | + +**data.data字段说明**: + +| 字段名 | 类型 | 描述 | +|--------|------|------| +| textContent | String | 回复的文本内容 | +| audioUrl | String | 回复音频文件URL | +| intention | String | 用户意图识别结果,如"StartSleepMode"等 | + +#### 3. 语音选择故事响应 (ChooseStoryResponse) +**命令描述**:服务端推送语音选择故事响应,流式返回故事内容 +**消息示例**: +```json +{ + "deviceId": "DEVICE_001", + "timestamp": 1640995203, + "messageId": "story_response_001", + "command": "ChooseStoryResponse", + "data": { + "chatId": "story_12345", + "finished": false, + "data": { + "storyTheme": "童话故事", + "storyContent": "从前有一个可爱的小女孩", + "storyAudioUrl": "https://example.com/story/audio/chunk_001.mp3", + "storyDuration": null + }, + "errorCode": null + } +} +``` + +**data字段说明**: + +| 字段名 | 类型 | 描述 | +|--------|------|------| +| chatId | String | 对话ID,与客户端请求中的chatId对应 | +| finished | Boolean | 是否为最后一个故事片段 | +| data | Object | 故事数据,包含主题、内容、音频等 | +| errorCode | String | 错误码,正常情况下为null | + +**data.data字段说明**: + +| 字段名 | 类型 | 描述 | +|--------|------|------| +| storyTheme | String | 故事主题 | +| storyContent | String | 故事片段文本内容 | +| storyAudioUrl | String | 故事片段音频文件URL | +| storyDuration | Integer | 故事片段时长(秒) | + +#### 4. 随机故事响应 (RandomStoryResponse) +**命令描述**:服务端推送随机故事响应,流式返回故事内容 +**消息示例**: +```json +{ + "deviceId": "DEVICE_001", + "timestamp": 1640995201, + "messageId": "random_story_response_001", + "command": "RandomStoryResponse", + "data": { + "chatId": "random_story_12345", + "finished": false, + "data": { + "storyTheme": "冒险故事", + "storyContent": "在一个阳光明媚的早晨", + "storyAudioUrl": "https://example.com/story/audio/chunk_001.mp3", + "storyDuration": null + }, + "errorCode": null + } +} +``` + +**data字段说明**:与语音选择故事响应相同 + +#### 5. 角色切换 (CharacterChange) +**命令描述**:通知设备切换到指定角色 +**消息示例**: +```json +{ + "deviceId": "DEVICE_001", + "timestamp": 1640995200, + "messageId": "msg_001", + "command": "CharacterChange", + "data": { + "characterId": "char_001", + "characterName": "小艾", + "characterAvatar": { + "eyesShape": "upturned-eyes", + "hairColor": "blue", + "eyesColor": "green", + "hairStyle": "side-parted", + "screenImage": "https://example.com/avatar.jpg", + "screenImageAsEmoji": false + } + } +} +``` + +**data字段说明**: + +| 字段名 | 类型 | 描述 | +|--------|------|------| +| characterId | String | 角色ID | +| characterName | String | 角色名称 | +| characterAvatar | Object | 角色形象配置 | + +**characterAvatar字段说明**: + +| 字段名 | 类型 | 描述 | 可选值 | +|--------|------|------|--------| +| eyesShape | String | 眼型 | calm-eyes, round-eyes, upturned-eyes | +| eyesColor | String | 瞳色 | red, yellow, blue, green, purple, brown, purple-orange-gradient, blue-pink-gradient, yellow-green-gradient | +| hairColor | String | 发色 | light-brown, dark-brown, black, white, gray, blue, purple, gold | +| hairStyle | String | 发型 | side-parted-comma, m-shaped-bangs, diagonal-bangs, center-parted-bangs, straight-bangs, side-parted-texture | +| screenImage | String | 屏保图片URL | | +| screenImageAsEmoji | Boolean | 屏保图片是否作为对话表情 | 默认false | + +**枚举说明**: + +眼型 +| 值 | 描述 | +|--------|------| +| calm-eyes | 平缓眼 | +| round-eyes | 圆眼 | +| upturned-eyes | 上挑眼 | + +瞳色 +| 值 | 描述 | +|--------|------| +| red | 红 | +| yellow | 黄 | +| blue | 蓝 | +| green | 绿 | +| purple | 紫 | +| brown | 棕 | +| purple-orange-gradient | 紫橙渐变 | +| blue-pink-gradient | 蓝粉渐变 | +| yellow-green-gradient | 黄绿渐变 | + +发色 +| 值 | 描述 | +|--------|------| +| light-brown | 浅棕色 | +| dark-brown | 深棕色 | +| black | 黑色 | +| white | 白色 | +| gray | 灰色 | +| blue | 蓝色 | +| purple | 紫色 | +| gold | 金色 | + +发型 +| 值 | 描述 | +|--------|------| +| side-parted-comma | 偏分逗号 | +| m-shaped-bangs | M形刘海 | +| diagonal-bangs | 斜刘海 | +| center-parted-bangs | 中分刘海 | +| straight-bangs | 齐刘海 | +| side-parted-texture | 偏分纹理 | + + +#### 6. 角色配置更改 (CharacterConfigChange) +**命令描述**:更新当前角色的配置信息 +**消息示例**: +```json +{ + "deviceId": "DEVICE_001", + "timestamp": 1640995200, + "messageId": "msg_002", + "command": "CharacterConfigChange", + "data": { + "characterId": "char_001", + "characterName": "小艾", + "characterAvatar": { + "eyesShape": "upturned-eyes", + "hairColor": "blue", + "eyesColor": "green", + "hairStyle": "side-parted-comma", + "screenImage": "https://example.com/new_avatar.jpg", + "screenImageAsEmoji": true + } + } +} +``` + +**data字段说明**:与角色切换命令相同 + +#### 7. 哄睡模式开始 (SleepModeStart) +**命令描述**:通知设备启动哄睡模式 +**消息示例**: +```json +{ + "deviceId": "DEVICE_001", + "timestamp": 1640995200, + "messageId": "msg_003", + "command": "SleepModeStart", + "data": { + "storyTheme": "爱情故事" + } +} +``` + +**data字段说明**: + +| 字段名 | 类型 | 描述 | +|--------|------|------| +| storyTheme | String | 故事主题 | + +设备收到此命令后,使用推送的主题调用randomStory接口,播放故事。 + + +#### 8. 哄睡模式结束 (SleepModeEnd) +**命令描述**:通知设备结束哄睡模式 +**消息示例**: +```json +{ + "deviceId": "DEVICE_001", + "timestamp": 1640995200, + "messageId": "msg_004", + "command": "SleepModeEnd", + "data": {} +} +``` + +**data字段说明**:无特殊字段 + +设备收到改命令后,需要停止播放故事。 + + +#### 9. 哄睡模式故事内容 + +设备收到`SleepModeStart` 命令后,需要调用`/v1/story/randomStory`接口获取故事内容。 + + + +#### 10. 设备绑定 (DeviceBind) +**命令描述**:通知设备已被用户绑定 +**消息示例**: +```json +{ + "deviceId": "DEVICE_001", + "timestamp": 1640995200, + "messageId": "msg_007", + "command": "DeviceBind", + "data": { + "userId": "user_001", + "userName": "张三", + "bindTime": 1640995200 + } +} +``` + +**data字段说明**: + +| 字段名 | 类型 | 描述 | +|--------|------|------| +| userId | String | 用户ID | +| userName | String | 用户名称 | +| bindTime | Long | 绑定时间戳,单位:秒 | + +#### 11. 设备解绑 (DeviceUnbind) +**命令描述**:通知设备已被用户解绑 +**消息示例**: ```json { "deviceId": "DEVICE_001", @@ -1307,7 +1938,7 @@ pong | reason | String | 解绑原因 | | unbindTime | Long | 解绑时间戳,单位:秒 | -#### 9. 日程提醒 (ScheduleReminder) +#### 12. 日程提醒 (ScheduleReminder) **命令描述**:推送日程提醒信息 **消息示例**: ```json @@ -1340,7 +1971,7 @@ pong | enableVoice | Integer | 是否启用语音,1:启用,0:未启用 | | enableVibration | Integer | 是否启用震动,1:启用,0:未启用 | -#### 10. 日程提醒配置 (ScheduleReminderConfig) +#### 13. 日程提醒配置 (ScheduleReminderConfig) **命令描述**:配置日程提醒相关设置 **消息示例**: ```json @@ -1361,9 +1992,312 @@ pong |--------|------|------| | scheduleName | String | 日程名称 | +#### 14. 下载表情 (DownloadEmoji) +**命令描述**:通知设备下载指定角色的表情包 +**消息示例**: +```json +{ + "deviceId": "DEVICE_001", + "timestamp": 1640995200, + "messageId": "msg_011", + "command": "DownloadEmoji", + "data": { + "characterId": "char_001", + "eyesColor": "blue", + "eyesShape": "calm-eyes", + "emotionEmojis": [ + { + "emotion": "happy", + "emojiUrl": "https://example.com/emoji/happy.mp4" + }, + { + "emotion": "sad", + "emojiUrl": "https://example.com/emoji/sad.mp4" + } + ] + } +} +``` + +**data字段说明**: + +| 字段名 | 类型 | 描述 | +|--------|------|------| +| characterId | String | 角色ID | +| eyesColor | String | 瞳色,用于标识表情包组合 | +| eyesShape | String | 眼型,用于标识表情包组合 | +| emotionEmojis | Array | 表情列表 | + +**emotionEmojis字段说明**: + +| 字段名 | 类型 | 描述 | +|--------|------|------| +| emotion | String | 心情类型,如"happy"、"sad"、"angry"等 | +| emojiUrl | String | 表情动画文件URL,通常为mp4格式 | + +**设备处理说明**: +- 设备收到此命令后,应下载所有emotionEmojis中的表情文件 +- 下载完成后,调用`/v1/emoji/reportEmoji`接口上报下载状态 +- 表情文件建议缓存到本地,以便快速显示 + +#### 15. 删除表情 (DeleteEmoji) +**命令描述**:通知设备删除指定角色的表情包 +**消息示例**: +```json +{ + "deviceId": "DEVICE_001", + "timestamp": 1640995200, + "messageId": "msg_012", + "command": "DeleteEmoji", + "data": { + "characterId": "char_001", + "eyesColor": "blue", + "eyesShape": "calm-eyes" + } +} +``` + +**data字段说明**: + +| 字段名 | 类型 | 描述 | +|--------|------|------| +| characterId | String | 角色ID | +| eyesColor | String | 瞳色,用于标识要删除的表情包组合 | +| eyesShape | String | 眼型,用于标识要删除的表情包组合 | + +**设备处理说明**: +- 设备收到此命令后,应删除对应角色和瞳色、眼型组合的所有表情文件 +- 删除完成后,调用`/v1/emoji/reportEmoji`接口上报删除状态 +- 删除操作应清理本地缓存的表情文件 + + +## 7. 表情管理接口 + +### 时序图 + +```mermaid +sequenceDiagram + participant Device as 设备端 + participant Server as 服务端 + participant MiniProgram as 小程序端 + + Note over Device,MiniProgram: 表情管理流程 + + %% 表情下载流程 + rect rgb(240, 248, 255) + Note over MiniProgram, Device: 1. 表情下载流程 + MiniProgram->>Server: 用户在小程序选择下载表情 + Server->>Device: WebSocket推送
{"command": "DownloadEmoji", "data": {...}} + Device->>Device: 下载表情文件到本地 + Device->>Server: POST /v1/emoji/reportEmoji
上报下载状态 + Server->>MiniProgram: 同步表情状态到小程序 + end + + %% 表情删除流程 + rect rgb(255, 250, 240) + Note over MiniProgram, Device: 2. 表情删除流程 + MiniProgram->>Server: 用户在小程序删除表情 + Server->>Device: WebSocket推送
{"command": "DeleteEmoji", "data": {...}} + Device->>Device: 删除本地表情文件 + Device->>Server: POST /v1/emoji/reportEmoji
上报删除状态 + Server->>MiniProgram: 同步表情状态到小程序 + end + + %% 定时同步流程 + rect rgb(245, 255, 250) + Note over Device, Server: 3. 定时同步流程 + Device->>Device: 每日0点触发 + Device->>Server: POST /v1/emoji/reportAllEmoji
上报所有表情状态 + Server->>Server: 更新设备表情状态 + end +``` + +### 7.1 上报角色表情组下载状态 + +#### 接口描述 +上报角色表情组下载状态接口。设备收到删除表情指令或者下载表情指令,执行成功后调用该接口,用以同步表情下载状态到小程序端。该接口需要设备Token认证。 + +#### 请求信息 +- **URL**: `/v1/emoji/reportEmoji` +- **方法**: `POST` +- **Content-Type**: `application/json` + +#### 认证要求 +该接口需要设备Token认证,Token通过请求头传递。 + +#### 请求头参数 +| 参数名 | 类型 | 必填 | 描述 | 示例 | +|--------|------|------|------|------| +| deviceId | String | 是 | 设备唯一标识符 | "DEVICE_001" | +| deviceToken | String | 是 | 设备访问令牌 | "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." | + +#### 请求体参数 +| 参数名 | 类型 | 必填 | 描述 | 示例 | +|--------|------|------|------|------| +| characterId | String | 是 | 角色ID | "char_001" | +| eyesColor | String | 是 | 瞳色 | "blue" | +| eyesShape | String | 是 | 眼型 | "calm-eyes" | +| status | String | 是 | 状态 | "download_success", "download_fail", "delete_success", "delete_fail" | + +#### 请求示例 +```json +{ + "characterId": "char_001", + "eyesColor": "blue", + "eyesShape": "calm-eyes", + "status": "download_success" +} +``` + +#### 响应数据 +**成功响应**: +```json +{ + "errorCode": null, + "message": null, + "data": "ok" +} +``` + +**失败响应(认证失败)**: +```json +{ + "errorCode": "AUTH_FAILURE", + "message": "设备Token无效", + "data": null +} +``` + +#### 响应字段说明 +| 字段名 | 类型 | 描述 | +|--------|------|------| +| data | String | 操作结果,成功时返回"ok" | + +#### 错误码 +| 错误码 | 描述 | +|--------|------| +| AUTH_FAILURE | 认证失败(设备ID为空或Token无效) | +| MISSING_PARAMETER | 必填参数缺失 | +| SERVER_ERROR | 服务器内部错误 | + +#### 使用说明 +- 该接口用于设备向服务器同步表情下载/删除状态 +- 设备执行表情下载或删除操作成功后,必须调用此接口 +- 服务器会根据上报的信息更新小程序端的表情状态显示 +- characterId、eyesColor、eyesShape三个字段组合标识一个唯一的表情组 + +### 7.2 上报设备所有表情组状态 + +#### 接口描述 +上报设备已下载的所有非预设表情组接口。需每天0点上报一次,同步表情下载状态到小程序端。该接口需要设备Token认证。 + +#### 请求信息 +- **URL**: `/v1/emoji/reportAllEmoji` +- **方法**: `POST` +- **Content-Type**: `application/json` + +#### 认证要求 +该接口需要设备Token认证,Token通过请求头传递。 + +#### 请求头参数 +| 参数名 | 类型 | 必填 | 描述 | 示例 | +|--------|------|------|------|------| +| deviceId | String | 是 | 设备唯一标识符 | "DEVICE_001" | +| deviceToken | String | 是 | 设备访问令牌 | "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." | +#### 请求体参数 +| 参数名 | 类型 | 必填 | 描述 | 示例 | +|--------|------|------|------|------| +| emojiGroups | Array | 是 | 已下载的表情组列表 | 见下方示例 | + +#### EmojiGroup对象说明 +| 字段名 | 类型 | 必填 | 描述 | 示例 | +|--------|------|------|------|------| +| characterId | String | 是 | 角色ID | "char_001" | +| eyesColor | String | 是 | 瞳色 | "blue" | +| eyesShape | String | 是 | 眼型 | "calm-eyes" | +| status | String | 是 | 状态 | "download_success", "download_fail", "delete_success", "delete_fail" | + +#### 请求示例 +```json +{ + "emojiGroups": [ + { + "characterId": "char_001", + "eyesColor": "blue", + "eyesShape": "calm-eyes", + "status": "download_success" + }, + { + "characterId": "char_001", + "eyesColor": "green", + "eyesShape": "round-eyes", + "status": "download_success" + }, + { + "characterId": "char_002", + "eyesColor": "red", + "eyesShape": "upturned-eyes", + "status": "download_success" + } + ] +} +``` + +#### 响应数据 +**成功响应**: +```json +{ + "errorCode": null, + "message": null, + "data": "ok" +} +``` + +**失败响应(认证失败)**: +```json +{ + "errorCode": "AUTH_FAILURE", + "message": "设备Token无效", + "data": null +} +``` + +#### 响应字段说明 +| 字段名 | 类型 | 描述 | +|--------|------|------| +| data | String | 操作结果,成功时返回"ok" | + +#### 错误码 +| 错误码 | 描述 | +|--------|------| +| AUTH_FAILURE | 认证失败(设备ID为空或Token无效) | +| MISSING_PARAMETER | 必填参数缺失 | +| SERVER_ERROR | 服务器内部错误 | + +#### 使用说明 +- 该接口用于设备定时向服务器同步所有已下载的表情组状态 +- 建议每天0点自动调用一次,确保服务器端数据与设备端一致 +- emojiGroups数组包含设备当前已下载的所有非预设表情组 +- 空数组表示设备没有下载任何非预设表情组 +- 服务器会根据上报的信息更新小程序端的表情状态显示 + +### 表情管理接口使用流程 +1. **表情下载**:小程序端触发表情下载 → 服务器通过WebSocket推送DownloadEmoji命令 → 设备下载表情文件 → 设备调用reportEmoji接口上报状态 +2. **表情删除**:小程序端触发表情删除 → 服务器通过WebSocket推送DeleteEmoji命令 → 设备删除表情文件 → 设备调用reportEmoji接口上报状态 +3. **状态同步**:设备每日0点调用reportAllEmoji接口 → 服务器更新设备表情状态 → 小程序端显示最新状态 + +### 表情包标识说明 +表情包通过三个字段的组合进行唯一标识: +- **characterId**:角色ID,标识表情属于哪个角色 +- **eyesColor**:瞳色 +- **eyesShape**:眼型 + +相同characterId、eyesColor、eyesShape组合的所有表情文件构成一个表情组,设备需要统一管理这些表情文件的下载和删除。 + +--- -## 7. 二维码生成接口 +## 8. 二维码生成接口 ### 接口描述 生成二维码图片接口,根据提供的内容生成PNG格式的二维码图片并直接返回图片二进制数据。该接口无需认证。 @@ -1427,7 +2361,7 @@ pong --- -## 8. 系统整体时序图 +## 9. 系统整体时序图 ### 设备完整生命周期流程 @@ -1522,7 +2456,7 @@ sequenceDiagram end ``` -## 9. 通用说明 +## 10. 通用说明 ### 设备认证流程 1. 设备首次启动时,使用签名算法调用获取设备Token接口 @@ -1549,6 +2483,7 @@ sequenceDiagram 4. **设备信息管理**:展示设备角色配置和用户绑定流程 5. **WebSocket通信**:展示实时通信和命令推送流程 6. **OTA升级流程**:展示固件升级的完整过程 -7. **系统整体流程**:展示设备完整生命周期的综合时序图 +7. **表情管理流程**:展示表情下载、删除和状态同步的完整过程 +8. **系统整体流程**:展示设备完整生命周期的综合时序图 每个时序图都详细描述了参与方之间的交互序列,有助于开发者理解系统架构和实现细节。 -- 2.17.1