whx 1 天之前
父节点
当前提交
39f268a525
共有 26 个文件被更改,包括 239 次插入148 次删除
  1. 4 3
      virgo.wzfrontend/aiChat/package-lock.json
  2. 1 1
      virgo.wzfrontend/aiChat/package.json
  3. 2 2
      virgo.wzfrontend/aiChat/src/api/ai.js
  4. 3 4
      virgo.wzfrontend/aiChat/src/assets/scss/common.scss
  5. 61 22
      virgo.wzfrontend/aiChat/src/components/AIFlowChat.vue
  6. 2 3
      virgo.wzfrontend/aiChat/src/components/Admin/DataSetUpload.vue
  7. 4 1
      virgo.wzfrontend/aiChat/src/main.js
  8. 25 6
      virgo.wzfrontend/aiChat/src/views/Home.vue
  9. 46 15
      virgo.wzfrontend/aiChat/src/views/admin/Reading.vue
  10. 0 10
      virgo.wzfrontend/src/main/resources/static/ai/assets/AIChat-BUeyZLEH.css
  11. 8 0
      virgo.wzfrontend/src/main/resources/static/ai/assets/AIChat-D4JVlfQL.js
  12. 10 0
      virgo.wzfrontend/src/main/resources/static/ai/assets/AIChat-D65jsWTc.css
  13. 0 8
      virgo.wzfrontend/src/main/resources/static/ai/assets/AIChat-RA6aavIS.js
  14. 1 1
      virgo.wzfrontend/src/main/resources/static/ai/assets/Chats-BYP7mn8r.js
  15. 1 0
      virgo.wzfrontend/src/main/resources/static/ai/assets/Home-Coo1DjZF.js
  16. 1 1
      virgo.wzfrontend/src/main/resources/static/ai/assets/Home-Dv8GG1Yu.css
  17. 0 1
      virgo.wzfrontend/src/main/resources/static/ai/assets/Home-r0mnIQ-v.js
  18. 1 1
      virgo.wzfrontend/src/main/resources/static/ai/assets/Layout-DYL6SxtY.js
  19. 0 1
      virgo.wzfrontend/src/main/resources/static/ai/assets/Reading-B16EbW2H.js
  20. 1 0
      virgo.wzfrontend/src/main/resources/static/ai/assets/Reading-Rz5_3sJB.js
  21. 3 3
      virgo.wzfrontend/src/main/resources/static/ai/assets/ai-CRvZnbP2.js
  22. 0 1
      virgo.wzfrontend/src/main/resources/static/ai/assets/index-6QHqnDT6.css
  23. 62 0
      virgo.wzfrontend/src/main/resources/static/ai/assets/index-BRY_gmZo.js
  24. 0 62
      virgo.wzfrontend/src/main/resources/static/ai/assets/index-DyOYl7hb.js
  25. 1 0
      virgo.wzfrontend/src/main/resources/static/ai/assets/index-YZrFNSdb.css
  26. 2 2
      virgo.wzfrontend/src/main/resources/static/ai/index.html

+ 4 - 3
virgo.wzfrontend/aiChat/package-lock.json

@@ -11,7 +11,7 @@
 				"@microsoft/fetch-event-source": "^2.0.1",
 				"axios": "^1.11.0",
 				"dayjs": "^1.11.13",
-				"element-plus": "^2.10.4",
+				"element-plus": "^2.10.6",
 				"highlight.js": "^11.11.1",
 				"marked": "^16.1.1",
 				"pinia": "^3.0.3",
