You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
167 lines
4.0 KiB
167 lines
4.0 KiB
<!--
|
|
@ 作者: han2015
|
|
@ 时间: 2025-05-12 15:39:13
|
|
@ 备注: aibot组件
|
|
-->
|
|
<script lang="ts" setup>
|
|
|
|
import { doAiChat,aiChatData} from "@/api/doc/space"
|
|
import { useUserStore } from "@/store/modules/user";
|
|
|
|
//选中的咨询模式
|
|
const userStore = useUserStore();
|
|
const userid="p0"+userStore.userInfoCont.userId;
|
|
|
|
const baseURL=import.meta.env.VITE_APP_BASE_API
|
|
const conversation=ref("") //当前会话的uuid
|
|
const controller = ref<AbortController | null>(null)
|
|
|
|
const interact_msg=ref<{ask:boolean,think:string,content:string}[]>([])
|
|
|
|
|
|
//消息体
|
|
interface message{
|
|
ask:boolean,
|
|
think:string,
|
|
content:string
|
|
}
|
|
//会话记录
|
|
interface chatRecord{
|
|
uuid:string,
|
|
agentuuid:string,
|
|
brief:string,
|
|
messages:message[]
|
|
}
|
|
|
|
|
|
defineExpose({onSendParamToAI})
|
|
|
|
async function onSendParamToAI(arr:Array<{ uuids: string[]; params: { [key: string]: any } }>){
|
|
interact_msg.value=[]
|
|
for (let ele of arr){
|
|
interact_msg.value.unshift({ask:true,think:"", content:"AI正在分析。。。"})
|
|
for (let uid of ele.uuids){
|
|
await doRequest(userid,uid,ele.params)
|
|
}
|
|
}
|
|
}
|
|
|
|
async function doRequest(_user:string,uuid:string,param:any){
|
|
let mRespMsg=""
|
|
const params={
|
|
"checkType":"travel",
|
|
"checkInfo":JSON.stringify(param)
|
|
}
|
|
|
|
controller.value = new AbortController();
|
|
try{
|
|
const res= await doAiChat(`${baseURL}/aibot/assisted/${uuid}/workflow`,{
|
|
inputs: params,
|
|
response_mode:"streaming",
|
|
user:_user,//这里已经base64解析了
|
|
},controller.value.signal
|
|
)
|
|
|
|
if (!res.ok) {
|
|
throw new Error(`HTTP ${res.status} ${res.statusText}`);
|
|
}
|
|
|
|
const reader = res.body!.getReader();
|
|
const decoder = new TextDecoder('utf-8');
|
|
|
|
let chunk = ''; // 行缓存
|
|
while (true) {
|
|
const {done, value} = await reader.read()
|
|
if (done) break;
|
|
|
|
// 服务器可能一次返回多行,需要手动按行拆分
|
|
chunk += decoder.decode(value, {stream: true});
|
|
const lines = chunk.split(/\n/);
|
|
chunk = lines.pop() || ''
|
|
for (const line of lines) {
|
|
if (!line.trim()) continue; // 跳过空行
|
|
if (line.startsWith('data: ')) {
|
|
const data = line.slice(6);
|
|
const json = JSON.parse(data);
|
|
if(json.event==="text_chunk"){
|
|
//conversation.value=json.conversation_id
|
|
mRespMsg+=json.data.text
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}catch (e: any) {
|
|
if (e.name === 'AbortError') {
|
|
console.log('用户手动中断')
|
|
}
|
|
}
|
|
|
|
interact_msg.value.unshift({ask:true,think:"", content:JSON.stringify(param)})
|
|
const arr=mRespMsg.split("</think>")
|
|
if(arr.length===1){
|
|
interact_msg.value.unshift({ask:false,think:"",content:arr[0]})
|
|
}else{
|
|
//思考模式
|
|
let st = arr[1].trim().match(/({.*})/s)
|
|
if (st){
|
|
let res= JSON.parse(st[1])
|
|
interact_msg.value.unshift({ask:false,think:res.success,content:res.reason})
|
|
}else{
|
|
interact_msg.value.unshift({ask:false,think:arr[0],content:arr[1]})
|
|
}
|
|
}
|
|
}
|
|
|
|
function resetContext(){
|
|
interact_msg.value=[]
|
|
conversation.value=""
|
|
//props.closefunc()
|
|
}
|
|
|
|
//渲染完页面再执行
|
|
// onMounted(() => {
|
|
// });
|
|
</script>
|
|
|
|
<template>
|
|
<div :style="{backgroundColor:'#f3f3f3'}">
|
|
<div class="reply_area" >
|
|
<template v-for="msg of interact_msg">
|
|
<div v-if="msg.ask" class="t_ask" >{{ msg.content }}</div>
|
|
<div v-else class="t_resp" :class="{merr:msg.think==false}">
|
|
{{ msg.content }}
|
|
<!-- <VueMarkdown :markdown="msg.content"></VueMarkdown> -->
|
|
</div>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
.reply_area{
|
|
width: 260px;
|
|
background: white;
|
|
overflow-y: auto;
|
|
display: flex;
|
|
flex-direction: column;
|
|
overflow-wrap:anywhere;
|
|
}
|
|
|
|
.t_ask{
|
|
margin: 5px;
|
|
align-self: end;
|
|
background-color: rgb(188 211 241);
|
|
border-radius:10px;
|
|
}
|
|
.t_resp{
|
|
margin: 5px;
|
|
font-size:14px;
|
|
align-self: start;
|
|
color: black;
|
|
background-color: rgb(222, 243, 222);
|
|
}
|
|
.merr{
|
|
background-color: rgb(253 176 211);
|
|
}
|
|
</style>
|
|
|