whx 1 day ago
parent
commit
94f7cd4a25

File diff suppressed because it is too large
+ 1334 - 339
virgo.wzfrontend/aiChat/package-lock.json


+ 1 - 0
virgo.wzfrontend/aiChat/package.json

@@ -10,6 +10,7 @@
 	},
 	"dependencies": {
 		"axios": "^1.11.0",
+		"dayjs": "^1.11.13",
 		"element-plus": "^2.10.4",
 		"highlight.js": "^11.11.1",
 		"marked": "^16.1.1",

+ 5 - 5
virgo.wzfrontend/aiChat/src/api/ai.js

@@ -184,7 +184,7 @@ export function updateHtml(data) {
 		method: 'post',
 		data: data
 	})
-}
+}
 /* 
  * 创建聊天
  * 
@@ -196,7 +196,7 @@ export function createFLowChat(difyTypeId, data) {
 		method: 'post',
 		data: data
 	})
-}
+}
 /* 
  * 获取聊天状态
  * 
@@ -229,15 +229,15 @@ export function getHistoryChatList(conversationId) {
 		url: `/api/ai/chat/message/${conversationId}`,
 		method: 'get'
 	})
-}
+}
 /* 
  * 获取回话列表
  * 
  * 
  */
-export function getDifyChatList(difyTypeId) {
+export function getDifyChatList(difyTypeId, lastId, limit) {
 	return request({
-		url: `/api/ai/chat/conversations/${difyTypeId}`,
+		url: `/api/ai/chat/conversations/${difyTypeId}/${lastId}/${limit}`,
 		method: 'get'
 	})
 }

+ 9 - 8
virgo.wzfrontend/aiChat/src/components/AIFlowChat.vue

@@ -36,15 +36,12 @@
 	const prompt = ref('');
 	// 当前AI流式响应内容
 	const currentAIResponse = ref('');
-	const UUID = ref(useRoute().params.id);
+	const paramId = ref(useRoute().params.id);
 	const conversationId = ref('');
 	const chatBody = ref(null);
 	const previewUrl = ref('');
-	const formatTime = () => {
-		return ''
-	}
 	onMounted(() => {
-		if (UUID.value.trim()) init();
+		if (paramId.value.trim()) init();
 	})
 	// 监听对话历史变化,自动滚动到底部
 	watch(chatHistory, () => {
@@ -54,7 +51,12 @@
 	})
 	let timerId = null;
 	const init = async () => {
-		let flowChatData = await getFlowChatStatus(UUID.value);
+		if (useRoute().params.type === 'chat') {
+			conversationId.value = paramId.value;
+			initChatList();
+			return;
+		}
+		let flowChatData = await getFlowChatStatus(paramId.value);
 		if (flowChatData.state) {
 			if (flowChatData.data.status === 'succeeded') {
 				conversationId.value = flowChatData.data.conversationId;
@@ -194,8 +196,7 @@
 			div.className = 'version-href'
 			versionIndex++;
 			divBox.appendChild(div);
-			previewUrl.value = href.href;
-			console.log(versionIndex);
+			previewUrl.value = href.href;
 			return divBox.innerHTML;
 		};
 		return marked(markdown, {

+ 4 - 4
virgo.wzfrontend/aiChat/src/router/index.js

@@ -10,13 +10,13 @@ const routes = [{
 	name: 'Home',
 	component: () => import('../views/Home.vue')
 }, {
-	path: '/aichat/:id',
+	path: '/aichat/:type/:id',
 	name: 'AIChat',
 	component: () => import('../views/AIChat.vue')
 }, {
-	path: '/Projects',
-	name: 'Projects',
-	component: () => import('../views/Projects.vue')
+	path: '/Chats',
+	name: 'Chats',
+	component: () => import('../views/Chats.vue')
 }]
 
 const router = createRouter({

+ 2 - 0
virgo.wzfrontend/aiChat/src/store/index.js

@@ -8,8 +8,10 @@ import {
 import {
 	useUserStore
 } from '@/store/modules/user.js'
+
 const pinia = createPinia();
 pinia.use(registerPlugin); // 使用插件
+
 export default pinia;
 
 export {

+ 0 - 3
virgo.wzfrontend/aiChat/src/store/modules/user.js

@@ -13,9 +13,6 @@ export const useUserStore = defineStore('user', {
 		},
 		setUserData(userData) {
 			this.userData = userData;
-		},
-		logout() {
-			this.token = null;
 		}
 	}
 })

+ 42 - 22
virgo.wzfrontend/aiChat/src/views/Projects.vue

@@ -15,29 +15,26 @@
 	import {
 		marked
 	} from 'marked';
+	import dayjs from 'dayjs'
 	const router = ref(useRouter())
 	const user = ref(useUserStore().userData);
 	const projectList = ref([]);
-	const str = ref('')
 	const init = async () => {
-		// let list = await getDifyChatList(7);
-		// if (list.state) {
-		projectList.value = [{
-			name: '生成科技型网站1',
-			id: '3683d9640fab4714a6fdbd09c6700b1c'
-		}, {
-			name: '生成科技型网站2',
-			id: '79d14ab1c26c46a195abd4626d29a1e5'
-		}]
-		// }
+		let list = await getDifyChatList(7, null, 100);
+		if (list.state) projectList.value = list.data.data;
+	}
+	const formatTime = (time) => {
+		if (String(time).length === 10) time *= 1000;
+		let date = new Date(time)
+		return dayjs(date).format('YYYY-MM-DD HH:mm:ss')
 	}
 	onMounted(() => {
 		init();
 	})
 </script>
 <template>
-	<div class="projects">
-		<header class="projects-header">
+	<div class="chats">
+		<header class="chats-header">
 			<div class="home-nav-left" @click="router.push('/')">
 				<img class="img"
 					src="https://file-node.oss-cn-shanghai.aliyuncs.com/youji/f9617c7f80da485cb3cc72b6accc62ed"
@@ -50,25 +47,30 @@
 				</div>
 			</div>
 		</header>
-		<div class="projects-content">
-			<div> {{str}}</div>
-			<el-button v-for="(item,index) in projectList" :key="index" @click="router.push(`/aichat/${item.id}`)">
-				{{item.name}}
-			</el-button>
+		<div class="chats-content">
+			<el-row :gutter="15">
+				<el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="1" v-for="(item,index) in projectList" :key="index">
+					<div class="chats-item" @click="router.push(`/aichat/chat/${item.id}`)">
+						<div class="content">{{item.name}}</div>
+						<div class="time">{{formatTime(item.createdAt)}}</div>
+					</div>
+				</el-col>
+			</el-row>
+
 		</div>
 	</div>
 </template>
 
 
 <style lang="scss">
-	.projects {
+	.chats {
 		width: 100%;
 		height: 100%;
 		display: flex;
 		background: #fcfbf8;
 		flex-direction: column;
 
-		.projects-header {
+		.chats-header {
 			height: 44px;
 			display: flex;
 			justify-content: space-between;
@@ -117,12 +119,30 @@
 			}
 		}
 
-		.projects-content {
-			display: flex;
+		.chats-content {
 			width: 100%;
 			height: 0;
 			flex: 1;
 			padding: 0 10px 10px 10px;
 		}
+
+		.chats-item {
+			background: #fff;
+			box-shadow: var(--el-box-shadow-light);
+			margin-bottom: 15px;
+			border-radius: 6px;
+			cursor: pointer;
+
+			.content {
+				padding: 6px 10px;
+				border-bottom: 1px solid var(--el-border-color);
+			}
+
+			.time {
+				padding: 6px 10px;
+				font-size: 12px;
+				color: var(--el-text-color-primary);
+			}
+		}
 	}
 </style>

+ 42 - 17
virgo.wzfrontend/aiChat/src/views/Home.vue

@@ -77,6 +77,7 @@
 		}
 		if (command === 'url') openUrl();
 		if (command === 'image') hideUploadRef.value.handleUpload();
+		if (command === 'out') logOut();
 	}
 	const openUrl = () => {
 		ElMessageBox.prompt('请输入参考网站网址', 'WorkArk.AI提示', {
@@ -91,6 +92,21 @@
 			websiteURL.value = value;
 		}).catch(() => {});
 	}
+	const logOut = () => {
+		ElMessageBox.confirm('是否确认退出登录', 'WorkArk.AI提示', {
+			confirmButtonText: '确认',
+			cancelButtonText: '取消',
+			type: 'warning',
+		}).then(() => {
+			userStore.setToken(null);
+			userStore.setUserData({});
+			ElMessage({
+				message: '退出成功',
+				type: 'success',
+			})
+			init();
+		}).catch(() => {});
+	}
 	const imageList = ref([])
 	const uploadImage = url => {
 		imageList.value.push(url);
@@ -232,7 +248,7 @@
 		loading.value = true;
 		let createChatData = await createFLowChat(7, postData)
 		loading.value = false;
-		if (createChatData.state) router.push(`/aichat/${createChatData.data}`);
+		if (createChatData.state) router.push(`/aichat/uuid/${createChatData.data}`);
 	}
 	const linkTo = (url) => {
 		if (!url) {
@@ -250,7 +266,7 @@
 			loginVisible.value = true;
 			return;
 		}
-		router.push('/Projects');
+		router.push('/Chats');
 	}
 	onMounted(() => {
 		init();
@@ -262,6 +278,15 @@
 			clearInterval(typeInterval);
 		}
 	})
+	const dropOption = ref({
+		modifiers: [{
+			name: 'computeStyles',
+			options: {
+				gpuAcceleration: false,
+				adaptive: false
+			},
+		}, ],
+	})
 </script>
 
 <template>
@@ -273,9 +298,7 @@
 					alt="logo.png" />
 				<span class="title">WorkArk AI</span>
 				<ul class="header-ul">
-					<li class="header-li" @click="linkTo('/Projects')">项目</li>
-					<li class="header-li" @click="linkTo()">定价</li>
-					<li class="header-li" @click="linkTo()">学习</li>
+					<li class="header-li" @click="linkTo('/Chats')">历史会话</li>
 				</ul>
 			</div>
 			<div class="home-nav-right">
@@ -283,10 +306,18 @@
 					<el-avatar :size="36" :icon="UserFilled"></el-avatar>
 					<span class="name">登录/注册</span>
 				</div>
-				<div class="item no-token" v-else>
-					<el-avatar :size="36" :src="user.portrait"></el-avatar>
-					<span class="name">{{user.userName}}</span>
-				</div>
+				<el-dropdown v-else @command="commandFunction" :popper-options="dropOption">
+					<div class="item no-token">
+						<el-avatar :size="36" :src="user.portrait"></el-avatar>
+						<span class="name">{{user.userName}}</span>
+					</div>
+					<template #dropdown>
+						<el-dropdown-menu>
+							<el-dropdown-item command="out">退出登录</el-dropdown-item>
+						</el-dropdown-menu>
+					</template>
+				</el-dropdown>
+
 			</div>
 		</div>
 		<div class="home-form">
@@ -301,14 +332,7 @@
 				<HideUpload ref="hideUploadRef" v-show="false" @uploadImage="uploadImage"></HideUpload>
 				<div class="form-submit">
 					<div class="form-operation">
-						<el-dropdown @command="commandFunction" :popper-options="{
-							modifiers: [
-							  {
-								name: 'computeStyles',
-								options: { gpuAcceleration: false, adaptive: false },
-							  },
-							],
-						  }">
+						<el-dropdown @command="commandFunction" :popper-options="dropOption">
 							<el-button size="default" :icon="Paperclip" circle></el-button>
 							<template #dropdown>
 								<el-dropdown-menu>
@@ -439,6 +463,7 @@
 
 				.name {
 					margin-left: 10px;
+					color: #000;
 				}
 
 				.el-avatar {