@@ -1848,8 +1848,9 @@
 			"peer": true
 		},
 		"node_modules/element-plus": {
-			"version": "2.10.4",
-			"integrity": "sha512-UD4elWHrCnp1xlPhbXmVcaKFLCRaRAY6WWRwemGfGW3ceIjXm9fSYc9RNH3AiOEA6Ds1p9ZvhCs76CR9J8Vd+A==",
+			"version": "2.10.6",
+			"resolved": "https://registry.npmmirror.com/element-plus/-/element-plus-2.10.6.tgz",
+			"integrity": "sha512-N1XfO+x46p9Df9KNHeRQiHW4ilt4k+Jh6jeA1Ip9WpVzwDW8CRz+NqaLLDEZmnez62bBdCuWGfV7lIRq3+FQyg==",
 			"dependencies": {
 				"@ctrl/tinycolor": "^3.4.1",
 				"@element-plus/icons-vue": "^2.3.1",

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

@@ -12,7 +12,7 @@
 		"@microsoft/fetch-event-source": "^2.0.1",
 		"axios": "^1.11.0",
 		"dayjs": "^1.11.13",
-		"element-plus": "^2.10.4",
+		"element-plus": "^2.10.6",
 		"highlight.js": "^11.11.1",
 		"marked": "^16.1.1",
 		"pinia": "^3.0.3",

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

@@ -270,9 +270,9 @@ export function insertDataset(data) {
  * 
  * 
  */
-export function getDatasetFileList(datasetId) {
+export function getDatasetFileList(datasetId, page, limit) {
 	return request({
-		url: `/api/ai/datasets/file/${datasetId}`,
+		url: `/api/ai/datasets/file/${datasetId}/${page}/${limit}`,
 		method: 'get'
 	})
 }

+ 3 - 4
virgo.wzfrontend/aiChat/src/assets/scss/common.scss

@@ -1,7 +1,7 @@
 
-.ai-dialog {
-	height: 70vh;
-	padding: 0;
+.wui-dialog {
+	height: 70vh;
+	padding: 0 !important; 
 	display: flex;
 	flex-direction: column;
 
@@ -24,7 +24,6 @@
 		width: 100%;
 		overflow-y: auto;
 		overflow-x: hidden;
-		padding: 15px;
 	}
 }
 //testfont

+ 61 - 22
virgo.wzfrontend/aiChat/src/components/AIFlowChat.vue

@@ -11,7 +11,9 @@
 	} from 'vue-router';
 	import {
 		getFlowChatStatus,
-		getHistoryChatList
+		getHistoryChatList,
+		getDatasetList,
+		insertDataset
 	} from '@/api/ai'
 	import {
 		Top,
@@ -33,6 +35,7 @@
 	import {
 		fetchEventSource
 	} from '@microsoft/fetch-event-source';
+	import Reading from '../views/admin/Reading.vue';
 	const emits = defineEmits(['updateURL', 'removeEdit']);
 	const user = ref(useUserStore().userData);
 	// 对话历史
@@ -49,6 +52,7 @@
 	const chatBody = ref(null);
 	const previewUrl = ref('');
 	onMounted(() => {
+		initReading();
 		if (paramId.value.trim()) init();
 	})
 	// 监听对话历史变化,自动滚动到底部
@@ -57,6 +61,25 @@
 	}, {
 		deep: true
 	})
+	const datasetId = ref('');
+	const initReading = async () => {
+		let list = await getDatasetList({
+			organizationId: user.value.organization.id
+		});
+		if (list.state) {
+			if (list.data.length === 0) return insertDatasetFunc();
+			datasetId.value = list.data[0].datasetId;
+		}
+	}
+	const insertDatasetFunc = async () => {
+		let insertData = await insertDataset({
+			description: user.value.organization.name,
+			name: String(user.value.organization.id),
+			organizationId: user.value.organization.id,
+			userId: user.value.userId
+		})
+		if (insertData.state) datasetId.value = insertData.data;
+	}
 	let timerId = null;
 	const init = async () => {
 		if (paramType.value === 'chat') {
@@ -152,11 +175,11 @@
 			let setTime = null;
 			let dom = '';
 			if (domItem.value.name && domItem.value.parts) {
-				dom = JSON.stringify(domItem.value.parts.map(node => {
-					return {
-						fileName: domItem.value.file,
-						line: node.lineNumber,
-						componentName: domItem.value.name
+				dom = JSON.stringify(domItem.value.parts.map(node => {
+					return {
+						fileName: domItem.value.file,
+						line: node.lineNumber,
+						componentName: domItem.value.name
 					}
 				}))
 				domItem.value = {};
@@ -178,7 +201,8 @@
 					inputs: {
 						websiteURL: "",
 						fileURL: "",
-						dom: dom
+						dom: dom,
+						datasetId: datasetId.value
 					}
 				}),
 				onmessage(event) {
@@ -302,6 +326,18 @@
 	defineExpose({
 		selectItem
 	})
+	const dropOption = ref({
+		modifiers: [{
+			name: 'computeStyles',
+			options: {
+				gpuAcceleration: false,
+				adaptive: false
+			},
+		}],
+	})
+	const commandFunction = (command) => {
+		if (command === 'reading') selectVisible.value = true;
+	}
 </script>
 <template>
 	<div class="ai-chat-container">
@@ -376,25 +412,24 @@
 					:autosize="{ minRows: 2, maxRows: 6 }">
 				</el-input>
 				<div class="input-button">
-					<el-button style="margin-left: 10px;" size="default" :icon="Plus" :disabled="loading || !previewUrl"
-						circle @click="selectVisible = true">
-					</el-button>
-					<el-button circle type="primary" @click="sendMessage" :disabled="!prompt.trim() || loading"
-						:icon="Top">
+					<el-dropdown v-if="user.userId" @command="commandFunction" :popper-options="dropOption">
+						<el-button size="default" :icon="Plus" circle>
+						</el-button>
+						<template #dropdown>
+							<el-dropdown-menu>
+								<el-dropdown-item command="reading">知识库</el-dropdown-item>
+								<el-dropdown-item command="out">图片</el-dropdown-item>
+							</el-dropdown-menu>
+						</template>
+					</el-dropdown>
+					<el-button circle type="primary" style="margin-left: 10px;" @click="sendMessage"
+						:disabled="!prompt.trim() || loading" :icon="Top">
 					</el-button>
 				</div>
 			</div>
 		</div>
-		<el-dialog v-model="selectVisible" title="新增功能" width="800px" class="ai-dialog select-dialog">
-			<div class="select-item">
-				<el-row :gutter="15">
-					<el-col :span="6" v-for="(item,index) in functionList" :key="index">
-						<el-button style="width: 100%;" @click="selectFunction(item)">
-							{{item}}
-						</el-button>
-					</el-col>
-				</el-row>
-			</div>
+		<el-dialog v-model="selectVisible" title="知识库" width="1100px" class="wui-dialog">
+			<Reading></Reading>
 		</el-dialog>
 	</div>
 </template>
@@ -685,6 +720,10 @@
 		margin-top: 10px;
 		text-align: right;
 		padding: 5px 10px;
+
+		.el-button:focus-visible {
+			outline: none;
+		}
 	}
 
 	/* 动画 */

+ 2 - 3
virgo.wzfrontend/aiChat/src/components/Admin/DataSetUpload.vue

@@ -19,15 +19,14 @@
 	const {
 		proxy
 	} = getCurrentInstance()
-	const emits = defineEmits(['uploadImage']);
+	const emits = defineEmits(['uploadSuccess']);
 	const uploadRef = ref(null);
 	const fileList = ref([])
 	const successFile = (res) => {
 		if (res.code != 200) return errorUpload();
 		proxy.$hideLoading();
-		let data = res.data;
 		ElMessage.success('上传成功');
-		emits('uploadImage', data.node.url);
+		emits('uploadSuccess');
 	}
 	const errorUpload = () => {
 		proxy.$hideLoading();

+ 4 - 1
virgo.wzfrontend/aiChat/src/main.js

@@ -6,6 +6,7 @@ import router from './router'
 // 引入SCSS
 import '@/assets/scss/variables.scss'
 import ElementPlus from 'element-plus'
+import locale from "element-plus/es/locale/lang/zh-cn";
 
 import pinia from './store'
 
@@ -14,7 +15,9 @@ import GlobalLoading from "@/components/GlobalLoading";
 const app = createApp(App)
 app.use(pinia)
 app.use(router)
-app.use(ElementPlus)
+app.use(ElementPlus, {
+	locale
+})
 app.use(GlobalLoading)
 
 app.mount('#app')

+ 25 - 6
virgo.wzfrontend/aiChat/src/views/Home.vue

@@ -28,7 +28,9 @@
 		useRouter
 	} from 'vue-router';
 	import {
-		createFLowChat
+		createFLowChat,
+		getDatasetList,
+		insertDataset
 	} from '@/api/ai'
 	const router = useRouter();
 	const userStore = useUserStore()
@@ -68,6 +70,25 @@
 	});
 	const loading = ref(false);
 	const websiteURL = ref('');
+	const datasetId = ref('');
+	const initReading = async () => {
+		let list = await getDatasetList({
+			organizationId: user.value.organization.id
+		});
+		if (list.state) {
+			if (list.data.length === 0) return insertDatasetFunc();
+			datasetId.value = list.data[0].datasetId;
+		}
+	}
+	const insertDatasetFunc = async () => {
+		let insertData = await insertDataset({
+			description: user.value.organization.name,
+			name: String(user.value.organization.id),
+			organizationId: user.value.organization.id,
+			userId: user.value.userId
+		})
+		if (insertData.state) datasetId.value = insertData.data;
+	}
 	const commandFunction = (command) => {
 		if (!userStore.token) {
 			ElMessage({
@@ -131,6 +152,7 @@
 	const user = ref({});
 	const init = () => {
 		user.value = userStore.userData;
+		if (userStore.token) initReading()
 	}
 	const selectVisible = ref(false);
 	const selectData = ref({});
@@ -241,7 +263,8 @@
 			query: message.value,
 			inputs: {
 				websiteURL: websiteURL.value || "",
-				fileURL: imageList.value.join(',') || ""
+				fileURL: imageList.value.join(',') || "",
+				datasetId: datasetId.value || ''
 			}
 		}
 		loading.value = true;
@@ -559,10 +582,6 @@
 				}
 			}
 
-			.el-button:focus-visible {
-				outline: none;
-			}
-
 			.form-submit {
 				margin-top: 10px;
 				display: flex;

+ 46 - 15
virgo.wzfrontend/aiChat/src/views/admin/Reading.vue

@@ -12,7 +12,10 @@
 		getDatasetFileList,
 		deleteFileById
 	} from '@/api/ai'
-
+	import {
+		ElMessage,
+		ElMessageBox
+	} from 'element-plus'
 	import {
 		useUserStore
 	} from '@/store'
@@ -22,7 +25,10 @@
 	const userStore = useUserStore().userData;
 	const datasetId = ref('');
 	const dataSetUploadRef = ref(null);
+	const loading = ref(false)
 	const total = ref(0);
+	const currentPage = ref(1);
+	const pageSize = ref(10);
 	const init = async () => {
 		let list = await getDatasetList({
 			organizationId: userStore.organization.id
@@ -40,18 +46,19 @@
 			organizationId: userStore.organization.id,
 			userId: userStore.userId
 		})
-		// if (insertData.state) init();
+		if (insertData.state) datasetId.value = insertData.data;
 	}
 	const getFileData = async () => {
-		let fileData = await getDatasetFileList(datasetId.value)
-		console.log(fileData);
-
+		loading.value = true;
+		let fileData = await getDatasetFileList(datasetId.value, currentPage.value, pageSize.value);
+		if (fileData.state) {
+			total.value = fileData.data.total;
+			tableData.value = fileData.data.data;
+		}
+		loading.value = false;
 	}
 	const upload = () => {
 		dataSetUploadRef.value.handleUpload();
-	}
-	const uploadImage = () => {
-
 	}
 	const testWordCount = (num) => {
 		return num < 1000 ? num : parseFloat(num / 1000).toFixed(1) + 'K'
@@ -62,7 +69,22 @@
 		let date = new Date(time)
 		return dayjs(date).format('YYYY-MM-DD HH:mm:ss')
 	}
-
+	const deleteFile = (item) => {
+		ElMessageBox.confirm(
+			'是否确认删除该文档,删除后不可恢复?',
+			'WorkArk.AI提示', {
+				confirmButtonText: '确认',
+				cancelButtonText: '取消',
+				type: 'warning',
+			}
+		).then(async () => {
+			let deleteNode = await deleteFileById(item.id);
+			if (deleteNode.state) {
+				ElMessage.success('操作成功');
+				init();
+			}
+		}).catch(() => {})
+	}
 	onMounted(() => {
 		init();
 	})
@@ -74,11 +96,11 @@
 			<el-button type="primary" :icon="Plus" @click="upload">添加文件</el-button>
 			<DataSetUpload v-if="datasetId" :action="`/api/ai/dataset/file/${datasetId}`" ref="dataSetUploadRef"
 				accept=".TXT,.MARKDOWN,.MDX,.PDF,.HTML,.XLSX,.XLS,.DOCX,.CSV,.VTT,.PROPERTIES,.MD,.HTM" v-show="false"
-				@uploadImage="uploadImage">
+				@uploadSuccess="getFileData">
 			</DataSetUpload>
 		</div>
 		<div class="wui-flex-box">
-			<el-table :data="tableData" height="100%">
+			<el-table :data="tableData" height="100%" v-loading="loading">
 				<el-table-column label="序号" width="80">
 					<template #default="{ $index }">{{ $index + 1 }}</template>
 				</el-table-column>
@@ -86,13 +108,19 @@
 				<el-table-column label="字符数" width="180">
 					<template #default="scope">{{ testWordCount(scope.row.word_count)}}</template>
 				</el-table-column>
-				<el-table-column label="上传时间" width="180">
+				<el-table-column label="上传时间" width="200">
 					<template #default="scope">{{ formatTime(scope.row.created_at)}}</template>
 				</el-table-column>
+				<el-table-column label="状态" width="180">
+					<template #default="scope">
+						<el-tag type="success" v-if="scope.row.enabled">可用</el-tag>
+						<el-tag type="info" v-else>禁用</el-tag>
+					</template>
+				</el-table-column>
 				<el-table-column label="操作" width="180">
 					<template #default="scope">
-						<div class="">
-							<el-button type="danger" size="small">删除</el-button>
+						<div>
+							<el-button type="danger" size="small" @click="deleteFile(scope.row)">删除</el-button>
 						</div>
 					</template>
 				</el-table-column>
@@ -102,7 +130,10 @@
 			</el-table>
 		</div>
 		<div class="wui-table-pagination">
-			<el-pagination background layout="prev, pager, next" :total="total"></el-pagination>
+			<el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" background
+				layout="total,sizes, prev, pager, next" :pager-count="7" :total="total" :page-sizes="[10,15,20,25]"
+				@change="getFileData">
+			</el-pagination>
 		</div>
 	</div>
 </template>

文件差异内容过多而无法显示
+ 0 - 10
virgo.wzfrontend/src/main/resources/static/ai/assets/AIChat-BUeyZLEH.css


文件差异内容过多而无法显示
+ 8 - 0
virgo.wzfrontend/src/main/resources/static/ai/assets/AIChat-D4JVlfQL.js


文件差异内容过多而无法显示
+ 10 - 0
virgo.wzfrontend/src/main/resources/static/ai/assets/AIChat-D65jsWTc.css


文件差异内容过多而无法显示
+ 0 - 8
virgo.wzfrontend/src/main/resources/static/ai/assets/AIChat-RA6aavIS.js


文件差异内容过多而无法显示
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/ai/assets/Chats-BYP7mn8r.js


文件差异内容过多而无法显示
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/ai/assets/Home-Coo1DjZF.js


文件差异内容过多而无法显示
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/ai/assets/Home-Dv8GG1Yu.css


文件差异内容过多而无法显示
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/ai/assets/Home-r0mnIQ-v.js


文件差异内容过多而无法显示
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/ai/assets/Layout-DYL6SxtY.js


文件差异内容过多而无法显示
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/ai/assets/Reading-B16EbW2H.js


文件差异内容过多而无法显示
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/ai/assets/Reading-Rz5_3sJB.js


文件差异内容过多而无法显示
+ 3 - 3
virgo.wzfrontend/src/main/resources/static/ai/assets/ai-CRvZnbP2.js


文件差异内容过多而无法显示
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/ai/assets/index-6QHqnDT6.css


文件差异内容过多而无法显示
+ 62 - 0
virgo.wzfrontend/src/main/resources/static/ai/assets/index-BRY_gmZo.js


文件差异内容过多而无法显示
+ 0 - 62
virgo.wzfrontend/src/main/resources/static/ai/assets/index-DyOYl7hb.js


文件差异内容过多而无法显示
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/ai/assets/index-YZrFNSdb.css


+ 2 - 2
virgo.wzfrontend/src/main/resources/static/ai/index.html

@@ -5,8 +5,8 @@
 		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
 		<link rel="icon" href="https://file-node.oss-cn-shanghai.aliyuncs.com/youji/f9617c7f80da485cb3cc72b6accc62ed">
 		<title>WorkArk AI</title>

-		<script type="module" crossorigin src="./assets/index-DyOYl7hb.js"></script>
-		<link rel="stylesheet" crossorigin href="./assets/index-6QHqnDT6.css">
+		<script type="module" crossorigin src="./assets/index-BRY_gmZo.js"></script>
+		<link rel="stylesheet" crossorigin href="./assets/index-YZrFNSdb.css">
 	</head>
 	<body>
 		<div id="app"></div>