diff --git a/src/services/index.ts b/src/services/index.ts index 354aa78a..541585af 100644 --- a/src/services/index.ts +++ b/src/services/index.ts @@ -1,7 +1,7 @@ import axios from './config' -const SERVER_URL = (import.meta.env.MODE === 'development') ? '/api' : 'https://server.pptist.cn' -const ASSET_URL = 'https://asset.pptist.cn' +export const SERVER_URL = (import.meta.env.MODE === 'development') ? '/api' : 'https://server.pptist.cn' +export const ASSET_URL = 'https://asset.pptist.cn' export default { getMockData(filename: string): Promise { @@ -12,8 +12,18 @@ export default { return axios.get(`${ASSET_URL}/data/${filename}.json`) }, - AIPPT_Outline(content: string, language: string) { - return axios.post(`${SERVER_URL}/tools/aippt_outline`, { content, language }) + AIPPT_Outline(content: string, language: string): Promise { + return fetch(`${SERVER_URL}/tools/aippt_outline`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + content, + language, + stream: true, + }), + }) }, AIPPT(content: string, language: string) { diff --git a/src/views/Editor/AIPPTDialog.vue b/src/views/Editor/AIPPTDialog.vue index 673a6100..83aa49ae 100644 --- a/src/views/Editor/AIPPTDialog.vue +++ b/src/views/Editor/AIPPTDialog.vue @@ -6,8 +6,8 @@ 在下方输入您的PPT主题,并适当补充信息,如行业、岗位、学科、用途等
-
{{ outline }}
-
+
{{ outline }}
+
@@ -22,6 +22,7 @@ > @@ -47,19 +48,25 @@ import Button from '@/components/Button.vue' import FullscreenSpin from '@/components/FullscreenSpin.vue' const mainStore = useMainStore() -const { getMdContent, AIPPT } = useAIPPT() +const { AIPPT } = useAIPPT() const language = ref<'zh' | 'en'>('zh') const keyword = ref('') const outline = ref('') const loading = ref(false) +const outlineCreating = ref(false) +const outlineRef = ref() const inputRef = ref>() const recommends = ref([ - '年度工作总结', '大学生职业生涯规划', '公司年会策划方案', '大数据如何改变世界', '餐饮市场调查与研究', + 'AIGC在教育领域的应用', + '5G技术如何改变我们的生活', + '社交媒体与品牌营销', + '年度工作总结与展望', + '区块链技术及其应用', ]) onMounted(() => { @@ -72,12 +79,33 @@ const createOutline = async () => { if (!keyword.value) return message.error('请先输入PPT主题') loading.value = true - - outline.value = await api.AIPPT_Outline(keyword.value, language.value).then(ret => { - return getMdContent(ret.data[0].content) - }) + outlineCreating.value = true + + const stream = await api.AIPPT_Outline(keyword.value, language.value) loading.value = false + + const reader: ReadableStreamDefaultReader = stream.body.getReader() + const decoder = new TextDecoder('utf-8') + + const readStream = () => { + reader.read().then(({ done, value }) => { + if (done) { + outlineCreating.value = false + return + } + + const chunk = decoder.decode(value, { stream: true }) + outline.value += chunk + + if (outlineRef.value) { + outlineRef.value.scrollTop = outlineRef.value.scrollHeight + 20 + } + + readStream() + }) + } + readStream() } const createPPT = async () => { @@ -152,21 +180,32 @@ const createPPT = async () => { .recommends { display: flex; flex-wrap: wrap; - margin-top: 15px; + margin-top: 10px; .recommend { font-size: 12px; background-color: #f1f1f1; border-radius: $borderRadius; - padding: 2px 4px; + padding: 3px 5px; margin-right: 5px; + margin-top: 5px; cursor: pointer; + + &:hover { + color: $themeColor; + } } } .count { font-size: 12px; color: #999; - margin-right: 5px; + margin-right: 10px; +} +.language { + font-size: 12px; + margin-right: 10px; + color: $themeColor; + cursor: pointer; } .submit { height: 20px;