From 54821326506c12d9a1b2643da415d56c92a55df4 Mon Sep 17 00:00:00 2001
From: yangyin <1850366751@qq.com>
Date: 星期四, 10 十月 2024 16:29:14 +0800
Subject: [PATCH] 修改知识索引

---
 src/views/project/yw/dataManage/knowledge/AddKnowledge.vue |  441 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 407 insertions(+), 34 deletions(-)

diff --git a/src/views/project/yw/dataManage/knowledge/AddKnowledge.vue b/src/views/project/yw/dataManage/knowledge/AddKnowledge.vue
index b95cf3e..d627a23 100644
--- a/src/views/project/yw/dataManage/knowledge/AddKnowledge.vue
+++ b/src/views/project/yw/dataManage/knowledge/AddKnowledge.vue
@@ -1,19 +1,25 @@
 <template>
 	<div class="flex flex-col h100">
 		<div class="mb-[10px] flex flex-shrink-0 items-center">
-			<el-button style="margin-left: 8px; width: 40px" text @click="handleExitFlow">
+			<el-button style="margin-left: 8px; width: 40px" link @click="handleExitFlow">
 				<el-icon style="font-size: 24px !important">
 					<ArrowLeft />
 				</el-icon>
 			</el-button>
 			<span class="text-[24px] text-[#26244c] font-[700]">{{ state.detailTitle }}</span>
 		</div>
-		<div class="set-form-height">
-			<el-form :model="state.categoryForm" label-width="120px" label-position="left">
+		<div class="set-form-height" v-show="!state.showKnowledgeForm">
+			<el-form
+				:model="state.knowledgeForm"
+				label-width="120px"
+				label-position="left"
+				ref="knowledgeFormRef"
+				:rules="knowledgeFormRules"
+			>
 				<el-divider content-position="left"><span class="text-[18px] font-[500]">鐭ヨ瘑搴撳熀纭�淇℃伅</span></el-divider>
-				<el-form-item label="鐭ヨ瘑搴撳悕绉�:">
+				<el-form-item label="鐭ヨ瘑搴撳悕绉�:" prop="title">
 					<el-input
-						v-model="state.categoryForm.ImportCategory"
+						v-model="state.knowledgeForm.title"
 						style="width: 532px"
 						maxlength="20"
 						placeholder="璇疯緭鍏ョ煡璇嗗簱鍚嶇О"
@@ -21,9 +27,9 @@
 						type="text"
 					/>
 				</el-form-item>
-				<el-form-item label="鐭ヨ瘑搴撴弿杩�:">
+				<el-form-item label="鐭ヨ瘑搴撴弿杩�:" prop="prompt">
 					<el-input
-						v-model="state.categoryForm.CategoryType"
+						v-model="state.knowledgeForm.prompt"
 						maxlength="1000"
 						style="width: 532px"
 						placeholder="璇疯緭鍏ョ煡璇嗗簱鎻忚堪銆傚鐭ヨ瘑搴撳寘鍚殑鍐呭鍜屾暟鎹殑鐢ㄩ�旇繘琛屾弿杩般��"
@@ -32,11 +38,14 @@
 						type="textarea"
 					/>
 				</el-form-item>
+				<el-form-item label="绱㈠紩鍒嗘暟:" prop="scope">
+					<el-input v-model="state.knowledgeForm.scope" style="width: 532px" />
+				</el-form-item>
 				<el-form-item label="鏁版嵁绫诲瀷:">
 					<div v-for="(item, index) in state.dataTypeList" :key="index">
 						<div
 							class="bg-[#fff] border-[1px] border-solid border-[#d8d9e6] py-[12px] w-[215px] mr-[10px] px-[16px] rounded-lg cursor-pointer"
-							:class="{ activeColor: state.categoryForm.dataType === item.ID }"
+							:class="{ activeColor: state.knowledgeForm.dataType === item.ID }"
 							@click="activeDataType(item.ID)"
 						>
 							<div class="flex items-center">
@@ -44,7 +53,7 @@
 									<img :src="item.ImageURL" class="w-[40px] h-[40px] mr-[10px]" />
 								</div>
 								<div class="data_right">
