| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- /**
- * SSE 流式接收工具(支持多事件类型)
- * 适用于 uni-app 微信小程序
- *
- * 事件类型:
- * intent — 意图分类
- * status — 思考状态
- * content — 回答内容(默认)
- * meta — 元数据(来源、conversation_id)
- */
- export function createSSE(url, data, options = {}) {
- const {
- headers = {},
- onMessage = () => {},
- onDone = () => {},
- onError = () => {},
- onIntent = () => {},
- onStatus = () => {},
- onMeta = () => {}
- } = options
- let buffer = ''
- let aborted = false
- let currentEvent = ''
- const defaultHeaders = {
- 'Content-Type': 'application/json',
- 'Accept': 'text/event-stream',
- }
- const token = uni.getStorageSync('access_token')
- if (token) {
- defaultHeaders['Authorization'] = 'Bearer ' + token
- }
- const task = uni.request({
- url,
- method: 'POST',
- data,
- header: { ...defaultHeaders, ...headers },
- enableChunked: true,
- responseType: 'text',
- success: () => { if (!aborted) onDone() },
- fail: (err) => { if (!aborted) onError(err) }
- })
- task.onChunkReceived((res) => {
- if (aborted) return
- try {
- const chunk = typeof res.data === 'string'
- ? res.data
- : new TextDecoder('utf-8').decode(res.data)
- buffer += chunk
- const lines = buffer.split('\n')
- buffer = lines.pop() || ''
- for (const line of lines) {
- if (line.startsWith('event: ')) {
- currentEvent = line.slice(7).trim()
- continue
- }
- if (!line.startsWith('data: ')) continue
- const d = line.slice(6)
- if (d === '[DONE]') { onDone(); return }
- if (currentEvent === 'intent') {
- onIntent(d)
- } else if (currentEvent === 'status') {
- onStatus(d)
- } else if (currentEvent === 'meta') {
- try { onMeta(JSON.parse(d)) } catch(e) {}
- } else {
- // content 或默认
- onMessage(d)
- }
- currentEvent = ''
- }
- } catch (e) {
- console.error('[SSE] Parse error:', e)
- }
- })
- return {
- abort: () => {
- aborted = true
- task.abort()
- }
- }
- }
- export default { createSSE }
|