提交 9ee0bb8c authored 作者: 王鹏飞's avatar 王鹏飞

chore: update

上级 5aa3bc6d
import React, { useState, useEffect, useCallback } from 'react';
import { SendOutlined } from '@ant-design/icons';
import { Input, Space, Button, message } from 'antd';
import md5 from 'js-md5';
import dayjs from 'dayjs';
import { sleep } from '@/utils/common';
import React, { useState, useEffect, useCallback } from 'react'
import { SendOutlined } from '@ant-design/icons'
import { Input, Space, Button, message } from 'antd'
import md5 from 'js-md5'
import dayjs from 'dayjs'
import { sleep } from '@/utils/common'
import './index.less';
import { useSelector, useDispatch } from 'react-redux';
import { setEditorAi } from '@/store/modules/editor';
import normalAvatar from '@/assets/images/icon-normal-avatar.png';
import './index.less'
import { useSelector, useDispatch } from 'react-redux'
import { setEditorAi } from '@/store/modules/editor'
import normalAvatar from '@/assets/images/icon-normal-avatar.png'
const UUID = 'f3846153ba784b6d86bdcd5533259c88';
const auth_key = 'f3846153ba784b6d86bdcd5533259c88';
const auth_secret = 'HO4IyLEwEOHpeOXBxaLQUOqWslJRGs1M';
const UUID = 'f3846153ba784b6d86bdcd5533259c88'
const auth_key = 'f3846153ba784b6d86bdcd5533259c88'
const auth_secret = 'HO4IyLEwEOHpeOXBxaLQUOqWslJRGs1M'
const AIDrawerComponent = (props) => {
const { selectText } = props;
const dispatch = useDispatch();
const { userInfo } = useSelector((state) => state.user); // 用户状态信息
const { editorAi } = useSelector((state) => state.editor); // ai信息设置
const AIDrawerComponent = props => {
const { selectText } = props
const dispatch = useDispatch()
const { userInfo } = useSelector(state => state.user) // 用户状态信息
const { editorAi } = useSelector(state => state.editor) // ai信息设置
const [value, setValue] = useState(selectText); // 输入值
const [loading, setLoading] = useState(false); // loading
const [chatId, setChatId] = useState(null); // 对话的id
const [chatContentList, setChatContentList] = useState([]); // 对话数据
const element = document.querySelector('#chat-content');
let str = '';
const [value, setValue] = useState(selectText) // 输入值
const [loading, setLoading] = useState(false) // loading
const [chatId, setChatId] = useState(null) // 对话的id
const [chatContentList, setChatContentList] = useState([]) // 对话数据
const element = document.querySelector('#chat-content')
let str = ''
useEffect(() => {
if (editorAi && Object.entries(editorAi).length > 0) {
let tempJSON = JSON.parse(JSON.stringify(chatContentList));
let conversationId = editorAi.conversationId;
const item = tempJSON.filter((item) => item.conversationId === conversationId);
let tempJSON = JSON.parse(JSON.stringify(chatContentList))
let conversationId = editorAi.conversationId
const item = tempJSON.filter(item => item.conversationId === conversationId)
if (item && item.length > 0) {
tempJSON[tempJSON.length - 1] = editorAi;
tempJSON[tempJSON.length - 1] = editorAi
} else {
tempJSON.push(editorAi);
tempJSON.push(editorAi)
}
setChatId(editorAi.chatId);
setChatContentList(tempJSON);
element.scrollTo(0, 999999);
setChatId(editorAi.chatId)
setChatContentList(tempJSON)
element.scrollTo(0, 999999)
} else {
setLoading(false);
setLoading(false)
}
}, [editorAi]);
}, [editorAi])
useEffect(() => {
if (selectText) {
targetChat();
targetChat()
}
return () => {
setValue('');
setChatContentList([]);
setChatId(null);
};
}, []);
setValue('')
setChatContentList([])
setChatId(null)
}
}, [])
let cData = [];
let buffer = '';
let cData = []
let buffer = ''
const readBuffer = (reader, decoder) => {
return reader.read().then(async ({ done, value }) => {
if (done) {
// 处理最后的缓冲数据
setLoading(false);
setValue('');
dispatch(setEditorAi({}));
str = '';
processBuffer(buffer);
return;
setLoading(false)
setValue('')
dispatch(setEditorAi({}))
str = ''
processBuffer(buffer)
return
}
await sleep(80);
buffer += decoder.decode(value, { stream: true });
await sleep(80)
buffer += decoder.decode(value, { stream: true })
// 检查缓冲区中是否有完整的消息
const messages = buffer.split('\n\n'); // 假设每个消息以换行符结束
const messages = buffer.split('\n\n') // 假设每个消息以换行符结束
messages.forEach((message, index) => {
if (index < messages.length - 1) {
processBuffer(message);
processBuffer(message)
}
});
buffer = messages[messages.length - 1]; // 更新缓冲区
readBuffer(reader, decoder);
});
};
})
buffer = messages[messages.length - 1] // 更新缓冲区
readBuffer(reader, decoder)
})
}
const processBuffer = (text) => {
let aiContent = {};
const processBuffer = text => {
let aiContent = {}
try {
const content = text.replace(/\n+/g, '').split('data:');
const content = text.replace(/\n+/g, '').split('data:')
if (content instanceof Array) {
const itemContent = JSON.parse(content[1]);
const itemContent = JSON.parse(content[1])
if (!(itemContent.finish && itemContent.finish === true)) {
str += itemContent.content;
str += itemContent.content
aiContent = {
type: 'ai',
content: str,
chatId: itemContent.chatId,
avatar: itemContent.role.avatar,
conversationId: itemContent.conversationId,
};
dispatch(setEditorAi(aiContent));
conversationId: itemContent.conversationId
}
dispatch(setEditorAi(aiContent))
}
}
} catch {}
};
}
// 提交对话
const targetChat = async () => {
if (value) {
setLoading(true);
const timestamp = Date.now();
setLoading(true)
const timestamp = Date.now()
fetch('/openapi/agent/chat/stream/v1', {
fetch('/api/tiangong/openapi/agent/chat/stream/v1', {
method: 'POST',
responseType: 'stream', // 设置响应类型为 'stream'
headers: {
......@@ -120,105 +120,96 @@ const AIDrawerComponent = (props) => {
authKey: auth_key,
timestamp: timestamp,
sign: md5(`${auth_key}${auth_secret}${timestamp}`),
stream: true, // or change to "false" 不处理流式返回内容
stream: true // or change to "false" 不处理流式返回内容
},
body: JSON.stringify({
agentId: UUID,
chatId: chatId,
userChatInput: value,
userChatInput: value
}),
mode: 'cors',
mode: 'cors'
})
.then((response) => {
.then(response => {
// response.body 是一个 ReadableStream 对象
const stream = response.body;
const stream = response.body
// 使用流式数据
const reader = stream.getReader();
const decoder = new TextDecoder(); // 用于解码二进制数据流
const reader = stream.getReader()
const decoder = new TextDecoder() // 用于解码二进制数据流
let userContent = {
type: 'user',
content: value,
time: Date.now(),
};
let tempJSON = JSON.parse(JSON.stringify(chatContentList));
tempJSON.push(userContent);
setChatContentList(tempJSON);
time: Date.now()
}
let tempJSON = JSON.parse(JSON.stringify(chatContentList))
tempJSON.push(userContent)
setChatContentList(tempJSON)
// 开始读取流数据
readBuffer(reader, decoder);
readBuffer(reader, decoder)
})
.catch((error) => {
.catch(error => {
// 处理请求错误
console.error('Request failed:', error);
});
console.error('Request failed:', error)
})
} else {
message.error('请输入对话内容!');
message.error('请输入对话内容!')
}
};
}
return (
<div className='ai-drawer-content'>
<div className='ai-chat-container'>
<div className='chat-content' id='chat-content'>
<div className='chat-content-padd'>
<div className="ai-drawer-content">
<div className="ai-chat-container">
<div className="chat-content" id="chat-content">
<div className="chat-content-padd">
{chatContentList &&
chatContentList.length > 0 &&
chatContentList.map((item, index) => {
return (
<div className={`chat-content-item`} key={index}>
{item.type === 'user' && (
<div className='time'>{dayjs(item.time).format('YYYY-MM-DD HH:mm')}</div>
)}
{item.type === 'user' && <div className="time">{dayjs(item.time).format('YYYY-MM-DD HH:mm')}</div>}
{item.type === 'ai' && (
<div className='inside'>
<div className='ai-in-content'>
<div className='img'>
<img src={item.avatar} alt='' />
<div className="inside">
<div className="ai-in-content">
<div className="img">
<img src={item.avatar} alt="" />
</div>
<div className='ask-content'>{item.content}</div>
<div className="ask-content">{item.content}</div>
</div>
</div>
)}
{item.type === 'user' && (
<div className='inside inside-user'>
<div className='user-in-content'>
<div className='ask-content'>{item.content}</div>
<div className='img'>
<img src={userInfo.pic ? userInfo.pic : normalAvatar} alt='用户头像' />
<div className="inside inside-user">
<div className="user-in-content">
<div className="ask-content">{item.content}</div>
<div className="img">
<img src={userInfo.pic ? userInfo.pic : normalAvatar} alt="用户头像" />
</div>
</div>
</div>
)}
</div>
);
)
})}
</div>
</div>
</div>
<div className='ai-chat-ask'>
<div className='text'>
<div className="ai-chat-ask">
<div className="text">
<Input.TextArea
value={value}
defaultValue={value}
allowClear
disabled={loading}
onChange={(e) => setValue(e.target.value)}
palceholder='请输入内容'
style={{ height: '80px', resize: 'none' }}
></Input.TextArea>
onChange={e => setValue(e.target.value)}
palceholder="请输入内容"
style={{ height: '80px', resize: 'none' }}></Input.TextArea>
</div>
<div className='button'>
<Button
type='primary'
icon={<SendOutlined />}
loading={loading}
size='large'
onClick={targetChat}
></Button>
<div className="button">
<Button type="primary" icon={<SendOutlined />} loading={loading} size="large" onClick={targetChat}></Button>
</div>
</div>
</div>
);
};
)
}
export default AIDrawerComponent;
export default AIDrawerComponent
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论