完成AI续写、优化、问答功能

This commit is contained in:
宇阳
2024-09-26 21:15:00 +08:00
parent e612fbb0ff
commit 3b383845e5
5 changed files with 91 additions and 18 deletions

3
src/api/Ai.ts Normal file
View File

@@ -0,0 +1,3 @@
import Request from '@/utils/request'
// export

View File

@@ -208,7 +208,7 @@ const VditorEditor = ({ value, getValue }: VditorProps) => {
// 监听 value 变化并更新编辑器内容 // 监听 value 变化并更新编辑器内容
useEffect(() => { useEffect(() => {
if (vd && value) { if (vd && value !== undefined && value !== vd.getValue()) {
vd.setValue(value); vd.setValue(value);
} }
}, [value, vd]); }, [value, vd]);

View File

@@ -10,21 +10,6 @@ import { Article } from '@/types/app/article';
import { getArticleDataAPI } from '@/api/Article' import { getArticleDataAPI } from '@/api/Article'
import { useSearchParams } from 'react-router-dom'; import { useSearchParams } from 'react-router-dom';
const items: MenuProps['items'] = [
{
key: '1',
label: 'AI 续写',
},
{
key: '2',
label: 'AI 优化',
},
{
key: '3',
label: 'AI 生成',
},
];
const CreatePage = () => { const CreatePage = () => {
const [params] = useSearchParams() const [params] = useSearchParams()
const id = +params.get('id')! const id = +params.get('id')!
@@ -58,6 +43,83 @@ const CreatePage = () => {
setData({ ...data, content }) setData({ ...data, content })
}, [content]) }, [content])
// 解析接口数据
const parsingData = async (command: string) => {
const res = await fetch(`/ai/v1/chat/completions`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${import.meta.env.VITE_AI_APIPassword}`
},
body: JSON.stringify({
model: import.meta.env.VITE_AI_MODEL,
messages: [{
role: "user",
content: `${command}${content}`
}],
stream: true
})
});
const reader = res.body.getReader();
const decoder = new TextDecoder("utf-8");
let receivedText = "";
while (true) {
const { done, value } = await reader.read();
if (done) break;
receivedText += decoder.decode(value, { stream: true });
// 处理每一块数据
const lines = receivedText.split("\n");
for (let i = 0; i < lines.length - 1; i++) {
const line = lines[i].trim();
if (line.startsWith("data:")) {
const jsonString = line.substring(5).trim();
if (jsonString !== "[DONE]") {
const data = JSON.parse(jsonString);
console.log("Received chunk:", data.choices[0].delta.content);
setContent((content) => content + data.choices[0].delta.content);
// 在这里处理每一块数据
} else {
console.log("Stream finished.");
return;
}
}
}
// 保留最后一行未处理的数据
receivedText = lines[lines.length - 1];
}
}
// AI功能
const items: MenuProps['items'] = [
{
key: '1',
label: 'AI 续写',
onClick: async () => {
parsingData("帮我续写:")
},
},
{
key: '2',
label: 'AI 优化',
onClick: async () => {
parsingData("帮我优化该文章,意思不变:")
},
},
{
key: '3',
label: 'AI 生成',
onClick: async () => {
parsingData("")
},
},
];
return ( return (
<> <>
<Title value="创作" /> <Title value="创作" />

3
src/types/env.d.ts vendored
View File

@@ -4,6 +4,9 @@ interface ImportMetaEnv {
readonly VITE_BAIDU_TONGJI_SITE_ID: string; readonly VITE_BAIDU_TONGJI_SITE_ID: string;
readonly VITE_BAIDU_TONGJI_ACCESS_TOKEN: string; readonly VITE_BAIDU_TONGJI_ACCESS_TOKEN: string;
readonly VITE_BAIDU_TONGJI_REFRESH_TOKEN: string; readonly VITE_BAIDU_TONGJI_REFRESH_TOKEN: string;
readonly VITE_AI_APIPassword: string;
readonly VITE_AI_MODEL: string;
} }
interface ImportMeta { interface ImportMeta {

View File

@@ -24,15 +24,20 @@ export default defineConfig({
server: { server: {
proxy: { proxy: {
'/api': { '/api': {
target: 'https://openapi.baidu.com/', // 你的后端服务器地址 target: 'https://openapi.baidu.com/',
changeOrigin: true, changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''), rewrite: (path) => path.replace(/^\/api/, ''),
}, },
'/qiniu': { '/qiniu': {
target: 'https://rsf.qiniuapi.com/', // 你的后端服务器地址 target: 'https://rsf.qiniuapi.com/',
changeOrigin: true, changeOrigin: true,
rewrite: (path) => path.replace(/^\/qiniu/, ''), rewrite: (path) => path.replace(/^\/qiniu/, ''),
}, },
'/ai': {
target: 'https://spark-api-open.xf-yun.com/',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/ai/, ''),
},
}, },
}, },
}) })