src/api/authority.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/assets/images/square_banner.png | 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/store/modules/user/index.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/authority/role/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/authority/users/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/sessionManager/components/agentSession.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/sessionManager/components/chatMenu.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/sessionManager/components/historySession.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/sessionManager/components/smartAi.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/sessionManager/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/sessionManager/style/layout.css | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/api/authority.ts
@@ -3,6 +3,7 @@ export interface User { userId: string; loginName:string; userName: string; nickName: string; email: string; @@ -14,6 +15,9 @@ dialogs: any; createTime: string; status: string; psw:string; role:string; roleName:string; } export interface Organization { @@ -78,6 +82,7 @@ resources: any; knowledges: any; dialogs: any; agents: any; } export function RoleList(params: Pagination) { src/assets/images/square_banner.png
src/store/modules/user/index.ts
@@ -76,6 +76,9 @@ name: res.data.nickname, email: res.data.email, }; if(res.data.roles && res.data.roles.length>0) this.resources=res.data.roles[0].resources; else this.resources=res.data.resources; setUserInfo(JSON.stringify(userInfo)); setUserResources(JSON.stringify(this.resources)) src/views/authority/role/index.vue
@@ -111,8 +111,8 @@ @cancel="handleCancel(1)" @ok="editHandleOk" > <a-form :model="editform"> <a-form-item required field="roleName" label="角色名"> <a-form ref="formRef" :model="editform"> <a-form-item required field="roleName" label="角色名" :rules="[{required:true,message:'角色名必填'},{maxLength:50,message:'长度不超过50'}]"> <a-input v-model="editform.roleName" /> </a-form-item> <a-form-item field="remark" label="备注"> @@ -193,8 +193,8 @@ </a-checkbox> </a-checkbox-group> <a-checkbox-group v-model="checkedKeysDialog" @change="onCheckDialog" v-model="checkedKeysAgent" @change="onCheckAgent" > <a-checkbox v-for="(agent, index) of AgentList" @@ -248,6 +248,13 @@ @close="handleDialogRemove(tag)" > {{ tag.dialogName }} </a-tag> <a-tag v-for="(tag, index) of checkStrictlyAgent" :key="tag.agentId" @close="handleDialogRemove(tag)" > {{ tag.agentTitle }} </a-tag> </a-space> </a-card> @@ -414,7 +421,7 @@ (tag) => tag !== key ); }; let formRef = ref(); const basePagination: Pagination = { current: 1, pageSize: 15, @@ -480,6 +487,7 @@ const editResourceHandleOk = async () => { let resources: Array = [], dialogs: Array = [], agents: Array = [], Knowledges: Array = [], role: Role = { roleId: selectRole.value.roleId }; checkStrictlyMenu.value.forEach((val) => { @@ -497,19 +505,20 @@ }); role.dialogs = dialogs; checkStrictlyAgent.value.forEach((val) => { agents.push(val.agentId); }); role.agents = agents; await RoleEdit(role).then((res) => { fetchData(); }); }; const editHandleOk = async () => { if(editform.value.roleName==""){ Modal.warning({ title: '警告', content: '名称不能为空' }); return; } const cb = async (err) => { if (err) { visible.value = true; } else { if (editform.value.roleId.length > 0) { await RoleEdit({ ...editform.value, @@ -523,6 +532,12 @@ fetchData(); }); } } }; const editHandleOk = () => { formRef.value.validate(cb); }; const operation = async (t, record) => { if (t == 0) { @@ -580,6 +595,15 @@ checkedKeysDialog.value.push(val.id); }); } if (record.agents) { record.agents.forEach((val) => { checkStrictlyAgent.value.push({ agentId: val.id, agentTitle: val.title, }); checkedKeysAgent.value.push(val.id); }); } } }; src/views/authority/users/index.vue
@@ -77,9 +77,6 @@ <template #index="{ rowIndex }"> {{ rowIndex + 1 + (pagination.current - 1) * pagination.pageSize }} </template> <template #dept="{ record }">{{ record.dept ? record.dept.deptName : '' }}</template> <template #status="{ record }"> <a-switch checked-value="1" @@ -110,7 +107,7 @@ type="dashed" status="warning" @click="operation(4, record)" >权限配置</a-button >查看权限</a-button > <a-button status="success" @click="operation(5, record)" >部门配置</a-button @@ -124,17 +121,52 @@ :title="save" @cancel="handleCancel(1)" @ok="editHandleOk" width="48%" > <a-form :model="editform"> <a-form-item field="email" label="用户名"> <a-input v-model="editform.email" /> <a-form ref="formRef" :model="editform"> <a-row :gutter="20"> <a-col :span="10"> <a-form-item field="loginName" label="用户名" :rules="[{required:true,message:'用户名必填'},{maxLength:50,message:'长度不超过50'}]" > <a-input v-model="editform.loginName" /> </a-form-item> <a-form-item field="name" label="昵称"> <a-input v-model="editform.nickName" /> </a-col> <a-col :span="10"> <a-form-item field="userName" label="姓名"> <a-input v-model="editform.userName" /> </a-form-item> </a-col> </a-row> <a-row :gutter="20"> <a-col :span="10"> <a-form-item field="phoneNumber" label="手机号"> <a-input v-model="editform.phoneNumber" /> </a-form-item> </a-col> <a-col :span="10"> <a-form-item required field="email" label="邮箱" :rules="[{required:true,message:'邮箱必填'},{maxLength:50,message:'长度不超过50'}]" > <a-input v-model="editform.email" /> </a-form-item> </a-col> </a-row> <a-row :gutter="20"> <a-col :span="10"> <a-form-item field="psw" label="密码"> <a-input v-model="editform.psw" /> </a-form-item> </a-col> <a-col :span="10"> <a-form-item required field="role" label="角色" :rules="[{required:true,message:'角色必选'}]" > <a-select v-model="editform.role" :options="roles" :field-names="fieldNames" @change="roleChange" > </a-select> </a-form-item> </a-col> </a-row> </a-form> </a-modal> <a-modal @@ -184,142 +216,14 @@ width="50%" v-model:visible="resourcevisible" v-if="resourcevisible" title="权限配置" title="用户所有权限" @cancel="handleCancel(3)" @ok="editResourceHandleOk" > <div :style="{ 'display': 'flex', 'flex-direction': 'column' }"> <a-tabs :style="{ 'width': '100%', 'height': '500px', 'overflow-y': 'auto' }" > <a-tab-pane key="1"> <template #title> <icon-calendar /> 菜单 </template> <a-tree class="tree-demo-box" v-model:checked-keys="checkedKeysMenu" v-model:expanded-keys="expandKdysMenu" :checkable="true" :data="treeDataMenu" :show-line="showLineMenu" @check="onCheckMenu" :fieldNames="{ key: 'menuId', title: 'menuName', children: 'children', }" :check-strictly="checkStrictlyMenu" > <!-- <template #extra="nodeData"> <div :class="{ 'custom-class': nodeData.menuType == 1 }"> <span> {{ nodeData.menuName }} </span> </div> </template> --> </a-tree> <!-- <a-space class="space_select_all"> <a-button type="primary">全选</a-button> <a-button>取消全选</a-button> </a-space> <div class="table_box" v-if="treeDataMenu[0].children"> <div class="table_row1"> <div class="row1_list" v-for="(item, index) in treeDataMenu[0].children" :key="item.menuId" > <div class="row1_clo"> <a-checkbox :checked="item.menuId" @change="onCheckChange(item, $event)" > {{ item.menuName }} </a-checkbox> </div> <div v-if="item.children" class="row1_clo2"> <div class="row2_clo2_1" v-for="(item2, index2) in item.children" :key="item2.menuId" > <div class="row1_clo2_1"> <a-checkbox :checked="item2.menuId" @change="onCheckChange(item2, $event)" > {{ item2.menuName }} </a-checkbox> </div> <div v-if="item2.children" class="row1_clo2_2"> <div v-for="(item3, index3) in item2.children" :key="item3.menuId" > <a-checkbox :checked="item3.menuId" @change="onCheckChange(item3, $event)" > {{ item3.menuName }}</a-checkbox > </div> </div> </div> </div> </div> </div> </div> --> </a-tab-pane> <a-tab-pane key="2"> <template #title> <icon-clock-circle /> 知识库 </template> <a-space direction="vertical" size="large"> <a-checkbox-group v-model="checkedKeysKnowledge" direction="vertical" @change="onCheckKnowledge" > <a-checkbox v-for="(knowledg, index) of knowledgeList" :value="knowledg.id" :lable="knowledg.name" @change="onCheckKnowledge" > {{ knowledg.name }} </a-checkbox> </a-checkbox-group> </a-space> </a-tab-pane> <a-tab-pane key="3"> <template #title> <icon-user /> 智能体 </template> <a-checkbox-group v-model="checkedKeysDialog" direction="vertical" @change="onCheckDialog" > <a-checkbox v-for="(dialog, index) of DialogsList" :value="dialog.id" :lable="dialog.name" @change="onCheckDialog" > {{ dialog.name }} </a-checkbox> </a-checkbox-group> </a-tab-pane> </a-tabs> <a-card :style="{ 'width': '100%', 'height': '200px', 'height': '40%', 'overflow-y': 'auto', 'margin': '1px', }" @@ -358,6 +262,13 @@ > {{ tag.dialogName }} </a-tag> <a-tag v-for="(tag, index) of checkStrictlyAgent" :key="tag.agentId" @close="handleDialogRemove(tag)" > {{ tag.agentName }} </a-tag> </a-space> </a-card> </div> @@ -375,38 +286,32 @@ DialogList, KnowledgeList, OrganizationList, ResourceList, ResourceList, Role, RoleList, User, UserAdd, UserChangePwd, UserDelete, UserEdit, UserList, Userstatus, } from '@/api/authority'; Userstatus } from "@/api/authority"; import { Modal } from '@arco-design/web-vue'; import Authheader from '@/views/authority/components/authheader.vue'; import { create } from 'lodash'; import { queryCanvasList } from "@/api/Agent"; const fieldNames = { value: 'roleId', label: 'roleName' }; const roles = ref([]); let treeData = ref([]); let checkedKeys = ref([]); let expandKdys = ref([]); let checkStrictly = ref([]); let treeDataMenu = ref<any>([]); let checkedKeysMenu = ref([]); let expandKdysMenu = ref([]); let checkStrictlyMenu = ref([]); let checkedKeysKnowledge = ref([]); let checkStrictlyKnowledge = ref([]); let checkedKeysDialog = ref([]); let checkStrictlyDialog = ref([]); let knowledgeList = ref([]); let DialogsList = ref([]); let checkStrictlyAgent = ref([]); let formRef = ref(); let menuTips = ref(['权限管理', '账号']); type SizeProps = 'mini' | 'small' | 'medium' | 'large'; @@ -431,7 +336,10 @@ phoneNumber: '', status: '', userId: '', loginName:'', userName: '', psw:'', role:'', }); let size = ref<SizeProps>('medium'); @@ -439,12 +347,15 @@ let deptvisible = ref(false); let resourcevisible = ref(false); let selectUser = ref({}); const treeDataList = ref([]); const checked1 = ref(false); //表格复选框选择 const onCheckChange = (checkedKeysValue: (string | number)[], e: any) => { console.log('onCheckChange', checkedKeysValue, e); const loadRole=async () => { await RoleList(null).then((res) => { roles.value = res.rows; }); } const roleChange = (val) => { editform.value.role = val; }; const onCheck = (newCheckedKeys, event) => { @@ -460,74 +371,6 @@ } }); } }; const onCheckMenu = (newCheckedKeys, event) => { let o = { menuId: event.node.menuId, menuName: event.node.menuName }; if (event.checked) { checkStrictlyMenu.value.push(o); } else { checkStrictlyMenu.value.forEach((val, idx, array) => { // val: 当前值 if (val.menuId == event.node.menuId) { checkStrictlyMenu.value.splice(idx, 1); return true; } }); } }; const onCheckKnowledge = (newCheckedKeys, event) => { let o = { knowledgeId: event.target.value, knowledgeName: event.target.labels[0].innerText, }; if (event.target.checked) { checkStrictlyKnowledge.value.push(o); } else { checkStrictlyKnowledge.value.forEach((val, idx, array) => { // val: 当前值 if (val.knowledgeId == event.target.value) { checkStrictlyKnowledge.value.splice(idx, 1); return true; } }); } }; const onCheckDialog = (newCheckedKeys, event) => { let o = { dialogId: event.target.value, dialogName: event.target.labels[0].innerText, }; if (event.target.checked) { checkStrictlyDialog.value.push(o); } else { checkStrictlyDialog.value.forEach((val, idx, array) => { // val: 当前值 if (val.dialogId == event.target.value) { checkStrictlyDialog.value.splice(idx, 1); return true; } }); } }; const handleRemove = (key) => { checkStrictly.value = checkStrictly.value.filter((tag) => tag !== key); }; const handleMenuRemove = (key) => { checkStrictlyMenu.value = checkStrictlyMenu.value.filter( (tag) => tag !== key ); }; const handleKnowledgeRemove = (key) => { checkStrictlyKnowledge.value = checkStrictlyKnowledge.value.filter( (tag) => tag !== key ); }; const handleDialogRemove = (key) => { checkStrictlyDialog.value = checkStrictlyDialog.value.filter( (tag) => tag !== key ); }; const basePagination: Pagination = { @@ -564,11 +407,11 @@ }, { title: t('用户名'), dataIndex: 'email', dataIndex: 'loginName', }, { title: t('创建时间'), dataIndex: 'createTime', title: t('角色'), dataIndex: 'roleName', }, { title: t('所属部门'), @@ -598,9 +441,6 @@ if (type == 2) { deptvisible.value = false; } if (type == 2) { resourcevisible.value = false; } }; const editDeptHandleOk = async () => { @@ -615,45 +455,29 @@ }); }; const editResourceHandleOk = async () => { let resources: Array = [], dialogs: Array = [], Knowledges: Array = [], user: User = { userId: selectUser.value.userId }; checkStrictlyMenu.value.forEach((val) => { resources.push(val.menuId); }); user.resources = resources; checkStrictlyKnowledge.value.forEach((val) => { Knowledges.push(val.knowledgeId); }); user.knowledges = Knowledges; checkStrictlyDialog.value.forEach((val) => { dialogs.push(val.dialogId); }); user.dialogs = dialogs; await UserEdit(user).then((res) => { fetchData(); }); }; const editHandleOk = async () => { const cb = async (err) => { if (err) { visible.value = true; } else { if (editform.value.userId.length > 0) { await UserEdit({ ...editform.value, ...editform.value } as unknown as User).then((res) => { fetchData(); }); } else { await UserAdd({ ...editform.value, ...editform.value } as unknown as User).then((res) => { fetchData(); }); } } }; const editHandleOk = () => { formRef.value.validate(cb); }; const operation = async (t, record) => { if (t == 0) { @@ -661,9 +485,11 @@ visible.value = true; editform.value.userId = ''; editform.value.userName = ''; editform.value.loginName = ''; editform.value.nickName = ''; editform.value.email = ''; editform.value.phoneNumber = ''; editform.value.role = ''; } //重置密码 if (t == 1) { @@ -687,9 +513,10 @@ save.value = '编辑'; editform.value.userId = record.userId; editform.value.userName = record.userName; editform.value.nickName = record.nickName; editform.value.loginName = record.loginName; editform.value.email = record.email; editform.value.phoneNumber = record.phoneNumber; editform.value.role = record.role; } //删除 if (t == 3) { @@ -702,40 +529,67 @@ //权限 if (t == 4) { resourcevisible.value = true; checkedKeysMenu.value = []; expandKdysMenu.value = []; checkStrictlyMenu.value = []; checkStrictlyKnowledge.value = []; checkedKeysKnowledge.value = []; checkStrictlyDialog.value = []; checkedKeysDialog.value = []; selectUser.value = record; let agents; if (record.agents){ agents=record.agents }else{ agents = record.roles ? record.roles[0].agents : null; } if (agents) { agents.forEach((val) => { checkStrictlyAgent.value.push({ agentId: val.id, agentName: val.title, }); }); } let resources; if (record.resources) { record.resources.forEach((val) => { resources=record.resources }else{ resources = record.roles ? record.roles[0].resources : null; } if (resources) { resources.forEach((val) => { checkStrictlyMenu.value.push({ menuId: val.menuId, menuName: val.menuName, }); checkedKeysMenu.value.push(val.menuId); expandKdysMenu.value.push(val.menuId); }); } let knowledges; if (record.knowledges) { record.knowledges.forEach((val) => { knowledges = record.knowledges; } else { knowledges = record.roles ? record.roles[0].knowledges : null; } if (knowledges) { knowledges.forEach((val) => { checkStrictlyKnowledge.value.push({ knowledgeId: val.id, knowledgeName: val.name, }); checkedKeysKnowledge.value.push(val.id); }); } let dialogs; if (record.dialogs) { record.dialogs.forEach((val) => { dialogs = record.dialogs; } else { dialogs = record.roles ? record.roles[0].dialogs : null; } if (dialogs) { dialogs.forEach((val) => { checkStrictlyDialog.value.push({ dialogId: val.id, dialogName: val.name, }); checkedKeysDialog.value.push(val.id); }); } } @@ -776,6 +630,15 @@ } } } if (user.roles) { for (const r of user.roles) { if (user.roleName) { user.roleName += r.roleName + ","; } else { user.roleName = r.roleName + ","; } } } } renderData.value = res.rows; console.log(renderData); @@ -805,30 +668,11 @@ treeData.value = [...res.rows]; }); }; const objArr = ref<any>([]); const MenuData = async (key) => { await ResourceList(key).then((res) => { treeDataMenu.value = [...res.rows]; // addClassToLeafNodes(treeDataMenu.value); treeDataList.value = res.rows; }); }; KnowledgeList().then((res) => { knowledgeList.value = res.rows; }); DialogList().then((res) => { DialogsList.value = res.rows; //加载agent queryCanvasList(null).then((r) => { }); }); fetchData(); OrganizationData(''); MenuData(); loadRole() const reset = () => { formModel.value = generateFormModel(); src/views/sessionManager/components/agentSession.vue
@@ -105,6 +105,7 @@ import { getAuthorization } from "@/utils/auth"; import { EventSourceParserStream } from 'eventsource-parser/stream'; import { agentResetApi, agentSetApi, getAgentSessionDetailsApi } from "@/api/agentSession"; import EventBus from '@/utils/EventBus'; const props = defineProps({ modalObj: Object, }); @@ -145,6 +146,15 @@ agentCompletion(); queryAgentSessionDetail(agentObj.id); }; const createNewAgent = async (session) => { Object.assign(agentObj, session); initPage(); } // 调用set方法 const agentSet = async () => { @@ -354,16 +364,18 @@ onMounted(() => { EventBus.on('createAgent', (data) => { createNewAgent(data); }); }); watch( () => props.modalObj, (newVal, oldVal) => { Object.assign(agentObj, newVal); // Object.assign(agentObj, newVal); //调用agent初始化方法 if(JSON.stringify(newVal) != '{}'){ initPage(); // initPage(); } },{ immediate: true, src/views/sessionManager/components/chatMenu.vue
@@ -4,14 +4,18 @@ <div class="myAgent___djnd_ myAgentAnim myAgentlight___yK7Gk"> <!-- <div data-testid="msh-sidebar-main" class="myAgentHome___PG6IZ"></div>--> <div class="myAgentLine___Isl6E"></div> <div class="myAgentTool___Y1_mC" data-testid="msh-sidebar-new"> <div class="myAgentTool___Y1_mC" data-testid="msh-sidebar-new" @click="()=>{ EventBus.emit('newChat') }"> <div class="myAgentToolIcon___gaAKI myAgentToolIconNew___DBZrW"> <img src="../../../assets/images/talkbg.svg" style="width: 24px" alt=""></div> </div> <div data-testid="msh-sidebar-history" class="myAgentTool___Y1_mC"> <div data-testid="msh-sidebar-history" class="myAgentTool___Y1_mC" @click="()=>{ EventBus.emit('history') }"> <div class="myAgentToolIcon___gaAKI myAgentToolIconHistory___GTLWk"> <img src="../../../assets/images/history.svg" @@ -19,14 +23,16 @@ alt=""> </div> </div> <div data-testid="msh-sidebar-square" class="myAgentTool___Y1_mC myAgentToolSquare___dbLm1"> <div data-testid="msh-sidebar-square" class="myAgentTool___Y1_mC myAgentToolSquare___dbLm1" @click="()=>{ EventBus.emit('smartAi') }"> <div class="myAgentToolIcon___gaAKI myAgentToolIconSquare___Rj1o_"><img src="../../../assets/images/agentbg.svg" style="width: 24px" alt=""></div> </div> <div class="myAgentLine___Isl6E" style="margin-top: 4px;"></div> <div class="myAgentBox___zrCit myAgentBoxhistoryconph28t7lagf3d1bhq0"> <div class="myAgentBox___zrCit"> <div class="myAgentBoxImg___Mgu9e"> <div class="myAgentBoxImgLayout___u69B_"> <div class="MuiBox-root css-5nczy5"><img @@ -38,7 +44,7 @@ </div> </div> </div> <div class="myAgentBox___zrCit myAgentBoxhistoryconpgu0t7lagecg63730"> <div class="myAgentBox___zrCit"> <div class="myAgentBoxImg___Mgu9e"> <div class="myAgentBoxImgLayout___u69B_"> <div class="MuiBox-root css-5nczy5"><img @@ -50,7 +56,7 @@ </div> </div> </div> <div class="myAgentBox___zrCit myAgentBoxhistoryconpg00t7lagbbsfqkq0"> <div class="myAgentBox___zrCit"> <div class="myAgentBoxImg___Mgu9e"> <div class="myAgentBoxImgLayout___u69B_"> <div class="MuiBox-root css-5nczy5"><img @@ -62,7 +68,7 @@ </div> </div> </div> <div class="myAgentBox___zrCit myAgentBoxhistoryconpgbgt7lagcavlq340"> <div class="myAgentBox___zrCit"> <div class="myAgentBoxImg___Mgu9e"> <div class="myAgentBoxImgLayout___u69B_"> <div class="MuiBox-root css-5nczy5"><img @@ -74,7 +80,31 @@ </div> </div> </div> <div class="myAgentBox___zrCit myAgentBoxhistoryconpgbot7lagcavlq34g"> <div class="myAgentBox___zrCit"> <div class="myAgentBoxImg___Mgu9e"> <div class="myAgentBoxImgLayout___u69B_"> <div class="MuiBox-root css-5nczy5"><img src="https://kimi-img.moonshot.cn/prod-chat-kimi/avatar/kimiplus/guess.png" alt="" style="border-radius: 50%; width: 100%; height: 100%;"></div> <span class="myAgentBoxImgLayoutTip___xHV4m">猜猜我在想谁</span></div> <div data-testid="msh-sidebar-bot-delete" class="myAgentBoxImgDelete___qXZuq"> <div class="myAgentBoxImgDeleteInner____Hawc">从侧边栏移除</div> </div> </div> </div> <div class="myAgentBox___zrCit"> <div class="myAgentBoxImg___Mgu9e"> <div class="myAgentBoxImgLayout___u69B_"> <div class="MuiBox-root css-5nczy5"><img src="https://kimi-img.moonshot.cn/prod-chat-kimi/avatar/kimiplus/guess.png" alt="" style="border-radius: 50%; width: 100%; height: 100%;"></div> <span class="myAgentBoxImgLayoutTip___xHV4m">猜猜我在想谁</span></div> <div data-testid="msh-sidebar-bot-delete" class="myAgentBoxImgDelete___qXZuq"> <div class="myAgentBoxImgDeleteInner____Hawc">从侧边栏移除</div> </div> </div> </div> <div class="myAgentBox___zrCit"> <div class="myAgentBoxImg___Mgu9e"> <div class="myAgentBoxImgLayout___u69B_"> <div class="MuiBox-root css-5nczy5"><img @@ -101,13 +131,7 @@ import { computed, nextTick, onMounted, watch, reactive, ref } from "vue"; import { Message } from "@arco-design/web-vue"; import { EventSourceParserStream } from "eventsource-parser/stream"; import { chatApi, getDialogListApi, getSessionDetailsApi, sessionListApi } from "@/api/session"; import EventBus from '@/utils/EventBus'; </script> <style scoped lang="less"> src/views/sessionManager/components/historySession.vue
New file @@ -0,0 +1,249 @@ <template> <div class="layoutHisCenter"> <a-button type="primary" status="danger" style=" position: absolute; top: 10px; left: -40px; font-size: 30px; z-index: 9999; cursor: pointer" @click="emit('changeAgentType','1')" > <template #icon> <icon-close style="font-size: 20px" /> </template> </a-button> <a-scrollbar class="left-list" style=" height: calc(100vh - 100px); overflow-y: auto; overflow-x: hidden; " > <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="historyCenter"> <div class="item historyCenter-box" v-for="session in sessionList" @click="querySessionDetail(session)" > <div class="text" > <img :style="{ width: '16px' }" alt="dessert" :src="session.avatar || imgSrc" /> {{ session.name }} </div> <div class="time" >{{ moment(new Date(session.create_time)).format( 'YYYY-MM-DD HH:mm:ss' ) }} </div> </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 { Message } from "@arco-design/web-vue"; import EventBus from '@/utils/EventBus'; import moment from "moment"; import { addSessionApi, chatApi, getDialogListApi, getSessionDetailsApi, sessionListApi } from "@/api/session"; import { queryCanvasList } from "@/api/Agent"; const emit = defineEmits(["querySessionDetail","changeAgentType"]); import logo from "@/assets/images/model.png"; 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 imgSrc = ref(logo); 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 sessionListApi(id); if (code === 200) { sessionList.value = data; } else { Message.warning("查询失败"); } }; const querySessionDetail = async (session) => { console.log(session, 'session'); emit('changeAgentType','1'); emit('querySessionDetail',session); } onBeforeMount(()=>{ DialogList() }) onMounted(() => { EventBus.on("history", () => { emit('changeAgentType','3'); DialogList() }); }) onBeforeUnmount(() => { EventBus.off("history"); }); </script> <style scoped lang="less"> .layoutHisCenter{ width: 100%; //background: #999999; position: absolute; left: 0; top: 0; .historyTitle___F_iam { font-size: 36px; line-height: 50px; font-weight: 700; text-align: center; } .search{ width: 100%; .search-box{ width: 70%; margin-left: 15%; border: 1px solid var(--color-text-4); padding: 10px; border-radius: 12px; background: var(--color-bg-2); margin-top: 20px; margin-bottom: 20px; :deep(.arco-input-wrapper){ border: none; background: var(--color-bg-2); } } } .historyCenter{ width: 100%; margin-top: 30px; .historyCenter-box{ display: flex; width: 70%; margin-left: 15%; //border: 1px solid var(--color-neutral-3); padding: 16px; border-radius: 12px; background: var(--color-bg-1); margin-top: 10px; cursor: pointer; justify-content: space-between; align-items: center; color: var(--color-text-2); } .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); } } } </style> src/views/sessionManager/components/smartAi.vue
New file @@ -0,0 +1,230 @@ <template> <div class="layoutAgentCenter"> <a-scrollbar style=" height: calc(100vh - 100px); overflow-y: auto; overflow-x: hidden; " > <div class="search"> <!-- 查询框--> <img src="@/assets/images/square_banner.png" style="width: 100%" alt=""> </div> <div class="agentMainCenter"> <a-row class="agentCenter"> <a-col :span="8" v-for="item in dialogs"> <div class="item agentCenter-box" @click="createNewSession(item)" > <div class="text" > <a-avatar> <img :style="{ width: '100%' }" alt="dessert" :src="item.avatar || 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> </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 { Message } from "@arco-design/web-vue"; import EventBus from '@/utils/EventBus'; import moment from "moment"; import { addSessionApi, chatApi, getDialogListApi, getSessionDetailsApi, sessionListApi } from "@/api/session"; import { queryCanvasList } from "@/api/Agent"; const emit = defineEmits(["querySessionDetail","changeAgentType","createSession"]); import logo from "@/assets/images/model.png"; 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 imgSrc = ref(logo); 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); } catch (err) { // you can report use errorHandler or other } finally { } }; // 查询会话列表 const querySessionList = async (id) => { const { code, data } = await sessionListApi(id); if (code === 200) { sessionList.value = data; } else { Message.warning("查询失败"); } }; const createNewSession = async (session) => { console.log(session, 'session'); // 查询历史记录 // emit('querySessionDetail',session); if (session.type == '1') { // 生成智能体新的对话 emit('createSession',session.id); emit('changeAgentType','1'); } else { // 生成agent新的对话 EventBus.emit("createAgent",session); emit('changeAgentType','2'); } } onBeforeMount(()=>{ DialogList() }) onMounted(() => { EventBus.on("smartAi", () => { emit('changeAgentType','4'); DialogList(); }); }) onBeforeUnmount(() => { EventBus.off("smartAi"); }); </script> <style scoped lang="less"> .layoutAgentCenter{ width: 100%; //background: #999999; position: absolute; left: 0; top: 0; .agentTitle___F_iam { font-size: 36px; line-height: 50px; font-weight: 700; text-align: center; } .search{ width: 100%; .search-box{ width: 70%; margin-left: 15%; border: 1px solid var(--color-text-4); padding: 10px; border-radius: 12px; background: var(--color-bg-2); margin-top: 20px; margin-bottom: 20px; :deep(.arco-input-wrapper){ border: none; background: var(--color-bg-2); } } } .agentMainCenter{ width: 70%; margin: 0 auto; .agentCenter{ width: 100%; margin-top: 30px; .agentCenter-box{ display: flex; width: 90%; margin: 0 auto; //border: 1px solid var(--color-neutral-3); padding: 16px; border-radius: 12px; background: var(--color-bg-1); margin-top: 10px; cursor: pointer; justify-content: space-between; align-items: center; color: var(--color-text-2); } .agentCenter-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); } } } } </style> src/views/sessionManager/index.vue
@@ -1,150 +1,25 @@ <template> <div class="container"> <AddSession :modalObj="modalObj" @addSession="addSession" :dialogId="dialogId" ></AddSession> <!-- <AddSession--> <!-- :modalObj="modalObj"--> <!-- @addSession="addSession"--> <!-- :dialogId="dialogId"--> <!-- ></AddSession>--> <!-- <a-card class="top-title">AI会话记录</a-card>--> <a-row :gutter="[5, 5]" style="margin-top: 3px;"> <!-- <a-col :span="6">--> <!-- <a-card class="left-select">--> <!-- <a-select--> <!-- v-model="selectValue"--> <!-- :options="dialogs"--> <!-- :field-names="fieldNames"--> <!-- @change="dialogChange"--> <!-- >--> <!-- </a-select>--> <!-- </a-card>--> <!-- <a-card style="height: 50px">--> <!-- <template #cover>--> <!-- <div style="display: flex; justify-content: space-between">--> <!-- <a-button--> <!-- type="primary"--> <!-- shape="round"--> <!-- class="card-btn-1"--> <!-- @click="modalObj.add = true"--> <!-- >--> <!-- +新建会话--> <!-- </a-button>--> <!-- <!– <a-button type="text" shape="circle" class="card-btn-2">--> <!-- <icon-search />--> <!-- </a-button> –>--> <!-- </div>--> <!-- </template>--> <!-- </a-card>--> <!-- <a-card class="left">--> <!-- <a-scrollbar--> <!-- class="left-list"--> <!-- style="--> <!-- height: calc(100vh - 350px);--> <!-- overflow-y: auto;--> <!-- overflow-x: hidden;--> <!-- "--> <!-- >--> <!-- <div--> <!-- class="item left-list-item"--> <!-- v-for="session in sessionList"--> <!-- @click="querySessionDetail(session)"--> <!-- :class="{ isLeftActive: activeSessionId === session.id }"--> <!-- >--> <!-- <div class="text" :class="{ time: theme === 'dark' }"--> <!-- >{{ session.name }}--> <!-- </div>--> <!-- <div class="time"--> <!-- >{{--> <!-- moment(new Date(session.create_time)).format(--> <!-- 'YYYY-MM-DD HH:mm:ss'--> <!-- )--> <!-- }}--> <!-- </div>--> <!-- </div>--> <!-- </a-scrollbar>--> <!-- </a-card>--> <!-- </a-col>--> <a-col :span="1"> <chatMenu></chatMenu> </a-col> <!-- 智能体会话--> <a-col :span="23" v-show="agentType == '1'"> <!-- <div v-if="sessionDetailList.length === 0" style=" width: 90%; overflow: auto; height: 65vh; margin: 0px auto 20px; " > <div class="center-title">智能问答</div> <div class="center-content"> 我可以理解和学习人类的语言,具备多轮对话的能力,现在和我开始交流吧~ </div> <div class="center-question"> <div class="center-question-left">试一试这样问我</div> <div class="center-question-right"> <a-button type="primary">换一换</a-button> </div> </div> <a-row justify="space-around" class="center-list"> <a-col :span="7" class="item"> <div class="item-title"> <IconTiktokColor></IconTiktokColor> 抖音带货脚本 </div> <div class="item-content" :class="{ dark: theme === 'dark' }"> 编写引人注目且具有说服力的、适用于产品的... </div> </a-col> <a-col :span="7" class="item"> <div class="item-title"> <IconTiktokColor></IconTiktokColor> 抖音带货脚本 </div> <div class="item-content" :class="{ dark: theme === 'dark' }"> 编写引人注目且具有说服力的、适用于产品的... </div> </a-col> <a-col :span="7" class="item"> <div class="item-title"> <IconTiktokColor></IconTiktokColor> 抖音带货脚本 </div> <div class="item-content" :class="{ dark: theme === 'dark' }"> 编写引人注目且具有说服力的、适用于产品的... </div> </a-col> <a-col :span="7" class="item"> <div class="item-title"> <IconTiktokColor></IconTiktokColor> 抖音带货脚本 </div> <div class="item-content" :class="{ dark: theme === 'dark' }"> 编写引人注目且具有说服力的、适用于产品的... </div> </a-col> <a-col :span="7" class="item"> <div class="item-title"> <IconTiktokColor></IconTiktokColor> 抖音带货脚本 </div> <div class="item-content" :class="{ dark: theme === 'dark' }"> 编写引人注目且具有说服力的、适用于产品的... </div> </a-col> <a-col :span="7" class="item"> <div class="item-title"> <IconTiktokColor></IconTiktokColor> 抖音带货脚本 </div> <div class="item-content" :class="{ dark: theme === 'dark' }"> 编写引人注目且具有说服力的、适用于产品的... </div> </a-col> </a-row> </div> --> <div class="center"> <div class="header___lEPyH"> <div class="chatHeader"> <div class="chatHeaderBox"> <span class="title">{{agentTitle}}</span> </div> </div> </div> <a-scrollbar ref="scrollbar" id="home" @@ -259,67 +134,16 @@ <agentSession :modalObj="agentObj"></agentSession> </div> </a-col> <!-- <a-col :span="5"> <a-card class="right"> <div class="right-top"> <div class="right-title">数智库</div> <div class="right-btn"> <a-button type="outline" shape="circle" style="border: none"> <icon-search /> </a-button> <a-button type="outline" shape="circle" style="border: none; margin-left: -10px" > <icon-close /> </a-button> <a-col :span="23" v-show="agentType == '3'"> <div class="center" style="padding: 0"> <historySession @querySessionDetail="querySessionDetail" @changeAgentType="changeAgentType"></historySession> </div> </a-col> <a-col :span="23" v-show="agentType == '4'"> <div class="center" style="padding: 0"> <smartAi @createSession="createSession" @querySessionDetail="querySessionDetail" @changeAgentType="changeAgentType"></smartAi> </div> <div class="right-tag"> <a-button type="primary" size="mini" class="btn">全部 </a-button> <a-button type="outline" size="mini" class="btn" >文档创作 </a-button> <a-button type="outline" size="mini" class="btn" >知识学习 </a-button> <a-button type="outline" size="mini" class="btn" >效率提升 </a-button> </div> <div class="right-list"> <div class="right-item"> <div class="item-title"> <IconTiktokColor></IconTiktokColor> 抖音带货脚本 </div> <div class="item-content" :class="{ dark: theme === 'dark' }"> 编写引人注目且具有说服力的、适用于产品的... </div> </div> <div class="right-item"> <div class="item-title"> <IconTiktokColor></IconTiktokColor> 抖音带货脚本 </div> <div class="item-content" :class="{ dark: theme === 'dark' }"> 编写引人注目且具有说服力的、适用于产品的... </div> </div> <div class="right-item"> <div class="item-title"> <IconTiktokColor></IconTiktokColor> 抖音带货脚本 </div> <div class="item-content" :class="{ dark: theme === 'dark' }"> 编写引人注目且具有说服力的、适用于产品的... </div> </div> </div> </a-card> </a-col> --> </a-col> </a-row> </div> </template> @@ -330,7 +154,7 @@ IconTiktokColor } from "@arco-design/web-vue/es/icon"; import { useAppStore, useUserStore } from "@/store"; import { computed, nextTick, onMounted, watch, reactive, ref } from "vue"; import { computed, nextTick, onMounted, watch, reactive, ref, onBeforeMount, onBeforeUnmount } from "vue"; import { Message } from "@arco-design/web-vue"; import { EventSourceParserStream } from "eventsource-parser/stream"; @@ -338,7 +162,11 @@ 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 historySession from "@/views/sessionManager/components/historySession.vue"; import smartAi from "@/views/sessionManager/components/smartAi.vue"; import EventBus from "@/utils/EventBus"; import { addSessionApi, chatApi, getDialogListApi, getSessionDetailsApi, @@ -355,6 +183,7 @@ const chatDis = ref(false); const loading = ref(false); const agentType = ref("1"); const agentTitle = ref("未命名会话"); const currIndex = ref(0); const displayedText = ref(""); // 正在显示的文字 @@ -382,7 +211,6 @@ }); console.log(data, "dialogs"); queryCanvas(); // querySessionList(); } } }; @@ -403,14 +231,35 @@ // 判断当前是智能体或agent // console.log(val, 'val'); if (dialogs.value.length > 0) { dialogChange(dialogs.value[0].id); } // if (dialogs.value.length > 0) { // dialogChange(dialogs.value[0].id); // } //新建会话 createSession(dialogs.value[0].id); } catch (err) { // you can report use errorHandler or other } finally { } }; // 新建会话 const createSession = async (id) => { const res = await addSessionApi({ dialog_id: id, conversation_desc: "未命名会话" }); // console.log(res, "res"); if (res.code == 200) { // console.log(res.data.conversation_id); activeSessionId.value = res.data?.conversation_id; queryNewSessionDetail(res.data?.conversation_id); } else { Message.error("创建会话失败,请重试"); } }; const handleShiftEnter = (event) => { event.preventDefault(); @@ -506,12 +355,12 @@ if (done) { console.info("done"); displayedText.value = ""; querySessionDetail(sectionList.value); queryNewSessionDetail(activeSessionId.value); break; } } } querySessionList(); // querySessionList(); chatDis.value = false; loading.value = false; inputMsg.value = ""; @@ -523,6 +372,22 @@ } } }; const queryNewSessionDetail = async (id) => { activeSessionId.value = id; const { code, data } = await getSessionDetailsApi(id); if (code === 200) { sessionDetailList.value = data.message; agentTitle.value = data.name; refreshScroll(); //刷新滚动条位置 } }; const changeAgentType = (val,session) => { agentType.value = val; console.log(val, "val"); } const querySessionDetail = async (session) => { sectionList.value = session; activeSessionId.value = session.id; @@ -574,8 +439,19 @@ const addSession = () => { querySessionList(); }; onBeforeMount(() => { // DialogList(); //新建会话 createSession(''); }); onMounted(() => { DialogList(); EventBus.on("newChat", () => { agentType.value = 1; createSession(''); }); }); onBeforeUnmount(() => { EventBus.off("newChat"); }); const appStore = useAppStore(); @@ -694,6 +570,7 @@ .center { position: relative; padding-left: 50px; .center-title { line-height: 60px; @@ -862,4 +739,22 @@ } } } .header___lEPyH { 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; } } </style> src/views/sessionManager/style/layout.css
@@ -1395,7 +1395,7 @@ .myAgentLine___Isl6E { width: 24px; height: 1px; background-color: #ece7e7; background-color: #f0f0f0; border-radius: 12px; margin-bottom: 16px; cursor: pointer @@ -1438,7 +1438,7 @@ height: 28px; line-height: 28px; text-align: center; content: "\5f00\542f\65b0\4f1a\8bdd"; content: "开启新会话"; position: absolute; left: 54px; display: none; @@ -1475,7 +1475,7 @@ height: 28px; line-height: 28px; text-align: center; content: "\5386\53f2\4f1a\8bdd"; content: "历史会话"; position: absolute; left: 54px; display: none; @@ -1508,11 +1508,11 @@ } .myAgent___djnd_ .myAgentTool___Y1_mC .myAgentToolIconSquare___Rj1o_:after { width: 58px; width: 70px; height: 28px; line-height: 28px; text-align: center; content: "Kimi+"; content: "SmartAl+"; position: absolute; left: 54px; display: none;