-									<el-radio v-model="state.categoryForm.dataType" size="large" :label="item.ID">
+									<el-radio v-model="state.knowledgeForm.dataType" size="large" :label="item.ID">
 										<span class="font-[500] text[16px]">{{ item.Name }}</span>
 									</el-radio>
 
@@ -65,7 +74,7 @@
 							<div v-for="(item, index) in state.configurationList" :key="index">
 								<div
 									class="bg-[#fff] border-[1px] border-solid border-[#d8d9e6] py-[12px] w-[215px] mr-[10px] px-[16px] rounded-lg cursor-pointer"
-									:class="{ activeColor: state.categoryForm.configurationMode === item.ID }"
+									:class="{ activeColor: state.knowledgeForm.configurationMode === item.ID }"
 									@click="activeConfigurationType(item.ID)"
 								>
 									<div class="flex items-center">
@@ -73,7 +82,7 @@
 											<img :src="item.ImageURL" class="w-[40px] h-[40px] mr-[10px]" />
 										</div>
 										<div class="data_right">
-											<el-radio v-model="state.categoryForm.configurationMode" size="large" :label="item.ID">
+											<el-radio v-model="state.knowledgeForm.configurationMode" size="large" :label="item.ID">
 												<span class="font-[500] text[16px]">{{ item.Name }}</span>
 											</el-radio>
 
@@ -87,7 +96,7 @@
 								</div>
 							</div>
 						</div>
-						<div class="set_model_desc">
+						<!-- <div class="set_model_desc">
 							<div v-for="(item, index) in state.modeList" :key="index">
 								<div class="flex items-center mb-[16px]">
 									<div class="relative w-[148px] text-[14px] text-[#26244c]">{{ item.Name }}</div>
@@ -95,8 +104,98 @@
 									<div v-show="item.ID == 3">
 										<div class="min-w-[148px] text-[14px] text-[#26244c]">{{ item.NameOrder }}</div>
 									</div>
-									<div style="width: 200px" class="custom-style min-w-[148px] text-[14px] text-[#26244c]" v-if="item.ID == 4">
-										<el-slider v-model="item.NameOrder" :max="1" />
+								</div>
+							</div>
+						</div> -->
+					</div>
+				</el-form-item>
+			</el-form>
+		</div>
+		<div class="set-form-height" v-show="state.showKnowledgeForm">
+			<el-form
+				:model="state.knowledgeFile"
+				label-width="120px"
+				label-position="left"
+				class="h100"
+				ref="knowledgeFileRef"
+				:rules="knowledgeFormRules"
+			>
+				<el-divider content-position="left"><span class="text-[18px] font-[500]">閫夋嫨鏂囦欢</span></el-divider>
+				<div class="flex items-start gap-[16px] max-h-[686px] min-h-[360px] set-file-height">
+					<div class="min-h-[360px] h100 set_file_left">
+						<div class="font-[500] mb-2">璇烽�夋嫨鏂囨。</div>
+						<div class="left_content">
+							<div class="file_menu">
+								<LeftTreeByMgr
+									title-name="绫荤洰"
+									ref="leftTreeRef"
+									:treedata="state.knowledgeBaseData"
+									:current-node-key="currentListID"
+									:defaultProps="{
+										id: 'group_id',
+										label: 'group_name',
+										children: 'Children',
+									}"
+									@click="handleClickNode"
+								>
+								</LeftTreeByMgr>
+							</div>
+							<div class="file_table">
+								<el-table
+									:data="state.fileData"
+									border
+									@select="handleSelectItem"
+									highlight-current-row
+									ref="multipleTableRef"
+									@select-all="
+										(selection) => {
+											handleSelectAll(selection, state.fileData);
+										}
+									"
+								>
+									<el-table-column type="selection" width="55" />
+									<el-table-column prop="name" label="鏂囦欢鍚嶇О" />
+								</el-table>
+							</div>
+						</div>
+					</div>
+					<div class="set_file_right">
+						<div class="h100">
+							<div class="font-[500] mb-[12px]">宸查�夋枃妗{ multipleSelection.length }}/50涓�</div>
+							<div class="selected_file">
+								<div v-for="(item, index) in multipleSelection" :key="index" class="set_file_item">
+									<span class="set_file_name">{{ item.name }}</span>
+									<span class="ywifont ywicon-guanbi set_file_close" @click="handleRemoveItem(item)"></span>
+								</div>
+							</div>
+						</div>
+					</div>
+				</div>
+				<el-divider content-position="left"><span class="text-[18px]">鏁版嵁澶勭悊</span></el-divider>
+				<el-form-item label="鏂囨。鍒囧垎chunk:">
+					<div class="flex-auto flex flex-col">
+						<div class="flex">
+							<div v-for="(item, index) in state.segmentationList" :key="index">
+								<div
+									class="bg-[#fff] border-[1px] border-solid border-[#d8d9e6] py-[12px] w-[215px] mr-[10px] px-[16px] rounded-lg cursor-pointer"
+									:class="{ activeColor: state.knowledgeForm.segmentationMode === item.ID }"
+									@click="activeDataProcessType(item.ID)"
+								>
+									<div class="flex items-center">
+										<div class="data_left">
+											<img :src="item.ImageURL" class="w-[40px] h-[40px] mr-[10px]" />
+										</div>
+										<div class="data_right">
+											<el-radio v-model="state.knowledgeForm.segmentationMode" size="large" :label="item.ID">
+												<span class="font-[500] text[16px]">{{ item.Name }}</span>
+											</el-radio>
+
+											<el-tooltip :content="item.DemoDesc" placement="top" effect="light" popper-class="set_tooltip_demo">
+												<div class="text-[#878aab] text-[12px] mx-0 mt-[2px] mb-0 set-desc">
+													{{ item.DemoDesc }}
+												</div>
+											</el-tooltip>
+										</div>
 									</div>
 								</div>
 							</div>
