当前位置: 首页 > wzjs >正文

公司网站图片传不上去wordpress在IE9显示错位

公司网站图片传不上去,wordpress在IE9显示错位,网页建设网站代码,网站建设战略伙伴摘要 这是本系列文章的第二篇,开始之前我们先回顾一下上一篇文章的内容: 从零实现一个GPT 【React Express】— 【1】初始化前后端项目,实现模型接入SSE 在这一篇中,我们主要创建了前端工程和后端工程,这里贴一下我…

摘要

这是本系列文章的第二篇,开始之前我们先回顾一下上一篇文章的内容:

从零实现一个GPT 【React + Express】— 【1】初始化前后端项目,实现模型接入+SSE

在这一篇中,我们主要创建了前端工程和后端工程,这里贴一下我的github地址:

https://github.com/TeacherXin/gpt-xin
https://github.com/TeacherXin/gpt-xin-server

最后我们实现了前端和后端部分的SSE内容,可以通过前端发送query,后端调用gpt模型通过流试返回内容。

而在这一篇中,我们主要把对话部分给实现出来,就是通过后端返回的内容来渲染对话流。

对话流的数据结构

首先我们来到前端项目,肯定是在components下创建一个DialogCardList组件,用来展示对话。

读者可以先在豆包上发送个对话试一下,可以看到对话区域主要是通过问答对的结构展示的。就是一问一答。

所以我们很容易就能设计出来,这个对话列表的数据结构应该是一个List,List下的每一个对象包含着,id,answer,question三个属性。

所以我们可以设计一下DialogCardList组件的store:

import { create } from 'zustand';interface DialogCard {question: string;answer: string;cardId: string;
}interface DialogCardListStore {sessionId: string;setSessionId: (id: string) => void;dialogCardList: DialogCard[];addDialogCard: (card: DialogCard) => void;changeLastAnswer: (question: string) => void;changeLastId: (id: string) => void;
}export const useDialogCardListStore = create<DialogCardListStore>((set) => ({sessionId: '',setSessionId: (id: string) => set(() => ({ sessionId: id })),dialogCardList: [],addDialogCard: (card: DialogCard) => set((state) => ({dialogCardList: [...state.dialogCardList, card],})),changeLastAnswer: (answer: string) => set((state) => {const dialogCard = state.dialogCardList[state.dialogCardList.length - 1];if (dialogCard) {dialogCard.answer += answer;}return { dialogCardList: [...state.dialogCardList] };}),changeLastId: (id: string) => set((state) => {const dialogCard = state.dialogCardList[state.dialogCardList.length - 1];if (dialogCard) {dialogCard.cardId = id;}return { dialogCardList: [...state.dialogCardList] };}),}));

dialogCardList就是代表每个问答对组成的列表;

changeLastAnswer方法主要是用来修改最后一个card的answer,这里是因为sse返回内容是流试的。所以我们要不停的更新最后一个节点的回答。

后端添加major事件

刚才我们说到,每个对话的card都有三个属性,id,question,answer,那id是从哪里来的呢,肯定是后端返回的。

后端可以在每次返回模型输出内容之前,先返回一个id。但是这个id肯定不能是message类型的,所以,我们可以在major事件里返回对应的id。

在getChat方法中,在for循环之前先发送一个major消息:

const eventName = 'major';
res.write(`event: ${eventName}\n`);
res.write(`data: ${JSON.stringify({id: Date.now()})}\n\n`);

这样我们再看一下接口的返回:

在这里插入图片描述

可以看到在SSE中会先返回一个major类型的消息。

本篇章里server端的内容就三行代码的修改,
具体的提交可以查看:

https://github.com/TeacherXin/gpt-xin-server/commit/1ecc36ceb29acec888df48102ec64edf0c3c676f

实现前端对话流

现在我们已经有了对话流的数据结构,现在我们来想一下流程应该是什么样子的。

最开始肯定是在输入框里面输入内容然后发送调用chat接口了,然后服务端通过SSE返回消息内容。

我们现在有三个回调,major,message,close。这三个函数调用的时机是什么,函数需要做什么呢。我们就来模拟整个流程来讲解。

【第一步】发送消息

给dialogCardList添加一个问答对,不过这个时候只有一个question,接口还没有返回。所以answer和cardId应该为空

const data = {message: inputStore.inputValue,
};dialogCardListStore.addDialogCard({question: inputStore.inputValue,answer: '',cardId: '',
});inputStore.setInputValue('');
inputStore.setInputLoading(true);

【第二步】设置三种事件类型的回调

const url = 'http://localhost:3002/chat';const messageCallback = (message: Message) => {dialogCardListStore.changeLastAnswer(message.content);
};const closeCallback = () => {inputStore.setInputLoading(false);
};const majorCallback = (major: Major) => {dialogCardListStore.changeLastId(major.id);
};connectSSE(url, data, {message: messageCallback,major: majorCallback,close: closeCallback,
});

我们需要在messageCallback,不停的更新dialogCardList中,最后一个card的answer。
在majorCallback中,更新最后一个card的id
在closeCallback中,更新一下输入框的loading状态。
然后传给connectSSE方法即可。

【第三步】实现DialogCardList组件

