Add File
This commit is contained in:
605
main/x/wap.html
Normal file
605
main/x/wap.html
Normal 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>
|
||||
Reference in New Issue
Block a user