- 新增 hooks/ 目录,包含三个专用 Hook: * useVoiceGeneration - 语音生成和校验逻辑 * useDigitalHumanGeneration - 数字人视频生成逻辑 * useIdentifyFaceController - 协调两个子 Hook 的控制器 - 新增 types/identify-face.ts 完整类型定义 - 重构 IdentifyFace.vue 使用 hooks 架构: * 视图层与业务逻辑分离 * 状态管理清晰化 * 模块解耦,逻辑清晰 - 遵循单一职责原则,每个 Hook 只负责一个领域 - 提升代码可测试性和可维护性 - 支持两种视频素材来源:素材库选择和直接上传 - 实现语音生成优先校验的业务规则 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
78 lines
2.0 KiB
JavaScript
78 lines
2.0 KiB
JavaScript
import request from '@/api/http'
|
|
import { fetchEventSource } from '@microsoft/fetch-event-source'
|
|
// 直接使用 tokenManager 实例(最简单、最可靠)
|
|
import tokenManager from '@gold/utils/token-manager'
|
|
// 使用公共配置
|
|
import { API_BASE } from '@gold/config/api'
|
|
|
|
// C 端使用 APP_AI
|
|
const SERVER_BASE_AI = API_BASE.APP_AI
|
|
|
|
|
|
|
|
// AI chat 聊天
|
|
export const ChatMessageApi = {
|
|
// 创建【我的】聊天对话
|
|
createChatConversationMy: async (data) => {
|
|
return await request.post(`${SERVER_BASE_AI}/chat/conversation/create-my`, data)
|
|
},
|
|
|
|
|
|
|
|
// 发送 Stream 消息(对象入参,便于维护)
|
|
// 为什么不用 axios 呢?因为它不支持 SSE 调用
|
|
sendChatMessageStream: async (options) => {
|
|
const {
|
|
conversationId,
|
|
content,
|
|
ctrl,
|
|
enableContext = true,
|
|
enableWebSearch = false,
|
|
onMessage,
|
|
onError,
|
|
onClose,
|
|
attachmentUrls = []
|
|
} = options || {}
|
|
const token = tokenManager.getAccessToken()
|
|
|
|
let retryCount = 0
|
|
const maxRetries = 0 // 禁用自动重试
|
|
|
|
return fetchEventSource(`${SERVER_BASE_AI}/chat/message/send-stream`, {
|
|
method: 'post',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
Authorization: `Bearer ${token}`,
|
|
'tenant-id': import.meta.env?.VITE_TENANT_ID
|
|
},
|
|
openWhenHidden: true,
|
|
body: JSON.stringify({
|
|
conversationId,
|
|
content,
|
|
useContext: enableContext,
|
|
useSearch: enableWebSearch,
|
|
attachmentUrls: attachmentUrls || []
|
|
}),
|
|
onmessage: onMessage,
|
|
onerror: (err) => {
|
|
retryCount++
|
|
|
|
if (typeof onError === 'function') {
|
|
onError(err)
|
|
}
|
|
|
|
if (retryCount > maxRetries) {
|
|
throw err
|
|
}
|
|
},
|
|
onclose: () => {
|
|
// 调用自定义关闭处理
|
|
if (typeof onClose === 'function') {
|
|
onClose()
|
|
}
|
|
},
|
|
signal: ctrl ? ctrl.signal : undefined
|
|
})
|
|
},
|
|
}
|