vue调用coze api实现流式ai问答webui交互效果代码

代码语言:html

所属分类:其他

代码描述:vue调用coze api实现流式ai问答webui交互效果代码,兼容chatgpt、千问、智谱、ollama等流式接口请求,实现了代码块格式化高亮显示、代码块高亮、附件上传、自动滚动、打字输出、复制及重回答、图片全屏放大、消息本地持久存储等ai助手常用功能。

代码标签: vue 调用 coze api 流式 ai 问答 webui 交互

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en">

<head>
   
<meta charset="UTF-8">
   
<title>Vue Chat with API</title>
   
<link type="text/css" rel="stylesheet" href="//repo.bfw.wiki/bfwrepo/css/font-awesome-4.7.0/css/font-awesome.css">
   
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/highlight.js"></script>
   
<link type="text/css" rel="stylesheet" href="//repo.bfw.wiki/bfwrepo/css/highlight.9.9.css">
   
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/marked.umd.min.js"></script>
           
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/localforage.min.js"></script>
   
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/vue@2.6.1-dev.js"></script>



   
<style>
    body
{
       
padding: 0;
       
margin: 0;
   
}
   
.cont{
       
position: fixed;
       
top:0;
       
left: 0;
       
right: 0;
       
display:flex; flex-direction: column;height:100vh;
   
}
       
.historylist {
       
         
flex: 1;
           
overflow-y: scroll;
         
       
}
       
.historylist img{
           
max-width: 100px;
       
}
       
.mesay, .aisay {
           
padding: 10px;
           
margin: 10px;
           
border-radius: 5px;
             
line-height: 30px;
       
}
       
.mesay {
           
background-color: #d0e7ff;
           
text-align: right;
       
}
       
.aisay {
           
background-color: aliceblue;
           
text-align: left;
       
}
       
.inputpannel {
           
display: flex;
           
margin: 10px;
           
background: white;
           
align-items: flex-end;
           
border: 2px solid grey;
           
border-radius: 14px;
       
}
       
.footer{
           
position: relative;
       
}

       
.inputpannel:focus-within {
   
border-color: blue;
}
       
           
.inputtext {
           
margin-top: 4px;
           
         
width: 100%;
         
background: white;
         
line-height: 20px;
         
box-sizing: border-box;
         
padding: 8px;
         
font-family: inherit;
         
font-size: 16px;
         
resize: none;
         
overflow: hidden;
         
border: none;
         
outline: none;
         
height: 40px;
         
         
min-height: 40px;
           
overflow-y: auto;
         
max-height: calc(24px * 5 );
         
       
}
       
.inputtext:focus {
         
border: none;
         
outline: none;
       
}
       
       
textarea::placeholder {
   


}
 
   
       
.historylist pre {
           
white-space: pre-wrap;
           
color: #ececec;
           
background: black;
           
border-radius: 4px;
           
padding: 10px;
           
margin: 0;
           
       
}
       
.historylist p {
           
margin: 0;
           
padding: 2px;
       
}
       
.typing-text {
           
font-size: 24px;
           
white-space: pre-wrap;
           
border-right: 2px solid black;
           
animation: blink 0.7s steps(2, start) infinite;
       
}
       
@keyframes blink {
            to
{
               
border-color: transparent;
           
}
       
}
             
.code-header {
           
position: absolute;
           
top: 0;
           
left:0;
           
right: 0;
           
width: 100%;
           
color: #cdcdcd;
           
height:24px;
         
background : #6767;
           
           
       
}
       
.language-label {
           
position: absolute;
           
top: -4px;
           
left: 0;
           
padding: 0 10px;
           
           
font-size: 0.8em;
           
       
}
       
.copy-button {
           
position: absolute;
           
top: 0;
           
right: 0px;
           
padding: 0.3em 0.6em;
           
           
           
border: none;
           
border-radius: 3px;
           
cursor: pointer;
           
font-size: 0.8em;
       
}
       
.code-content{
           
line-height: 20px;
display: block;
   
text-wrap: nowrap;
   
margin-top: -40px;
       
margin-bottom: -63px;
       
overflow-x: scroll;
       
}
       
.historylist pre{
             
position: relative;
           
background: black;
           
color: white;
             
border-radius: 6px;
           
padding: 1em;
           
margin: 1em 0;
       
}
.file-upload {
   
position: relative;
   
width: 30px;
   
height: 30px;
   
margin: 6px -1px 3px 10px;

   
overflow: hidden;
 
   
 
}
.sendbtn{
   
margin: 13px;
}

.file-upload input[type=file] {
   
position: absolute;
   
top: 0;
   
left: 0;
   
   
   
opacity: 0;
   
cursor: pointer;
}



ol
{
   
list-style: none;
   
padding: 0;margin: 10px;
}
i
{
   
cursor: pointer;

}
.recomminput li{
   
background: aliceblue;
   
border: 1px solid aliceblue;
   
margin:  2px 0 4px 0;
       
padding: 5px;
 
   
width: 64%;
   
font-size: 12px;
   
cursor: pointer;
   
border-radius: 5px;
}
.copybtn,.regenbtn{
   
cursor: pointer;
   
margin-right: 20px;
}
.scrollbar{
   
position: absolute;
   
top: -20px;
   
width: 100%;
   
right:0;
   
left: 0;
}
.scrollbar i{
   
width: 30px;
   
height: 30px;
   
border-radius: 15px;
   
background: white;
   
line-height: 30px;
}
.attachpannel{
     
position: absolute;
     
display: flex;
 
   
width: 100%;
   
height: 100px;
   
   
left: 0;
   
top:-80px;
}
   
       
/* 隐藏默认滚动条 */
textarea::-webkit-scrollbar {
   
display: none;
}

