Просмотр исходного кода

好像要改router,测试中

zb 2 лет назад
Родитель
Сommit
a8b7a2a34b

+ 10 - 0
SEChat-frontend/src/locales/zh-CN.ts

@@ -56,6 +56,16 @@ export default {
     showRawText: '显示原文',
     thinking: '思考中...',
   },
+	agent:{//agent命名域
+		newAgentButton: '新建助手',
+		newAgentTitle: '新建助手',
+		deleteAgentConfirm:'确定删除助手?',
+		deleteAgent:'删除助手',
+		thinking: '思考中...',
+		deleteAllAgentConfirm:"确定删除所有助手?",
+		deleteMessage: '删除消息',
+	},
+
   setting: {
     setting: '设置',
     general: '总览',

+ 13 - 0
SEChat-frontend/src/router/index.ts

@@ -18,6 +18,19 @@ const routes: RouteRecordRaw[] = [
       },
     ],
   },
+	// {
+	// 	path: '/',
+	// 	name: 'Root',
+	// 	component: ChatLayout,
+	// 	redirect: '/agent',
+	// 	children: [
+	// 		{
+	// 			path: '/agent/:uuid?',
+	// 			name: 'Agent',
+	// 			component: () => import('@/views/chat/index.vue'),
+	// 		},
+	// 	],
+	// },
 
   {
     path: '/404',

+ 160 - 2
SEChat-frontend/src/store/modules/agent/index.ts

@@ -6,7 +6,7 @@ import { t } from '@/locales'
 export const useAgentStore = defineStore('agent-store', {
 	state: (): Agent.AgentState => getLocalState(),
 	getters: {
-		getAgentHistoryByCurrentActive(state: Agent.AgentState) {
+		getAgentAgentHistoryByCurrentActive(state: Agent.AgentState) {
 			const index = state.history.findIndex(item => item.uuid === state.active)
 			if (index !== -1)
 				return state.history[index]
@@ -22,7 +22,165 @@ export const useAgentStore = defineStore('agent-store', {
 		},
 	},
 	actions: {
-		clearHistory() {
+		setUsingContext(context: boolean) {
+			this.usingContext = context
+			this.recordState()
+		},
+
+		addAgentHistory(history: Agent.AgentHistory, agentData: Agent.Agent[] = []) {
+			this.history.unshift(history)
+			this.agent.unshift({ uuid: history.uuid, data: agentData })
+			this.active = history.uuid
+			this.reloadRoute(history.uuid)
+		},
+
+		updateAgentHistory(uuid: number, edit: Partial<Agent.AgentHistory>) {
+			const index = this.history.findIndex(item => item.uuid === uuid)
+			if (index !== -1) {
+				this.history[index] = { ...this.history[index], ...edit }
+				this.recordState()
+			}
+		},
+
+		async deleteAgentHistory(index: number) {
+			this.history.splice(index, 1)
+			this.agent.splice(index, 1)
+
+			if (this.history.length === 0) {
+				this.active = null
+				this.reloadRoute()
+				return
+			}
+
+			if (index > 0 && index <= this.history.length) {
+				const uuid = this.history[index - 1].uuid
+				this.active = uuid
+				this.reloadRoute(uuid)
+				return
+			}
+
+			if (index === 0) {
+				if (this.history.length > 0) {
+					const uuid = this.history[0].uuid
+					this.active = uuid
+					this.reloadRoute(uuid)
+				}
+			}
+
+			if (index > this.history.length) {
+				const uuid = this.history[this.history.length - 1].uuid
+				this.active = uuid
+				this.reloadRoute(uuid)
+			}
+		},
+
+		async setActive(uuid: number) {
+			this.active = uuid
+			return await this.reloadRoute(uuid)
+		},
+
+		getAgentByUuidAndIndex(uuid: number, index: number) {
+			if (!uuid || uuid === 0) {
+				if (this.agent.length)
+					return this.agent[0].data[index]
+				return null
+			}
+			const agentIndex = this.agent.findIndex(item => item.uuid === uuid)
+			if (agentIndex !== -1)
+				return this.agent[agentIndex].data[index]
+			return null
+		},
+
+		addAgentByUuid(uuid: number, agent: Agent.Agent) {
+			if (!uuid || uuid === 0) {
+				if (this.history.length === 0) {
+					const uuid = Date.now()
+					this.history.push({ uuid, title: agent.text, isEdit: false })
+					this.agent.push({ uuid, data: [agent] })
+					this.active = uuid
+					this.recordState()
+				}
+				else {
+					this.agent[0].data.push(agent)
+					if (this.history[0].title === t('agent.newAgentTitle'))
+						this.history[0].title = agent.text
+					this.recordState()
+				}
+			}
+
+			const index = this.agent.findIndex(item => item.uuid === uuid)
+			if (index !== -1) {
+				this.agent[index].data.push(agent)
+				if (this.history[index].title === t('agent.newAgentTitle'))
+					this.history[index].title = agent.text
+				this.recordState()
+			}
+		},
+
+		updateAgentByUuid(uuid: number, index: number, agent: Agent.Agent) {
+			if (!uuid || uuid === 0) {
+				if (this.agent.length) {
+					this.agent[0].data[index] = agent
+					this.recordState()
+				}
+				return
+			}
+
+			const agentIndex = this.agent.findIndex(item => item.uuid === uuid)
+			if (agentIndex !== -1) {
+				this.agent[agentIndex].data[index] = agent
+				this.recordState()
+			}
+		},
+
+		updateAgentSomeByUuid(uuid: number, index: number, agent: Partial<Agent.Agent>) {
+			if (!uuid || uuid === 0) {
+				if (this.agent.length) {
+					this.agent[0].data[index] = { ...this.agent[0].data[index], ...agent }
+					this.recordState()
+				}
+				return
+			}
+
+			const agentIndex = this.agent.findIndex(item => item.uuid === uuid)
+			if (agentIndex !== -1) {
+				this.agent[agentIndex].data[index] = { ...this.agent[agentIndex].data[index], ...agent }
+				this.recordState()
+			}
+		},
+
+		deleteAgentByUuid(uuid: number, index: number) {
+			if (!uuid || uuid === 0) {
+				if (this.agent.length) {
+					this.agent[0].data.splice(index, 1)
+					this.recordState()
+				}
+				return
+			}
+
+			const agentIndex = this.agent.findIndex(item => item.uuid === uuid)
+			if (agentIndex !== -1) {
+				this.agent[agentIndex].data.splice(index, 1)
+				this.recordState()
+			}
+		},
+
+		clearAgentByUuid(uuid: number) {
+			if (!uuid || uuid === 0) {
+				if (this.agent.length) {
+					this.agent[0].data = []
+					this.recordState()
+				}
+				return
+			}
+
+			const index = this.agent.findIndex(item => item.uuid === uuid)
+			if (index !== -1) {
+				this.agent[index].data = []
+				this.recordState()
+			}
+		},
+		clearAgentHistory() {
 			this.$state = { ...defaultState() }
 			this.recordState()
 		},

+ 6 - 3
SEChat-frontend/src/typings/agent.d.ts

@@ -1,8 +1,10 @@
 declare namespace Agent{
 	//agent属性
 	interface Agent{
-		createTime: string
-		taskText: string
+		dateTime: string
+		text: string
+		// createTime: string
+		// taskText: string
 		inversion?: boolean
 		error?: boolean
 		loading?: boolean
@@ -10,7 +12,8 @@ declare namespace Agent{
 		knowledgeBase:string //搭载了什么知识库
 		promptList:string[]//?不确定是不是这样写,提示词列表
 		knowledgeGraph:string//?不确定是不是这样写,知识图谱
-
+		conversationOptions?: ConversationRequest | null
+		requestOptions: { prompt: string; options?: ConversationRequest | null }
 	}
 	interface AgentHistory {
 		title: string

+ 16 - 10
SEChat-frontend/src/views/chat/layout/sider/Agent.vue

@@ -3,9 +3,11 @@ import type { CSSProperties } from 'vue'
 import { computed, ref, watch } from 'vue'
 import { NButton, NLayoutSider, useDialog } from 'naive-ui'
 import List from './List.vue'
+import AgentList from "@/views/chat/layout/sider/AgentList.vue";
 import {useAgentStore, useAppStore, useChatStore} from '@/store'
 import { useBasicLayout } from '@/hooks/useBasicLayout'
 import { t } from '@/locales'
+import {SvgIcon} from "@/components/common";
 
 const appStore = useAppStore()
 const chatStore = useChatStore()
@@ -19,9 +21,9 @@ const show = ref(false)
 const collapsed = computed(() => appStore.agentSiderCollapsed)
 
 function handleAdd() {
-  //chatStore.addHistory({ title: t('chat.newAgentTitle'), uuid: Date.now(), isEdit: false })
-  //if (isMobile.value)
-    //appStore.setAgentSiderCollapsed(true)
+  agentStore.addAgentHistory({ title: t('agent.newAgentTitle'), uuid: Date.now(), isEdit: false })
+  if (isMobile.value)
+    appStore.setAgentSiderCollapsed(true)
 }
 
 function handleUpdateCollapsed() {
@@ -30,12 +32,12 @@ function handleUpdateCollapsed() {
 
 function handleClearAll() {
   dialog.warning({
-    title: t('chat.deleteMessage'),
-    content: t('chat.clearHistoryConfirm'),
+    title: t('agent.deleteMessage'),
+    content: t('agent.deleteAllAgentConfirm'),
     positiveText: t('common.yes'),
     negativeText: t('common.no'),
     onPositiveClick: () => {
-      chatStore.clearHistory()
+      agentStore.clearAgentHistory();
       if (isMobile.value)
         appStore.setAgentSiderCollapsed(true)
     },
@@ -88,12 +90,16 @@ watch(
       <main class="flex flex-col flex-1 min-h-0">
         <div class="p-4">
           <NButton dashed block @click="handleAdd">
-            {{ $t('chat.newAgentButton') }}
+            {{ $t('agent.newAgentButton') }}
           </NButton>
         </div>
-        <div class="flex-1 min-h-0 pb-4 overflow-hidden">
-          <List style="display: none" />
-        </div>
+
+<!--        <div class="flex-1 min-h-0 pb-4 overflow-hidden">-->
+<!--          <List  />-->
+<!--        </div>-->
+				<NButton @click="handleClearAll">
+					<SvgIcon icon="ri:close-circle-line" />
+				</NButton>
       </main>
     </div>
   </NLayoutSider>

+ 111 - 0
SEChat-frontend/src/views/chat/layout/sider/AgentList.vue

@@ -0,0 +1,111 @@
+<script setup lang="ts">
+import { computed } from 'vue'
+import { NInput, NPopconfirm, NScrollbar } from 'naive-ui'
+import { SvgIcon } from '@/components/common'
+import { useAppStore, useAgentStore } from '@/store'
+import { useBasicLayout } from '@/hooks/useBasicLayout'
+import { debounce } from '@/utils/functions/debounce'
+
+const { isMobile } = useBasicLayout()
+
+const appStore = useAppStore()
+const agentStore = useAgentStore()
+
+const dataSources = computed(() => agentStore.history)
+
+async function handleSelect({ uuid }: Agent.AgentHistory) {
+	if (isActive(uuid))
+		return
+
+	if (agentStore.active)
+		agentStore.updateAgentHistory(agentStore.active, { isEdit: false })
+	await agentStore.setActive(uuid)
+
+	if (isMobile.value)
+		appStore.setSiderCollapsed(true)
+}
+
+function handleEdit({ uuid }: Agent.AgentHistory, isEdit: boolean, event?: MouseEvent) {
+	event?.stopPropagation()
+	agentStore.updateAgentHistory(uuid, { isEdit })
+}
+
+function handleDelete(index: number, event?: MouseEvent | TouchEvent) {
+	event?.stopPropagation()
+	agentStore.deleteAgentHistory(index)
+	if (isMobile.value)
+		appStore.setSiderCollapsed(true)
+}
+
+const handleDeleteDebounce = debounce(handleDelete, 600)
+
+function handleEnter({ uuid }: Agent.AgentHistory, isEdit: boolean, event: KeyboardEvent) {
+	event?.stopPropagation()
+	if (event.key === 'Enter')
+		agentStore.updateAgentHistory(uuid, { isEdit })
+}
+
+function isActive(uuid: number) {
+	return agentStore.active === uuid
+}
+</script>
+
+
+
+<template>
+	<NScrollbar class="px-4">
+		<div class="flex flex-col gap-2 text-sm">
+			<template v-if="!dataSources.length">
+				<div class="flex flex-col items-center mt-4 text-center text-neutral-300">
+					<SvgIcon icon="ri:inbox-line" class="mb-2 text-3xl" />
+					<span>{{ $t('common.noData') }}</span>
+				</div>
+			</template>
+			<template v-else>
+				<div v-for="(item, index) of dataSources" :key="index">
+					<a
+						class="relative flex items-center gap-3 px-3 py-3 break-all border rounded-md cursor-pointer hover:bg-neutral-100 group dark:border-neutral-800 dark:hover:bg-[#24272e]"
+						:class="isActive(item.uuid) && ['border-[#4b9e5f]', 'bg-neutral-100', 'text-[#4b9e5f]', 'dark:bg-[#24272e]', 'dark:border-[#4b9e5f]', 'pr-14']"
+						@click="handleSelect(item)"
+					>
+            <span>
+              <SvgIcon icon="ri:message-3-line" />
+            </span>
+						<div class="relative flex-1 overflow-hidden break-all text-ellipsis whitespace-nowrap">
+							<NInput
+								v-if="item.isEdit"
+								v-model:value="item.title" size="tiny"
+								@keypress="handleEnter(item, false, $event)"
+							/>
+							<span v-else>{{ item.title }}</span>
+						</div>
+						<div v-if="isActive(item.uuid)" class="absolute z-10 flex visible right-1">
+							<template v-if="item.isEdit">
+								<button class="p-1" @click="handleEdit(item, false, $event)">
+									<SvgIcon icon="ri:save-line" />
+								</button>
+							</template>
+							<template v-else>
+								<button class="p-1">
+									<SvgIcon icon="ri:edit-line" @click="handleEdit(item, true, $event)" />
+								</button>
+								<NPopconfirm placement="bottom" @positive-click="handleDeleteDebounce(index, $event)">
+									<template #trigger>
+										<button class="p-1">
+											<SvgIcon icon="ri:delete-bin-line" />
+										</button>
+									</template>
+									{{ $t('agent.deleteAgentConfirm') }}
+								</NPopconfirm>
+							</template>
+						</div>
+					</a>
+				</div>
+			</template>
+		</div>
+	</NScrollbar>
+</template>
+
+<style scoped lang="less">
+
+</style>