有了数据结构以及更新流程之后,我们就可以实现DialogCardList组件了:

const DialogCardList: React.FunctionComponent = () => {const dialogCardListStore = useDialogCardListStore();return (<div className={styles.scrollContainer}><div className={styles.dialogCardList}>{dialogCardListStore.dialogCardList.map((item) => {return (<div className={styles.dialogCard} key={item.cardId}><div className={styles.question}><p>{item.question}</p></div><div className={styles.answer}>{item.answer}</div></div>);})}</div></div>);
};

只需要遍历dialogCardList把对应的问答对展示出来即可,CSS的样式这里我就不写了,可以直接看我的提交记录(贴在后面了)。

最终我们就可以通过发送query实现对话功能了,这里展示一下效果:

请添加图片描述

停止生成

现在我们发送完对话,如何停止生成,让这个对话结束呢。

其实我们只需要把SSE的请求取消即可,回到我们的sse.ts中,在最外层定义个abortController

let abortController = new AbortController();

然后修改connectSSE方法,把abortController传给fetch请求:

const res = await fetch(url, {headers: {'Content-Type': 'application/json', // 必须设置Accept: 'text/event-stream','Cache-Control': 'no-cache',},method: 'POST',body: JSON.stringify(params),signal: abortController.signal, // 用于取消请求});

最后再实现一个stopSSE方法,这里注意一下,每次停止生成都要生成一个新的AbortController,因为下次发送fetch请求不能用之前的AbortController,不然所有的请求都发不出去了:

const stopSSE = () => {abortController.abort(); // 取消 fetch 请求abortController = new AbortController();
}

当inputLoading为true的时候,点击按钮就停止生成。

前端部分在这一篇的内容也就实现完了,具体的代码变更可以看下面的提交记录:
https://github.com/TeacherXin/gpt-xin/commit/6cb2c719cce51ae9cd6af92cad1283de41c485c9


文章转载自:

http://V0LKfxnf.hqwtm.cn
http://iCM0ZBfW.hqwtm.cn
http://XOjbpPFk.hqwtm.cn
http://toBrIc6U.hqwtm.cn
http://MQ496pxT.hqwtm.cn
http://C2Ynngl5.hqwtm.cn
http://moqdHGcE.hqwtm.cn
http://NDTnHk8p.hqwtm.cn
http://h87G5IY6.hqwtm.cn
http://pWnlZbjC.hqwtm.cn
http://Df90ZdxE.hqwtm.cn
http://2vBMUDyF.hqwtm.cn
http://z31RGQfM.hqwtm.cn
http://HPPntRj9.hqwtm.cn
http://0i74Lmdm.hqwtm.cn
http://qxxEB35h.hqwtm.cn
http://xiLpyUbf.hqwtm.cn
http://CxyQEqW6.hqwtm.cn
http://q57jkLzV.hqwtm.cn
http://9qKCM2nH.hqwtm.cn
http://1JOt0TT0.hqwtm.cn
http://gDTUHtCx.hqwtm.cn
http://yyhVwJpp.hqwtm.cn
http://xZ1qyIXH.hqwtm.cn
http://2r6jaF0X.hqwtm.cn
http://GJiuj3Yq.hqwtm.cn
http://mh0R6Kwr.hqwtm.cn
http://lD4wa579.hqwtm.cn
http://3jKHchc6.hqwtm.cn
http://6auou68q.hqwtm.cn
http://www.dtcms.com/wzjs/655847.html

相关文章:

  • 北京p2p网站建设即速应用小程序官网
  • 创意设计网站公司医药行业网站建设
  • 怎么推广公司网站做直播导航网站
  • 石家庄市环保局网站建设项目备案系统wordpress 评论贴图
  • 做国外的营销的网站vr网站建设
  • 民治营销型网站上国外的网站很慢
  • 自己做的网页加在网站文章上为什么打不开游戏网站排行
  • 电子商务网站怎么做推广创意界面
  • 北海住房和城乡建设局网站网站设计宽屏尺寸
  • 网站大全app下载代理记账包含哪些业务
  • 怀化找什么人做网站域名购买网站有哪些
  • 建设项目验收在哪个网站公示深圳建网站的公
  • 百度上如何做优化网站wordpress主题排名
  • 网站界面设计试题怎么做网页签到
  • 宁波网站建设流程利用excel做填报网站
  • 建站模板工程造价做金融的免费发帖的网站有哪些
  • 网站建设运营公司企业特色wordpress4中文
  • 做网站网页版和手机版企业咨询顾问的工作内容
  • 河南省和城乡建设厅网站首页wordpress英文源码
  • 百度推广 做网站河南省住房和建设厅安监站网站
  • 怎么修改网站备案信息怎么创建一个网页
  • 个人电台网站模版商城官方平台入口
  • 青岛网站推广 软件创意互动网站
  • 找外贸客户的网站品牌网络营销策划
  • 好的网站首页的特点竞价是什么工作
  • 二级域名对网站帮助吴桥县做网站
  • 进不了建设银行网站做网站英文编辑有前途
  • 网络教学网站建设北京定制网站开发公司浩森宇特
  • 找一个免费域名的网站怎么做网页txt
  • l礼品文化网站建设中国建行网银登录