Add File
This commit is contained in:
250
main/ui/chat_history.html
Normal file
250
main/ui/chat_history.html
Normal file
@@ -0,0 +1,250 @@
|
||||
<div x-data="his" x-init="fetchSomething">
|
||||
<!-- 查询器 四角弧形的矩形容器 -->
|
||||
<div class="flex rounded-lg bg-white shadow-lg p-4 space-x-4">
|
||||
<!-- 横向排列的四个元素 -->
|
||||
|
||||
<div class="relative flex w-full max-w-xs flex-col gap-1 text-neutral-600 dark:text-zinc-200">
|
||||
<input x-model="demo" type="search" class="w-full rounded border border-zinc-300 bg-zinc-100 py-2 pl-10 pr-2 text-sm 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:border-zinc-700 dark:bg-zinc-800/50 dark:focus-visible:outline-sky-600" name="search" placeholder="Search" aria-label="search"/>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true" class="absolute left-2.5 top-1/2 size-5 -translate-y-1/2 text-neutral-600/50 dark:text-zinc-200/50">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<button @click="fetchSomething" type="button" class="cursor-pointer whitespace-nowrap rounded bg-sky-700 px-4 py-2 text-sm font-medium tracking-wide text-white transition hover:opacity-75 text-center focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-700 active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:bg-sky-600 dark:text-white dark:focus-visible:outline-sky-600">查询</button>
|
||||
</div>
|
||||
<!-- 结果表格-->
|
||||
<div class="mt-4 overflow-hidden w-full overflow-x-auto rounded border border-zinc-300 dark:border-zinc-700">
|
||||
<table class="w-full text-left text-sm text-neutral-600 dark:text-zinc-200">
|
||||
<thead class="border-b border-zinc-300 bg-zinc-100 text-sm text-neutral-900 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-50">
|
||||
<tr>
|
||||
<th scope="col" class="p-4">
|
||||
<label for="checkAll" class="flex items-center cursor-pointer text-neutral-600 dark:text-zinc-200 ">
|
||||
<div class="relative flex items-center">
|
||||
<input type="checkbox" x-model="checkAll" id="checkAll" class="before:content[''] peer relative size-4 cursor-pointer appearance-none overflow-hidden rounded border border-zinc-300 bg-zinc-50 before:absolute before:inset-0 checked:border-sky-700 checked:before:bg-sky-700 focus:outline focus:outline-2 focus:outline-offset-2 focus:outline-zinc-500 checked:focus:outline-sky-700 active:outline-offset-0 dark:border-zinc-700 dark:bg-zinc-800 dark:checked:border-sky-600 dark:checked:before:bg-sky-600 dark:focus:outline-zinc-500 dark:checked:focus:outline-sky-600" />
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" stroke="currentColor" fill="none" stroke-width="4" class="pointer-events-none invisible absolute left-1/2 top-1/2 size-3 -translate-x-1/2 -translate-y-1/2 text-white peer-checked:visible dark:text-white">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/>
|
||||
</svg>
|
||||
</div>
|
||||
</label>
|
||||
</th>
|
||||
<th scope="col" class="p-4">操作时间</th>
|
||||
<th scope="col" class="p-4">用户名</th>
|
||||
<th scope="col" class="p-4">问题</th>
|
||||
<th scope="col" class="p-4">回答</th>
|
||||
<th scope="col" class="p-4">终端IP</th>
|
||||
|
||||
<th scope="col" class="p-4">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-zinc-300 dark:divide-zinc-700">
|
||||
<template x-for="(item,index) in Items" :key="index">
|
||||
<tr>
|
||||
<td class="p-2 px-4">
|
||||
<label for="user2338" class="flex items-center cursor-pointer text-neutral-600 dark:text-zinc-200 ">
|
||||
<div class="relative flex items-center">
|
||||
<input type="checkbox" x-model="selected" :value="item.id" class="before:content[''] peer relative size-4 cursor-pointer appearance-none overflow-hidden rounded border border-zinc-300 bg-zinc-50 before:absolute before:inset-0 checked:border-sky-700 checked:before:bg-sky-700 focus:outline focus:outline-2 focus:outline-offset-2 focus:outline-zinc-500 checked:focus:outline-sky-700 active:outline-offset-0 dark:border-zinc-700 dark:bg-zinc-800 dark:checked:border-sky-600 dark:checked:before:bg-sky-600 dark:focus:outline-zinc-500 dark:checked:focus:outline-sky-600" />
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" stroke="currentColor" fill="none" stroke-width="4" class="pointer-events-none invisible absolute left-1/2 top-1/2 size-3 -translate-x-1/2 -translate-y-1/2 text-white peer-checked:visible dark:text-white">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/>
|
||||
</svg>
|
||||
</div>
|
||||
</label>
|
||||
</td>
|
||||
<td class="p-2 max-w-s1">
|
||||
<div class="relative">
|
||||
<button x-text="item.c_time.slice(0,19).replace('T',' ')" type="button" class="peer cursor-pointer rounded bg-zinc-100 px-4 py-2 font-medium tracking-wide text-neutral-600 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-700 dark:bg-zinc-800 dark:text-zinc-200 dark:focus-visible:outline-sky-600" aria-describedby="tooltipExample">Hover Me</button>
|
||||
|
||||
</div>
|
||||
</td>
|
||||
<td class="p-2" x-text="item.username">用户名</td>
|
||||
|
||||
<td class="p-2 max-w-s2">
|
||||
<div class="relative">
|
||||
<button x-on:click="copyToClipboard(item.query);" x-text="item.query.slice(0,20)" type="button" class="peer cursor-pointer rounded bg-zinc-100 px-4 py-2 font-medium tracking-wide text-neutral-600 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-700 dark:bg-zinc-800 dark:text-zinc-200 dark:focus-visible:outline-sky-600" aria-describedby="tooltipExample">Hover Me</button>
|
||||
<div x-text="item.query" id="tooltipExample" class="absolute -top-9 left-0 -translate-x-0 z-50 rounded bg-zinc-900 px-2 py-1 text-center text-sm text-zinc-50 opacity-0 transition-all ease-out peer-hover:opacity-100 peer-focus:opacity-100 dark:bg-zinc-50 dark:text-neutral-900" role="tooltip">问题</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="p-2 max-w-xs">
|
||||
<div class="relative">
|
||||
<button x-on:click="copyToClipboard(item.answer);" x-text="item.answer.slice(0,20)" type="button" class="peer cursor-pointer rounded bg-zinc-100 px-4 py-2 font-medium tracking-wide text-neutral-600 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-700 dark:bg-zinc-800 dark:text-zinc-200 dark:focus-visible:outline-sky-600" aria-describedby="tooltipExample">Hover Me</button>
|
||||
<div class="pointer-events-none absolute bottom-full mb-2 -left-10 -translate-x-0 z-40 w-100 flex flex-col gap-1 rounded bg-zinc-900 p-2.5 text-xs text-zinc-200 opacity-0 transition-all ease-out peer-hover:opacity-100 peer-focus:opacity-100 dark:bg-zinc-50 dark:text-neutral-600" role="tooltip">
|
||||
<span class="text-sm font-medium text-zinc-50 dark:text-neutral-900">回答内容如下:</span>
|
||||
<p class="text-balance" x-html="marked.parse(item.answer.slice(0,500))">A rich tooltip that contains longer text and is usually used to add a description.</p>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="p-2" x-text="item.client_ip">IP</td>
|
||||
<td class="p-2">
|
||||
<button @click="detail_his(index)" type="button" class="cursor-pointer whitespace-nowrap rounded bg-transparent p-0.5 font-semibold text-sky-700 outline-sky-700 hover:opacity-75 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 active:opacity-100 active:outline-offset-0 dark:text-sky-600 dark:outline-sky-600">详情</button>
|
||||
<button x-show="is_del" @click="delete_his(item.id)" type="button" class="cursor-pointer whitespace-nowrap rounded bg-transparent p-0.5 font-semibold text-sky-700 outline-sky-700 hover:opacity-75 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 active:opacity-100 active:outline-offset-0 dark:text-sky-600 dark:outline-sky-600">删除</button>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<!-- 翻页-->
|
||||
<nav aria-label="pagination">
|
||||
<ul class="flex flex-shrink-0 items-center gap-2 text-sm font-medium">
|
||||
<li> 共<span x-text="count" class="font-bold">200</span>条/显示前<span x-text="view_count" class="font-bold"></span>条</li>
|
||||
<li>
|
||||
<a href="#" @click="curPage===1 ? pageSlie(1): pageSlie(curPage-1) " class="flex items-center rounded p-1 text-neutral-600 hover:text-sky-700 dark:text-zinc-200 dark:hover:text-sky-600" aria-label="previous page">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="size-6">
|
||||
<path fill-rule="evenodd" d="M11.78 5.22a.75.75 0 0 1 0 1.06L8.06 10l3.72 3.72a.75.75 0 1 1-1.06 1.06l-4.25-4.25a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0Z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
上一页
|
||||
</a>
|
||||
</li>
|
||||
<li x-show="count/pageSize+1 >=ps+1"><a href="#" x-text="ps+1" @click="pageSlie(ps+1)" :class="curPage===ps+1 ? 'bg-sky-700 text-white font-bold ' :''" class="flex size-6 items-center justify-center rounded p-1 text-neutral-600 hover:text-sky-700 dark:text-zinc-200 dark:hover:text-sky-600" aria-label="page 1">1</a></li>
|
||||
<li x-show="count/pageSize+1 >=ps+2"><a href="#" x-text="ps+2" @click="pageSlie(ps+2)" :class="curPage===ps+2 ? 'bg-sky-700 text-white font-bold ' :''" class="flex size-6 items-center justify-center rounded p-1 text-neutral-600 hover:text-sky-700 dark:bg-sky-600 dark:text-white" aria-label="page 2">2</a></li>
|
||||
<li x-show="count/pageSize+1 >=ps+3"><a href="#" x-text="ps+3" @click="pageSlie(ps+3)" :class="curPage===ps+3 ? 'bg-sky-700 text-white font-bold ' :''" class="flex size-6 items-center justify-center rounded p-1 text-neutral-600 hover:text-sky-700 dark:text-zinc-200 dark:hover:text-sky-600" aria-label="page 3">3</a></li>
|
||||
<li x-show="count/pageSize+1 >=ps+4"><a href="#" x-text="ps+4" @click="pageSlie(ps+4)" :class="curPage===ps+4 ? 'bg-sky-700 text-white font-bold ' :''" class="flex size-6 items-center justify-center rounded p-1 text-neutral-600 hover:text-sky-700 dark:text-zinc-200 dark:hover:text-sky-600" aria-label="page 4">4</a></li>
|
||||
<li x-show="count/pageSize+1 >=ps+5"><a href="#" x-text="ps+5" @click="pageSlie(ps+5)" :class="curPage===ps+5 ? 'bg-sky-700 text-white font-bold ' :''" class="flex size-6 items-center justify-center rounded p-1 text-neutral-600 hover:text-sky-700 dark:text-zinc-200 dark:hover:text-sky-600" aria-label="page 5">5</a></li>
|
||||
<li x-show="count/pageSize+1 >=ps+6"><a href="#" x-text="ps+6" @click="pageSlie(ps+6)" :class="curPage===ps+6 ? 'bg-sky-700 text-white font-bold ' :''" class="flex size-6 items-center justify-center rounded p-1 text-neutral-600 hover:text-sky-700 dark:text-zinc-200 dark:hover:text-sky-600" aria-label="page 1">6</a></li>
|
||||
<li x-show="count/pageSize+1 >=ps+7"><a href="#" x-text="ps+7" @click="pageSlie(ps+7)" :class="curPage===ps+7 ? 'bg-sky-700 text-white font-bold ' :''" class="flex size-6 items-center justify-center rounded p-1 text-neutral-600 hover:text-sky-700 dark:bg-sky-600 dark:text-white" aria-label="page 2">7</a></li>
|
||||
<li x-show="count/pageSize+1 >=ps+8"><a href="#" x-text="ps+8" @click="pageSlie(ps+8)" :class="curPage===ps+8 ? 'bg-sky-700 text-white font-bold ' :''" class="flex size-6 items-center justify-center rounded p-1 text-neutral-600 hover:text-sky-700 dark:text-zinc-200 dark:hover:text-sky-600" aria-label="page 3">8</a></li>
|
||||
<li x-show="count/pageSize+1 >=ps+9"><a href="#" x-text="ps+9" @click="pageSlie(ps+9)" :class="curPage===ps+9 ? 'bg-sky-700 text-white font-bold ' :''" class="flex size-6 items-center justify-center rounded p-1 text-neutral-600 hover:text-sky-700 dark:text-zinc-200 dark:hover:text-sky-600" aria-label="page 4">9</a></li>
|
||||
<li x-show="count/pageSize+1 >=ps+10"><a href="#" x-text="ps+10" @click="pageSlie(ps+10)" :class="curPage===ps+10 ? 'bg-sky-700 text-white font-bold ' :''" class="flex size-6 items-center justify-center rounded p-1 text-neutral-600 hover:text-sky-700 dark:text-zinc-200 dark:hover:text-sky-600" aria-label="page 5">10</a></li>
|
||||
|
||||
<li>
|
||||
<a href="#" @click="curPage=== parseInt(count/pageSize)+1 ? pageSlie(parseInt(count/pageSize)+1): pageSlie(curPage+1) " class="flex items-center rounded p-1 text-neutral-600 hover:text-sky-700 dark:text-zinc-200 dark:hover:text-sky-600" aria-label="next page">
|
||||
下一页
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="size-6">
|
||||
<path fill-rule="evenodd" d="M8.22 5.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.75.75 0 0 1-1.06-1.06L11.94 10 8.22 6.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<!-- Info 对话日志详情 -->
|
||||
<div x-show="Info" class="fixed top-10 left-0 right-0 z-30 w-full mx-auto max-w-2xl flex items-center justify-center rounded border border-sky-700 bg-zinc-50 text-neutral-600 dark:bg-zinc-900 dark:text-zinc-200" role="alert">
|
||||
<div class="flex w-full items-center gap-2 bg-sky-700/10 p-4">
|
||||
<div class="bg-sky-700/15 text-sky-700 rounded-full p-1" aria-hidden="true">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-6" aria-hidden="true">
|
||||
<path fill-rule="evenodd" d="M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0Zm-7-4a1 1 0 1 1-2 0 1 1 0 0 1 2 0ZM9 9a.75.75 0 0 0 0 1.5h.253a.25.25 0 0 1 .244.304l-.459 2.066A1.75 1.75 0 0 0 10.747 15H11a.75.75 0 0 0 0-1.5h-.253a.25.25 0 0 1-.244-.304l.459-2.066A1.75 1.75 0 0 0 9.253 9H9Z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-2 max-h-[80vh] overflow-y-auto">
|
||||
<h3 class="text-sm font-semibold text-sky-700">对话详情</h3>
|
||||
<p class="text-xs font-medium sm:text-sm">时间:<span class="m-2 font-bold" x-text="chat.c_time"></span></p>
|
||||
<p class="text-xs font-medium sm:text-sm">用户ID:<span class="m-2 font-bold" x-text="chat.userid"></span></p>
|
||||
<p class="text-xs font-medium sm:text-sm">用户名:<span class="m-2 font-bold" x-text="chat.username"></span></p>
|
||||
<p class="text-xs font-medium sm:text-sm">操作IP:<span class="m-2 font-bold" x-text="chat.client_ip"></span></p>
|
||||
<p class="text-xs font-medium sm:text-sm">关联信息:<span class="m-2 font-bold" x-text="chat.ref"></span></p>
|
||||
<hr>
|
||||
<p class="text-xs font-medium sm:text-sm">提问:<br><span class="m-2 font-bold" x-text="chat.query"></span></p>
|
||||
<hr>
|
||||
<p class="text-xs font-medium sm:text-sm">回答:<br><span class="m-2" x-html="marked.parse(chat.answer)"></span></p>
|
||||
</div>
|
||||
<button @click="Info=false" class="ml-auto" aria-label="dismiss alert">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" stroke="currentColor" fill="none" stroke-width="2.5" class="w-4 h-4 shrink-0">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 选中的面板操作 -->
|
||||
<div x-show="show_op" class="fixed bottom-4 right-5 z-30 min-w-xl flex rounded-lg bg-zinc-100 shadow-lg p-4 space-x-4">
|
||||
<div class="relative flex w-full px-4 text-sky-700">已选中<span x-text="selected.length"></span>条</div>
|
||||
<button @click="delete_selected" type="button" class="cursor-pointer whitespace-nowrap rounded bg-sky-700 px-4 py-2 text-sm font-medium tracking-wide text-white transition hover:opacity-75 text-center focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-700 active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:bg-sky-600 dark:text-white dark:focus-visible:outline-sky-600">批量删除</button>
|
||||
<button @click="(checkAll=false, selected = [])" type="button" class="cursor-pointer whitespace-nowrap rounded bg-sky-700 px-4 py-2 text-sm font-medium tracking-wide text-white transition hover:opacity-75 text-center focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-700 active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:bg-sky-600 dark:text-white dark:focus-visible:outline-sky-600">取消</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function his(){
|
||||
return {
|
||||
checkAll: false,
|
||||
selected: [],
|
||||
show_op: false,
|
||||
demo: '',
|
||||
count: 10,
|
||||
view_count:10,
|
||||
pageSize:10,
|
||||
curPage: 1,
|
||||
ps:0,
|
||||
aItems:[],
|
||||
Items:[],
|
||||
Info: false,
|
||||
chat:{},
|
||||
is_del:true,
|
||||
init(){
|
||||
//监听选择变化
|
||||
this.$watch('selected',value => {
|
||||
console.log(value);
|
||||
if(value.length >0){
|
||||
this.show_op = true;
|
||||
}else{
|
||||
this.show_op = false;
|
||||
}
|
||||
});
|
||||
|
||||
this.$watch('checkAll',value => {
|
||||
if(value){
|
||||
//选中当前页
|
||||
this.selected = this.Items.map(item =>item.id);
|
||||
|
||||
}else{
|
||||
this.selected = [];
|
||||
}
|
||||
});
|
||||
},
|
||||
open_aieditor(doc_id){
|
||||
this.AIEditorOpen=true;
|
||||
},
|
||||
close_aieditor(){
|
||||
this.AIEditorOpen=false;
|
||||
this.fetchSomething();
|
||||
},
|
||||
fetchSomething() {
|
||||
if('gdSelectedTab' in this && this.gdSelectedTab=="my" ){
|
||||
|
||||
this.pageSize =5;
|
||||
this.is_del = false;
|
||||
}
|
||||
axios.get('/api/chat_history?demo='+this.demo).then(response => {
|
||||
//console.log('Data:', response.data);
|
||||
this.aItems = response.data.data;
|
||||
this.view_count = this.aItems.length;
|
||||
this.Items = this.aItems.slice(0,this.pageSize);
|
||||
this.curPage = 1;
|
||||
this.count=response.data.count;
|
||||
}).catch(error => {
|
||||
console.error('Error fetching data:', error);
|
||||
throw error; // 重新抛出错误以便调用者可以处理
|
||||
});
|
||||
},
|
||||
pageSlie(page){
|
||||
this.ps = Math.floor((page-1)/10)*10;
|
||||
this.curPage = page;
|
||||
this.Items = this.aItems.slice(this.pageSize*(this.curPage-1),this.pageSize*this.curPage);
|
||||
},
|
||||
detail_his(index){
|
||||
//显示详情
|
||||
this.chat = this.Items[index];
|
||||
this.Info = true;
|
||||
},
|
||||
delete_his(chat_id){
|
||||
axios.delete('/api/chat_history/'+chat_id).then(response => {
|
||||
this.fetchSomething();
|
||||
}).catch(error => {
|
||||
console.error('Error fetching data:', error);
|
||||
throw error; // 重新抛出错误以便调用者可以处理
|
||||
});
|
||||
|
||||
},
|
||||
delete_selected(){
|
||||
let chat_ids = this.selected.join(",");
|
||||
this.delete_his(chat_ids);
|
||||
this.checkAll = false;
|
||||
this.selected = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user