@@ -105,28 +204,44 @@
 				</el-form-item>
 			</el-form>
 		</div>
-
 		<div class="set-form-footer">
-			<el-button type="primary" @click="onSubmit">涓嬩竴姝�</el-button>
-			<el-button>鍙栨秷</el-button>
+			<div v-show="!state.showKnowledgeForm">
+				<el-button type="primary" @click="nextKnowledge">涓嬩竴姝�</el-button>
+			</div>
+			<div v-show="state.showKnowledgeForm">
+				<el-button @click="importCompleted" type="primary">瀵煎叆瀹屾垚</el-button>
+				<el-button @click="backKnowledge" v-show="state.showKnowledgeForm">涓婁竴姝�</el-button>
+			</div>
+			<el-button @click="handleExitFlow">鍙栨秷</el-button>
 		</div>
 	</div>
 </template>
 
 <script setup lang="ts">
-import type { UploadUserFile } from 'element-plus';
-import { reactive, ref } from 'vue';
-import { useRouter } from 'vue-router';
+import { ElMessage, type FormRules } from 'element-plus';
+import moment from 'moment';
+import { computed, nextTick, onMounted, reactive, ref } from 'vue';
+import { useRoute, useRouter } from 'vue-router';
+import { add_docvector_file, add_docvector_name } from '/@/api/knowledge/docvector';
+import { get_knowledge_group_list, list_knowledge_file } from '/@/api/knowledge/group';
+import LeftTreeByMgr from '/@/components/tree/leftTreeByMgr.vue';
+import mittBus from '/@/utils/mitt';
+import { verifiyNumberInteger } from '/@/utils/toolsValidate';
+import { convertListToTree } from '/@/utils/util';
+const route = useRoute();
 // 瀹氫箟鍙橀噺鍐呭
 const state = reactive({
 	soliderValue: 0,
 	detailTitle: '鍒涘缓鐭ヨ瘑搴�',
-	categoryForm: {
-		ImportCategory: '',
-		CategoryType: '鏈湴绫荤洰',
+	knowledgeForm: {
+		title: '',
+		prompt: '',
+		scope: null,
 		dataType: 1,
 		configurationMode: 1,
+		segmentationMode: 1,
 	},
+	knowledgeFile: {},
 	dataTypeList: [
 		{
 			ID: 1,
@@ -140,7 +255,7 @@
 			ImageURL: 'static/images/knowledge/data_type_2.png',
 			DemoDesc: '閫夋嫨鏁版嵁绠$悊鍔熻兘涓凡鍒涘缓鐨勬暟鎹〃',
 		},
-	],
+	], //鏁版嵁绫诲瀷
 	configurationList: [
 		{
 			ID: 1,
@@ -153,6 +268,20 @@
 			Name: '鑷畾涔�',
 			ImageURL: 'static/images/knowledge/data_type_4.png',
 			DemoDesc: '瀹屽叏寮�鏀剧殑绂荤嚎鐭ヨ瘑搴撻厤缃紝鎸夌収妫�绱㈤渶姹傝嚜鐢遍厤缃紝鑾峰緱鎺ㄧ悊鏁堟灉鍜屾椂寤舵柟闈㈢殑涓嶅悓浣撻獙',
+		},
+	], //閰嶇疆妯″紡
+	segmentationList: [
+		{
+			ID: 1,
+			Name: '鏅鸿兘鍒囧垎',
+			ImageURL: 'static/images/knowledge/data_type_3.png',
+			DemoDesc: '鍦ㄩ�氱敤鏂囨。涓婄殑鏈�浼榗hunk鍒囧垎鏂规硶锛岀粡杩囪瘎娴嬪彲鍦ㄥ鏁版枃妗d笂鑾峰緱鏈�浣崇殑妫�绱㈡晥鏋�',
+		},
+		{
+			ID: 3,
+			Name: '鑷畾涔夊垏鍒�',
+			ImageURL: 'static/images/knowledge/data_type_4.png',
+			DemoDesc: '瀹屽叏寮�鏀剧殑chunk鍒囧垎閰嶇疆锛屾寜鐓у疄闄呮枃妗f儏鍐佃嚜鐢遍厤缃紝閫氳繃璋冭瘯鑾峰緱鏇村ソ鐨勬绱㈡晥鏋�',
 		},
 	],
 	modeList: [
@@ -181,28 +310,206 @@
 			ID: 4,
 			Name: '',
 			NameFn: '鐩镐技搴﹂槇鍊�',
-			NameOrder: 0.01,
+			NameOrder: null,
 			NameFnWidthStyle: '148px',
 		},
 	],
+	showKnowledgeForm: false,
+	knowledgeBaseData: [], //鐭ヨ瘑搴撶被鐩�
+	fileData: [], //鏂囦欢鏁版嵁婧�
+	isCreateIndex: false, //鏄惁璋冪敤鍒涘缓鐨勭储寮曠殑瀛楁
+	knowlg_id: '',
+	groupKnow_id: null,
 });
