chat.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import { ElNotification } from 'element-plus'
  2. export const chatMessage = (params, funcs) => {
  3. fetch(
  4. `${(import.meta as any).env.VITE_WORKFLOW_API_PROXY}/app/chat-messages`,
  5. {
  6. method: 'POST',
  7. body: JSON.stringify(params),
  8. headers: {
  9. Authorization: localStorage.getItem(
  10. (import.meta as any).env.VITE_TOKEN,
  11. ),
  12. 'Content-Type': 'application/json',
  13. } as any,
  14. },
  15. ).then((res) => {
  16. handleStream({ response: res, ...funcs })
  17. })
  18. }
  19. const handleStream = ({
  20. response,
  21. onData,
  22. onMessageEnd,
  23. onStart,
  24. onEnd,
  25. onError,
  26. }) => {
  27. if (!response.ok) {
  28. onError?.(`${response.status}:${response.statusText}`, response)
  29. throw new Error('Network response was not ok')
  30. }
  31. const reader = response.body?.getReader()
  32. const decoder = new TextDecoder('utf-8')
  33. let buffer = ''
  34. let bufferObj: any = {}
  35. const dataFlag = 'data:'
  36. const read = () => {
  37. let hasError = false
  38. reader?.read().then((result: any) => {
  39. if (result.done) {
  40. onEnd?.()
  41. return
  42. }
  43. buffer += decoder.decode(result.value, { stream: true })
  44. const lines = buffer.split('\n')
  45. try {
  46. lines.forEach((message) => {
  47. if (message.startsWith(dataFlag)) {
  48. try {
  49. bufferObj = JSON.parse(message.substring(dataFlag.length))
  50. } catch (e) {
  51. return
  52. }
  53. const { event } = bufferObj
  54. if (event === 'chat_start') {
  55. onStart?.(bufferObj)
  56. } else if (event === 'message') {
  57. onData(unicodeToChar(bufferObj.answer), bufferObj)
  58. } else if (event === 'message_end') {
  59. onMessageEnd(bufferObj)
  60. } else if (event === 'error') {
  61. ElNotification({
  62. title: bufferObj.error_type,
  63. message: bufferObj.error_message,
  64. type: 'error',
  65. duration: 0,
  66. })
  67. onError?.(bufferObj.message, bufferObj)
  68. } else {
  69. console.error(bufferObj)
  70. }
  71. }
  72. })
  73. buffer = lines[lines.length - 1]
  74. } catch (e) {
  75. hasError = true
  76. return
  77. }
  78. if (!hasError) read()
  79. })
  80. }
  81. read()
  82. }
  83. const unicodeToChar = (text: string) => {
  84. if (!text) return ''
  85. return text.replace(/\\u[0-9a-f]{4}/g, (_match, p1) => {
  86. return String.fromCharCode(parseInt(p1, 16))
  87. })
  88. }
  89. // //判断当前浏览器是否支持SSE
  90. // let source = ''
  91. // if (!!window.EventSource) {
  92. // source = new EventSource('http://localhost:8088/sse/')
  93. // } else {
  94. // thrownewError('当前浏览器不支持SSE')
  95. // }
  96. //
  97. // //对于建立链接的监听
  98. // source.onopen = function (event) {
  99. // console.log(source.readyState)
  100. // console.log('长连接打开')
  101. // }
  102. //
  103. // //对服务端消息的监听
  104. // source.onmessage = function (event) {
  105. // console.log(JSON.parse(event.data))
  106. // console.log('收到长连接信息')
  107. // let li = createLi(JSON.parse(event.data))
  108. // document.getElementById('ul').appendChild(li)
  109. // }
  110. //
  111. // //对断开链接的监听
  112. // source.onerror = function (event) {
  113. // console.log(source.readyState)
  114. // console.log('长连接中断')
  115. // }