-
-
-
-
-
+
+
+
+
+
+
-
- {{ item.content }}
-
+
+
+ {{ item.content }}
+
+
{{fileName.file}}
-
-
-

-
+
+
+
+
+
+
+ 回到这里
+
+
+
+
+
+
+
+
-
-
-
+
+
数据治理管理专家
+
+

+
智能导航专家
+
@@ -146,6 +160,41 @@

+
+
+
+
+
+
+
+
+
+ 全部自动审批
+
+
+
+
+
+
+
+
+
+
+
@@ -184,10 +233,11 @@ import OperationButton from './OperationButton.vue'
import MdRenderer from '@/views/aichat/MdRenderer.vue'
import fullscreenG6 from '@/views/aichat/fullscreenG6.vue'
import {getToken} from "@/utils/auth.js";
-import {postChatMessage} from "@/api/aichat/aichat.js"
+import {addChat, DeleteChatList, postChatMessage, updateChatProcessData} from "@/api/aichat/aichat.js"
import cache from "@/plugins/cache.js";
import Cookies from "js-cookie";
-import {addChat} from "@/api/aichat/aichat";
+import Interrupt from "@/views/aichat/Interrupt.vue";
+import { v4 as uuidv4 } from 'uuid';
defineOptions({ name: 'AiChat' })
const route = useRoute()
@@ -226,11 +276,17 @@ const scrollDiv = ref()
const dialogScrollbar = ref()
const loading = ref(false)
const inputValue = ref('')
+const currentQuestion = ref({})
const chartOpenId = ref('')
const chatList = ref([])
const answerList = ref([])
const controller = ref(null)
-
+const autoProcess = ref({
+ checkAll: false,
+ isIndeterminate: false,
+ autoArray:[],
+ robots:['数据治理管理专家自动批准','元数据专家自动批准','数据标准专家自动批准','数据安全专家自动批准','数据分析专家自动批准','数据模型专家自动批准','数据质量专家自动批准','智能导航专家自动审批'],
+})
const popoverVisible = ref(false)
const currentMachine = ref([])
const currentFiles = ref([])
@@ -258,6 +314,39 @@ function setScrollBottom() {
scrollDiv.value.setScrollTop(getMaxHeight())
}
+function confirmReturn(item,index){
+ DeleteChatList(item.chatId).then(res=>{
+ chatList.value.splice(index, chatList.value.length - index);
+ let reqData = {
+ "user_id": cache.local.get("username"),
+ "session_id": Cookies.get("chatSessionId"),
+ "checkpointer": item.checkpointer
+ }
+ sendChatMessage(reqData)
+ })
+
+}
+
+function handleCheckAllRobot(){
+ autoProcess.value.checkAll = !autoProcess.value.checkAll
+ autoProcess.value.autoArray = autoProcess.value.checkAll ? autoProcess.value.robots : []
+ autoProcess.value.isIndeterminate = false
+}
+
+function toggleRobot(robot){
+ const index = autoProcess.value.autoArray.indexOf(robot)
+ if (index !== -1) {
+ // 已选中则取消
+ autoProcess.value.autoArray = autoProcess.value.autoArray.filter(item => item !== robot)
+ } else {
+ // 未选中则添加
+ autoProcess.value.autoArray = [...autoProcess.value.autoArray, robot]
+ }
+ const checkedCount = autoProcess.value.autoArray.length
+ autoProcess.value.checkAll = checkedCount === autoProcess.value.robots.length
+ autoProcess.value.isIndeterminate = checkedCount > 0 && checkedCount < autoProcess.value.robots.length
+}
+
/**
* 滚动条距离最上面的高度
*/
@@ -329,6 +418,7 @@ watch(() => props.cookieSessionId, value => upload.data = {sessionId:value})
function regenerationChart(index){
let question = chatList.value[index - 1]
let chat = {
+ "chatId":uuidv4(),
"type":"question",
"content":question.content,
"time": formatDate(new Date()),
@@ -340,7 +430,6 @@ function regenerationChart(index){
"robot": currentMachine.value.length>0?currentMachine.value[0]:"",
"session_id": Cookies.get("chatSessionId"),
"doc": chat.file,
- "history": []
}
sendChatMessage(data)
}
@@ -413,6 +502,25 @@ function downloadFile(file,bucket,sessionId){
}, file);
}
+function processAuth(data){
+ let updateData = {
+ chatId: data.chatId,
+ action: data.action,
+ interrupt: JSON.stringify(data.interrupt)
+ }
+ updateChatProcessData(updateData).then(res=>{
+ let reqData = {
+ "user_id": cache.local.get("username"),
+ "session_id": Cookies.get("chatSessionId"),
+ "checkpointer": data.checkpointer,
+ "action": data.action,
+ "resume": true,
+ "block": data.interrupt.block
+ }
+ sendChatMessage(reqData)
+ })
+}
+
async function sendChatHandle(event) {
if (!event.ctrlKey) {
// 如果没有按下组合键ctrl,则会阻止默认事件
@@ -421,6 +529,7 @@ async function sendChatHandle(event) {
(chatList.value[chatList.value.length - 1].isStop ||
chatList.value[chatList.value.length - 1].isEnd))) {
chatList.value.push({
+ "chatId": uuidv4(),
"type": "question",
"content": inputValue.value.trim(),
"time": formatDate(new Date()),
@@ -440,9 +549,14 @@ async function sendChatHandle(event) {
"user_id": cache.local.get("username"),
"robot": currentMachine.value.length > 0 ? currentMachine.value[0] : "",
"session_id": Cookies.get("chatSessionId"),
- "doc": currentFiles.value,
- "history": []
+ "doc": currentFiles.value
+ }
+ if (chatList.value.length > 1){
+ // 判断为1 因为上方已将问题加入 chatList了 , >1 则视为已存在提问交互
+ //取最新的checkpointer值
+ data.checkpointer = chatList.value[chatList.value.length - 2].content.checkpointer
}
+ currentQuestion.value = data
inputValue.value = ''
sendChatMessage(data)
}
@@ -456,23 +570,73 @@ function sendChatMessage(data){
controller.value = new AbortController()
postChatMessage(data,{signal:controller.value.signal}).then(res=>{
if (res.status !== 200){
- chatList.value.push({"type":"answer","content":[{"type":"text","content":"服务异常,错误码:"+res.status}],"isEnd":true,"isStop":false,"sessionId":chatList.value[0].sessionId,"sessionName":chatList.value[0].sessionName,"operate":'',"thumbDownReason":''})
+ chatList.value.push({"chatId":uuidv4(),"type":"answer","content":[{"type":"text","content":"服务异常,错误码:"+res.status}],"isEnd":true,"isStop":false,"sessionId":chatList.value[0].sessionId,"sessionName":chatList.value[0].sessionName,"operate":'',"thumbDownReason":''})
}else {
currentFiles.value = []
- chatList.value.push({"type":"answer","content":[],"isEnd":false,"isStop":false,"sessionId":chatList.value[0].sessionId,"sessionName":chatList.value[0].sessionName, "operate":'',"thumbDownReason":''})
+ chatList.value.push({"chatId":uuidv4(),"type":"answer","content":[],"isEnd":false,"isStop":false,"sessionId":chatList.value[0].sessionId,"sessionName":chatList.value[0].sessionName, "operate":'',"thumbDownReason":''})
const reader = res.body.getReader()
const write = getWrite(reader)
reader.read().then(write).then(()=> {
let answer = JSON.parse(JSON.stringify(chatList.value[chatList.value.length - 1]))
answer.content = JSON.stringify(answer.content)
+ answer.interrupt = JSON.stringify(answer.interrupt)? answer.interrupt: null
+ answer.checkpointer = JSON.stringify(answer.checkpointer)
addChat(answer)
+ }).then(()=>{
+ let answer = JSON.parse(JSON.stringify(chatList.value[chatList.value.length - 1]))
+ if(answer.interrupt){
+ let robot = answer.interrupt.robot
+ let block = answer.interrupt.block
+ let action = answer.interrupt.action
+ let autoRequest = false
+ if (autoProcess.value.autoArray.length > 0 && autoProcess.value.autoArray.indexOf(robot) !== -1){
+ //自动审批信号有效,需判断 block内容的必填项,有无默认值,有的话,可以自动发送,没有需填写
+ autoRequest = true
+ if (block && block.length>0){
+ for (let i = 0; i < block.length; i++) {
+ if (block[i].required){
+ if (block[i].ct_type === 'dateRangePicker' || block[i].ct_type === 'checkboxGroup' || block[i].ct_type === 'multiselect'){
+ //default_value 是数组
+ if (!block[i].default_value || block[i].default_value === []){
+ autoRequest = false
+ }
+ }
+ if (block[i].ct_type === 'datePicker' || block[i].ct_type === 'input' || block[i].ct_type === 'radioGroup' ||block[i].ct_type === 'select'){
+ //default_value 是文字
+ if (!block[i].default_value || block[i].default_value.trim() === ''){
+ autoRequest = false
+ }
+ }
+ }
+ }
+ }
+ if (autoRequest){
+ let reqData = {
+ "user_id": cache.local.get("username"),
+ "session_id": Cookies.get("chatSessionId"),
+ "checkpointer": answer.checkpointer,
+ "action":"",
+ "resume": true,
+ "block": block
+ }
+ for (let i = 0; i < action.length; i++) {
+ if (action[i].style === 'primary'){
+ reqData.action = action[i].action
+ }
+ }
+ sendChatMessage(reqData)
+ }
+ }
+ }
})
}
}).catch((e) => {
- chatList.value.push({"type":"answer","content":[{"type":"text","content":"服务异常"}],"isEnd":true,"isStop":false,"sessionId":chatList.value[0].sessionId,"sessionName":chatList.value[0].sessionName,"operate":"","thumbDownReason":""})
+ chatList.value.push({"chatId":uuidv4(),"type":"answer","content":[{"type":"text","content":"服务异常"}],"isEnd":true,"isStop":false,"sessionId":chatList.value[0].sessionId,"sessionName":chatList.value[0].sessionName,"operate":"","thumbDownReason":""})
})
}
+
+
watch(
chatList,
() => {
@@ -504,7 +668,6 @@ const getWrite = (reader) => {
for (let i = 0; i < split.length; i++) {
const chunkStr = split[i];
tempResult = tempResult.replace(chunkStr, '', 1); // 修复点4:单次替换避免残留
-
try {
const chunk = JSON.parse(chunkStr.replace('data:', '').trim());
processChunk(chunk);
@@ -512,7 +675,6 @@ const getWrite = (reader) => {
console.error('解析错误:', e, chunkStr);
}
}
-
// 递归处理剩余数据
return reader.read().then(write_stream);
} else {
@@ -523,7 +685,6 @@ const getWrite = (reader) => {
const processChunk = (chunk) => {
const lastMsg = chatList.value[chatList.value.length - 1];
- console.log(chunk)
// 修复点5:统一处理所有类型的数据块
if (chunk.docs?.length) {
lastMsg.content.push({ content: chunk.docs, type: "docs" });
@@ -552,13 +713,15 @@ const getWrite = (reader) => {
lastMsg.content.push({ content: text, type: "text" });
}
}
-
+ if (chunk.interrupt){
+ lastMsg.interrupt = chunk.interrupt
+ }
// 修复点7:统一处理结束标志
- if (chunk.isEnd || chunk.is_end) {
+ if (chunk.checkpointer) {
+ lastMsg.checkpointer = chunk.checkpointer
lastMsg.isEnd = true;
lastMsg.time = formatDate(new Date());
}
-
nextTick(() => scrollDiv.value.setScrollTop(getMaxHeight()));
};
@@ -586,7 +749,7 @@ defineExpose({
diff --git a/vue-fastapi-frontend/src/views/aichat/index.vue b/vue-fastapi-frontend/src/views/aichat/index.vue
index b6021ec..8bc1164 100644
--- a/vue-fastapi-frontend/src/views/aichat/index.vue
+++ b/vue-fastapi-frontend/src/views/aichat/index.vue
@@ -14,7 +14,7 @@
果知小助手