-const fileList = ref<UploadUserFile[]>([]);
+//楠岃瘉scope瀛楁鍙兘杈撳叆姝f暣鏁�
+const validateNumber = (rule, value, callback) => {
+	if (value < 31) {
+		callback(new Error('璇疯緭鍏ュぇ浜�30鐨勬鏁存暟'));
+	} else {
+		state.knowledgeForm.scope = verifiyNumberInteger(value);
+		callback();
+	}
+};
+const knowledgeFormRules = reactive<FormRules>({
+	title: [
+		{
+			required: true,
+			message: '蹇呭~椤�',
+			trigger: 'blur',
+		},
+	],
+	prompt: [
+		{
+			required: true,
+			message: '蹇呭~椤�',
+			trigger: 'blur',
+		},
+	],
+	scope: [{ validator: validateNumber, trigger: 'blur' }],
+});
+const knowledgeFormRef = ref();
 const router = useRouter();
+
+//#region ====================== 鐭ヨ瘑搴撹〃鍗曟搷浣� ======================
 //杩斿洖
 const handleExitFlow = () => {
 	//鏄惁鏄剧ず杩斿洖
 	router.back();
+	//娓呯┖琛ㄥ崟
+	knowledgeFormRef.value.resetFields();
+	state.showKnowledgeForm = false;
 };
 //閫夋嫨鏁版嵁绫诲瀷
 const activeDataType = (id: number) => {
-	state.categoryForm.dataType = id;
+	state.knowledgeForm.dataType = id;
 };
 //閫夋嫨閰嶇疆妯″紡
 const activeConfigurationType = (id: number) => {
-	state.categoryForm.configurationMode = id;
+	state.knowledgeForm.configurationMode = id;
 };
