Files
happy-life-star/mini-program/src/services/scriptChat.js
T

93 lines
2.8 KiB
JavaScript

import { get, post, put, del } from './request.js'
import { getApiBaseUrl, getAuthHeader } from './request.js'
export const createScriptWithDialogue = async (payload) => {
return post('/epicScript/createWithDialogue', payload)
}
export const streamScriptChat = async ({ operationType, conversationId, messageId, userMessageId, content, scriptId, onDelta, onDone, onError }) => {
const requestTask = uni.request({
url: `${getApiBaseUrl()}/chat/stream`,
method: 'POST',
data: { operationType, conversationId, messageId, userMessageId, content, scriptId },
header: {
'Content-Type': 'application/json',
...getAuthHeader()
},
enableChunked: true,
timeout: 300000,
success: (res) => {
if (res.statusCode >= 400) {
onError?.(res.data?.message || '流式请求失败')
return
}
if (typeof res.data === 'string' && res.data) {
consumeSseText(res.data, onDelta, onDone, onError)
}
},
fail: (error) => {
onError?.(error.errMsg || '流式请求失败')
}
})
requestTask?.onChunkReceived?.((res) => {
try {
const text = decodeChunk(res.data)
consumeSseText(text, onDelta, onDone, onError)
} catch (error) {
onError?.(error.message || '流式解析失败')
}
})
}
export const listMessagesByConversation = async ({ conversationId, includeVersions = false }) => {
return get('/message/listByConversation', { conversationId, includeVersions })
}
export const listMessageVersions = async (messageId) => {
return get('/message/versions', { messageId })
}
export const switchVersion = async ({ scriptId, messageId }) => {
return put('/epicScript/switchVersion', { scriptId, messageId })
}
export const deleteVersion = async (messageId) => {
return del('/message/deleteVersion', { id: messageId })
}
function decodeChunk(chunk) {
if (typeof chunk === 'string') return chunk
const decoder = new TextDecoder('utf-8')
return decoder.decode(new Uint8Array(chunk))
}
function consumeSseText(text, onDelta, onDone, onError) {
const lines = text.split(/\r?\n/)
let eventName = ''
let dataBuffer = ''
lines.forEach((line) => {
if (line.startsWith('event:')) {
eventName = line.slice(6).trim()
} else if (line.startsWith('data:')) {
dataBuffer += line.slice(5).trim()
} else if (line === '' && dataBuffer) {
try {
if (eventName === 'delta') {
onDelta?.(dataBuffer)
} else if (eventName === 'metadata') {
onDone?.({ type: 'metadata', data: JSON.parse(dataBuffer) })
} else if (eventName === 'done') {
onDone?.({ type: 'done', data: JSON.parse(dataBuffer) })
} else if (eventName === 'error') {
onError?.(dataBuffer)
}
} catch (e) {
onError?.(e.message)
}
eventName = ''
dataBuffer = ''
}
})
}