This commit is contained in:
2025-11-19 19:42:47 +08:00
parent 7ccd1dcd8e
commit d9ec2bf39d

605
main/x/wap.html Normal file
View File

@@ -0,0 +1,605 @@
<!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>