-//纭
-const onSubmit = () => {};
+//閫夋嫨鏁版嵁鏂囨。鍒囧垎
+const activeDataProcessType = (id: number) => {
+	state.knowledgeForm.segmentationMode = id;
+};
+//涓嬩竴姝�
+const nextKnowledge = async () => {
+	const valid = await knowledgeFormRef.value.validate().catch(() => {});
+	if (!valid) return;
+	state.showKnowledgeForm = true;
+	if (!state.isCreateIndex) {
+		emptyKnowledgeBase();
+		state.isCreateIndex = true;
+	}
+};
+const backKnowledge = () => {
+	state.showKnowledgeForm = false;
+};
+
+//#endregion
+//#region ====================== 绌虹煡璇嗗簱鐨勫垱寤� ======================
+
+//鍒涘缓涓�涓┖鐭ヨ瘑搴�
+const emptyKnowledgeBase = async () => {
+	const valid = await knowledgeFormRef.value.validate().catch(() => {});
+	if (!valid) return;
+	const res = await add_docvector_name({
+		title: state.knowledgeForm.title,
+		prompt: state.knowledgeForm.prompt,
+		scope: state.knowledgeForm.scope,
+		group_id: state.groupKnow_id,
+	});
+	if (res.json_ok) {
+		state.knowlg_id = res.knowlg_id;
+		getFileTreeData(true);
+	}
+};
+//瀵煎叆瀹屾垚
+const importCompleted = async () => {
+	var currentTime = moment().format('YYYY-MM-DD HH:mm:ss');
+	// 涓婁紶鏂囦欢
+	if (multipleSelection.value.length == 0) return ElMessage.warning('璇峰厛閫夋嫨鏂囦欢');
+	const file_id = multipleSelection.value.map((v) => v.id).join(',');
+	const res = await add_docvector_file({
+		knowlg_id: state.knowlg_id,
+		file_id: file_id,
+	});
+	if (res.json_ok) {
+		let obj = {
+			id: state.knowlg_id,
+			title: state.knowledgeForm.title,
+			prompt: state.knowledgeForm.prompt,
+			publish: 'N',
+			create_time: currentTime,
+			user_name: '',
+			scope: state.knowledgeForm.scope,
+		};
+		mittBus.emit('addKnowledgeBaseObj', obj);
+		router.push({ name: 'Knowledge' });
+		//娓呯┖琛ㄥ崟
+		knowledgeFormRef.value.resetFields();
+		state.showKnowledgeForm = false;
+		state.isCreateIndex = false;
+	}
+};
+//#endregion
+//#region ====================== 鐭ヨ瘑搴撴枃浠朵笂浼� ==========
+const currentTreeNode = ref(null);
+const leftTreeRef = ref(null);
+const currentListID = computed(() => currentTreeNode.value?.group_id);
+//鑾峰彇鏂囦欢鍒楄〃
+const getFileTreeData = async (selectFirst = false) => {
+	const res = await get_knowledge_group_list();
+	if (res?.json_ok) {
+		const resData = (res.groups || []) as [];
+		state.knowledgeBaseData = convertListToTree(resData, {
+			ID: 'group_id',
+			Children: 'Children',
+			ParentID: 'p_group_id',
+		});
+		if (selectFirst) {
+			const firstListTreeNode = state.knowledgeBaseData[0];
+			if (firstListTreeNode) {
+				handleClickNode(firstListTreeNode);
+			} else {
+				state.fileData = [];
+				multipleSelection.value = [];
+			}
+		} else {
+			currentTreeNode.value && handleClickNode(currentTreeNode.value);
+		}
+	}
+};
+const handleClickNode = (data: any) => {
+	multipleSelection.value = [];
+	nextTick(() => {
+		leftTreeRef.value?.treeRef.setCurrentKey(data.group_id);
+	});
+	currentTreeNode.value = data;
+	getFileTableData();
+};
+//鑾峰彇鏂囦欢琛ㄦ牸鍒楄〃
+const getFileTableData = async () => {
+	const res = await list_knowledge_file({
+		group_id: currentListID.value,
+	}).finally(() => {});
+	if (res?.json_ok) {
+		const resData = (res.values || []) as [];
+		state.fileData = resData;
+	} else {
+		ElMessage.error('鑾峰彇鏂囨。鍒楄〃澶辫触' + (res?.json_msg ? `锛�${JSON.stringify(res.json_msg)}` : ''));
+	}
+};
+let multipleSelection = ref([]);
+const multipleTableRef = ref(null);
+//琛ㄦ牸鍗曢�夊拰澶氶��
+const handleSelectAll = (selection: any[], pageSelectionData: any[]) => {
+	let checked = selection.length ? true : false; // selection涓虹┖鏁扮粍鏃朵唬琛ㄥ彇娑堝叏閫�
+	if (checked) {
+		let mIds = multipleSelection.value.map((v) => v.id);
+		let filterData = pageSelectionData.filter((v) => {
+			// 绛涢�夊嚭闈為噸澶嶉」
+			return !mIds.includes(v.id);
+		});
+		multipleSelection.value = multipleSelection.value.concat(filterData);
+	} else {
+		let pIds = pageSelectionData.map((v) => v.id);
+		multipleSelection.value = multipleSelection.value.filter((v) => !pIds.includes(v.id));
+	}
+};
+
+const handleSelectItem = (selection: any[], row) => {
+	multipleSelection.value = selection;
+};
+// 绉婚櫎宸查�夋枃浠�
+const handleRemoveItem = (item) => {
+	multipleSelection.value = multipleSelection.value.filter((v) => v.id !== item.id);
+	multipleTableRef.value.toggleRowSelection(item, false);
+};
+//#endregion
+onMounted(() => {
+	const group_id = route.query.group_id;
+	state.groupKnow_id = group_id;
+});
 </script>
 <style scoped lang="scss">
 .set-form-height {
@@ -249,10 +556,76 @@
 	margin-top: 12px;
 	padding: 16px 24px;
 }
