Showing
7 changed files
with
80 additions
and
197 deletions
1 | -import React, {useState, useEffect, useMemo, memo} from "react"; | |
1 | +import React, {useState, useMemo, memo, useEffect} from "react"; | |
2 | 2 | import './base.less' |
3 | 3 | import './style.less' |
4 | 4 | import ReactMarkdown from 'react-markdown' |
... | ... | @@ -18,8 +18,7 @@ import ThinkBlock from './markdown-block' |
18 | 18 | import VideoGallery from './videoGallery' |
19 | 19 | |
20 | 20 | interface MarkdownProps { |
21 | - content: any | |
22 | - customDisallowedElements?: any | |
21 | + content: string | |
23 | 22 | } |
24 | 23 | |
25 | 24 | const capitalizationLanguageNameMap: Record<string, string> = { |
... | ... | @@ -77,7 +76,7 @@ const preprocessLaTeX = (content: string) => { |
77 | 76 | |
78 | 77 | |
79 | 78 | const CodeBlock: any = memo(({ inline, className, children, ...props }: any) => { |
80 | - const [isSVG, setIsSVG] = useState(true) | |
79 | + const [isSVG, setIsSVG] = useState<boolean>() | |
81 | 80 | const match = /language-(\w+)/.exec(className || '') |
82 | 81 | const language = match?.[1] |
83 | 82 | const languageShowName = getCorrectCapitalizationLanguageName(language || '') |
... | ... | @@ -91,26 +90,33 @@ const CodeBlock: any = memo(({ inline, className, children, ...props }: any) => |
91 | 90 | return JSON.parse('{"title":{"text":"ECharts error - Wrong JSON format."}}') |
92 | 91 | }, [language, children]) |
93 | 92 | |
93 | + useEffect(() => { | |
94 | + setIsSVG(true) | |
95 | + }, []) | |
96 | + | |
94 | 97 | const renderCodeContent = useMemo(() => { |
95 | 98 | const content = String(children).replace(/\n$/, '') |
96 | 99 | if (language === 'mermaid' && isSVG) { |
97 | - return <Flowchart PrimitiveCode={content} /> | |
100 | + // return <Flowchart PrimitiveCode={content} /> | |
101 | + return '' | |
98 | 102 | } |
99 | 103 | else if (language === 'echarts') { |
100 | - return ( | |
101 | - <div style={{ minHeight: '350px', minWidth: '100%', overflowX: 'scroll' }}> | |
102 | - <ErrorBoundary> | |
103 | - <ReactEcharts option={chartData} style={{ minWidth: '700px' }} /> | |
104 | - </ErrorBoundary> | |
105 | - </div> | |
106 | - ) | |
104 | + // return ( | |
105 | + // <div style={{ minHeight: '350px', minWidth: '100%', overflowX: 'scroll' }}> | |
106 | + // <ErrorBoundary> | |
107 | + // <ReactEcharts option={chartData} style={{ minWidth: '700px' }} /> | |
108 | + // </ErrorBoundary> | |
109 | + // </div> | |
110 | + // ) | |
111 | + return '' | |
107 | 112 | } |
108 | 113 | else if (language === 'svg' && isSVG) { |
109 | - return ( | |
110 | - <ErrorBoundary> | |
111 | - <SVGRenderer content={content} /> | |
112 | - </ErrorBoundary> | |
113 | - ) | |
114 | + // return ( | |
115 | + // <ErrorBoundary> | |
116 | + // <SVGRenderer content={content} /> | |
117 | + // </ErrorBoundary> | |
118 | + // ) | |
119 | + return '' | |
114 | 120 | } |
115 | 121 | else { |
116 | 122 | return ( |
... | ... | @@ -166,7 +172,8 @@ const AudioBlock: any = memo(({ node }: any) => { |
166 | 172 | const srcs = node.children.filter((child: any) => 'properties' in child).map((child: any) => (child as any).properties.src) |
167 | 173 | if (srcs.length === 0) |
168 | 174 | return null |
169 | - return <AudioGallery key={srcs.join()} srcs={srcs} /> | |
175 | + // return <AudioGallery key={srcs.join()} srcs={srcs} /> | |
176 | + return '' | |
170 | 177 | }) |
171 | 178 | AudioBlock.displayName = 'AudioBlock' |
172 | 179 | |
... | ... | @@ -179,28 +186,26 @@ ScriptBlock.displayName = 'ScriptBlock' |
179 | 186 | const Paragraph = (paragraph: any) => { |
180 | 187 | const children_node = paragraph?.node?.children |
181 | 188 | if (children_node && children_node?.[0] && 'tagName' in children_node?.[0] && children_node?.[0]?.tagName === 'img') { |
182 | - return ( | |
183 | - <> | |
184 | - <ImageGallery srcs={[children_node?.[0].properties?.src]} /> | |
185 | - { | |
186 | - Array.isArray(paragraph?.children) ? <p>{paragraph?.children?.slice(1)}</p> : null | |
187 | - } | |
188 | - </> | |
189 | - ) | |
189 | + // return ( | |
190 | + // <> | |
191 | + // <ImageGallery srcs={[children_node?.[0].properties?.src]} /> | |
192 | + // { | |
193 | + // Array.isArray(paragraph?.children) ? <p>{paragraph?.children?.slice(1)}</p> : null | |
194 | + // } | |
195 | + // </> | |
196 | + // ) | |
197 | + return '' | |
190 | 198 | } |
191 | 199 | return <p>{paragraph?.children}</p> |
192 | 200 | } |
193 | 201 | |
194 | 202 | const Img = ({ src }: any) => { |
195 | - return (<ImageGallery srcs={[src]} />) | |
203 | + return (<img src={src} />) | |
196 | 204 | } |
197 | 205 | |
198 | 206 | const Link = ({ node, ...props }: any) => { |
199 | 207 | if (node.properties?.href && node.properties.href?.toString().startsWith('abbr')) { |
200 | - // eslint-disable-next-line react-hooks/rules-of-hooks | |
201 | - // const { onSend } = useChatContext() | |
202 | - const hidden_text = decodeURIComponent(node.properties.href.toString().split('abbr:')[1]) | |
203 | - | |
208 | + // const hidden_text = decodeURIComponent(node.properties.href.toString().split('abbr:')[1]) | |
204 | 209 | return <abbr className="cursor-pointer underline !decoration-primary-700 decoration-dashed" title={node.children[0]?.value}>{node.children[0]?.value}</abbr> |
205 | 210 | } |
206 | 211 | else { |
... | ... | @@ -208,7 +213,9 @@ const Link = ({ node, ...props }: any) => { |
208 | 213 | } |
209 | 214 | } |
210 | 215 | |
211 | -const Markdown: React.FC = (props: MarkdownProps) => { | |
216 | + | |
217 | + | |
218 | +const Markdown: React.FC<MarkdownProps> = (props) => { | |
212 | 219 | |
213 | 220 | const latexContent = flow([ |
214 | 221 | preprocessThinkTag, |
... | ... | @@ -245,7 +252,7 @@ const Markdown: React.FC = (props: MarkdownProps) => { |
245 | 252 | } |
246 | 253 | }, |
247 | 254 | ]} |
248 | - disallowedElements={['iframe', 'head', 'html', 'meta', 'link', 'style', 'body', ...(props?.customDisallowedElements || [])]} | |
255 | + disallowedElements={['iframe', 'head', 'html', 'meta', 'link', 'style', 'body']} | |
249 | 256 | components={{ |
250 | 257 | code: CodeBlock, |
251 | 258 | img: Img, | ... | ... |
1 | +// @ts-ignore | |
1 | 2 | import React, { useEffect, useState } from 'react' |
2 | 3 | import './base.less' |
3 | 4 | import './style.less' |
... | ... | @@ -5,7 +6,6 @@ import { |
5 | 6 | Button, |
6 | 7 | Input, |
7 | 8 | DatePicker, |
8 | - TimePicker, | |
9 | 9 | Checkbox, |
10 | 10 | Select |
11 | 11 | } from 'antd'; |
... | ... | @@ -95,39 +95,12 @@ const MarkdownForm = ({ node }: any) => { |
95 | 95 | <DatePicker |
96 | 96 | key={index} |
97 | 97 | value={formValues[child.properties.name]} |
98 | - needTimePicker={child.properties.type === SUPPORTED_TYPES.DATETIME} | |
99 | 98 | onChange={(date) => { |
100 | 99 | setFormValues(prevValues => ({ |
101 | 100 | ...prevValues, |
102 | 101 | [child.properties.name]: date, |
103 | 102 | })) |
104 | 103 | }} |
105 | - onClear={() => { | |
106 | - setFormValues(prevValues => ({ | |
107 | - ...prevValues, | |
108 | - [child.properties.name]: undefined, | |
109 | - })) | |
110 | - }} | |
111 | - /> | |
112 | - ) | |
113 | - } | |
114 | - if (child.properties.type === SUPPORTED_TYPES.TIME) { | |
115 | - return ( | |
116 | - <TimePicker | |
117 | - key={index} | |
118 | - value={formValues[child.properties.name]} | |
119 | - onChange={(time) => { | |
120 | - setFormValues(prevValues => ({ | |
121 | - ...prevValues, | |
122 | - [child.properties.name]: time, | |
123 | - })) | |
124 | - }} | |
125 | - onClear={() => { | |
126 | - setFormValues(prevValues => ({ | |
127 | - ...prevValues, | |
128 | - [child.properties.name]: undefined, | |
129 | - })) | |
130 | - }} | |
131 | 104 | /> |
132 | 105 | ) |
133 | 106 | } |
... | ... | @@ -137,7 +110,7 @@ const MarkdownForm = ({ node }: any) => { |
137 | 110 | <Checkbox |
138 | 111 | key={index} |
139 | 112 | checked={formValues[child.properties.name]} |
140 | - onCheck={() => { | |
113 | + onChange={() => { | |
141 | 114 | setFormValues(prevValues => ({ |
142 | 115 | ...prevValues, |
143 | 116 | [child.properties.name]: !prevValues[child.properties.name], |
... | ... | @@ -152,24 +125,23 @@ const MarkdownForm = ({ node }: any) => { |
152 | 125 | return ( |
153 | 126 | <Select |
154 | 127 | key={index} |
155 | - allowSearch={false} | |
156 | 128 | className="w-full" |
157 | - items={(() => { | |
158 | - let options = child.properties.dataOptions || child.properties['data-options'] || [] | |
159 | - if (typeof options === 'string') { | |
160 | - try { | |
161 | - options = JSON.parse(options) | |
162 | - } | |
163 | - catch (e) { | |
164 | - console.error('Failed to parse options:', e) | |
165 | - options = [] | |
166 | - } | |
167 | - } | |
168 | - return options.map((option: string) => ({ | |
169 | - name: option, | |
170 | - value: option, | |
171 | - })) | |
172 | - })()} | |
129 | + // items={(() => { | |
130 | + // let options = child.properties.dataOptions || child.properties['data-options'] || [] | |
131 | + // if (typeof options === 'string') { | |
132 | + // try { | |
133 | + // options = JSON.parse(options) | |
134 | + // } | |
135 | + // catch (e) { | |
136 | + // console.error('Failed to parse options:', e) | |
137 | + // options = [] | |
138 | + // } | |
139 | + // } | |
140 | + // return options.map((option: string) => ({ | |
141 | + // name: option, | |
142 | + // value: option, | |
143 | + // })) | |
144 | + // })()} | |
173 | 145 | defaultValue={formValues[child.properties.name]} |
174 | 146 | onSelect={(item) => { |
175 | 147 | setFormValues(prevValues => ({ | ... | ... |
... | ... | @@ -61,7 +61,7 @@ const DeepSeekIndex: React.FC = () => { |
61 | 61 | const [disabled, setDisabled] = useState<boolean>(false); |
62 | 62 | const [exampleFlag, setExampleFlag] = useState<string>('1') |
63 | 63 | |
64 | - const [chatHistory, setChatHistory] = useState<any[]>([]); | |
64 | + const [chatHistory, setChatHistory] = useState<{role: string, answer: string, info?: any[]}[]>([]); | |
65 | 65 | const [currentResponse, setCurrentResponse] = useState<string>(''); |
66 | 66 | |
67 | 67 | const chatRef = useRef(null); |
... | ... | @@ -72,7 +72,8 @@ const DeepSeekIndex: React.FC = () => { |
72 | 72 | {role: 'time', answer: _time}, |
73 | 73 | { |
74 | 74 | role: 'example', |
75 | - answer: example_1 | |
75 | + answer: '', | |
76 | + info: example_1 | |
76 | 77 | } |
77 | 78 | ]; |
78 | 79 | console.log('newHistory', newHistory) |
... | ... | @@ -85,7 +86,7 @@ const DeepSeekIndex: React.FC = () => { |
85 | 86 | const _chatHistory = _.cloneDeep(chatHistory); |
86 | 87 | _chatHistory?.forEach((item: any) => { |
87 | 88 | if (item?.role === 'example') { |
88 | - item.answer = _example | |
89 | + item.info = _example | |
89 | 90 | } |
90 | 91 | }) |
91 | 92 | setChatHistory(_chatHistory); |
... | ... | @@ -133,17 +134,17 @@ const DeepSeekIndex: React.FC = () => { |
133 | 134 | throw new Error(`HTTP error! status: ${response.status}`); |
134 | 135 | } |
135 | 136 | |
136 | - const reader = response.body.getReader(); | |
137 | + const reader: any = response?.body?.getReader(); | |
137 | 138 | const decoder = new TextDecoder(); |
138 | - let buffer = ''; | |
139 | + let buffer: string = ''; | |
139 | 140 | |
140 | 141 | while (true) { |
141 | - const {done, value} = await reader.read(); | |
142 | + const {done, value} = await reader?.read(); | |
142 | 143 | if (done) break; |
143 | 144 | buffer += decoder?.decode(value, {stream: true}); |
144 | - const lines = buffer?.split('\n'); | |
145 | - buffer = lines.pop(); | |
146 | - lines.forEach(line => { | |
145 | + const lines: any[] = buffer?.split('\n'); | |
146 | + buffer = lines?.pop(); | |
147 | + lines?.forEach(line => { | |
147 | 148 | if (line.startsWith('data:')) { |
148 | 149 | const data = JSON.parse(line?.slice(5)?.trim()); |
149 | 150 | setCurrentResponse(prev => prev + (data?.answer || '')); |
... | ... | @@ -168,6 +169,7 @@ const DeepSeekIndex: React.FC = () => { |
168 | 169 | // 让会话一直展示最新 |
169 | 170 | useEffect(() => { |
170 | 171 | if (chatRef.current) { |
172 | + // @ts-ignore | |
171 | 173 | chatRef.current.scrollTop = chatRef.current.scrollHeight; |
172 | 174 | } |
173 | 175 | }, [currentResponse]); |
... | ... | @@ -177,7 +179,7 @@ const DeepSeekIndex: React.FC = () => { |
177 | 179 | console.log('chatHistory', chatHistory) |
178 | 180 | }, [chatHistory]) |
179 | 181 | |
180 | - const handleKeyDown = (e) => { | |
182 | + const handleKeyDown = (e: any) => { | |
181 | 183 | if (e.key === 'Enter' && !e.shiftKey) { |
182 | 184 | e.preventDefault(); // 阻止默认换行 |
183 | 185 | send(); |
... | ... | @@ -205,7 +207,7 @@ const DeepSeekIndex: React.FC = () => { |
205 | 207 | <img src={refresh} className={'refresh'} alt="" onClick={refreshFun}/> |
206 | 208 | </div> |
207 | 209 | { |
208 | - msg?.answer?.map((item:any) => { | |
210 | + msg?.info?.map((item:any) => { | |
209 | 211 | return <div |
210 | 212 | className={'omit1 current-example_title'} |
211 | 213 | key={item?.id} |
... | ... | @@ -215,16 +217,16 @@ const DeepSeekIndex: React.FC = () => { |
215 | 217 | } |
216 | 218 | </div> : |
217 | 219 | msg.role === 'user' ? <p className={'current-ask'}>{msg?.answer}</p> : |
218 | - <Markdown content={msg?.answer}/> | |
220 | + <Markdown content={msg?.answer || ''}/> | |
219 | 221 | } |
220 | 222 | |
221 | 223 | </div> |
222 | 224 | ))} |
223 | - {currentResponse && ( | |
225 | + {currentResponse ? ( | |
224 | 226 | <div className="content-left"> |
225 | - <Markdown content={currentResponse}/> | |
227 | + <Markdown content={currentResponse || ''}/> | |
226 | 228 | </div> |
227 | - )} | |
229 | + ) : ''} | |
228 | 230 | </div> |
229 | 231 | <div className={'deep-seek_footer'}> |
230 | 232 | <Input |
... | ... | @@ -235,7 +237,7 @@ const DeepSeekIndex: React.FC = () => { |
235 | 237 | onChange={(val: string) => setSearchValue(val)} |
236 | 238 | onKeyDown={handleKeyDown} |
237 | 239 | /> |
238 | - <Button className={`deep-seek_footer-send ${disabled ? 'disabled' : ''}`} color={'primary'} onClick={send}>发送</Button> | |
240 | + <Button className={`deep-seek_footer-send ${disabled ? 'disabled' : ''}`} color={'primary'} onClick={() =>send}>发送</Button> | |
239 | 241 | </div> |
240 | 242 | |
241 | 243 | </div> | ... | ... |
... | ... | @@ -40,7 +40,7 @@ const Test: React.FC = () => { |
40 | 40 | // 消息列表 |
41 | 41 | const { messages, appendMsg, setTyping } = useMessages(initialMessages); |
42 | 42 | // 发送回调 |
43 | - function handleSend(type, val) { | |
43 | + function handleSend(type: any, val: any) { | |
44 | 44 | if (type === 'text' && val.trim()) { |
45 | 45 | // TODO: 发送请求 |
46 | 46 | appendMsg({ |
... | ... | @@ -62,11 +62,11 @@ const Test: React.FC = () => { |
62 | 62 | } |
63 | 63 | |
64 | 64 | // 快捷短语回调,可根据 item 数据做出不同的操作,这里以发送文本消息为例 |
65 | - function handleQuickReplyClick(item) { | |
65 | + function handleQuickReplyClick(item: any) { | |
66 | 66 | handleSend('text', item.name); |
67 | 67 | } |
68 | 68 | |
69 | - function renderMessageContent(msg) { | |
69 | + function renderMessageContent(msg: any) { | |
70 | 70 | const { type, content } = msg; |
71 | 71 | |
72 | 72 | // 根据消息类型来渲染 | ... | ... |
src/utils/request.tsx
deleted
100644 → 0
1 | -import axios from 'axios'; | |
2 | -import {currentCorpCode, _baseUrl} from "@/utils/common" | |
3 | - | |
4 | -// 创建axios实例 | |
5 | -const service = axios.create({ | |
6 | - baseURL: _baseUrl, // 你可以通过.env文件设置API的基础URL | |
7 | - timeout: 5000 // 请求超时时间 | |
8 | -}); | |
9 | - | |
10 | -// 请求拦截器 | |
11 | -service.interceptors.request.use( | |
12 | - config => { | |
13 | - // 在发送请求之前做些什么,例如设置请求头 | |
14 | - // if (store.getters.token) { | |
15 | - // config.headers['X-Token'] = getToken(); | |
16 | - // } | |
17 | - console.log('config---2', config) | |
18 | - return config; | |
19 | - }, | |
20 | - error => { | |
21 | - // 对请求错误做些什么 | |
22 | - console.error('请求拦截器错误:', error); // for debug | |
23 | - Promise.reject(error); | |
24 | - } | |
25 | -); | |
26 | - | |
27 | -// 响应拦截器 | |
28 | -service.interceptors.response.use( | |
29 | - response => { | |
30 | - /** | |
31 | - * 可以在这里对响应数据做点什么 | |
32 | - */ | |
33 | - const res = response.data; | |
34 | - if (res?.success || res?.code === 200) { | |
35 | - return res.data; | |
36 | - } else { | |
37 | - // 如果后端有统一的错误码处理,可以在这里统一处理 | |
38 | - console.error('接口错误:', res.message); | |
39 | - // 你可以抛出一个错误,或者返回一个错误对象 | |
40 | - // throw new Error(res.message || 'Error'); | |
41 | - return Promise.reject(new Error(res.message || 'Error')); | |
42 | - } | |
43 | - }, | |
44 | - error => { | |
45 | - console.error('响应拦截器错误:', error); | |
46 | - // 对响应错误做点什么 | |
47 | - return Promise.reject(error); | |
48 | - } | |
49 | -); | |
50 | - | |
51 | -// 封装get请求 | |
52 | -export function get(url: string, params = {}, customHeaders?: any, notCorpCode?: boolean) { | |
53 | - | |
54 | - const _params = notCorpCode ? { | |
55 | - ...params, | |
56 | - } : { | |
57 | - corpCode: currentCorpCode(), | |
58 | - ...params, | |
59 | - } | |
60 | - return service.get(url, {params: _params, headers: customHeaders}) | |
61 | - | |
62 | -} | |
63 | - | |
64 | -// 封装post请求 | |
65 | -export function post(url: string, params = {}, data = {}, customHeaders?: any, notCorpCode?: boolean) { | |
66 | - const _params = notCorpCode ? { | |
67 | - ...params, | |
68 | - } : { | |
69 | - corpCode: currentCorpCode(), | |
70 | - ...params, | |
71 | - } | |
72 | - return service.post(url, data, {params: _params, headers: customHeaders}) | |
73 | -} | |
\ No newline at end of file |
src/utils/util.ts
deleted
100644 → 0
1 | -import Cookie from "js-cookie"; | |
2 | -import {get} from "@/utils/request"; | |
3 | - | |
4 | -// 1.行业大脑集成页/行业大脑明细页 | |
5 | -// 1.判断缓存token | |
6 | -// 无 直接404 --empty | |
7 | -// 有 | |
8 | -// 1.调用getUserInfo接口 | |
9 | -// 失败 404 --empty | |
10 | -// 成功 | |
11 | -// 1.管理员角色才能看行业大脑 | |
12 | -// 2.其他 404 --empty | |
13 | - | |
14 | -// 处理权限相关 --- 前端 | |
15 | -export const judgePermission = async (navigate: any) => { | |
16 | - let _hasPermission = true; | |
17 | - return { | |
18 | - _hasPermission | |
19 | - } | |
20 | -} | |
21 | - | |
22 | -const toEmpty = (navigate: any) => { | |
23 | - // 去往没有权限的页面 -- 前端处理 | |
24 | - const _url = '/empty'; | |
25 | - navigate(_url, { replace: true }); | |
26 | -} | |
\ No newline at end of file |