useMsg.ts 6.6 KB

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