| | |
| | | '/api/v1/canvas/reset', |
| | | data |
| | | ); |
| | | } |
| | | } |
| | | |
| | | //高级agent会话 |
| | | export function agentConversationSetApi(data) { |
| | | return axios.post( |
| | | '/api/v1/advanced-agent/conversation-set', |
| | | data |
| | | ); |
| | | } |
| | | |
| | | //高级会话下载 |
| | | export function agentConverDownloadApi(data) { |
| | | return axios.post( |
| | | '/api/v1/advanced-agent/download', |
| | | data |
| | | ); |
| | | } |
| | | |
| | | export const downloadFile = ({ |
| | | url, |
| | | filename, |
| | | target, |
| | | }: { |
| | | url: string; |
| | | filename?: string; |
| | | target?: string; |
| | | }) => { |
| | | const downloadElement = document.createElement('a'); |
| | | downloadElement.style.display = 'none'; |
| | | downloadElement.href = url; |
| | | if (target) { |
| | | downloadElement.target = '_blank'; |
| | | } |
| | | downloadElement.rel = 'noopener noreferrer'; |
| | | if (filename) { |
| | | downloadElement.download = filename; |
| | | } |
| | | document.body.appendChild(downloadElement); |
| | | downloadElement.click(); |
| | | document.body.removeChild(downloadElement); |
| | | }; |
| | |
| | | // 获取解析方法列表 |
| | | export function getParseMethodsListApi() { |
| | | return axios.get<ISessionListResult>('/api/v1/user/parse-methods'); |
| | | } |
| | | } |
| | | |
| | | // 上传v1/document/upload_and_parse |
| | | export function uploadAndParse(params) { |
| | | const config = { |
| | | headers: { |
| | | 'Content-Type': 'application/x-www-form-urlencoded', |
| | | // token: token, |
| | | }, |
| | | }; |
| | | return axios.post('/api/v1/document/upload_and_parse', params, config); |
| | | } |
| | | |
| | | //高级会话 |
| | | export function seniorAgentApi(params) { |
| | | return axios.get<ISessionListResult>( |
| | | '/api/v1/advanced-agent/list', |
| | | params |
| | | ); |
| | | } |
| | |
| | | setUserResources(JSON.stringify(this.resources)) |
| | | for (const r of this.resources) { |
| | | if (r.menuType == 0) { |
| | | |
| | | return r.component |
| | | } |
| | | } |
| | |
| | | " |
| | | > |
| | | <div class="myAgentToolIcon___gaAKI myAgentToolIconNew___DBZrW"> |
| | | <img src="@/assets/images/icon-new.png" style="width: 24px" alt="" /> |
| | | <img |
| | | src="@/assets/images/icon-new.png" |
| | | style="width: 24px" |
| | | alt="" |
| | | /> |
| | | </div> |
| | | </div> |
| | | <div |
| | |
| | | " |
| | | > |
| | | <div class="myAgentToolIcon___gaAKI myAgentToolIconHistory___GTLWk"> |
| | | <!-- <img |
| | | <!-- <img |
| | | src="@/assets/images/historybg.png" |
| | | style="width: 24px" |
| | | alt="" |
| | |
| | | > |
| | | <div class="myAgentToolIcon___gaAKI myAgentToolIconSquare___Rj1o_"> |
| | | <!-- <img src="@/assets/images/agent.png" style="width: 24px" alt=""/> --> |
| | | <img src="@/assets/images/icon-zhi.png" style="width: 24px" alt="" |
| | | /> |
| | | <img |
| | | src="@/assets/images/icon-zhi.png" |
| | | style="width: 24px" |
| | | alt="" |
| | | /> |
| | | </div> |
| | | </div> |
| | | <div class="myAgentLine___Isl6E" style="margin-top: 4px"></div> |
| | |
| | | <template> |
| | | <div class="layoutHisCenter"> |
| | | <a-button |
| | | type="primary" |
| | | status="danger" |
| | | style=" |
| | | position: absolute; |
| | | top: 10px; |
| | | left: -40px; |
| | | font-size: 30px; |
| | | z-index: 99; |
| | | cursor: pointer" |
| | | @click="emit('changeAgentType','1')" |
| | | > |
| | | <template #icon> |
| | | <icon-close style="font-size: 20px" /> |
| | | </template> |
| | | </a-button> |
| | | <a-button |
| | | type="primary" |
| | | status="danger" |
| | | style=" |
| | | position: absolute; |
| | | top: 10px; |
| | | left: -40px; |
| | | font-size: 30px; |
| | | z-index: 99; |
| | | cursor: pointer; |
| | | " |
| | | @click="emit('changeAgentType', '1')" |
| | | > |
| | | <template #icon> |
| | | <icon-close style="font-size: 20px" /> |
| | | </template> |
| | | </a-button> |
| | | |
| | | <a-scrollbar |
| | | ref="scrollRef" |
| | | class="left-list" |
| | | style=" |
| | | height: calc(100vh - 160px); |
| | | overflow-y: scroll; |
| | | overflow-x: hidden; |
| | | " |
| | | v-if="isReached" |
| | | @scroll="handleScroll" |
| | | > |
| | | <div class="historyTitle___F_iam">历史会话</div> |
| | | <a-scrollbar |
| | | ref="scrollRef" |
| | | class="left-list" |
| | | style=" |
| | | height: calc(100vh - 160px); |
| | | overflow-y: scroll; |
| | | overflow-x: hidden; |
| | | " |
| | | v-if="isReached" |
| | | @scroll="handleScroll" |
| | | > |
| | | <div class="historyTitle___F_iam">历史会话</div> |
| | | |
| | | <div class="search"> |
| | | <!-- 查询框--> |
| | | <div class="search-box"> |
| | | <icon-search /> |
| | | <a-input |
| | | placeholder="搜索历史会话" |
| | | v-model="searchValue" |
| | | style="width: 90%" |
| | | /> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="search"> |
| | | <!-- 查询框--> |
| | | <div class="search-box"> |
| | | <icon-search /> |
| | | <a-input |
| | | placeholder="搜索历史会话" |
| | | v-model="searchValue" |
| | | style="width: 90%;" |
| | | /> |
| | | </div> |
| | | |
| | | </div> |
| | | |
| | | |
| | | <div class="historyCenter"> |
| | | <div |
| | | class="item historyCenter-box" |
| | | v-for="session in sessionList" |
| | | @click="querySessionDetail(session)" |
| | | @mouseenter="handleMouseEnter(session)" |
| | | @mouseleave="handleMouseLeave(session)" |
| | | > |
| | | <div class="text" > |
| | | <img |
| | | :style="{ width: '16px' }" |
| | | alt="dessert" |
| | | :src="session.icon ? httpUrl + session.icon : imgSrc" |
| | | /> |
| | | {{ session.name }} |
| | | </div> |
| | | <div class="time" |
| | | > |
| | | <span v-show="session.showtype == 1" style="font-size: 14px"> |
| | | {{ |
| | | moment(new Date(session.create_time)).format( |
| | | 'YYYY-MM-DD HH:mm:ss' |
| | | ) |
| | | }} |
| | | </span> |
| | | </div> |
| | | <a-button type="text" @click.stop="deleteSession(session)" style="color: red;position: absolute;right: 10px;top: 10px;" v-show="session.showtype == 2"> |
| | | <icon-delete style="font-size: 14px" /> |
| | | </a-button> |
| | | </div> |
| | | </div> |
| | | </a-scrollbar> |
| | | <div class="historyCenter"> |
| | | <div |
| | | class="item historyCenter-box" |
| | | v-for="session in sessionList" |
| | | @click="querySessionDetail(session)" |
| | | @mouseenter="handleMouseEnter(session)" |
| | | @mouseleave="handleMouseLeave(session)" |
| | | > |
| | | <div class="text"> |
| | | <img |
| | | :style="{ width: '16px' }" |
| | | alt="dessert" |
| | | :src="session.icon ? httpUrl + session.icon : imgSrc" |
| | | /> |
| | | {{ session.name }} |
| | | </div> |
| | | <div class="time"> |
| | | <span v-show="session.showtype == 1" style="font-size: 14px"> |
| | | {{ |
| | | moment(new Date(session.create_time)).format( |
| | | 'YYYY-MM-DD HH:mm:ss' |
| | | ) |
| | | }} |
| | | </span> |
| | | </div> |
| | | <a-button |
| | | type="text" |
| | | @click.stop="deleteSession(session)" |
| | | style="color: red; position: absolute; right: 10px; top: 10px" |
| | | v-show="session.showtype == 2" |
| | | > |
| | | <icon-delete style="font-size: 14px" /> |
| | | </a-button> |
| | | </div> |
| | | </div> |
| | | </a-scrollbar> |
| | | </div> |
| | | </template> |
| | | <script setup lang="ts"> |
| | | import { |
| | | IconClose, |
| | | IconSearch, |
| | | IconTiktokColor |
| | | } from "@arco-design/web-vue/es/icon"; |
| | | import { useAppStore, useUserStore } from "@/store"; |
| | | import { computed, nextTick, onMounted, watch, reactive, ref, onBeforeMount, onBeforeUnmount } from "vue"; |
| | | import { |
| | | IconClose, |
| | | IconSearch, |
| | | IconTiktokColor, |
| | | } from '@arco-design/web-vue/es/icon'; |
| | | import { useAppStore, useUserStore } from '@/store'; |
| | | import { |
| | | computed, |
| | | nextTick, |
| | | onMounted, |
| | | watch, |
| | | reactive, |
| | | ref, |
| | | onBeforeMount, |
| | | onBeforeUnmount, |
| | | } from 'vue'; |
| | | |
| | | import { Message, Modal } from "@arco-design/web-vue"; |
| | | import EventBus from '@/utils/EventBus'; |
| | | import moment from "moment"; |
| | | import { |
| | | addSessionApi, |
| | | chatApi, |
| | | getDialogListApi, |
| | | getSessionDetailsApi, |
| | | deleteSessionApi, |
| | | sessionListApiPage |
| | | } from "@/api/session"; |
| | | import { Message, Modal } from '@arco-design/web-vue'; |
| | | import EventBus from '@/utils/EventBus'; |
| | | import moment from 'moment'; |
| | | import { |
| | | addSessionApi, |
| | | chatApi, |
| | | getDialogListApi, |
| | | getSessionDetailsApi, |
| | | deleteSessionApi, |
| | | sessionListApiPage, |
| | | } from '@/api/session'; |
| | | |
| | | import { queryCanvasList } from "@/api/Agent"; |
| | | const emit = defineEmits(["querySessionDetail","changeAgentType"]); |
| | | import logo from "@/assets/images/model.png"; |
| | | import { deleteKnow } from "@/api/kbList"; |
| | | import { getAgentSessionDetailsApi } from "@/api/agentSession"; |
| | | const sessionList = ref([]); //会话列表 |
| | | const activeSessionId = ref(""); |
| | | const fieldNames = { value: "id", label: "name" }; |
| | | const dialogs = ref([]); |
| | | const dialogObj = reactive({}); |
| | | const agentObj = reactive({}); |
| | | const agentList = ref([]); |
| | | const searchValue = ref(""); |
| | | const selectValue = ref(""); |
| | | const sectionList = ref({}); |
| | | const scrollRef = ref(null); |
| | | const httpUrl = localStorage.getItem('httpUrl'); |
| | | const imgSrc = ref(logo); |
| | | let scrollTopVal = ref(0); |
| | | let queryPage = reactive({ |
| | | page: 1, |
| | | page_size: 50 |
| | | }) |
| | | let total = ref(0); |
| | | let sessionScrollList = ref([]); |
| | | let isReached = ref(true); |
| | | |
| | | const DialogList = async () => { |
| | | const { code, data } = await getDialogListApi(); |
| | | if (code === 200) { |
| | | if (data) { |
| | | selectValue.value = data[0].id; |
| | | dialogs.value = data.map((item) => { |
| | | return { |
| | | ...item, |
| | | type: 1 //智能体 |
| | | }; |
| | | }); |
| | | // console.log(data, "dialogs"); |
| | | queryCanvas(); |
| | | } |
| | | } |
| | | }; |
| | | |
| | | const queryCanvas = async (params = {}) => { |
| | | try { |
| | | const { data } = await queryCanvasList(params); |
| | | console.log(data, "agent"); |
| | | agentList.value = data.map((item) => { |
| | | return { |
| | | ...item, |
| | | name: item.title, |
| | | type: 2 //agent |
| | | }; |
| | | }); |
| | | // 合并数组 |
| | | dialogs.value = dialogs.value.concat(agentList.value); |
| | | |
| | | // 判断当前是智能体或agent |
| | | // console.log(val, 'val'); |
| | | // if (dialogs.value.length > 0) { |
| | | // dialogChange(dialogs.value[0].id); |
| | | // } |
| | | //新建会话 |
| | | querySessionList(dialogs.value[0].id); |
| | | |
| | | |
| | | } catch (err) { |
| | | // you can report use errorHandler or other |
| | | } finally { |
| | | } |
| | | }; |
| | | |
| | | |
| | | // 查询会话列表 |
| | | const querySessionList = async (id) => { |
| | | const { code, data } = await sessionListApiPage({ |
| | | dialog_id: id, |
| | | ...queryPage |
| | | import { queryCanvasList } from '@/api/Agent'; |
| | | const emit = defineEmits(['querySessionDetail', 'changeAgentType']); |
| | | import logo from '@/assets/images/model.png'; |
| | | import { deleteKnow } from '@/api/kbList'; |
| | | import { getAgentSessionDetailsApi } from '@/api/agentSession'; |
| | | const sessionList = ref([]); //会话列表 |
| | | const activeSessionId = ref(''); |
| | | const fieldNames = { value: 'id', label: 'name' }; |
| | | const dialogs = ref([]); |
| | | const dialogObj = reactive({}); |
| | | const agentObj = reactive({}); |
| | | const agentList = ref([]); |
| | | const searchValue = ref(''); |
| | | const selectValue = ref(''); |
| | | const sectionList = ref({}); |
| | | const scrollRef = ref(null); |
| | | const httpUrl = localStorage.getItem('httpUrl'); |
| | | const imgSrc = ref(logo); |
| | | let scrollTopVal = ref(0); |
| | | let queryPage = reactive({ |
| | | page: 1, |
| | | page_size: 50, |
| | | }); |
| | | if (code === 200) { |
| | | sessionList.value = data.map((item) => { |
| | | return { |
| | | ...item, |
| | | showtype: 1 |
| | | } |
| | | }); |
| | | isReached.value = false; |
| | | setTimeout(()=>{ |
| | | isReached.value = true; |
| | | },100) |
| | | // total.value = sessionList.value.length; |
| | | let total = ref(0); |
| | | let sessionScrollList = ref([]); |
| | | let isReached = ref(true); |
| | | |
| | | |
| | | } else { |
| | | Message.warning("查询失败"); |
| | | } |
| | | }; |
| | | |
| | | //根据会话id删除会话 |
| | | const deleteSession = async (session) => { |
| | | Modal.confirm({ |
| | | title: '提示信息', |
| | | content: '确认删除吗', |
| | | okText: '确定', |
| | | cancelText: '取消', |
| | | hideTitle: true, |
| | | onOk: async () => { |
| | | const { code } = await deleteSessionApi([session.id]); |
| | | if (code === 200) { |
| | | Message.success('删除成功'); |
| | | querySessionList(''); |
| | | } |
| | | }, |
| | | onCancel: () => {}, |
| | | }); |
| | | }; |
| | | |
| | | const querySessionDetail = async (session) => { |
| | | console.log(session, 'session'); |
| | | // 查询历史记录 app_type 1:智能体 2:agent |
| | | if (!session.base) { |
| | | // 生成智能体新的对话 |
| | | emit('changeAgentType','1'); |
| | | emit('querySessionDetail',session); |
| | | } else if (session.base == 'agent'){ |
| | | // agent对象数据封装 |
| | | // const { code, data } = await getAgentSessionDetailsApi(session.dialog_id); |
| | | // if (code == 0) { |
| | | // console.log(data,'会话详情'); |
| | | // // let sessionObj = { |
| | | // // id: session.app_id, |
| | | // // dsl: data.dsl, |
| | | // // title: session.name, |
| | | // // } |
| | | // } |
| | | EventBus.emit("queryAgentSessionDetail",session); |
| | | emit('changeAgentType','2'); |
| | | } |
| | | } |
| | | |
| | | |
| | | const handleMouseEnter = (session) => { |
| | | session.showtype = 2; |
| | | }; |
| | | |
| | | const handleMouseLeave = (session) => { |
| | | session.showtype = 1; |
| | | }; |
| | | |
| | | |
| | | const handleScroll = async (e: any) => { |
| | | scrollTopVal.value = e.target.scrollTop; |
| | | let offsetHeight = e.target.offsetHeight; |
| | | let scrollHeight = e.target.scrollHeight; |
| | | |
| | | if (scrollTopVal.value + offsetHeight >= scrollHeight-1) { |
| | | console.log(scrollTopVal.value); |
| | | // console.log(offsetHeight); |
| | | // console.log(scrollHeight); |
| | | //滚动条到达底部 |
| | | // if (sessionList.value.length < total.value) { |
| | | // //数据为加载完,继续赋值 |
| | | // // queryPage.page++ |
| | | // |
| | | // |
| | | // |
| | | // } |
| | | queryPage.page++ |
| | | const { code, data } = await sessionListApiPage({ |
| | | dialog_id: '', |
| | | ...queryPage |
| | | }); |
| | | const DialogList = async () => { |
| | | const { code, data } = await getDialogListApi(); |
| | | if (code === 200) { |
| | | sessionScrollList.value = data.map((item) => { |
| | | return { |
| | | ...item, |
| | | showtype: 1 |
| | | } |
| | | }); |
| | | // total.value = sessionList.value.length; |
| | | sessionList.value = [...sessionList.value,...sessionScrollList.value]; |
| | | isReached.value = false; |
| | | setTimeout(()=>{ |
| | | isReached.value = true; |
| | | nextTick(()=>{ |
| | | scrollRef.value.scrollTop(scrollTopVal.value); |
| | | // console.log(scrollRef.value.$el.scrollTop,'scrollTopVal'); |
| | | // console.log(scrollTopVal.value,'scrollTopVal'); |
| | | }) |
| | | },100) |
| | | |
| | | |
| | | } else { |
| | | Message.warning("查询失败"); |
| | | if (data) { |
| | | selectValue.value = data[0].id; |
| | | dialogs.value = data.map((item) => { |
| | | return { |
| | | ...item, |
| | | type: 1, //智能体 |
| | | }; |
| | | }); |
| | | // console.log(data, "dialogs"); |
| | | queryCanvas(); |
| | | } |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | onBeforeMount(()=>{ |
| | | // DialogList() |
| | | querySessionList(''); |
| | | }) |
| | | |
| | | onMounted(() => { |
| | | console.log(httpUrl,'当前地址'); |
| | | EventBus.on("history", () => { |
| | | emit('changeAgentType','3'); |
| | | // DialogList() |
| | | queryPage.page = 1; |
| | | querySessionList(''); |
| | | |
| | | }); |
| | | // 添加滚动事件监听器 |
| | | scrollRef.value.$el.addEventListener('scroll', handleScroll); |
| | | |
| | | // 清理函数 |
| | | return () => { |
| | | scrollRef.value.$el.removeEventListener('scroll', handleScroll); |
| | | }; |
| | | |
| | | const queryCanvas = async (params = {}) => { |
| | | try { |
| | | const { data } = await queryCanvasList(params); |
| | | console.log(data, 'agent'); |
| | | agentList.value = data.map((item) => { |
| | | return { |
| | | ...item, |
| | | name: item.title, |
| | | type: 2, //agent |
| | | }; |
| | | }); |
| | | // 合并数组 |
| | | dialogs.value = dialogs.value.concat(agentList.value); |
| | | |
| | | // 判断当前是智能体或agent |
| | | // console.log(val, 'val'); |
| | | // if (dialogs.value.length > 0) { |
| | | // dialogChange(dialogs.value[0].id); |
| | | // } |
| | | //新建会话 |
| | | querySessionList(dialogs.value[0].id); |
| | | } catch (err) { |
| | | // you can report use errorHandler or other |
| | | } finally { |
| | | } |
| | | }; |
| | | |
| | | }) |
| | | onBeforeUnmount(() => { |
| | | EventBus.off("history"); |
| | | }); |
| | | // 查询会话列表 |
| | | const querySessionList = async (id) => { |
| | | const { code, data } = await sessionListApiPage({ |
| | | dialog_id: id, |
| | | ...queryPage, |
| | | }); |
| | | if (code === 200) { |
| | | sessionList.value = data.map((item) => { |
| | | return { |
| | | ...item, |
| | | showtype: 1, |
| | | }; |
| | | }); |
| | | isReached.value = false; |
| | | setTimeout(() => { |
| | | isReached.value = true; |
| | | }, 100); |
| | | // total.value = sessionList.value.length; |
| | | } else { |
| | | Message.warning('查询失败'); |
| | | } |
| | | }; |
| | | |
| | | //根据会话id删除会话 |
| | | const deleteSession = async (session) => { |
| | | Modal.confirm({ |
| | | title: '提示信息', |
| | | content: '确认删除吗', |
| | | okText: '确定', |
| | | cancelText: '取消', |
| | | hideTitle: true, |
| | | onOk: async () => { |
| | | const { code } = await deleteSessionApi([session.id]); |
| | | if (code === 200) { |
| | | Message.success('删除成功'); |
| | | querySessionList(''); |
| | | } |
| | | }, |
| | | onCancel: () => {}, |
| | | }); |
| | | }; |
| | | |
| | | const querySessionDetail = async (session) => { |
| | | console.log(session, 'session'); |
| | | // 查询历史记录 app_type 1:智能体 2:agent |
| | | if (!session.base) { |
| | | // 生成智能体新的对话 |
| | | emit('changeAgentType', '1'); |
| | | emit('querySessionDetail', session); |
| | | } else if (session.base == 'agent') { |
| | | // agent对象数据封装 |
| | | // const { code, data } = await getAgentSessionDetailsApi(session.dialog_id); |
| | | // if (code == 0) { |
| | | // console.log(data,'会话详情'); |
| | | // // let sessionObj = { |
| | | // // id: session.app_id, |
| | | // // dsl: data.dsl, |
| | | // // title: session.name, |
| | | // // } |
| | | // } |
| | | EventBus.emit('queryAgentSessionDetail', session); |
| | | emit('changeAgentType', '2'); |
| | | } else if (session.base == 'advanced-agent') { |
| | | EventBus.emit('queryAgentSessionDetails', session); |
| | | emit('changeAgentType', '5'); |
| | | } |
| | | }; |
| | | |
| | | const handleMouseEnter = (session) => { |
| | | session.showtype = 2; |
| | | }; |
| | | |
| | | const handleMouseLeave = (session) => { |
| | | session.showtype = 1; |
| | | }; |
| | | |
| | | const handleScroll = async (e: any) => { |
| | | scrollTopVal.value = e.target.scrollTop; |
| | | let offsetHeight = e.target.offsetHeight; |
| | | let scrollHeight = e.target.scrollHeight; |
| | | |
| | | if (scrollTopVal.value + offsetHeight >= scrollHeight - 1) { |
| | | console.log(scrollTopVal.value); |
| | | // console.log(offsetHeight); |
| | | // console.log(scrollHeight); |
| | | //滚动条到达底部 |
| | | // if (sessionList.value.length < total.value) { |
| | | // //数据为加载完,继续赋值 |
| | | // // queryPage.page++ |
| | | // |
| | | // |
| | | // |
| | | // } |
| | | queryPage.page++; |
| | | const { code, data } = await sessionListApiPage({ |
| | | dialog_id: '', |
| | | ...queryPage, |
| | | }); |
| | | if (code === 200) { |
| | | sessionScrollList.value = data.map((item) => { |
| | | return { |
| | | ...item, |
| | | showtype: 1, |
| | | }; |
| | | }); |
| | | // total.value = sessionList.value.length; |
| | | sessionList.value = [...sessionList.value, ...sessionScrollList.value]; |
| | | isReached.value = false; |
| | | setTimeout(() => { |
| | | isReached.value = true; |
| | | nextTick(() => { |
| | | scrollRef.value.scrollTop(scrollTopVal.value); |
| | | // console.log(scrollRef.value.$el.scrollTop,'scrollTopVal'); |
| | | // console.log(scrollTopVal.value,'scrollTopVal'); |
| | | }); |
| | | }, 100); |
| | | } else { |
| | | Message.warning('查询失败'); |
| | | } |
| | | } |
| | | }; |
| | | |
| | | onBeforeMount(() => { |
| | | // DialogList() |
| | | querySessionList(''); |
| | | }); |
| | | |
| | | onMounted(() => { |
| | | console.log(httpUrl, '当前地址'); |
| | | EventBus.on('history', () => { |
| | | emit('changeAgentType', '3'); |
| | | // DialogList() |
| | | queryPage.page = 1; |
| | | querySessionList(''); |
| | | }); |
| | | // 添加滚动事件监听器 |
| | | scrollRef.value.$el.addEventListener('scroll', handleScroll); |
| | | |
| | | // 清理函数 |
| | | return () => { |
| | | scrollRef.value.$el.removeEventListener('scroll', handleScroll); |
| | | }; |
| | | }); |
| | | onBeforeUnmount(() => { |
| | | EventBus.off('history'); |
| | | }); |
| | | </script> |
| | | <style scoped lang="less"> |
| | | .layoutHisCenter{ |
| | | .layoutHisCenter { |
| | | width: 100%; |
| | | //background: #999999; |
| | | position: absolute; |
| | |
| | | font-weight: 700; |
| | | text-align: center; |
| | | } |
| | | .search{ |
| | | .search { |
| | | width: 100%; |
| | | .search-box{ |
| | | .search-box { |
| | | width: 70%; |
| | | margin-left: 15%; |
| | | border: 1px solid var(--color-text-4); |
| | |
| | | background: var(--color-bg-2); |
| | | margin-top: 20px; |
| | | margin-bottom: 20px; |
| | | :deep(.arco-input-wrapper){ |
| | | :deep(.arco-input-wrapper) { |
| | | border: none; |
| | | background: var(--color-bg-2); |
| | | } |
| | | } |
| | | } |
| | | .historyCenter{ |
| | | .historyCenter { |
| | | width: 100%; |
| | | margin-top: 30px; |
| | | .historyCenter-box{ |
| | | .historyCenter-box { |
| | | position: relative; |
| | | display: flex; |
| | | width: 70%; |
| | |
| | | align-items: center; |
| | | color: var(--color-text-2); |
| | | } |
| | | .historyCenter-box:hover{ |
| | | .historyCenter-box:hover { |
| | | color: var(--color-text-2); |
| | | //border: 1px solid var(--color-neutral-3); |
| | | background: var(--color-bg-3); |
| | | box-shadow: 0 1px 2px -2px rgba(0, 0, 0, 0.16), 0 3px 6px 0 rgba(0, 0, 0, 0.12), 0 5px 12px 4px rgba(0, 0, 0, 0.09); |
| | | box-shadow: 0 1px 2px -2px rgba(0, 0, 0, 0.16), |
| | | 0 3px 6px 0 rgba(0, 0, 0, 0.12), 0 5px 12px 4px rgba(0, 0, 0, 0.09); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <!-- 内容--> |
| | | <div class="header___section"> |
| | | <div class="chatHeader"> |
| | | <div class="chatHeaderBox"> |
| | | <!-- <span class="title">{{agentTitle}}</span>--> |
| | | <a-popover position="bottom" trigger="click"> |
| | | <a-button border> |
| | | <span |
| | | style=" |
| | | width: 100px; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | " |
| | | >{{ from.name }}</span |
| | | > |
| | | <icon-down style="margin-left: 4px" /> |
| | | </a-button> |
| | | <template #content> |
| | | <a-button |
| | | type="text" |
| | | class="button" |
| | | style="color: #2a2a2b" |
| | | @click="handleClick()" |
| | | > |
| | | <template #icon> |
| | | <icon-edit /> |
| | | </template> |
| | | 修改名称 |
| | | </a-button> |
| | | <!-- <a-divider style="margin: 10px 0" />--> |
| | | </template> |
| | | </a-popover> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <a-scrollbar |
| | | ref="scrollbar" |
| | | id="agentHome" |
| | | class="chat-list" |
| | | style=" |
| | | width: 80%; |
| | | overflow: auto; |
| | | height: calc(100vh - 380px); |
| | | margin: 0px auto 20px; |
| | | " |
| | | > |
| | | <div class="chat-item" v-for="(sessionDetail, index) in sessionDetailList"> |
| | | <a-comment v-if="sessionDetail.role === 'user'"> |
| | | <template #avatar> |
| | | <img |
| | | class="icon-user-jpg" |
| | | src="../../../assets/images/icon-user.jpg" |
| | | alt="本地图片" |
| | | /> |
| | | </template> |
| | | <template #content> |
| | | <div :class="{ chartUserText: theme === 'light' }" |
| | | >{{ sessionDetail.content }} |
| | | </div> |
| | | </template> |
| | | </a-comment> |
| | | <a-comment v-else-if="sessionDetail.role === 'assistant'"> |
| | | <template #avatar> |
| | | <img |
| | | class="icon-user-jpg" |
| | | src="../../../assets/images/icon-picture.png" |
| | | alt="本地图片" |
| | | /> |
| | | </template> |
| | | <template #content> |
| | | <!-- <a-card :class="{ chatItemAnswer: theme === 'light' }">--> |
| | | <!-- <div :class="{ light: theme === 'light' }"--> |
| | | <!-- >{{ sessionDetail.content }}--> |
| | | <!-- </div>--> |
| | | <!-- </a-card>--> |
| | | <a-textarea |
| | | readonly |
| | | auto-size |
| | | v-model="sessionDetail.content" |
| | | :class="{ chatItemAnswer: theme === 'light' }" |
| | | :style="{ |
| | | backgroundColor: theme === 'light' ? '#ffffff' : '#000000', |
| | | }" |
| | | style="border: none" |
| | | > |
| | | </a-textarea> |
| | | <!-- <div class="prompt"> |
| | | <ul> |
| | | <li class="prompt-item" @click="copyText('43234')"> |
| | | <span> |
| | | 344343klsdjkjksdjkjksdjk就开始大家看数据库登记卡受打击凯撒登记卡受打击凯撒登记卡受打击凯撒的43</span |
| | | > |
| | | <span style="margin-left: 20px"> |
| | | <icon-right /> |
| | | </span> |
| | | </li> |
| | | </ul> |
| | | </div> --> |
| | | </template> |
| | | <template #actions> |
| | | <span |
| | | class="action" |
| | | v-if="index != 0" |
| | | @click="copy(sessionDetail.content)" |
| | | > |
| | | <icon-copy /> 复制 |
| | | </span> |
| | | <span |
| | | class="action" |
| | | v-if="index != 0 && index == sessionDetailList.length - 1" |
| | | @click="reGenerate()" |
| | | > |
| | | <icon-refresh /> 重新生成 |
| | | </span> |
| | | <span |
| | | class="action" |
| | | v-if="sessionDetail.filename" |
| | | @click="iconDownload(sessionDetail)" |
| | | ><icon-to-bottom />下载 |
| | | </span> |
| | | </template> |
| | | </a-comment> |
| | | <a-comment v-else-if="sessionDetail.role === 'last'"> |
| | | <template #avatar> |
| | | <img |
| | | class="icon-user-jpg" |
| | | src="../../../assets/images/icon-picture.png" |
| | | alt="本地图片" |
| | | /> |
| | | </template> |
| | | <template #content> |
| | | <a-textarea |
| | | readonly |
| | | auto-size |
| | | v-model="displayedText" |
| | | :class="{ chatItemAnswer: theme === 'light' }" |
| | | :style="{ |
| | | backgroundColor: theme === 'light' ? '#ffffff' : '#000000', |
| | | }" |
| | | style="border: none" |
| | | > |
| | | </a-textarea> |
| | | </template> |
| | | <template #actions> |
| | | <div |
| | | class="action" |
| | | @click="stopChat" |
| | | style=" |
| | | background: var(--color-bg-2); |
| | | color: var(--color-primary-light-4); |
| | | " |
| | | v-if="displayedText != ''" |
| | | > |
| | | <icon-record-stop /> |
| | | 停止生成 |
| | | </div> |
| | | </template> |
| | | </a-comment> |
| | | </div> |
| | | <!-- <div class="chartStart" v-if="isStart" @click="startChat" |
| | | >停止生成</div |
| | | > |
| | | <div class="chartStart v-else" @click="stopChat">重新生成</div> --> |
| | | </a-scrollbar> |
| | | <div class="chat_bottom"> |
| | | <div class="center-bottom"> |
| | | <a-textarea |
| | | v-model="inputMsg" |
| | | @keydown.shift.enter="handleShiftEnter" |
| | | @keydown.enter="sendMessage" |
| | | placeholder="输入您想了解的内容,Shift+Enter换行,Enter发送" |
| | | allow-clear |
| | | show-word-limit |
| | | :disabled="chatDis" |
| | | :class="{ textItemAnswer: theme === 'dark' }" |
| | | :style="{ backgroundColor: theme === 'light' ? '#ffffff' : '#000000' }" |
| | | style="border: none" |
| | | :auto-size="{ |
| | | minRows: 12, |
| | | maxRows: 5, |
| | | }" |
| | | /> |
| | | <div style="width: 100%; display: flex; justify-content: space-between"> |
| | | <span></span> |
| | | <a-button |
| | | :disabled="chatDis" |
| | | @click="sentClick" |
| | | type="text" |
| | | style="border-radius: 24px" |
| | | :loading="loading" |
| | | > |
| | | <icon-send size="32" style="color: #0960bd" /> |
| | | </a-button> |
| | | </div> |
| | | <!-- <div class="btn-send">--> |
| | | <!-- <!– <icon-send size="32" /> –>--> |
| | | <!-- <a-button--> |
| | | <!-- :disabled="chatDis"--> |
| | | <!-- @click="sentClick"--> |
| | | <!-- type="text"--> |
| | | <!-- style="border-radius: 24px"--> |
| | | <!-- :loading="loading"--> |
| | | <!-- >--> |
| | | <!-- <icon-send size="32" style="color: #0960bd;"/>--> |
| | | <!-- </a-button--> |
| | | <!-- >--> |
| | | <!-- </div>--> |
| | | </div> |
| | | <a-modal |
| | | v-model:visible="visible" |
| | | title="修改名称" |
| | | @before-open="handleOpened" |
| | | @cancel="handleCancel" |
| | | :footer="false" |
| | | title-align="start" |
| | | > |
| | | <a-form ref="formRef" :rules="rules" :model="from" @submit="handleSubmit"> |
| | | <a-form-item field="name" label="名称"> |
| | | <a-input v-model="from.name" placeholder="请输入名称" /> |
| | | </a-form-item> |
| | | <a-form-item> |
| | | <div style="width: 100%; text-align: right"> |
| | | <a-button @click="visible = false">取消</a-button> |
| | | <a-button |
| | | style="margin-left: 10px" |
| | | type="primary" |
| | | html-type="submit" |
| | | >确定</a-button |
| | | > |
| | | </div> |
| | | </a-form-item> |
| | | </a-form> |
| | | </a-modal> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { |
| | | defineProps, |
| | | ref, |
| | | watch, |
| | | defineEmits, |
| | | onMounted, |
| | | reactive, |
| | | computed, |
| | | nextTick, |
| | | onBeforeUnmount, |
| | | } from 'vue'; |
| | | import { Message } from '@arco-design/web-vue'; |
| | | import { useAppStore } from '@/store'; |
| | | import { getAuthorization } from '@/utils/auth'; |
| | | import { EventSourceParserStream } from 'eventsource-parser/stream'; |
| | | import { |
| | | agentResetApi, |
| | | agentSetApi, |
| | | getAgentSessionDetailsApi, |
| | | agentConversationSetApi, |
| | | agentConverDownloadApi, |
| | | downloadFile, |
| | | } from '@/api/agentSession'; |
| | | import EventBus from '@/utils/EventBus'; |
| | | import useClipboard from 'vue-clipboard3'; |
| | | import { addSessionApi, getSessionDetailsApi } from '@/api/session'; |
| | | const props = defineProps({ |
| | | modalObj: Object, |
| | | }); |
| | | |
| | | // const emit = defineEmits(['addSession']); |
| | | |
| | | const sessionDetailList = ref([ |
| | | { |
| | | content: '你好! 我是你的助理,有什么可以帮到你的吗?', |
| | | role: 'assistant', |
| | | }, |
| | | ]); //根据会话id出来的会话详情 |
| | | const sessionList = ref([]); //会话列表 |
| | | const modalObj = reactive({}); |
| | | const dialogId = ref(''); |
| | | const chatDis = ref(false); |
| | | const loading = ref(false); |
| | | const agentTitle = ref('未命名会话'); |
| | | |
| | | const currIndex = ref(0); |
| | | const displayedText = ref(''); // 正在显示的文字 |
| | | let timer: number | null = null; |
| | | const streamStr = ref(''); |
| | | const inputMsg = ref(''); |
| | | const activeSessionId = ref(''); |
| | | const conversation_id = ref(''); |
| | | const fieldNames = { value: 'id', label: 'name' }; |
| | | const agentObj = reactive({}); |
| | | const agentList = ref([]); |
| | | const selectValue = ref(''); |
| | | const sectionList = ref({}); |
| | | let chatObj = reactive({}); |
| | | const isStopChat = ref(false); |
| | | const appStore = useAppStore(); |
| | | const sessionObj = reactive({}); |
| | | const theme = computed(() => { |
| | | return appStore.theme; |
| | | }); |
| | | let from = reactive({ |
| | | name: '未命名会话', |
| | | }); |
| | | |
| | | const visible = ref(false); |
| | | let isHistory = ref(false); //是否是历史记录 |
| | | let dsl = reactive({}); |
| | | const chatDataMeg = reactive({}); |
| | | |
| | | const rules = { |
| | | name: [ |
| | | { |
| | | required: true, |
| | | message: '名称不允许为空', |
| | | }, |
| | | ], |
| | | }; |
| | | |
| | | const handleSubmit = async ({ values, errors }) => { |
| | | if (errors) return; |
| | | |
| | | let chatData = { |
| | | id: conversation_id.value, |
| | | conversation_id: conversation_id.value, |
| | | name: from.name, |
| | | }; |
| | | const { code, data } = await addSessionApi(chatData); |
| | | if (data) { |
| | | Message.success('修改成功'); |
| | | handleCancel(); |
| | | } |
| | | }; |
| | | |
| | | const handleClick = () => { |
| | | visible.value = true; |
| | | }; |
| | | const handleCancel = () => { |
| | | visible.value = false; |
| | | }; |
| | | |
| | | const handleOpened = (el) => { |
| | | // Object.assign(form,{ |
| | | // name: '',// 用户名 |
| | | // }); |
| | | // formRef.value.resetFields(); |
| | | }; |
| | | |
| | | // 初始化页面 |
| | | const initPage = async () => { |
| | | // agentSet(); |
| | | }; |
| | | |
| | | const createNewAgent = async (session) => { |
| | | sessionDetailList.value = [ |
| | | { |
| | | content: '你好! 我是你的助理,有什么可以帮到你的吗?', |
| | | role: 'assistant', |
| | | }, |
| | | ]; |
| | | Object.assign(agentObj, session); |
| | | from.name = session.name; |
| | | const dataSession = session.prompt_config; |
| | | if (dataSession.prologue) { |
| | | sessionDetailList.value[0].content = dataSession.prologue; |
| | | } |
| | | |
| | | isHistory.value = false; |
| | | initPage(); |
| | | }; |
| | | // 调用set方法 |
| | | const agentSet = async () => { |
| | | const res = await agentSetApi({ |
| | | id: agentObj.id, |
| | | title: agentObj.title, |
| | | dsl: agentObj.dsl, |
| | | }); |
| | | // console.log(res,'agentSet'); |
| | | if (res.code == 0) { |
| | | conversation_id.value = res.data.conversation_id; |
| | | agentReset(); |
| | | } |
| | | }; |
| | | // 调用reset方法 |
| | | const agentReset = async () => { |
| | | const res = await agentResetApi({ |
| | | id: agentObj.id, |
| | | }); |
| | | if (res.code == 0) { |
| | | // Message.success('修改成功'); |
| | | agentCompletion(); |
| | | } |
| | | }; |
| | | // 调用completion方法 |
| | | const agentCompletion = async () => { |
| | | const response = await fetch('/api/v1/canvas/completion', { |
| | | method: 'POST', |
| | | headers: { |
| | | 'Authorization': getAuthorization(), |
| | | 'Content-Type': 'application/json', |
| | | }, |
| | | body: JSON.stringify({ |
| | | id: agentObj.id, |
| | | }), |
| | | }); |
| | | |
| | | const reader = response?.body |
| | | ?.pipeThrough(new TextDecoderStream()) |
| | | .pipeThrough(new EventSourceParserStream()) |
| | | .getReader(); |
| | | currIndex.value = 0; |
| | | while (true) { |
| | | const x = await reader?.read(); |
| | | if (x) { |
| | | const { done, value } = x; |
| | | |
| | | try { |
| | | const val = JSON.parse(value?.data || ''); |
| | | const d = val?.data; |
| | | if (typeof d !== 'boolean') { |
| | | console.info('data:', d); |
| | | streamStr.value = d.content; |
| | | startDisplayStr(); |
| | | } |
| | | } catch (e) { |
| | | console.warn(e); |
| | | } |
| | | if (done) { |
| | | console.info('done'); |
| | | displayedText.value = ''; |
| | | // queryAgentSessionDetail(activeSessionId.value); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | chatDis.value = false; |
| | | loading.value = false; |
| | | inputMsg.value = ''; |
| | | }; |
| | | // 调用get方法 |
| | | const queryAgentSessionDetails = async (id) => { |
| | | const { code, data } = await getSessionDetailsApi(id); |
| | | |
| | | if (code == 200) { |
| | | console.log(data, 'agent会话详情'); |
| | | Object.assign(chatObj, data); |
| | | // nextTick(() => { |
| | | // sessionDetailList.value = data.dsl.messages; |
| | | // }); |
| | | sessionDetailList.value = data.message; |
| | | |
| | | agentTitle.value = `${data.name}` || '未命名会话'; |
| | | from.name = `${data.name}` || '未命名会话'; |
| | | refreshScroll(); //刷新滚动条位置 |
| | | } |
| | | }; |
| | | |
| | | const copyText = (text) => { |
| | | inputMsg.value = text; |
| | | }; |
| | | |
| | | // 历史记录跳转获取agent会话详情 |
| | | const querySessionDetail = async (session) => { |
| | | conversation_id.value = session.id; |
| | | activeSessionId.value = session.id; |
| | | from.name = session.name; |
| | | const { code, data } = await getSessionDetailsApi(session.id); |
| | | |
| | | if (code == 200) { |
| | | sessionDetailList.value = data.message; |
| | | refreshScroll(); //刷新滚动条位置 |
| | | // const res = await getAgentSessionDetailsApi(session.dialog_id); |
| | | // if (res.code == 0) { |
| | | // Object.assign(agentObj, res.data); |
| | | // Object.assign(chatObj, res.data); |
| | | // Object.assign(dsl, res.data.dsl); |
| | | // refreshScroll(); //刷新滚动条位置 |
| | | // } |
| | | } |
| | | }; |
| | | |
| | | const { toClipboard } = useClipboard(); |
| | | const copy = async (text) => { |
| | | await toClipboard(text); //参数为要复制的文本 |
| | | }; |
| | | |
| | | const sentClick = () => { |
| | | sendMessage('click'); |
| | | }; |
| | | |
| | | // 重新生成 |
| | | const reGenerate = () => { |
| | | let inputContent = |
| | | sessionDetailList.value[sessionDetailList.value.length - 2].content; |
| | | startChat(inputContent); |
| | | }; |
| | | |
| | | const sendMessage = async (event) => { |
| | | if (event.keyCode == 13 || event === 'click') { |
| | | if (!event.shiftKey) { |
| | | //只有enter没有shift,或进行你的其他逻辑 |
| | | if (event !== 'click') { |
| | | event.preventDefault(); // 阻止默认行为,即不换行 |
| | | } |
| | | |
| | | // chatDis.value = true; |
| | | // loading.value = true; |
| | | // if (!agentObj.id) { |
| | | // Message.warning('请选择会话'); |
| | | // chatDis.value = false; |
| | | // loading.value = false; |
| | | // return; |
| | | // } |
| | | |
| | | // if (displayedText.value) { |
| | | // querySessionList(); |
| | | // } |
| | | |
| | | if (inputMsg.value) { |
| | | // const res = await addSessionApi({ |
| | | // dialog_id: '', |
| | | // conversation_desc: inputMsg.value, |
| | | // }); |
| | | // // console.log(res, "res"); |
| | | // if (res.code == 200) { |
| | | // // console.log(res.data.conversation_id); |
| | | // activeSessionId.value = res.data?.conversation_id; |
| | | // const { code, data } = await getSessionDetailsApi( |
| | | // res.data?.conversation_id |
| | | // ); |
| | | // if (code === 200) { |
| | | // console.log(data, '新建会话详情'); |
| | | // Object.assign(chatObj, data); |
| | | // startChat(inputMsg.value); |
| | | // inputMsg.value = ''; |
| | | // } |
| | | // } else { |
| | | // Message.error('创建会话失败,请重试'); |
| | | // } |
| | | |
| | | // startChat(inputMsg.value); |
| | | // inputMsg.value = ''; |
| | | createSession(); |
| | | } else { |
| | | Message.warning('消息不能为空'); |
| | | chatDis.value = false; |
| | | loading.value = false; |
| | | } |
| | | } |
| | | } |
| | | }; |
| | | //创建会话 |
| | | const createSession = async () => { |
| | | try { |
| | | loading.value = true; |
| | | chatDis.value = true; |
| | | |
| | | if (!activeSessionId.value) { |
| | | let message = [ |
| | | { |
| | | content: sessionDetailList.value[0].content, |
| | | role: 'assistant', |
| | | }, |
| | | { |
| | | content: inputMsg.value, |
| | | role: 'user', |
| | | }, |
| | | ]; |
| | | const res = await agentConversationSetApi({ |
| | | id: '', |
| | | app_id: agentObj.id, |
| | | name: inputMsg.value, |
| | | message: message, |
| | | }); |
| | | // console.log(res, "res"); |
| | | if (res.code == 200) { |
| | | // console.log(res.data.conversation_id); |
| | | activeSessionId.value = res.data?.id; |
| | | |
| | | startChat(inputMsg.value); |
| | | inputMsg.value = ''; |
| | | } |
| | | } else { |
| | | startChat(inputMsg.value); |
| | | inputMsg.value = ''; |
| | | } |
| | | } catch (err) { |
| | | // throw err; |
| | | Message.error('创建会话失败,请重试'); |
| | | loading.value = false; |
| | | chatDis.value = false; |
| | | } |
| | | }; |
| | | |
| | | //下载 |
| | | const iconDownload = async (val) => { |
| | | await downloadFile({ |
| | | url: `/api/v1/advanced-agent/download?file_id=` + val.filename, |
| | | }); |
| | | }; |
| | | |
| | | //聊天 |
| | | const startChat = async (valMsg) => { |
| | | sessionDetailList.value.push({ |
| | | content: valMsg, |
| | | role: 'user', |
| | | }); |
| | | sessionDetailList.value.push({ role: 'last' }); |
| | | refreshScroll(); |
| | | let chatStr = { |
| | | id: activeSessionId.value, |
| | | message: valMsg, |
| | | }; |
| | | if (isHistory.value) { |
| | | chatStr.dsl = dsl; |
| | | } |
| | | const response = await fetch('/api/v1/advanced-agent/completion', { |
| | | method: 'POST', |
| | | headers: { |
| | | 'Authorization': getAuthorization(), |
| | | 'Content-Type': 'application/json', |
| | | }, |
| | | body: JSON.stringify(chatStr), |
| | | }); |
| | | |
| | | const reader = response?.body |
| | | ?.pipeThrough(new TextDecoderStream()) |
| | | .pipeThrough(new EventSourceParserStream()) |
| | | .getReader(); |
| | | currIndex.value = 0; |
| | | while (true) { |
| | | const x = await reader?.read(); |
| | | if (x) { |
| | | const { done, value } = x; |
| | | // console.log(x, 999); |
| | | |
| | | if (value && value?.event == 'message') { |
| | | try { |
| | | const val = JSON.parse(value?.data || ''); |
| | | const d = val?.data; |
| | | |
| | | if (typeof d !== 'boolean') { |
| | | console.info('data:', d); |
| | | streamStr.value = d.content; |
| | | startDisplayStr(); |
| | | } |
| | | } catch (e) { |
| | | console.warn(e); |
| | | } |
| | | } |
| | | |
| | | if (done) { |
| | | console.info('done'); |
| | | // displayedText.value = ''; |
| | | if (isStopChat.value) { |
| | | isStopChat.value = false; |
| | | setChatDataMeg(chatDataMeg); |
| | | } else { |
| | | // queryAgentSessionDetail(activeSessionId.value); |
| | | // EventBus.emit('queryAppUsageList'); |
| | | } |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | chatDis.value = false; |
| | | loading.value = false; |
| | | }; |
| | | |
| | | const stopChat = async () => { |
| | | // const { code, data } = await stopChatApi(agentObj.id); |
| | | // if (code === 200) { |
| | | // Message.success("已停止"); |
| | | // } |
| | | loading.value = false; |
| | | chatDis.value = false; |
| | | isStopChat.value = true; |
| | | |
| | | let inputText = |
| | | sessionDetailList.value[sessionDetailList.value.length - 2].content; |
| | | // 数组合并 |
| | | let lastArr = [ |
| | | { |
| | | content: inputText, |
| | | role: 'user', |
| | | }, |
| | | { |
| | | content: displayedText.value, |
| | | role: 'assistant', |
| | | }, |
| | | ]; |
| | | sessionDetailList.value = sessionDetailList.value |
| | | .splice(0, sessionDetailList.value.length - 2) |
| | | .concat(lastArr); |
| | | |
| | | chatObj.dsl.messages = chatObj.dsl.messages.concat(lastArr); |
| | | Object.assign(chatDataMeg, { |
| | | id: chatObj.id, |
| | | conversation_id: chatObj.id, |
| | | message: sessionDetailList.value, |
| | | }); |
| | | }; |
| | | |
| | | const setChatDataMeg = async (chatData) => { |
| | | const { code, data } = await addSessionApi(chatData); |
| | | if (data) { |
| | | //停止定时器 |
| | | clearTimeout(timer!); |
| | | timer = null; |
| | | // displayedText.value = ""; |
| | | queryAgentSessionDetails(activeSessionId.value); |
| | | } |
| | | }; |
| | | |
| | | const handleShiftEnter = (event) => { |
| | | event.preventDefault(); |
| | | inputMsg.value += '\n'; |
| | | }; |
| | | |
| | | //文字动态输出 |
| | | const startDisplayStr = () => { |
| | | if (timer) { |
| | | clearTimeout(timer!); |
| | | } |
| | | const res = streamStr.value; |
| | | // 将数组中的字符串拼接起来 |
| | | |
| | | if (currIndex.value < res.length) { |
| | | displayedText.value += res[currIndex.value]; |
| | | |
| | | currIndex.value++; |
| | | setTimeout(startDisplayStr, 100); |
| | | refreshScroll(); |
| | | } else { |
| | | displayedText.value = ''; |
| | | queryAgentSessionDetails(activeSessionId.value); |
| | | clearTimeout(timer!); |
| | | timer = null; |
| | | } |
| | | }; |
| | | |
| | | const scrollbar = ref(null); |
| | | const refreshScroll = () => { |
| | | nextTick(() => { |
| | | const container = document.getElementById('agentHome'); |
| | | scrollbar.value.scrollTop(container.scrollHeight); |
| | | }); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | EventBus.on('createSeniorAgent', (data) => { |
| | | createNewAgent(data); |
| | | }); |
| | | EventBus.on('queryAgentSessionDetails', (data) => { |
| | | isHistory.value = true; |
| | | querySessionDetail(data); |
| | | }); |
| | | }); |
| | | onBeforeUnmount(() => { |
| | | EventBus.off('createSeniorAgent'); |
| | | EventBus.off('queryAgentSessionDetails'); |
| | | }); |
| | | |
| | | watch( |
| | | () => props.modalObj, |
| | | (newVal, oldVal) => { |
| | | // Object.assign(agentObj, newVal); |
| | | //调用agent初始化方法 |
| | | if (JSON.stringify(newVal) != '{}') { |
| | | // initPage(); |
| | | } |
| | | }, |
| | | { |
| | | immediate: true, |
| | | deep: true, |
| | | } |
| | | ); |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .dark { |
| | | color: gray !important; |
| | | } |
| | | |
| | | .container { |
| | | .chatItemAnswer { |
| | | box-sizing: border-box; |
| | | background: #f1f1f1; |
| | | border-radius: 10px; |
| | | padding: 5px; |
| | | .light { |
| | | box-sizing: border-box; |
| | | background: #f1f1f1; |
| | | border-radius: 10px; |
| | | } |
| | | } |
| | | .textItemAnswer { |
| | | background-color: #373739; |
| | | } |
| | | |
| | | .center { |
| | | box-sizing: border-box; |
| | | height: calc(100vh - 200px); |
| | | position: relative; |
| | | |
| | | .center-title { |
| | | line-height: 60px; |
| | | font-size: 25px; |
| | | font-family: 黑体; |
| | | color: deepskyblue; |
| | | } |
| | | |
| | | .center-content { |
| | | font-size: 14px; |
| | | color: gray; |
| | | } |
| | | |
| | | .center-question { |
| | | margin-top: 20px; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | |
| | | .center-question-left { |
| | | margin-top: 5px; |
| | | margin-left: 20px; |
| | | } |
| | | |
| | | .center-question-right { |
| | | margin-right: 20px; |
| | | } |
| | | } |
| | | .center-list { |
| | | margin-top: 10px; |
| | | |
| | | .item { |
| | | border-radius: 10px; |
| | | margin-top: 10px; |
| | | padding: 10px; |
| | | min-height: 120px; |
| | | background-color: #e9f3ff; |
| | | .item-content { |
| | | color: #666; |
| | | } |
| | | .item-title { |
| | | text-align: center; |
| | | line-height: 40px; |
| | | font-size: 20px; |
| | | font-family: 黑体; |
| | | color: #333; |
| | | } |
| | | } |
| | | } |
| | | .chartStart { |
| | | color: #4955f5; |
| | | cursor: pointer; |
| | | font-family: PingFangSC-Medium; |
| | | font-size: 12px; |
| | | font-weight: 500; |
| | | } |
| | | .chat_bottom { |
| | | display: flex; |
| | | align-items: center; |
| | | width: 78%; |
| | | margin: 0 auto; |
| | | .center-bottom { |
| | | // position: absolute; |
| | | // width: 90%; |
| | | // bottom: 20px; |
| | | // left: 5%; |
| | | background: #fff; |
| | | border: 1px solid #00000014; |
| | | border-radius: 24px; |
| | | display: flex; |
| | | flex: 1 1; |
| | | flex-direction: column; |
| | | overflow: hidden; |
| | | position: relative; |
| | | // padding-top:10px; |
| | | :deep(.arco-textarea-wrapper) { |
| | | border-radius: 24px; |
| | | } |
| | | |
| | | .btn-send { |
| | | position: absolute !important; |
| | | right: 4px; |
| | | top: 80px; |
| | | z-index: 10; |
| | | } |
| | | :deep(.arco-btn-size-large) { |
| | | height: 28px; |
| | | width: 50px; |
| | | } |
| | | } |
| | | :deep(.arco-textarea-wrapper) { |
| | | padding-top: 5px; |
| | | } |
| | | } |
| | | } |
| | | .chat-item { |
| | | padding: 10px 0; |
| | | .chartUserText { |
| | | font-weight: 600; |
| | | font-size: 14px; |
| | | color: #333; |
| | | margin-top: 4px; |
| | | } |
| | | .icon-user-jpg { |
| | | border: 1px solid #d9d9d9; |
| | | } |
| | | .prompt { |
| | | ul { |
| | | margin: 0; |
| | | padding: 0; |
| | | display: flex; |
| | | } |
| | | ul > li { |
| | | list-style-type: none; |
| | | } |
| | | .prompt-item { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | background-color: #fff; |
| | | cursor: pointer; |
| | | border-radius: 8px; |
| | | padding: 10px; |
| | | border: #e5e5e5; |
| | | &:hover { |
| | | background-color: #eee; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .header___section { |
| | | width: 100%; |
| | | height: 46px; |
| | | position: relative; |
| | | backdrop-filter: blur(15px); |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | -webkit-backdrop-filter: blur(15px); |
| | | .chatHeaderBox { |
| | | width: auto; |
| | | border-radius: 8px; |
| | | padding: 4px 20px; |
| | | transition: all var(--animation-duration) var(--animation-transition); |
| | | display: flex; |
| | | align-items: flex-end; |
| | | overflow: hidden; /* 隐藏超出的内容 */ |
| | | text-overflow: ellipsis; /* 使用省略号来代替被隐藏的文字 */ |
| | | white-space: nowrap; /* 不换行,使内容在一行内显示 */ |
| | | max-width: 200px; |
| | | .title { |
| | | color: var(--color-text-1); |
| | | font-size: 12px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .action { |
| | | cursor: pointer; |
| | | display: inline-block; |
| | | padding: 0 10px; |
| | | color: var(--color-text-1); |
| | | line-height: 24px; |
| | | background: transparent; |
| | | border-radius: 2px; |
| | | cursor: pointer; |
| | | transition: all 0.1s ease; |
| | | font-size: 12px; |
| | | } |
| | | .action:hover { |
| | | background: var(--color-fill-3); |
| | | } |
| | | </style> |
| | |
| | | <div class="time"> </div> |
| | | </div> |
| | | </a-col> |
| | | <a-col :span="8" v-for="item in seniorAgentList"> |
| | | <div class="item agentCenter-box" @click="createNewSession(item)"> |
| | | <div class="text"> |
| | | <a-avatar> |
| | | <img |
| | | :style="{ width: '100%' }" |
| | | alt="dessert" |
| | | :src="item.icon || imgSrc" |
| | | /> |
| | | </a-avatar> |
| | | <span |
| | | style=" |
| | | margin-left: 10px; |
| | | font-weight: 500; |
| | | color: var(--color-text-1); |
| | | " |
| | | > |
| | | {{ item.name }} |
| | | </span> |
| | | </div> |
| | | <div class="time"> </div> |
| | | </div> |
| | | </a-col> |
| | | </a-row> |
| | | </div> |
| | | </a-scrollbar> |
| | |
| | | getDialogListApi, |
| | | getSessionDetailsApi, |
| | | sessionListApi, |
| | | seniorAgentApi, |
| | | } from '@/api/session'; |
| | | import { queryCanvasList } from '@/api/Agent'; |
| | | const emit = defineEmits([ |
| | |
| | | 'createSession', |
| | | ]); |
| | | import logo from '@/assets/images/model.png'; |
| | | import { create } from 'lodash'; |
| | | const sessionList = ref([]); //会话列表 |
| | | const activeSessionId = ref(''); |
| | | const fieldNames = { value: 'id', label: 'name' }; |
| | |
| | | const dialogObj = reactive({}); |
| | | const agentObj = reactive({}); |
| | | const agentList = ref([]); |
| | | const seniorAgentList = ref([]); |
| | | const searchValue = ref(''); |
| | | const selectValue = ref(''); |
| | | const sectionList = ref({}); |
| | |
| | | } |
| | | }; |
| | | |
| | | //高级会话 |
| | | const querySeniorAgent = async () => { |
| | | const { code, data } = await seniorAgentApi(); |
| | | if (code === 200) { |
| | | seniorAgentList.value = data; |
| | | } |
| | | }; |
| | | |
| | | // 查询会话列表 |
| | | const querySessionList = async (id) => { |
| | | const { code, data } = await sessionListApi(id); |
| | |
| | | const createNewSession = async (session) => { |
| | | console.log(session, 'session'); |
| | | // emit('querySessionDetail',session); |
| | | if (session.type == '1') { |
| | | // 生成智能体新的对话 |
| | | emit('createSession', session.id, `和${session.name}的会话`); |
| | | emit('changeAgentType', '1'); |
| | | |
| | | if (session.app_type == '3') { |
| | | //高级agent |
| | | EventBus.emit('createSeniorAgent', session); |
| | | emit('changeAgentType', '5'); |
| | | } else { |
| | | // 生成agent新的对话 |
| | | EventBus.emit('createAgent', session); |
| | | emit('changeAgentType', '2'); |
| | | if (session.type == '1') { |
| | | // 生成智能体新的对话 |
| | | emit('createSession', session.id, `和${session.name}的会话`); |
| | | emit('changeAgentType', '1'); |
| | | } else { |
| | | // 生成agent新的对话 |
| | | EventBus.emit('createAgent', session); |
| | | emit('changeAgentType', '2'); |
| | | } |
| | | } |
| | | }; |
| | | |
| | | onBeforeMount(() => { |
| | | DialogList(); |
| | | queryCanvas(); |
| | | querySeniorAgent(); |
| | | }); |
| | | |
| | | onMounted(() => { |
| | |
| | | emit('changeAgentType', '4'); |
| | | DialogList(); |
| | | queryCanvas(); |
| | | querySeniorAgent(); |
| | | }); |
| | | }); |
| | | onBeforeUnmount(() => { |
| | |
| | | <a-radio :value="item.value" style="margin-right: 10px">{{ |
| | | item.name |
| | | }}</a-radio> |
| | | <!-- <template #content> |
| | | <p style="max-width: 300px">{{ item.parser_config_str }}</p> |
| | | </template> --> |
| | | |
| | | <template #content> |
| | | <p>{{ item.parser_config_str }}</p> |
| | | </template> |
| | |
| | | getParseMethodsListApi, |
| | | getSessionDetailsApi, |
| | | uploadWithoutKb, |
| | | uploadAndParse, |
| | | } from '@/api/session'; |
| | | |
| | | const visible = ref(false); |
| | |
| | | formData.append('parser_id', parser_id.value); |
| | | } |
| | | } |
| | | console.log(formData, 'formData'); |
| | | // uploadAndParse(formData).then((res) => { |
| | | // debugger; |
| | | // onFileSelectedLoading.value = false; |
| | | // if (res.code == 200) { |
| | | // cancel(); |
| | | // // uploaditemList.value = []; |
| | | // emit('selectFileCallback', uploaditemList.value); |
| | | // Message.success('上传成功'); |
| | | // } else { |
| | | // Message.error('上传失败'); |
| | | // } |
| | | // }); |
| | | uploadWithoutKb(formData).then((res) => { |
| | | onFileSelectedLoading.value = false; |
| | | if (res.code == 200) { |
New file |
| | |
| | | <template> |
| | | <div> |
| | | <a-upload |
| | | v-model:fileList="fileList" |
| | | :limit="limit" |
| | | @change="handleChange" |
| | | @before-remove="beforeRemove" |
| | | image-preview |
| | | > |
| | | <template #upload-button> |
| | | <a-button |
| | | type="text" |
| | | style="border-radius: 24px" |
| | | @click="visibleChange" |
| | | > |
| | | <icon-attachment size="28" style="color: #0960bd" /> |
| | | </a-button> |
| | | </template> |
| | | </a-upload> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { computed, ref, onMounted, watch, watchEffect } from 'vue'; |
| | | import { uploadAndParse } from '@/api/session'; |
| | | import { useUserStore } from '@/store'; |
| | | |
| | | const userStore = useUserStore(); |
| | | const props = defineProps({ |
| | | limit: { |
| | | type: Number, |
| | | default: 3, |
| | | }, |
| | | sessionId: String, |
| | | action: String, // 上传的服务器地址 |
| | | url: String, //回显的文件地址 |
| | | }); |
| | | |
| | | const emit = defineEmits([ |
| | | 'update:fileList', |
| | | 'success', |
| | | 'handleRemove', |
| | | 'selectFileCallback', |
| | | ]); |
| | | const urls = computed(() => props.url); |
| | | const fileList = ref([]); |
| | | |
| | | watch( |
| | | () => [props.url, props.sessionId], |
| | | ([newVal, newSessionId], [oldVal, oldSessionId]) => { |
| | | // if (newVal) { |
| | | // fileList.value = newVal.split(',').map((item) => ({ |
| | | // uid: item, |
| | | // name: item, |
| | | // status: 'done', |
| | | // url: item, |
| | | // })); |
| | | // } |
| | | }, |
| | | { |
| | | deep: true, // 开启深度监听 |
| | | } |
| | | ); |
| | | |
| | | onMounted(() => { |
| | | if (urls.value) { |
| | | fileList.value = urls.value.split(',').map((item) => ({ |
| | | uid: item, |
| | | name: item, |
| | | status: 'done', |
| | | url: item, |
| | | })); |
| | | } |
| | | }); |
| | | |
| | | // console.log(urls.value, 8988); |
| | | const beforeRemove = (file) => { |
| | | emit('handleRemove'); |
| | | fileList.value = []; |
| | | }; |
| | | |
| | | const handleChange = (fileList) => { |
| | | // emit('update:fileList', fileList); |
| | | |
| | | // const successFiles = fileList.filter((item) => item.status === 'done'); |
| | | // if (successFiles.length > 0) { |
| | | // emit( |
| | | // 'success', |
| | | // successFiles.map((item) => item.response.data) |
| | | // ); |
| | | // emit( |
| | | // 'selectFileCallback', |
| | | // successFiles.map((item) => item.response.data) |
| | | // ); |
| | | const formData = new FormData(); |
| | | for (let i = 0; i < fileList.length; i++) { |
| | | formData.append('file', fileList[i].file); |
| | | formData.append('conversation_id', props.sessionId); |
| | | // formData.append('parser_config', ''); |
| | | // if (!parser_id.value) { |
| | | // formData.append( |
| | | // 'parser_id', |
| | | // getIconByExtension(successFiles[i].name) |
| | | // ); |
| | | // } else { |
| | | // formData.append('parser_id', parser_id.value); |
| | | // } |
| | | } |
| | | uploadAndParse(formData).then((res) => { |
| | | onFileSelectedLoading.value = false; |
| | | if (res.code == 200) { |
| | | cancel(); |
| | | // uploaditemList.value = []; |
| | | emit('selectFileCallback', uploaditemList.value); |
| | | Message.success('上传成功'); |
| | | } else { |
| | | Message.error('上传失败'); |
| | | } |
| | | }); |
| | | // } |
| | | }; |
| | | </script> |
| | |
| | | display: flex; |
| | | justify-content: space-between; |
| | | " |
| | | class="uploadFileDis" |
| | | > |
| | | <updataFile |
| | | ref="fileInput" |
| | | :sessionId="activeSessionId" |
| | | @selectFileCallback="selectFileCallback" |
| | | ></updataFile> |
| | | <!-- <uploadFile |
| | | ref="fileInput" |
| | | :sessionId="activeSessionId" |
| | | @selectFileCallback="selectFileCallback" |
| | | ></uploadFile> --> |
| | | <a-button |
| | | :disabled="chatDis" |
| | | @click="sentClick" |
| | |
| | | ></smartAi> |
| | | </div> |
| | | </a-col> |
| | | <a-col :span="23" v-show="agentType == '5'"> |
| | | <div class="center"> |
| | | <seniorAgentSession :modalObj="agentObj"></seniorAgentSession> |
| | | </div> |
| | | </a-col> |
| | | </a-row> |
| | | <a-modal title=" " v-model:visible="fileVisible" :footer="false" fullscreen> |
| | | <!-- <docx previewSrc="http://192.168.20.116:1080/v1/document/get/405c3efa4d8c11ef97560242ac120006"></docx>--> |
| | |
| | | import chatMenu from '@/views/sessionManager/components/chatMenu.vue'; |
| | | import AddSession from '@/views/sessionManager/components/addSession.vue'; |
| | | import agentSession from '@/views/sessionManager/components/agentSession.vue'; |
| | | import seniorAgentSession from '@/views/sessionManager/components/seniorAgentSession.vue'; |
| | | import historySession from '@/views/sessionManager/components/historySession.vue'; |
| | | import smartAi from '@/views/sessionManager/components/smartAi.vue'; |
| | | import updataFile from '@/views/sessionManager/components/updataFile.vue'; |
| | | |
| | | import EventBus from '@/utils/EventBus'; |
| | | import { |
| | | addSessionApi, |
| | |
| | | import excel from '@/views/dmx/knowledgeLib/components/excel.vue'; |
| | | import txtPdf from '@/views/dmx/knowledgeLib/components/txtPdf.vue'; |
| | | import { is } from 'immutable'; |
| | | import uploadFile from './components/uploadFile.vue'; |
| | | |
| | | // const url = ref('../../assets/session/PDF.png'); |
| | | |
| | |
| | | const uploadRef = ref(); |
| | | const files = ref([]); |
| | | const file = ref(''); |
| | | const fileInput = ref(null); |
| | | const fileInput = ref(); |
| | | const chatDataMeg = reactive({}); |
| | | const visible = ref(false); |
| | | const fileVisible = ref(false); |
| | |
| | | }; |
| | | |
| | | const selectFileCallback = (data) => { |
| | | debugger; |
| | | console.log(data, 'selectFileCallback'); |
| | | uploaditemList.value = [...uploaditemList.value, ...data]; |
| | | }; |
| | |
| | | } |
| | | } |
| | | } |
| | | .uploadFileDis { |
| | | :deep(.arco-upload-list-type-text) { |
| | | display: none; |
| | | } |
| | | } |
| | | .prompt { |
| | | ul { |
| | | margin: 0; |