Flex
9 天以前 f7c82de7684f9f28eaa6725b36936d87fe4bbb3c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import * as ConfigApi from "@/api/infra/config";
import axios from 'axios'
 
interface ChatParams {
  business_code: string
  content_param: string
}
 
export class ChatApi {
  static async streamChat(params: ChatParams) {
    // 获取基础URL和API Key
    const baseUrl = await ConfigApi.getConfigKey('easegen.core.url')
    const apiKey = await ConfigApi.getConfigKey('easegen.core.key')
 
    const response = await fetch(`${baseUrl}/api/chat`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-API-Key': apiKey
      },
      body: JSON.stringify(params)
    })
 
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`)
    }
 
    if (!response.body) {
      throw new Error('Response body is null')
    }
 
    // 创建流式读取器
    const reader = response.body.getReader()
    const decoder = new TextDecoder()
    let buffer = '' // 添加缓冲区存储不完整的JSON
 
    return {
      async *iterateStream() {
        try {
          while (true) {
            const { done, value } = await reader.read()
            if (done) break
 
            // 解码二进制数据
            const chunk = decoder.decode(value, { stream: true })
            buffer += chunk
            
            // 处理返回的数据块
            const lines = buffer
              .split('data: ')
              .map(line => line.trim())
              .filter(Boolean)
 
            // 最后一行可能不完整,保存到buffer中
            buffer = lines.pop() || ''
              
            for (const line of lines) {
              if (line === '[DONE]') return
              
              try {
                const parsed = JSON.parse(line)
                yield parsed
              } catch (e) {
                console.error('Error parsing JSON:', e)
                // 不要清空buffer,因为可能是不完整的JSON
              }
            }
          }
          // 处理最后可能剩余的数据
          if (buffer) {
            const lines = buffer
              .split('data: ')
              .map(line => line.trim())
              .filter(Boolean)
              
            for (const line of lines) {
              if (line === '[DONE]') return
              
              try {
                const parsed = JSON.parse(line)
                yield parsed
              } catch (e) {
                console.error('Error parsing final buffer:', e)
              }
            }
          }
        } finally {
          reader.releaseLock()
        }
      }
    }
  }
}
 
// 使用示例:
/*
const chat = await ChatApi.streamChat({
  business_code: "BUSI_0003",
  content_param: JSON.stringify({
    ppt_title: "管理痛点",
    ppt_content: "...",
    image_url: "...",
    custom_requirements: ""
  })
})
 
for await (const chunk of chat.iterateStream()) {
  console.log(chunk)
}
*/