DeekSeekHome.tsx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. import * as React from 'react';
  2. import { useNavigate } from "react-router-dom";
  3. import { Dropdown, Spin, Tooltip } from 'antd';
  4. import { Chat } from './DeepSeekChat';
  5. import whiteLogo from "../icons/whiteLogo.png";
  6. import jkxz from "../icons/jkxz.png";
  7. import { useChatStore } from "../store";
  8. import { useMobileScreen } from '../utils';
  9. import api from "@/app/api/api";
  10. import './deepSeekHome.scss';
  11. const DeekSeek: React.FC = () => {
  12. const chatStore = useChatStore();
  13. const isMobileScreen = useMobileScreen();
  14. const navigate = useNavigate();
  15. const [listLoading, setListLoading] = React.useState(false);
  16. type List = {
  17. title: string,
  18. children: {
  19. title: string,
  20. showMenu: string,
  21. chatMode: string,
  22. appId: string,
  23. children?: List[number]['children'],
  24. }[],
  25. }[];
  26. const [list, setList] = React.useState<List>([
  27. {
  28. "children": [
  29. {
  30. "chatMode": "LOCAL",
  31. "showMenu": "false",
  32. "appId": "2935625422066814976",
  33. "title": "公司作业指导书(2023版)"
  34. },
  35. {
  36. "chatMode": "LOCAL",
  37. "showMenu": "false",
  38. "appId": "2935200536655695872",
  39. "title": "常用验收规范问答"
  40. },
  41. {
  42. "chatMode": "LOCAL",
  43. "showMenu": "false",
  44. "appId": "2942568790025965568",
  45. "title": "钢结构AI监理师"
  46. }
  47. ],
  48. "title": "专业知识"
  49. },
  50. {
  51. "children": [
  52. {
  53. "chatMode": "LOCAL",
  54. "showMenu": "false",
  55. "appId": "2919677614293913600",
  56. "title": "员工入职小百科"
  57. },
  58. {
  59. "chatMode": "LOCAL",
  60. "showMenu": "false",
  61. "appId": "2919668410128666624",
  62. "title": "数字系统答疑"
  63. },
  64. {
  65. "chatMode": "LOCAL",
  66. "showMenu": "false",
  67. "appId": "2945774476037853184",
  68. "title": "企业介绍"
  69. }
  70. ],
  71. "title": "职能管理"
  72. },
  73. {
  74. "children": [],
  75. "title": "项目级应用"
  76. }
  77. ]);
  78. const init = async () => {
  79. setListLoading(true);
  80. try {
  81. const res = await api.get('/deepseek/api/appType');
  82. setList(res.data);
  83. } catch (error) {
  84. console.error(error);
  85. } finally {
  86. setListLoading(false);
  87. }
  88. }
  89. React.useEffect(() => {
  90. chatStore.clearSessions();
  91. const userInfo = localStorage.getItem('userInfo');
  92. if (userInfo) {
  93. init();
  94. }
  95. }, []);
  96. const formatMenuTitle = React.useCallback(
  97. (title: string) => {
  98. if (isMobileScreen) {
  99. return title;
  100. }
  101. return title.length > 7 ? `${title.slice(0, 7)}...` : title;
  102. },
  103. [isMobileScreen]
  104. );
  105. const dropdownAlign = React.useMemo(() => {
  106. if (isMobileScreen) {
  107. return undefined;
  108. }
  109. return {
  110. points: ['tl', 'bl'],
  111. offset: [0, 8],
  112. overflow: {
  113. adjustY: false,
  114. adjustX: true,
  115. },
  116. };
  117. }, [isMobileScreen]);
  118. return (
  119. <Spin spinning={listLoading}>
  120. <div className='deekSeek'>
  121. <div className='deekSeek-header' style={{ justifyContent: isMobileScreen ? 'flex-start' : 'center' }}>
  122. <div
  123. style={{
  124. display: 'flex',
  125. alignItems: 'center',
  126. margin: '0 20px',
  127. fontSize: isMobileScreen ? undefined : 14,
  128. fontWeight: isMobileScreen ? undefined : 600,
  129. }}
  130. >
  131. <img src={whiteLogo.src} style={{ width: 20, marginRight: 10 }} />
  132. <div style={{ whiteSpace: 'nowrap' }}>
  133. 上海建科
  134. </div>
  135. </div>
  136. {
  137. list.map((item, index) => {
  138. return <Dropdown
  139. menu={{
  140. items: item.children.map((child, i) => {
  141. return {
  142. key: 'child' + i,
  143. label: <div
  144. className='deekSeek-menuds'
  145. onClick={() => {
  146. const search = `?showMenu=${child.showMenu}&chatMode=${child.chatMode}&appId=${child.appId}`;
  147. if (child.appId) {
  148. navigate({
  149. pathname: '/knowledgeChat',
  150. search: search,
  151. })
  152. }
  153. }}
  154. >
  155. <Tooltip placement="top" title={child.title}>
  156. {formatMenuTitle(child.title)}
  157. </Tooltip>
  158. </div>,
  159. children: child.children ? child.children.map((record, ind) => {
  160. return {
  161. key: 'record' + ind,
  162. label: (
  163. <Tooltip placement="bottom" title={record.title}>
  164. <div
  165. onClick={() => {
  166. const search = `?showMenu=${record.showMenu}&chatMode=${record.chatMode}&appId=${record.appId}`;
  167. if (record.appId) {
  168. navigate({
  169. pathname: '/knowledgeChat',
  170. search: search,
  171. })
  172. }
  173. }}
  174. >
  175. {formatMenuTitle(record.title)}
  176. </div>
  177. </Tooltip>
  178. )
  179. };
  180. }) : undefined,
  181. };
  182. })
  183. }}
  184. overlayClassName="deekSeek-dropdown"
  185. placement="bottomLeft"
  186. align={dropdownAlign}
  187. getPopupContainer={(triggerNode) => {
  188. if (isMobileScreen) {
  189. return document.body;
  190. }
  191. return triggerNode.parentElement || document.body;
  192. }}
  193. key={index}
  194. >
  195. <div
  196. className='deekSeek-header__item'
  197. style={{
  198. marginRight: isMobileScreen ? 12 : 20,
  199. fontSize: isMobileScreen ? undefined : 14,
  200. fontWeight: isMobileScreen ? undefined : 600,
  201. }}
  202. title={item.title}
  203. >
  204. {formatMenuTitle(item.title)}
  205. </div>
  206. </Dropdown>
  207. })
  208. }
  209. {/*<div style={{ whiteSpace: 'nowrap', marginRight: 20, color: '#98b4fa', cursor: 'pointer' }} onClick={() => {*/}
  210. {/* navigate({*/}
  211. {/* pathname: '/deepseekChat',*/}
  212. {/* })*/}
  213. {/*}}>*/}
  214. {/* DeepSeek问答*/}
  215. {/*</div>*/}
  216. {/* 右侧区域 - 开放平台按钮 */}
  217. <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'flex-end' }}>
  218. <button
  219. className='open-platform-btn'
  220. onClick={() => {
  221. // 跳转到其他平台的逻辑,这里使用window.open举例
  222. const userInfo = localStorage.getItem('userInfo');
  223. const tokenParam = userInfo ? "?token=" + JSON.parse(userInfo).token : "";
  224. window.open('https://llm.jkec.info:11431/deepseek/questionAnswer' + tokenParam, '_blank');
  225. }}
  226. >
  227. 更多
  228. </button>
  229. </div>
  230. </div>
  231. <div className='deekSeek-content'>
  232. <div className='deekSeek-content-title'>
  233. <img src={jkxz.src} />
  234. </div>
  235. <div className='deekSeek-content-title-sm' style={{ marginBottom: isMobileScreen ? 14 : 20 }}>
  236. 智能问答助手
  237. </div>
  238. <div className={isMobileScreen ? 'deekSeek-content-mobile' : 'deekSeek-content-pc'}>
  239. <Chat />
  240. </div>
  241. </div>
  242. </div>
  243. </Spin>
  244. );
  245. };
  246. export default DeekSeek;