ChatDefault.tsx 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. import { ChatContext } from '@/app/chat-context';
  2. import { apiInterceptors, getAppList, newDialogue, recommendApps } from '@/client/api';
  3. import { getRecommendQuestions } from '@/client/api/chat';
  4. import TabContent from '@/new-components/app/TabContent';
  5. import ChatInput from '@/new-components/chat/input/ChatInput';
  6. import { STORAGE_INIT_MESSAGE_KET } from '@/utils';
  7. import { useRequest } from 'ahooks';
  8. import { ConfigProvider, Segmented, SegmentedProps } from 'antd';
  9. import { t } from 'i18next';
  10. import Image from 'next/image';
  11. import { useRouter } from 'next/router';
  12. import { useContext, useEffect, useState } from 'react';
  13. function ChatDefault() {
  14. const { setCurrentDialogInfo, model } = useContext(ChatContext);
  15. const router = useRouter();
  16. const [apps, setApps] = useState<any>({
  17. app_list: [],
  18. total_count: 0,
  19. });
  20. const [activeKey, setActiveKey] = useState('recommend');
  21. const getAppListWithParams = (params: Record<string, string>) =>
  22. apiInterceptors(
  23. getAppList({
  24. ...params,
  25. page_no: '1',
  26. page_size: '6',
  27. }),
  28. );
  29. const getHotAppList = (params: Record<string, string>) =>
  30. apiInterceptors(
  31. recommendApps({
  32. page_no: '1',
  33. page_size: '6',
  34. ...params,
  35. }),
  36. );
  37. // 获取应用列表
  38. const {
  39. run: getAppListFn,
  40. loading,
  41. refresh,
  42. } = useRequest(
  43. async (app_name?: string) => {
  44. switch (activeKey) {
  45. case 'recommend':
  46. return await getHotAppList({});
  47. case 'used':
  48. return await getAppListWithParams({
  49. is_recent_used: 'true',
  50. need_owner_info: 'true',
  51. ...(app_name && { app_name }),
  52. });
  53. default:
  54. return [];
  55. }
  56. },
  57. {
  58. manual: true,
  59. onSuccess: res => {
  60. const [_error, data] = res;
  61. if (activeKey === 'recommend') {
  62. return setApps({
  63. app_list: data,
  64. total_count: data?.length || 0,
  65. });
  66. }
  67. setApps(data || {});
  68. },
  69. debounceWait: 500,
  70. },
  71. );
  72. useEffect(() => {
  73. getAppListFn();
  74. }, [activeKey, getAppListFn]);
  75. const items: SegmentedProps['options'] = [
  76. {
  77. value: 'recommend',
  78. label: t('recommend_apps'),
  79. },
  80. {
  81. value: 'used',
  82. label: t('used_apps'),
  83. },
  84. ];
  85. // 获取推荐问题
  86. const { data: helps } = useRequest(async () => {
  87. const [, res] = await apiInterceptors(getRecommendQuestions({ is_hot_question: 'true' }));
  88. return res ?? [];
  89. });
  90. return (
  91. <ConfigProvider
  92. theme={{
  93. components: {
  94. Button: {
  95. defaultBorderColor: 'white',
  96. },
  97. Segmented: {
  98. itemSelectedBg: '#2867f5',
  99. itemSelectedColor: 'white',
  100. },
  101. },
  102. }}
  103. >
  104. <div className='px-28 py-10 h-full flex flex-col justify-between'>
  105. <div>
  106. <div className='flex justify-between'>
  107. <Segmented
  108. className='backdrop-filter h-10 backdrop-blur-lg bg-white bg-opacity-30 border border-white rounded-lg shadow p-1 dark:border-[#6f7f95] dark:bg-[#6f7f95] dark:bg-opacity-60'
  109. options={items}
  110. value={activeKey}
  111. onChange={value => {
  112. setActiveKey(value as string);
  113. }}
  114. />
  115. <span className='flex items-center text-gray-500 gap-1 dark:text-slate-300'>
  116. <span>{t('app_in_mind')}</span>
  117. <span
  118. className='flex items-center cursor-pointer'
  119. onClick={() => {
  120. router.push('/');
  121. }}
  122. >
  123. <Image
  124. key='image_explore'
  125. src={'/pictures/explore_active.png'}
  126. alt='construct_image'
  127. width={24}
  128. height={24}
  129. />
  130. <span className='text-default'>{t('explore')}</span>
  131. </span>
  132. <span>{t('Discover_more')}</span>
  133. </span>
  134. </div>
  135. <TabContent apps={apps?.app_list || []} loading={loading} refresh={refresh} type={activeKey as any} />
  136. {helps && helps.length > 0 && (
  137. <div>
  138. <h2 className='font-medium text-xl my-4'>{t('help')}</h2>
  139. <div className='flex justify-start gap-4'>
  140. {helps.map(help => (
  141. <span
  142. key={help.id}
  143. className='flex gap-4 items-center backdrop-filter backdrop-blur-lg cursor-pointer bg-white bg-opacity-70 border-0 rounded-lg shadow p-2 relative dark:bg-[#6f7f95] dark:bg-opacity-60'
  144. onClick={async () => {
  145. const [, res] = await apiInterceptors(newDialogue({ chat_mode: 'chat_knowledge', model }));
  146. if (res) {
  147. setCurrentDialogInfo?.({
  148. chat_scene: res.chat_mode,
  149. app_code: help.app_code,
  150. });
  151. localStorage.setItem(
  152. 'cur_dialog_info',
  153. JSON.stringify({
  154. chat_scene: res.chat_mode,
  155. app_code: help.app_code,
  156. }),
  157. );
  158. localStorage.setItem(
  159. STORAGE_INIT_MESSAGE_KET,
  160. JSON.stringify({ id: res.conv_uid, message: help.question }),
  161. );
  162. router.push(`/chat/?scene=${res.chat_mode}&id=${res?.conv_uid}`);
  163. }
  164. }}
  165. >
  166. <span>{help.question}</span>
  167. <Image key='image_explore' src={'/icons/send.png'} alt='construct_image' width={20} height={20} />
  168. </span>
  169. ))}
  170. </div>
  171. </div>
  172. )}
  173. </div>
  174. <div>
  175. <ChatInput />
  176. </div>
  177. </div>
  178. </ConfigProvider>
  179. );
  180. }
  181. export default ChatDefault;