修复智控台音频播放权限bug

This commit is contained in:
hrz
2025-05-04 20:03:13 +08:00
parent a144570ed7
commit 81359bf419
5 changed files with 67 additions and 29 deletions
@@ -103,4 +103,11 @@ public class RedisKeys {
public static String getDictDataByTypeKey(String dictType) { public static String getDictDataByTypeKey(String dictType) {
return "sys:dict:data:" + dictType; return "sys:dict:data:" + dictType;
} }
/**
* 获取智能体音频ID的缓存key
*/
public static String getAgentAudioIdKey(String uuid) {
return "agent:audio:id:" + uuid;
}
} }
@@ -3,7 +3,9 @@ package xiaozhi.modules.agent.controller;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
@@ -28,6 +30,8 @@ import jakarta.validation.Valid;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import xiaozhi.common.constant.Constant; import xiaozhi.common.constant.Constant;
import xiaozhi.common.page.PageData; import xiaozhi.common.page.PageData;
import xiaozhi.common.redis.RedisKeys;
import xiaozhi.common.redis.RedisUtils;
import xiaozhi.common.user.UserDetail; import xiaozhi.common.user.UserDetail;
import xiaozhi.common.utils.ConvertUtils; import xiaozhi.common.utils.ConvertUtils;
import xiaozhi.common.utils.Result; import xiaozhi.common.utils.Result;
@@ -55,6 +59,7 @@ public class AgentController {
private final DeviceService deviceService; private final DeviceService deviceService;
private final AgentChatHistoryService agentChatHistoryService; private final AgentChatHistoryService agentChatHistoryService;
private final AgentChatAudioService agentChatAudioService; private final AgentChatAudioService agentChatAudioService;
private final RedisUtils redisUtils;
@GetMapping("/list") @GetMapping("/list")
@Operation(summary = "获取用户智能体列表") @Operation(summary = "获取用户智能体列表")
@@ -235,17 +240,37 @@ public class AgentController {
return new Result<List<AgentChatHistoryDTO>>().ok(result); return new Result<List<AgentChatHistoryDTO>>().ok(result);
} }
@GetMapping("/audio/{audioId}") @PostMapping("/audio/{audioId}")
@Operation(summary = "下载音频") @Operation(summary = "获取音频下载ID")
@RequiresPermissions("sys:role:normal") @RequiresPermissions("sys:role:normal")
public ResponseEntity<byte[]> downloadAudio(@PathVariable("audioId") String audioId) { public Result<String> getAudioId(@PathVariable("audioId") String audioId) {
byte[] audioData = agentChatAudioService.getAudio(audioId);
if (audioData == null) {
return new Result<String>().error("音频不存在");
}
String uuid = UUID.randomUUID().toString();
redisUtils.set(RedisKeys.getAgentAudioIdKey(uuid), audioId);
return new Result<String>().ok(uuid);
}
@GetMapping("/play/{uuid}")
@Operation(summary = "播放音频")
public ResponseEntity<byte[]> playAudio(@PathVariable("uuid") String uuid) {
String audioId = (String) redisUtils.get(RedisKeys.getAgentAudioIdKey(uuid));
if (StringUtils.isBlank(audioId)) {
return ResponseEntity.notFound().build();
}
byte[] audioData = agentChatAudioService.getAudio(audioId); byte[] audioData = agentChatAudioService.getAudio(audioId);
if (audioData == null) { if (audioData == null) {
return ResponseEntity.notFound().build(); return ResponseEntity.notFound().build();
} }
redisUtils.delete(RedisKeys.getAgentAudioIdKey(uuid));
return ResponseEntity.ok() return ResponseEntity.ok()
.contentType(MediaType.APPLICATION_OCTET_STREAM) .contentType(MediaType.APPLICATION_OCTET_STREAM)
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"play.wav\"") .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"play.wav\"")
.body(audioData); .body(audioData);
} }
} }
@@ -86,6 +86,7 @@ public class ShiroConfig {
// 将config路径使用server服务过滤器 // 将config路径使用server服务过滤器
filterMap.put("/config/**", "server"); filterMap.put("/config/**", "server");
filterMap.put("/agent/chat-history/report", "server"); filterMap.put("/agent/chat-history/report", "server");
filterMap.put("/agent/play/**", "anon");
filterMap.put("/**", "oauth2"); filterMap.put("/**", "oauth2");
shiroFilter.setFilterChainDefinitionMap(filterMap); shiroFilter.setFilterChainDefinitionMap(filterMap);
+15 -15
View File
@@ -128,19 +128,19 @@ export default {
}); });
}).send(); }).send();
}, },
} // 获取音频下载ID
getAudioId(audioId, callback) {
export function getAgentSessions(agentId, params) { RequestService.sendRequest()
return request({ .url(`${getServiceUrl()}/agent/audio/${audioId}`)
url: `/agent/${agentId}/sessions`, .method('POST')
method: 'get', .success((res) => {
params RequestService.clearRequestTime();
}); callback(res);
} })
.fail(() => {
export function getAgentChatHistory(agentId, sessionId) { RequestService.reAjaxFun(() => {
return request({ this.getAudioId(audioId, callback);
url: `/agent/${agentId}/chat-history/${sessionId}`, });
method: 'get' }).send();
}); },
} }
@@ -66,7 +66,7 @@ export default {
currentSessionId: '', currentSessionId: '',
currentMacAddress: '', currentMacAddress: '',
page: 1, page: 1,
limit: 10, limit: 20,
loading: false, loading: false,
hasMore: true, hasMore: true,
scrollTimer: null, scrollTimer: null,
@@ -237,16 +237,21 @@ export default {
this.audioElement = null; this.audioElement = null;
} }
// 播放新音频 // 先获取音频下载ID
this.playingAudioId = message.audioId; this.playingAudioId = message.audioId;
this.audioElement = new Audio(Api.getServiceUrl() + `/agent/audio/${message.audioId}`); Api.agent.getAudioId(message.audioId, (res) => {
if (res.data && res.data.data) {
// 使用获取到的下载ID播放音频
this.audioElement = new Audio(Api.getServiceUrl() + `/agent/play/${res.data.data}`);
this.audioElement.onended = () => { this.audioElement.onended = () => {
this.playingAudioId = null; this.playingAudioId = null;
this.audioElement = null; this.audioElement = null;
}; };
this.audioElement.play(); this.audioElement.play();
}
});
}, },
getUserAvatar(sessionId) { getUserAvatar(sessionId) {
// 从 sessionId 中提取所有数字 // 从 sessionId 中提取所有数字
@@ -269,7 +274,7 @@ export default {
<style scoped> <style scoped>
.chat-container { .chat-container {
display: flex; display: flex;
height: 600px; height: 100%;
} }
.session-list { .session-list {
@@ -422,7 +427,7 @@ export default {
top: 50%; top: 50%;
left: 50%; left: 50%;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
height: 80vh; height: 90vh;
max-width: 85vw; max-width: 85vw;
border-radius: 12px; border-radius: 12px;
overflow: hidden; overflow: hidden;
@@ -436,7 +441,7 @@ export default {
.chat-history-dialog .el-dialog__body { .chat-history-dialog .el-dialog__body {
padding: 0; padding: 0;
overflow: hidden; overflow: hidden;
height: calc(80vh - 54px); height: calc(90vh - 54px);
/* 减去标题栏的高度 */ /* 减去标题栏的高度 */
} }
</style> </style>