Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

hooks.ts 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. import { useFetchMindMap, useFetchRelatedQuestions } from '@/hooks/chat-hooks';
  2. import { useTestChunkRetrieval } from '@/hooks/knowledge-hooks';
  3. import {
  4. useGetPaginationWithRouter,
  5. useSendMessageWithSse,
  6. } from '@/hooks/logic-hooks';
  7. import { IAnswer } from '@/interfaces/database/chat';
  8. import api from '@/utils/api';
  9. import { get, isEmpty, trim } from 'lodash';
  10. import { ChangeEventHandler, useCallback, useEffect, useState } from 'react';
  11. export const useSendQuestion = (kbIds: string[]) => {
  12. const { send, answer, done } = useSendMessageWithSse(api.ask);
  13. const { testChunk, loading } = useTestChunkRetrieval();
  14. const [sendingLoading, setSendingLoading] = useState(false);
  15. const [currentAnswer, setCurrentAnswer] = useState({} as IAnswer);
  16. const { fetchRelatedQuestions, data: relatedQuestions } =
  17. useFetchRelatedQuestions();
  18. const {
  19. fetchMindMap,
  20. data: mindMap,
  21. loading: mindMapLoading,
  22. } = useFetchMindMap();
  23. const [searchStr, setSearchStr] = useState<string>('');
  24. const [isFirstRender, setIsFirstRender] = useState(true);
  25. const [selectedDocumentIds, setSelectedDocumentIds] = useState<string[]>([]);
  26. const { pagination } = useGetPaginationWithRouter();
  27. const sendQuestion = useCallback(
  28. (question: string) => {
  29. const q = trim(question);
  30. if (isEmpty(q)) return;
  31. setIsFirstRender(false);
  32. setCurrentAnswer({} as IAnswer);
  33. setSendingLoading(true);
  34. send({ kb_ids: kbIds, question: q });
  35. testChunk({ kb_id: kbIds, highlight: true, question: q });
  36. fetchMindMap({
  37. question: q,
  38. kb_ids: kbIds,
  39. });
  40. fetchRelatedQuestions(q);
  41. },
  42. [send, testChunk, kbIds, fetchRelatedQuestions, fetchMindMap],
  43. );
  44. const handleSearchStrChange: ChangeEventHandler<HTMLInputElement> =
  45. useCallback((e) => {
  46. setSearchStr(e.target.value);
  47. }, []);
  48. const handleClickRelatedQuestion = useCallback(
  49. (question: string) => () => {
  50. if (sendingLoading) return;
  51. setSearchStr(question);
  52. sendQuestion(question);
  53. },
  54. [sendQuestion, sendingLoading],
  55. );
  56. const handleTestChunk = useCallback(
  57. (documentIds: string[], page: number = 1, size: number = 10) => {
  58. const q = trim(searchStr);
  59. if (sendingLoading || isEmpty(q)) return;
  60. testChunk({
  61. kb_id: kbIds,
  62. highlight: true,
  63. question: q,
  64. doc_ids: documentIds ?? selectedDocumentIds,
  65. page,
  66. size,
  67. });
  68. },
  69. [sendingLoading, searchStr, kbIds, testChunk, selectedDocumentIds],
  70. );
  71. useEffect(() => {
  72. if (!isEmpty(answer)) {
  73. setCurrentAnswer(answer);
  74. }
  75. return () => {
  76. setCurrentAnswer({} as IAnswer);
  77. };
  78. }, [answer]);
  79. useEffect(() => {
  80. if (done) {
  81. setSendingLoading(false);
  82. }
  83. }, [done]);
  84. return {
  85. sendQuestion,
  86. handleSearchStrChange,
  87. handleClickRelatedQuestion,
  88. handleTestChunk,
  89. setSelectedDocumentIds,
  90. loading,
  91. sendingLoading,
  92. answer: currentAnswer,
  93. relatedQuestions: relatedQuestions?.slice(0, 5) ?? [],
  94. mindMap,
  95. mindMapLoading,
  96. searchStr,
  97. isFirstRender,
  98. selectedDocumentIds,
  99. };
  100. };
  101. export const useFetchBackgroundImage = () => {
  102. const [imgUrl, setImgUrl] = useState<string>('');
  103. const fetchImage = useCallback(async () => {
  104. try {
  105. const res = await fetch(
  106. '/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=zh-CN',
  107. );
  108. const ret = await res.json();
  109. const url = get(ret, 'images.0.url');
  110. if (url) {
  111. setImgUrl(url);
  112. }
  113. } catch (error) {
  114. console.log('🚀 ~ fetchImage ~ error:', error);
  115. }
  116. }, []);
  117. useEffect(() => {
  118. fetchImage();
  119. }, [fetchImage]);
  120. return `https://cn.bing.com${imgUrl}`;
  121. };
  122. export const useTestRetrieval = (
  123. kbIds: string[],
  124. searchStr: string,
  125. sendingLoading: boolean,
  126. ) => {
  127. const { testChunk, loading } = useTestChunkRetrieval();
  128. const { pagination } = useGetPaginationWithRouter();
  129. const [selectedDocumentIds, setSelectedDocumentIds] = useState<string[]>([]);
  130. const handleTestChunk = useCallback(() => {
  131. const q = trim(searchStr);
  132. if (sendingLoading || isEmpty(q)) return;
  133. testChunk({
  134. kb_id: kbIds,
  135. highlight: true,
  136. question: q,
  137. doc_ids: Array.isArray(selectedDocumentIds) ? selectedDocumentIds : [],
  138. page: pagination.current,
  139. size: pagination.pageSize,
  140. });
  141. }, [
  142. sendingLoading,
  143. searchStr,
  144. kbIds,
  145. testChunk,
  146. selectedDocumentIds,
  147. pagination,
  148. ]);
  149. useEffect(() => {
  150. handleTestChunk();
  151. }, [handleTestChunk]);
  152. return {
  153. loading,
  154. selectedDocumentIds,
  155. setSelectedDocumentIds,
  156. };
  157. };