协议文档更新 2273/1
authorcheng <chengyf@zhihuishixun.com>
Wed, 17 Sep 2025 02:07:34 +0000 (10:07 +0800)
committercheng <chengyf@zhihuishixun.com>
Wed, 17 Sep 2025 02:07:34 +0000 (10:07 +0800)
code/sdk/zhihui/leiniao/设备API接口文档.md

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