/* 添加自定义滚动条 */
textarea
{
   
scrollbar-width: thin; /* 调整滚动条宽度 */
   
scrollbar-color: #ccc transparent; /* 调整滚动条颜色 */
   
overflow-y: auto; /* 确保溢出时出现滚动条 */
}

/* Firefox 上的滚动条样式 */
textarea
{
   
scrollbar-width: thin;
}

/* WebKit 上的滚动条样式 */
textarea::-webkit-scrollbar {
   
width: 8px; /* 调整滚动条宽度 */
}

textarea::-webkit-scrollbar-track {
   
background-color: transparent; /* 滚动条背景颜色 */
}

textarea::-webkit-scrollbar-thumb {
   
background-color: #ccc; /* 滚动条颜色 */
   
border-radius: 4px; /* 滚动条圆角 */
}

textarea::-webkit-scrollbar-thumb:hover {
 
   
background-color: #999; /* 鼠标悬停时的滚动条颜色 */
}

   
       
/* 隐藏默认滚动条 */
.historylist::-webkit-scrollbar {
   
display: none;
}

/* 添加自定义滚动条 */
.historylist {
   
scrollbar-width: thin; /* 调整滚动条宽度 */
   
scrollbar-color: #ccc transparent; /* 调整滚动条颜色 */
   
overflow-y: auto; /* 确保溢出时出现滚动条 */
}

/* Firefox 上的滚动条样式 */
.historylist {
   
scrollbar-width: thin;
}

/* WebKit 上的滚动条样式 */
.historylist::-webkit-scrollbar {
   
width: 8px; /* 调整滚动条宽度 */
}
.historylist::-webkit-scrollbar-track {
   
background-color: transparent; /* 滚动条背景颜色 */
}

.historylist::-webkit-scrollbar-thumb {
   
background-color: #ccc; /* 滚动条颜色 */
   
border-radius: 4px; /* 滚动条圆角 */
}

.historylist::-webkit-scrollbar-thumb:hover {
 
   
background-color: #999; /* 鼠标悬停时的滚动条颜色 */
}
   
       
/* 隐藏默认滚动条 */
.code-content::-webkit-scrollbar {
   
display: none;
}

/* 添加自定义滚动条 */
.code-content {
   
scrollbar-width: thin; /* 调整滚动条宽度 */
   
scrollbar-color: #ccc transparent; /* 调整滚动条颜色 */
   
overflow-y: auto; /* 确保溢出时出现滚动条 */
}

/* Firefox 上的滚动条样式 */
.code-content{
   
scrollbar-width: thin;
}

/* WebKit 上的滚动条样式 */
.code-content::-webkit-scrollbar {
   
width: 8px; /* 调整滚动条宽度 */
}
.code-content::-webkit-scrollbar-track {
   
background-color: transparent; /* 滚动条背景颜色 */
}

.code-content::-webkit-scrollbar-thumb {
   
background-color: #ccc; /* 滚动条颜色 */
   
border-radius: 4px; /* 滚动条圆角 */
}

.code-content::-webkit-scrollbar-thumb:hover {
 
   
background-color: #999; /* 鼠标悬停时的滚动条颜色 */
}

   
#overlay {
           
display: none;
           
position: fixed;
           
top: 0;
           
left: 0;
           
width: 100%;
           
height: 100%;
           
background-color: rgba(0, 0, 0, 0.8);
           
z-index: 9999;
           
justify-content: center;
           
align-items: center;
       
}

       
#overlay img {
           
max-width: 100%;
           
max-height: 100%;
       
}

       
#closeBtn {
           
position: absolute;
           
top: 10px;
           
right: 10px;
         
           
color: white;
           
border: none;
           
padding: 10px;
           
cursor: pointer;
           
font-size: 16px;
       
}
.feedbackpanel{
   
font-size: 12px;
}
   
</style>
</head>

<body>
   
<div id="overlay" onclick="hideImage()">

   
<i id="closeBtn" onclick="hideImage()" class="fa fa-lg fa-times-circle"></i>
   
<img id="overlayImage" src="" alt="Fullscreen Image">
</div>



   
<div id="app" class="cont" >
       
         
<div style="text-align:center;">
       
<h2>COZE API实现AI聊天</h2>    
       
</div>
       
<div id="historylist"  @scroll="handleScroll"  class="historylist">
           
<div v-for="(msg,index) in newmess" :key="index" :class="{'mesay': msg.role === 'user', 'aisay': msg.role === 'system'}" >
               
               
<div v-html="msg.content"></div>
                 
<div  v-if="aistatus==1&&msg.content==''&&msg.role === 'system'"><img style="height:30px;" src='//repo.bfw.wiki/bfwrepo/icon/667d490a27acd.gif' /></div>
                 
<div  v-if="aistatus==2&&msg.content==''&&msg.role === 'system'">调用插件中……</div>
                   
                 
<div v-if="msg.role === 'system'&&msg.isfinished" class="feedbackpanel"><a title="复制" class="copybtn"  @click="copy(index)"><i class="fa  fa-copy"></i></a><a title="重新生成" class="regenbtn" @click="regen(index)"><i class="fa  fa-rotate-left"></i></a>
                 
<a title="非常好" class="regenbtn" ><i class="fa  fa-thumbs-o-up"></i></a>
                 
                 
<a title="不好" class="regenbtn" ><i class="fa fa-thumbs-o-down">&l.........完整代码请登录后点击上方下载按钮下载查看

网友评论0