Files
k3GPT/main/x/wap.html
2025-11-19 19:42:47 +08:00

605 lines
30 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>知识体</title>
<link rel="stylesheet" href="tw.k3gpt.css">
<script src="js/axios.min.js"></script>
<script src="js/marked.js"></script>
<script defer src="js/alpine.js"></script>
<script defer src="js/alp_unit.js"></script>
<style>
/* WebKit 浏览器的滚动条 */
::-webkit-scrollbar {
width: 4px; /* 滚动条宽度 */
height: 10px;
}
::-webkit-scrollbar-track {
background: #f1f1f1; /* 轨道背景色 */
}
::-webkit-scrollbar-thumb {
background: #888; /* 滚动条颜色 */
border-radius: 4px; /* 圆角 */
}
::-webkit-scrollbar-thumb:hover {
background: #555; /* 滚动条悬停时的颜色 */
}
/*WangEdit的样式*/
#editor-content-view {
border: 3px solid #ccc;
border-radius: 5px;
padding: 0 10px;
margin-top: 20px;
overflow-x: auto;
}
#editor-content-view p,
#editor-content-view li {
white-space: pre-wrap; /* 保留空格 */
}
#editor-content-view blockquote {
border-left: 8px solid #d0e5f2;
padding: 10px 10px;
margin: 10px 0;
background-color: #f1f1f1;
}
#editor-content-view code {
font-family: monospace;
background-color: #eee;
padding: 3px;
border-radius: 3px;
}
#editor-content-view pre>code {
display: block;
padding: 10px;
}
#editor-content-view table {
border-collapse: collapse;
}
#editor-content-view td,
#editor-content-view th {
border: 1px solid #ccc;
min-width: 50px;
height: 20px;
}
#editor-content-view th {
background-color: #f1f1f1;
}
#editor-content-view ul,
#editor-content-view ol {
padding-left: 20px;
}
#editor-content-view input[type="checkbox"] {
margin-right: 5px;
}
.button {
display: inline-block;
padding: 10px 15px;
margin-bottom: 10px;
margin-left: 10px;
border: none;
border-radius: 5px;
cursor: pointer;
color: white;
font-size: 16px;
transition: background-color 0.3s;
width: calc(100% - 22px); /* 调整按钮宽度以适应边距 */
}
.logout-btn {
background-color: #4f46e5;
}
.logout-btn:hover {
background-color: #0c8ab8;
}
#head {
width: 40px; /* 设置图片宽度 */
height: 40px; /* 设置图片高度 */
border-radius: 50%; /*将圆角半径设置为 50% */
/*border-radius: 5px; 圆角 */
object-fit: cover; /* 确保图片按比例缩放并覆盖容器 */
display: block;
margin: auto;
}
#username {
font-size: 12px;
}
.fixed-top-right {
position: fixed; /* 固定定位 */
top: 120px; /* 距离顶部 10px */
right: 10px; /* 距离右侧 10px */
background-color: #9333ea; /* 背景颜色 */
color: white; /* 文字颜色 */
padding: 10px; /* 内边距 */
border-radius: 5px; /* 圆角 */
min-width: 55px;
z-index: 1000; /* 确保层级高于其他内容 */
text-align: center;
}
.content-layer {
position: relative; /* 必须设置,否则 absolute 不生效 */
border: 1px solid #ddd;
color: white;
background-color: rgb(29 78 216 / 0.9);
border-radius: 5px;
margin-bottom: 5px;
padding:5px;
}
</style>
</head>
<body>
<!-- 用于绘制的隐藏画布 -->
<canvas id="canvas" width="100" height="100" style="display: none;"></canvas>
<div id="floating-layer" class="fixed-top-right">
<img id="head"></img>
<div id="username"></div>
</div>
<!-- 对话窗口-->
<div x-data="chat_agent" class="flex flex-col w-98 m-2 rounded-lg border shadow-lg">
<!-- 上面的 div -->
<div class="text-white bg-gradient-to-t from-blue-600 to-purple-600 flex flex-col rounded-lg">
<h3 x-text="kagent.title" class="text-lg font-bold text-center p-2 mt-2"></h3>
<div class="flex-grow overflow-y-auto p-2">
<div x-html="kagent.demo" class="font-bold text-sm mx-2"></div>
</div>
</div>
<!-- 下面的 div -->
<div class="bg-zinc-50">
<div class="flex flex-col h-[80vh]">
<!-- 对话的展示-->
<div id="chat_display_2" class="flex-grow overflow-y-auto">
<!-- 对话列表-->
<div class="px-4">
<div class="flex flex-col gap-2 mx-4">
<!-- AI's Response -->
<div class="w-full mt-2 max-w-2xl border-zinc-300 bg-zinc-100 p-2 text-left dark:border-zinc-700 dark:bg-zinc-800 rounded-xl border shadow-sm" >
<div class="flex items-center gap-2 text-neutral-900 dark:text-zinc-50">
<span class="flex size-8 items-center justify-center rounded-full bg-gradient-to-br from-blue-600 to-purple-600 text-white dark:bg-sky-600 dark:text-white">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" class="size-5">
<path d="M6 12.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5M3 8.062C3 6.76 4.235 5.765 5.53 5.886a26.6 26.6 0 0 0 4.94 0C11.765 5.765 13 6.76 13 8.062v1.157a.93.93 0 0 1-.765.935c-.845.147-2.34.346-4.235.346s-3.39-.2-4.235-.346A.93.93 0 0 1 3 9.219zm4.542-.827a.25.25 0 0 0-.217.068l-.92.9a25 25 0 0 1-1.871-.183.25.25 0 0 0-.068.495c.55.076 1.232.149 2.02.193a.25.25 0 0 0 .189-.071l.754-.736.847 1.71a.25.25 0 0 0 .404.062l.932-.97a25 25 0 0 0 1.922-.188.25.25 0 0 0-.068-.495c-.538.074-1.207.145-1.98.189a.25.25 0 0 0-.166.076l-.754.785-.842-1.7a.25.25 0 0 0-.182-.135" />
<path d="M8.5 1.866a1 1 0 1 0-1 0V3h-2A4.5 4.5 0 0 0 1 7.5V8a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1v1a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-1a1 1 0 0 0 1-1V9a1 1 0 0 0-1-1v-.5A4.5 4.5 0 0 0 10.5 3h-2zM14 7.5V13a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V7.5A3.5 3.5 0 0 1 5.5 4h5A3.5 3.5 0 0 1 14 7.5" />
</svg>
</span>
<span class="text-sm font-bold" x-text="hello">Hello.AI</span>
</div>
<p x-html="marked.parse(kagent.guide)" class="text-pretty sm:pl-10 mt-4 sm:mt-0 text-sm text-neutral-600 dark:text-zinc-200">
你好,我是一个知识机器人,我可以帮你检索知识库并回答你的问题。
请问我有什么可以帮助你的?
</p>
</div>
<template x-for="(item, index) in Items" :key="index">
<div class="flex flex-col justify-end">
<!-- User's Chat -->
<div :id="'QA'+index" class="inline-flex max-w-xl ml-auto border-zinc-300 bg-blue-700/30 p-2 text-left dark:border-zinc-700 dark:bg-zinc-800 rounded-lg border shadow-sm" >
<div class="flex items-center px-1 gap-1 text-neutral-900 dark:text-zinc-50 group cursor-pointer">
<span x-text="item.req" class="text-sm">Alice Brown</span>
<button x-on:click="copy_query(item.req)" class="rounded-full text-neutral-600/75 opacity-0 group-hover:opacity-100 group-focus:opacity-100 hover:bg-zinc-900/10 hover:text-neutral-600 focus:outline-none focus-visible:text-neutral-600 focus-visible:zinc-300 focus-visible:outline-offset-0 focus-visible:outline-sky-700 active:bg-zinc-900/5 active:-outline-offset-2 dark:text-zinc-200/75 dark:hover:bg-zinc-50/10 dark:hover:text-zinc-200 dark:focus-visible:text-zinc-200 dark:focus-visible:outline-sky-600 dark:active:bg-zinc-50/5" title="再问一次" aria-label="再问一次" >
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-4" aria-hidden="true">
<path fill-rule="evenodd" d="M13.887 3.182c.396.037.79.08 1.183.128C16.194 3.45 17 4.414 17 5.517V16.75A2.25 2.25 0 0 1 14.75 19h-9.5A2.25 2.25 0 0 1 3 16.75V5.517c0-1.103.806-2.068 1.93-2.207.393-.048.787-.09 1.183-.128A3.001 3.001 0 0 1 9 1h2c1.373 0 2.531.923 2.887 2.182ZM7.5 4A1.5 1.5 0 0 1 9 2.5h2A1.5 1.5 0 0 1 12.5 4v.5h-5V4Z" clip-rule="evenodd"/>
</svg>
</button>
</div>
</div>
<!-- AI's Response -->
<div x-show="item.rsp_show" class="mt-2 w-full border-zinc-300 bg-zinc-100 p-2 text-left dark:border-zinc-700 dark:bg-zinc-800 rounded-xl border shadow-sm" >
<div class="flex items-center gap-2 text-neutral-900 dark:text-zinc-50">
<span class="flex size-8 items-center justify-center rounded-full bg-gradient-to-br from-blue-600 to-purple-600 text-white dark:bg-sky-600 dark:text-white">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" class="size-5">
<path d="M6 12.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5M3 8.062C3 6.76 4.235 5.765 5.53 5.886a26.6 26.6 0 0 0 4.94 0C11.765 5.765 13 6.76 13 8.062v1.157a.93.93 0 0 1-.765.935c-.845.147-2.34.346-4.235.346s-3.39-.2-4.235-.346A.93.93 0 0 1 3 9.219zm4.542-.827a.25.25 0 0 0-.217.068l-.92.9a25 25 0 0 1-1.871-.183.25.25 0 0 0-.068.495c.55.076 1.232.149 2.02.193a.25.25 0 0 0 .189-.071l.754-.736.847 1.71a.25.25 0 0 0 .404.062l.932-.97a25 25 0 0 0 1.922-.188.25.25 0 0 0-.068-.495c-.538.074-1.207.145-1.98.189a.25.25 0 0 0-.166.076l-.754.785-.842-1.7a.25.25 0 0 0-.182-.135" />
<path d="M8.5 1.866a1 1 0 1 0-1 0V3h-2A4.5 4.5 0 0 0 1 7.5V8a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1v1a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-1a1 1 0 0 0 1-1V9a1 1 0 0 0-1-1v-.5A4.5 4.5 0 0 0 10.5 3h-2zM14 7.5V13a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V7.5A3.5 3.5 0 0 1 5.5 4h5A3.5 3.5 0 0 1 14 7.5" />
</svg>
</span>
<span x-text="item.rsp" style="overflow-wrap: break-word;" class="text-sm font-bold">Pengu AI</span>
</div>
<p x-bind:id="item.chat_id" :x-ref="item.chat_id" class="text-pretty sm:pl-10 mt-4 sm:mt-0 text-sm text-neutral-600 dark:text-zinc-200"></p>
</div>
</div>
</template>
</ul>
</div>
</div>
</div>
<!-- 输入框 -->
<div class="flex w-full flex-col gap-2 m-2 px-4">
<div class="relative w-full">
<label for="aiPromt" for="aiPromt" class="sr-only">ai prompt</label>
<svg x-show="kagent.atype!=2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" aria-hidden="true" class="absolute left-3 top-1/2 size-4 -translate-y-1/2 fill-blue-700 dark:fill-blue-700">
<path fill-rule="evenodd" d="M5 4a.75.75 0 0 1 .738.616l.252 1.388A1.25 1.25 0 0 0 6.996 7.01l1.388.252a.75.75 0 0 1 0 1.476l-1.388.252A1.25 1.25 0 0 0 5.99 9.996l-.252 1.388a.75.75 0 0 1-1.476 0L4.01 9.996A1.25 1.25 0 0 0 3.004 8.99l-1.388-.252a.75.75 0 0 1 0-1.476l1.388-.252A1.25 1.25 0 0 0 4.01 6.004l.252-1.388A.75.75 0 0 1 5 4ZM12 1a.75.75 0 0 1 .721.544l.195.682c.118.415.443.74.858.858l.682.195a.75.75 0 0 1 0 1.442l-.682.195a1.25 1.25 0 0 0-.858.858l-.195.682a.75.75 0 0 1-1.442 0l-.195-.682a1.25 1.25 0 0 0-.858-.858l-.682-.195a.75.75 0 0 1 0-1.442l.682-.195a1.25 1.25 0 0 0 .858-.858l.195-.682A.75.75 0 0 1 12 1ZM10 11a.75.75 0 0 1 .728.568.968.968 0 0 0 .704.704.75.75 0 0 1 0 1.456.968.968 0 0 0-.704.704.75.75 0 0 1-1.456 0 .968.968 0 0 0-.704-.704.75.75 0 0 1 0-1.456.968.968 0 0 0 .704-.704A.75.75 0 0 1 10 11Z" clip-rule="evenodd" />
</svg>
<!-- 文件上传-->
<input x-ref="fileInput" @input="upload_file" type="file" multiple hidden class="w-full overflow-clip rounded border border-red-700 bg-zinc-100/50 text-sm text-red-700 file:mr-4 file:cursor-pointer file:border-none file:bg-zinc-100 file:px-4 file:py-2 file:font-medium file:text-neutral-900 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-700 disabled:cursor-not-allowed disabled:opacity-75 dark:bg-zinc-800/50 dark:file:bg-zinc-800 dark:file:text-zinc-50 dark:focus-visible:outline-sky-600" />
<svg x-show="kagent.atype==2" @click="$refs.fileInput.click()" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" class="absolute left-3 top-1/2 size-6 cursor-pointer -translate-y-1/2 fill-blue-700 dark:fill-sky-600">
<path fill-rule="evenodd" d="M10.5 3.75a6 6 0 0 0-5.98 6.496A5.25 5.25 0 0 0 6.75 20.25H18a4.5 4.5 0 0 0 2.206-8.423 3.75 3.75 0 0 0-4.133-4.303A6.001 6.001 0 0 0 10.5 3.75Zm2.03 5.47a.75.75 0 0 0-1.06 0l-3 3a.75.75 0 1 0 1.06 1.06l1.72-1.72v4.94a.75.75 0 0 0 1.5 0v-4.94l1.72 1.72a.75.75 0 1 0 1.06-1.06l-3-3Z" clip-rule="evenodd"/>
</svg>
<input x-show="one" x-model="query" x-on:input.debounce.100ms="query_len" x-on:keydown.enter="gen" type="text" class="w-full border-outline bg-zinc-100 border border-zinc-300 rounded px-2 py-2 pl-10 pr-24 text-sm text-neutral-600 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-700 disabled:cursor-not-allowed disabled:opacity-75 dark:border-zinc-700 dark:bg-zinc-800/50 dark:text-zinc-200 dark:focus-visible:outline-sky-600" value="" name="prompt" placeholder="Ask AI ..." />
<textarea id="aiPromt" x-show="!one" rows="5" x-model="query" x-on:input.debounce.100ms="query_len" type="text" class="w-full border-outline bg-zinc-100 border border-zinc-300 rounded px-2 py-2 pl-10 pr-24 text-sm text-neutral-600 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-700 disabled:cursor-not-allowed disabled:opacity-75 dark:border-zinc-700 dark:bg-zinc-800/50 dark:text-zinc-200 dark:focus-visible:outline-sky-600" value="" name="prompt" placeholder="Ask AI ..." ></textarea>
<button type="button" x-show="is_gen" x-on:click="gen" class="absolute right-3 top-1/2 -translate-y-1/2 cursor-pointer bg-blue-700 rounded px-2 py-1 text-xs tracking-wide text-white transition hover:opacity-75 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-700 active:opacity-100 active:outline-offset-0 dark:bg-sky-600 dark:text-white dark:focus-visible:outline-sky-600">提交</button>
<button type="button" x-show="!is_gen" x-on:click="stop" class="absolute right-3 top-1/2 -translate-y-1/2 cursor-pointer bg-blue-700 rounded px-2 py-1 text-xs tracking-wide text-white transition hover:opacity-75 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-700 active:opacity-100 active:outline-offset-0 dark:bg-sky-600 dark:text-white dark:focus-visible:outline-sky-600">停止</button>
</div>
</div>
</div>
</div>
</div>
<script>
const url = new URL(window.location.href);
var Agent_Kasn = url.searchParams.get('sn');
function chat_agent(){
return {
query:"",
HisOpen: false, //历史对话框
AIEditorOpen: false, // 百科创作对话框
aieditor_id:"", //百科id
eventSource: "", //对话流
hello:"Hello ", //欢迎用户,
is_gen: true, //生成模式
Info: false, // 显示上下文
fItems:[], //上下文信息
qItems:[],// 问题列表
Items:[], //对话全部内容
one:true, //一行文本输入
baike_id:0, //新增词条
ai_file:{}, // 默认的上传文件
kagent:{guide:""}, // 具体配置
Agent_Kasn:Agent_Kasn,
init(){
axios.get('/api/kagent_cfg/'+this.Agent_Kasn).then(response => {
this.kagent = response.data;
this.hello += this.kagent.username;
var username = this.kagent.username;
document.getElementById("username").innerText=username;
document.title= this.kagent.title;
if (getCookie("headimgurl")){
//图片
document.getElementById("head").src=getCookie("headimgurl").slice(1,-1);
}else{
draw_icon(username.slice(0,1));
}
}).catch(error => {
console.error('Error fetching data:', error);
throw error; // 重新抛出错误以便调用者可以处理
});
var doc = localStorage.getItem(this.Agent_Kasn);
if (doc){
this.ai_file = JSON.parse(doc);
this.push_item({chat_id:"",req:"你之前上传了文件: "+this.ai_file.name+", 可以继续对话",rsp:"",rsp_show:false});
}
},
logout(){
axios.get('/api/logout?sn='+document.title).then(response => {
if (response.data.code==200){
window.location.href = "login.html?sn="+this.Agent_Kasn;
}
}).catch(error => {
console.error('Error fetching data:', error);
throw error; // 重新抛出错误以便调用者可以处理
});
},
push_item(item){
this.Items.push(item);
},
push_qitem(item){
this.qItems.push(item);
},
update_last_item(chat_id,title,ctx){
var last = this.Items[this.Items.length-1];
last.chat_id=chat_id;
last.rsp=title;
last.rsp_show=true;
last.ctx=ctx;
},
update_last_qitem(answer){
//更新最后一个问题的答案
var last = this.qItems[this.qItems.length-1];
last.rsp=answer;
},
query_len(){
if (this.query.length >20){
this.one=false;
if (this.query.length >300){
const aiPromt = document.getElementById("aiPromt");
aiPromt.rows="10";
}
if (this.query.length >1000){
const aiPromt = document.getElementById("aiPromt");
aiPromt.rows="15";
}
}else{
this.one=true;
}
},
new0(){ //新建对话
this.qItems=[];
this.Items=[];
this.is_gen = true;
this.one = true;
},
copy_query(query){ //复制查询
this.query = query;
this.query_len()
},
copy_that(chat_id){
const messagesDiv = document.getElementById(chat_id);
let rsp = messagesDiv.innerHTML;
rsp = rsp.replace("<think>","<p>").replace("</think>","</p>");
copyToClipboard(rsp);
},
stop(){
this.eventSource.close();
this.is_gen = true;
this.one=true;
},
gen(){
this.is_gen = false;
this.push_item({chat_id:"",req:this.query,rsp:"",rsp_show:false});
var query=this.query;
if (this.query.length >100){
query = this.query.slice(0,100)+"...";
}
// 其它类型
var newItem = {
question: this.query,
kagent_sn: this.Agent_Kasn,
history: this.qItems.map(item => ({req:item.req,rsp:item.rsp})),
ai_mode: "",
};
//上传文件处理类型
if (this.kagent.atype==2){
newItem = {
question: this.query,
kagent_sn: this.Agent_Kasn,
file: this.ai_file.file,
base: this.ai_file.base,
path: this.ai_file.path,
history: this.qItems.map(item => ({req:item.req,rsp:item.rsp})),
ai_mode: "",
};
}
// 使用 axios 发送 POST 请求
axios.post('/api/chat_kagent', newItem)
.then(response =>{
rsp = response.data;
if (this.kagent.atype==3 || this.kagent.atype==100)
{
this.update_last_item(rsp.chat_id,`正在思考中...`,rsp.ctx);
}else{
this.update_last_item(rsp.chat_id,`搜索到${rsp.count}个相关信息,正在整理中...`,rsp.ctx);
}
this.push_qitem({chat_id:rsp.chat_id,req:query,rsp:""});
// 创建一个EventSource实例连接到服务器发送的事件流
this.eventSource = new EventSource('/api/chat_kagent/'+rsp.chat_id);
update_chat(this.eventSource,rsp.chat_id,this);
const div = document.getElementById("chat_display_2");
div.scrollTop = div.scrollHeight;
})
.catch(error => {
console.error('Error post data:', error);
throw error; // 重新抛出错误以便调用者可以处理
});
this.query="";
this.one=true;
const div = document.getElementById("chat_display_2");
div.scrollTop = div.scrollHeight;
},
del_chat(index){//删除对话列表中的对话
this.qItems.splice(index,1);
},
upload_file(){
const file = this.$refs.fileInput.files[0];
if (!file) return;
const formData = new FormData();
formData.append('file', file);
formData.append("curpath",this.kagent.files);
try {
axios.post('/api/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
}).then( response =>{
var doc = response.data;
if (doc.errno === 1) {
alert(doc.message);
}else{
this.ai_file = doc.file;
this.push_item({chat_id:"",req:"你上传了文件: "+this.ai_file.name,rsp:"",rsp_show:false});
// 保存本地缓存
localStorage.setItem(this.Agent_Kasn, JSON.stringify(doc.file))
}
})
} catch (error) {
console.error('Error:', error);
alert('An error occurred while uploading the file.');
}
}// upload_file 上传文件
}
}
//流式更新对话
function update_chat(eventSource,chat_id,fun){
fun.is_gen = false;
//分块更新
var ResponseDiv = null;
var messagesDiv = document.createElement('div');
// 监听消息事件
eventSource.onmessage = function(event) {
//首次创建
if (ResponseDiv==null){
ResponseDiv = document.getElementById(chat_id);
ResponseDiv.appendChild(messagesDiv);
}
const message = JSON.parse(event.data);
//console.log(message.rsp);
if (message.rsp.indexOf("<think>")==0){
var end = message.rsp.indexOf("</think>");
if (end==-1){ //思考还未结束
var think_mk = marked.parse(message.rsp.slice(7));
messagesDiv.innerHTML = think_mk;
}else{
var think_mk = marked.parse(message.rsp.slice(7,end));
var think_all=think_mk;
var result= marked.parse(message.rsp.slice(end+8));
if (result!=""){
think_all +=`<div class="content-layer">${result}</div>`;
}
messagesDiv.innerHTML = think_all;
fun.update_last_qitem(message.rsp.slice(end+8));
}
}else if(message.rsp.indexOf("<new>")==0){
//新的一个消息,新的一个层
messagesDiv = document.createElement('div');
ResponseDiv.appendChild(messagesDiv);
}else{
//正式内容都用蓝色背景
let result =marked.parse(message.rsp);
//var think_all=`<div style="color: white; background-color: rgb(3 105 161 / 0.7); border-radius: 5px; margin-bottom: 5px; padding:5px;">${result}</div>`;
var think_all=`<div class="content-layer">${result}</div>`;
messagesDiv.innerHTML = think_all;
fun.update_last_qitem(message.rsp);
}
//自动滚动
const div = document.getElementById("chat_display_2");
div.scrollTop = div.scrollHeight;
};
// 监听错误事件
eventSource.onerror = function(error) {
fun.is_gen = true;
fun.update_last_item(rsp.chat_id,`回答结束`,rsp.ctx);
console.info(chat_id+" 回答结束");
//结束后滚动
const div = document.getElementById("chat_display_2");
div.scrollTop = div.scrollHeight;
if (eventSource.readyState != EventSource.CLOSED){
eventSource.close(); // 关闭连接
}
};
}
function getCookie(name) {
// 将所有 Cookie 按分号分割成数组
const cookies = document.cookie.split('; ');
// 遍历每个 Cookie查找目标名称
for (let cookie of cookies) {
const [cookieName, cookieValue] = cookie.split('=');
// 如果找到匹配的 Cookie 名称,返回其值
if (cookieName === name) {
return decodeURIComponent(cookieValue); // 解码 URL 编码的值
}
}
// 如果未找到,返回 null
return null;
}
function draw_icon(text){
// 获取画布和绘图上下文
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
// 假设canvas和ctx已经正确定义并初始化
var canvasWidth = canvas.width;
var canvasHeight = canvas.height;
// 清空画布
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#FFFFFF'; // 背景颜色
ctx.fillRect(0, 0, canvas.width, canvas.height); // 填充整个画布
// 创建渐变
var gradient = ctx.createLinearGradient(0, 0, 0, canvasHeight); // 水平方向的渐变
// 给渐变添加颜色停止点color stops
gradient.addColorStop(0, '#0000FF'); // 深蓝色
gradient.addColorStop(1, '#4f46e5'); // 蓝色
// 设置字体样式
ctx.font = 'bold 65px "Microsoft YaHei"'; // 字体大小和类型
ctx.fillStyle = gradient; // 文字颜色
ctx.textAlign = 'center'; // 水平居中
ctx.textBaseline = 'middle'; // 垂直居中
// 绘制汉字
const centerX = canvas.width / 2;
const centerY = canvas.height / 2+5;
ctx.fillText(text, centerX, centerY);
// 将画布内容转换为图片
const imageData = canvas.toDataURL('image/png'); // 默认生成 PNG 格式的 Base64 图片
// 将生成的图片显示在页面上
document.getElementById('head').src = imageData;
}
</script>
</body>
</html>