useMsg.ts 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // 消息数组
  2. import { ref, reactive } from 'vue';
  3. import avator from '@/public/icon/32.png';
  4. import moment from 'moment'
  5. export function useMsg(scrollbar: any, type: any, xlsxData: any, fetchDataAndProcess: Function) {
  6. const inputMessage = ref('');
  7. const indexTemp = ref(0);
  8. const taklToHtml = ref<any>(false);
  9. const sendLoading = ref(false);
  10. const pageInfo = ref<any>({});
  11. const formMap = ref([]);
  12. const messages = ref([{
  13. username: '用户1',
  14. content: '你好!有什么我可以帮助你的吗?',
  15. rawContent: '你好!有什么我可以帮助你的吗?',
  16. timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
  17. isSelf: false,
  18. avatar: avator
  19. }]);
  20. // 发送消息
  21. const addMessage = (msg: any, fetch: any) => {
  22. if (!msg) return
  23. const newMessage: any = {
  24. id: messages.value.length + 1,
  25. username: '我',
  26. content: msg,
  27. timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
  28. isSelf: true,
  29. avatar: 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png',
  30. addToHistory: !taklToHtml.value
  31. }
  32. messages.value.push(newMessage)
  33. // 滚动到底部
  34. nextTick(() => {
  35. scrollbar.value?.setScrollTop(99999);
  36. fetch && sendRequese(msg, taklToHtml.value);
  37. })
  38. }
  39. const getPageInfo = () => {
  40. return new Promise((res, rej) => {
  41. chrome.runtime.sendMessage({
  42. type: 'FROM_SIDE_PANEL_TO_GET_PAGE_INFO',
  43. }, async (response) => {
  44. if (chrome.runtime.lastError) {
  45. console.error("消息发送错误:", chrome.runtime.lastError);
  46. rej(chrome.runtime.lastError)
  47. } else {
  48. pageInfo.value = response.data
  49. res(response.data)
  50. }
  51. });
  52. })
  53. }
  54. const sendRequese = async (msg: any, addHtml = false) => {
  55. const res: any = await getPageInfo()
  56. if (type.value === '2' && msg.startsWith('/')) {
  57. indexTemp.value = 0
  58. fetchRes(msg)
  59. }
  60. else {
  61. if (!addHtml) msg = getSummaryPrompt(res.content)
  62. streamRes(msg, addHtml)
  63. }
  64. }
  65. const fetchRes = async (msg: any) => {
  66. sendLoading.value = true
  67. const obj: any = reactive({
  68. id: moment(),
  69. username: '用户1',
  70. content: '',
  71. timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
  72. isSelf: false,
  73. avatar: avator,
  74. addToHistory: !taklToHtml.value
  75. })
  76. messages.value.push(obj)
  77. if (type.value === '2') {
  78. await fetchDataAndProcess(msg, obj)
  79. sendLoading.value = false
  80. }
  81. }
  82. const streamRes = async (msg: any, addHtml: any) => {
  83. sendLoading.value = true;
  84. const obj = reactive({
  85. username: '用户1',
  86. content: '',
  87. rawContent: '', // 存储原始内容
  88. timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
  89. isSelf: false,
  90. avatar: avator,
  91. addToHistory: !taklToHtml.value
  92. });
  93. let history = []
  94. if (taklToHtml.value) {
  95. if (addHtml) {
  96. history.push({
  97. role: 'user',
  98. content: `页面主要内容${pageInfo.value.content.mainContent}`
  99. })
  100. }
  101. history.push({
  102. role: 'user',
  103. content: msg
  104. })
  105. } else {
  106. history = messages.value
  107. .filter((item: any) => item.addToHistory).slice(-20)
  108. .map((item: any) => ({
  109. role: item.isSelf ? 'user' : 'system',
  110. content: item.isSelf ? item.content : item.rawContent
  111. }))
  112. }
  113. messages.value.push(obj)
  114. nextTick(() => {
  115. scrollbar.value?.setScrollTop(99999)
  116. })
  117. const iterator = await sendMessage(history, addHtml)
  118. for await (const chunk of iterator) {
  119. if (chunk) {
  120. const decodedChunk = chunk.choices[0].delta.content;
  121. if (decodedChunk) {
  122. // 保存原始内容
  123. obj.rawContent += decodedChunk
  124. // 实时格式化显示内容
  125. obj.content = formatMessage(obj.rawContent)
  126. }
  127. }
  128. scrollbar.value?.setScrollTop(99999)
  129. }
  130. scrollbar.value?.setScrollTop(99999)
  131. // 处理最终内容
  132. if (type.value === '2') {
  133. try {
  134. formMap.value = JSON.parse(obj.rawContent.split('json')[1].split('```')[0])
  135. handleInput()
  136. } catch (e) {
  137. console.error('解析JSON失败:', e)
  138. }
  139. }
  140. sendLoading.value = false
  141. nextTick(() => {
  142. scrollbar.value?.setScrollTop(99999)
  143. })
  144. }
  145. const handleInput = () => {
  146. const arr = xlsxData.value;
  147. chrome.runtime.sendMessage({
  148. type: 'FROM_SIDE_PANEL_TO_INPUT_FORM',
  149. data: {
  150. excelData: arr,
  151. formData: formMap.value
  152. }
  153. });
  154. }
  155. return {
  156. messages,
  157. inputMessage,
  158. indexTemp,
  159. taklToHtml,
  160. pageInfo,
  161. sendLoading,
  162. formMap,
  163. addMessage,
  164. sendRequese,
  165. getPageInfo,
  166. streamRes,
  167. handleInput
  168. }
  169. }