}\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
| 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
}\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
| 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
- 客户端可以边接收边播放,实现流式播放体验\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
}\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
| 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
"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
| 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
| 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
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
\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
\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
\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
| reason | String | 解绑原因 |\r
| unbindTime | Long | 解绑时间戳,单位:秒 |\r
\r
-#### 9. 日程提醒 (ScheduleReminder)\r
+#### 12. 日程提醒 (ScheduleReminder)\r
**命令描述**:推送日程提醒信息\r
**消息示例**:\r
```json\r
| enableVoice | Integer | 是否启用语音,1:启用,0:未启用 |\r
| enableVibration | Integer | 是否启用震动,1:启用,0:未启用 |\r
\r
-#### 10. 日程提醒配置 (ScheduleReminderConfig)\r
+#### 13. 日程提醒配置 (ScheduleReminderConfig)\r
**命令描述**:配置日程提醒相关设置\r
**消息示例**:\r
```json\r
|--------|------|------|\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
\r
---\r
\r
-## 8. 系统整体时序图\r
+## 9. 系统整体时序图\r
\r
### 设备完整生命周期流程\r
\r
end\r
```\r
\r
-## 9. 通用说明\r
+## 10. 通用说明\r
\r
### 设备认证流程\r
1. 设备首次启动时,使用签名算法调用获取设备Token接口\r
4. **设备信息管理**:展示设备角色配置和用户绑定流程\r
5. **WebSocket通信**:展示实时通信和命令推送流程\r
6. **OTA升级流程**:展示固件升级的完整过程\r
-7. **系统整体流程**:展示设备完整生命周期的综合时序图\r
+7. **表情管理流程**:展示表情下载、删除和状态同步的完整过程\r
+8. **系统整体流程**:展示设备完整生命周期的综合时序图\r
\r
每个时序图都详细描述了参与方之间的交互序列,有助于开发者理解系统架构和实现细节。\r