-.slider-demo-block {
-	max-width: 600px;
-	display: flex;
-	align-items: center;
+.set-file-height {
+	height: calc(100% - 48px);
+}
+.set_file_left {
+	border: 1px solid #e7e8ee;
+	border-radius: 12px;
+	flex: 1;
+	padding: 12px 16px 16px;
+	box-sizing: border-box;
+	.left_content {
+		align-items: flex-start;
+		display: flex;
+		gap: 12px;
+		height: calc(100% - 29px);
+		.file_menu {
+			flex-shrink: 0;
+			height: 100%;
+			overflow-y: auto;
+			border: 1px solid #e7e8ee;
+			border-radius: 6px;
+			max-height: 627px;
+			padding: 20px;
+			width: 280px;
+		}
+		.file_table {
+			flex-shrink: 0;
+			height: 100%;
+			overflow-y: auto;
+			border-radius: 8px 8px 0 0;
+			flex: 1;
+		}
+	}
+}
+.set_file_right {
+	border: 1px solid #e7e8ee;
+	border-radius: 6px;
+	flex-shrink: 0;
+	height: 100%;
+	padding: 12px 16px 16px;
+	width: 417px;
+	min-height: 360px;
+}
+.selected_file {
+	max-height: calc(100% - 36px);
+	overflow-y: auto;
+	box-sizing: border-box;
+	.set_file_item {
+		align-items: center;
+		background: linear-gradient(0deg, #f7f8fe, #f7f8fe), #fff;
+		border-radius: 8px;
+		display: flex;
+		font-size: 12px;
+		gap: 8px;
+		height: 40px;
+		justify-content: space-between;
+		padding: 0 16px;
+		margin-bottom: 9px;
+		.set_file_name {
+			max-width: calc(100% - 22px);
+		}
+		.set_file_close {
+			color: #878aab;
+			cursor: pointer;
+			flex-shrink: 0;
+			font-size: 14px;
+			align-items: center;
+			display: inline-flex;
+			justify-content: center;
+		}
+	}
 }
 </style>
 <style>

--
Gitblit v1.9.3