From f4354c5a98c6a3bdb4f355b107e2421848f1426b Mon Sep 17 00:00:00 2001
From: wujingjing <gersonwu@qq.com>
Date: 星期三, 13 十一月 2024 17:31:52 +0800
Subject: [PATCH] Merge branches 'test' and 'test' of http://47.103.154.90:83/r/WI/Web.Admin.V1.0 into test

---
 src/views/project/yw/systemManage/questionMgr/RecommendQuestions.vue |  103 ++++----
 src/api/login/UserMenuData.ts                                        |   15 +
 src/views/project/yw/systemManage/metricAgentMgr/MetricAgentMgr.vue  |   18 +
 src/views/project/yw/dataManage/knowledge/EditKnowledge.vue          |    9 
 src/views/project/yw/dataManage/knowledge/Knowledge.vue              |   54 +++-
 src/views/project/yw/dataManage/knowledge/AddKnowledge.vue           |   29 ++
 src/views/project/yw/systemManage/departmentMgr/DepartmentMgr.vue    |  150 +++++++++++++
 src/api/department/index.ts                                          |   30 ++
 customer_list/yw/static/config/route.js                              |    8 
 src/views/project/yw/systemManage/departmentMgr/optDlg/OptDlg.vue    |  129 +++++++++++
 src/views/project/yw/systemManage/metricMgr/MetricDetail.vue         |    8 
 src/utils/util.ts                                                    |    1 
 src/views/project/yw/lowCode/sqlAmis/SqlAmis.vue                     |   50 ++++
 src/views/project/yw/systemManage/chatLog/ChatLog.vue                |   24 ++
 14 files changed, 541 insertions(+), 87 deletions(-)

diff --git a/customer_list/yw/static/config/route.js b/customer_list/yw/static/config/route.js
index 8670816..a781642 100644
--- a/customer_list/yw/static/config/route.js
+++ b/customer_list/yw/static/config/route.js
@@ -27,6 +27,14 @@
 		path: '/authCenter/userMgr',
 		component: '/project/yw/systemManage/userMgr/UserMgr.vue',
 	},
+	//閮ㄩ棬绠$悊
+	{
+		name: 'DepartmentMgr',
+		isKeepAlive: true,
+		isAffix: false,
+		path: '/authCenter/departmentMgr',
+		component: '/project/yw/systemManage/departmentMgr/DepartmentMgr.vue',
+	},
 	{
 		name: 'AccessLog',
 		isKeepAlive: true,
diff --git a/src/api/department/index.ts b/src/api/department/index.ts
new file mode 100644
index 0000000..a8c8f11
--- /dev/null
+++ b/src/api/department/index.ts
@@ -0,0 +1,30 @@
+import request from '/@/utils/request';
+
+/**
+ * @description 娣诲姞閮ㄩ棬淇℃伅
+ **/
+export const add_department_info = (params) =>
+	request({
+		url: `/admin/department/add_department_info`,
+		method: 'post',
+		params: {},
+		data: params,
+	});
+/**
+ * @description 鍒犻櫎閮ㄩ棬淇℃伅
+ **/
+export const delete_department = (params) =>
+	request({
+		url: `/admin/department/delete_department`,
+		method: 'post',
+		params: {},
+		data: params,
+	});
+/**
+ * @description 鑾峰彇閮ㄩ棬淇℃伅
+ **/
+export const get_department_list = () =>
+	request({
+		url: `/admin/department/get_department_list`,
+		method: 'post',
+	});
diff --git a/src/api/login/UserMenuData.ts b/src/api/login/UserMenuData.ts
index 55d3d73..ae37c1b 100644
--- a/src/api/login/UserMenuData.ts
+++ b/src/api/login/UserMenuData.ts
@@ -426,6 +426,21 @@
 			{
 				Children: [],
 				ID: '333-3',
+				ParentID: '1742436890822447205',
+				Type: 2,
+				Name: '閮ㄩ棬绠$悊',
+				Path: '/authCenter/departmentMgr',
+				Permission: '',
+				Icon: 'ywifont ywicon-jiegou',
+				IsIframe: false,
+				IsHide: false,
+				Weight: 0,
+				SortCode: 2,
+				Description: '',
+			},
+			{
+				Children: [],
+				ID: '333-4',
 				ParentID: '1742436890822447105',
 				Type: 2,
 				Name: '鎿嶄綔鏃ュ織',
diff --git a/src/utils/util.ts b/src/utils/util.ts
index b378009..830c686 100644
--- a/src/utils/util.ts
+++ b/src/utils/util.ts
@@ -470,6 +470,7 @@
 	const startDate = new Date();
 	startDate.setTime(startDate.getTime() - 3600 * 1000 * 24 * dates);
 	startDate.setHours(0, 0, 0, 0);
+	endDate.setHours(23,59,59,59)
 	return [startDate, endDate];
 };
 
diff --git a/src/views/project/yw/dataManage/knowledge/AddKnowledge.vue b/src/views/project/yw/dataManage/knowledge/AddKnowledge.vue
index d627a23..d89123c 100644
--- a/src/views/project/yw/dataManage/knowledge/AddKnowledge.vue
+++ b/src/views/project/yw/dataManage/knowledge/AddKnowledge.vue
@@ -136,6 +136,7 @@
 										label: 'group_name',
 										children: 'Children',
 									}"
+									defaultExpandAll
 									@click="handleClickNode"
 								>
 								</LeftTreeByMgr>
@@ -228,6 +229,7 @@
 import mittBus from '/@/utils/mitt';
 import { verifiyNumberInteger } from '/@/utils/toolsValidate';
 import { convertListToTree } from '/@/utils/util';
+import { OptClassificationMap, classificationEnum } from '/@/views/types/metrics';
 const route = useRoute();
 // 瀹氫箟鍙橀噺鍐呭
 const state = reactive({
@@ -358,6 +360,7 @@
 	//娓呯┖琛ㄥ崟
 	knowledgeFormRef.value.resetFields();
 	state.showKnowledgeForm = false;
+	state.isCreateIndex = false;
 };
 //閫夋嫨鏁版嵁绫诲瀷
 const activeDataType = (id: number) => {
@@ -383,6 +386,7 @@
 };
 const backKnowledge = () => {
 	state.showKnowledgeForm = false;
+	state.isCreateIndex = true;
 };
 
 //#endregion
@@ -392,6 +396,7 @@
 const emptyKnowledgeBase = async () => {
 	const valid = await knowledgeFormRef.value.validate().catch(() => {});
 	if (!valid) return;
+	var currentTime = moment().format('YYYY-MM-DD HH:mm:ss');
 	const res = await add_docvector_name({
 		title: state.knowledgeForm.title,
 		prompt: state.knowledgeForm.prompt,
@@ -400,7 +405,19 @@
 	});
 	if (res.json_ok) {
 		state.knowlg_id = res.knowlg_id;
+		let obj = {
+			id: state.knowlg_id,
+			group_id: state.groupKnow_id,
+			title: state.knowledgeForm.title,
+			prompt: state.knowledgeForm.prompt,
+			publish: 'N',
+			create_time: currentTime,
+			user_name: '',
+			scope: state.knowledgeForm.scope,
+		};
+		mittBus.emit('addEmptyKnowledge', obj);
 		getFileTreeData(true);
+		state.isCreateIndex = false;
 	}
 };
 //瀵煎叆瀹屾垚
@@ -416,6 +433,7 @@
 	if (res.json_ok) {
 		let obj = {
 			id: state.knowlg_id,
+			group_id: state.groupKnow_id,
 			title: state.knowledgeForm.title,
 			prompt: state.knowledgeForm.prompt,
 			publish: 'N',
@@ -423,7 +441,7 @@
 			user_name: '',
 			scope: state.knowledgeForm.scope,
 		};
-		mittBus.emit('addKnowledgeBaseObj', obj);
+		mittBus.emit('updateKnowledgeBaseObj', obj);
 		router.push({ name: 'Knowledge' });
 		//娓呯┖琛ㄥ崟
 		knowledgeFormRef.value.resetFields();
@@ -441,11 +459,18 @@
 	const res = await get_knowledge_group_list();
 	if (res?.json_ok) {
 		const resData = (res.groups || []) as [];
-		state.knowledgeBaseData = convertListToTree(resData, {
+		const byParentData = convertListToTree(resData, {
 			ID: 'group_id',
 			Children: 'Children',
 			ParentID: 'p_group_id',
 		});
+		const result = [];
+		byParentData.forEach((item) => {
+			if (item.group_type == OptClassificationMap[classificationEnum.Knowledge]) {
+				result.push(item);
+			}
+		});
+		state.knowledgeBaseData = result;
 		if (selectFirst) {
 			const firstListTreeNode = state.knowledgeBaseData[0];
 			if (firstListTreeNode) {
diff --git a/src/views/project/yw/dataManage/knowledge/EditKnowledge.vue b/src/views/project/yw/dataManage/knowledge/EditKnowledge.vue
index 5082c77..8d6b28c 100644
--- a/src/views/project/yw/dataManage/knowledge/EditKnowledge.vue
+++ b/src/views/project/yw/dataManage/knowledge/EditKnowledge.vue
@@ -59,8 +59,8 @@
 import { onMounted, reactive, ref } from 'vue';
 import { useRoute, useRouter } from 'vue-router';
 import { update_docvector_name } from '/@/api/knowledge/docvector';
-import mittBus from '/@/utils/mitt';
 import { verifiyNumberInteger } from '/@/utils/toolsValidate';
+import mittBus from '/@/utils/mitt';
 // 瀹氫箟鍙橀噺鍐呭
 const state = reactive({
 	soliderValue: 0,
@@ -119,22 +119,23 @@
 			id: state.editKnowledgeForm.knowlg_id,
 			title: state.editKnowledgeForm.title,
 			prompt: state.editKnowledgeForm.prompt,
-			publish: 'N',
+			publish: state.editKnowledgeForm.publish,
 			create_time: currentTime,
 			user_name: '',
 			scope: state.editKnowledgeForm.scope,
 		};
-		mittBus.emit('addKnowledgeBaseObj', obj);
+		mittBus.emit('updateKnowledgeBaseObj', obj);
 		router.push({ name: 'Knowledge' });
 	}
 };
 
 onMounted(() => {
-	const { knowledge_title, knowledge_id, knowledge_prompt, knowledge_scope } = route.query;
+	const { knowledge_title, knowledge_id, knowledge_prompt, knowledge_scope,knowledge_publish } = route.query;
 	state.editKnowledgeForm.title = knowledge_title;
 	state.editKnowledgeForm.prompt = knowledge_prompt;
 	state.editKnowledgeForm.knowlg_id = knowledge_id;
 	state.editKnowledgeForm.scope = knowledge_scope;
+	state.editKnowledgeForm.publish = knowledge_publish;
 });
 </script>
 <style scoped lang="scss">
diff --git a/src/views/project/yw/dataManage/knowledge/Knowledge.vue b/src/views/project/yw/dataManage/knowledge/Knowledge.vue
index 86297a3..d5b973b 100644
--- a/src/views/project/yw/dataManage/knowledge/Knowledge.vue
+++ b/src/views/project/yw/dataManage/knowledge/Knowledge.vue
@@ -132,7 +132,6 @@
 import { SupervisorPublished, supervisorPublishedMap } from '/@/views/project/yw/lowCode/sqlAmis/types';
 import { OptClassificationMap, classificationEnum } from '/@/views/types/metrics';
 import knowledgeLeft from '/static/images/knowledge/data_type_1.png';
-import item from 'element-plus/es/components/space/src/item';
 const router = useRouter();
 //#region ====================== 宸︿晶鏍戞暟鎹紝tree init ======================
 const leftTreeRef = useCompRef(LeftTreeByMgr);
@@ -159,23 +158,20 @@
 		leftTreeRef.value?.treeRef.setCurrentKey(data.group_id);
 	});
 	currentNode.value = data;
-	docvectorList();
+	showKnowledgeBaseList.value = knowledgeBaseList.value.filter((item) => item.group_id === currentListID.value);
 };
 
 const getListTreeData = async () => {
 	const res = await agentGroupApi.getSceneGroupTreeByPost();
 	listData.value = res.groups || [];
 	const firstListTreeNode = listTreeData.value[0];
-	if (firstListTreeNode) {
-		handleClickNode(firstListTreeNode);
-	} else {
-		knowledgeBaseList.value = [];
-		currentNode.value = null;
-	}
+	currentNode.value = firstListTreeNode;
+	docvectorList();
 };
 //#endregion
 //#region ====================== 鑾峰彇鐭ヨ瘑搴搒heet鍒楄〃 ======================
 const knowledgeBaseList = ref([]);
+const showKnowledgeBaseList = ref([]);
 //鍒涘缓鐭ヨ瘑搴�
 const createKnowledgeBase = () => {
 	router.push({
@@ -192,12 +188,19 @@
 		res.values.forEach((item) => {
 			item.create_time = new Date(item.create_time).toLocaleString();
 		});
-		const filterDocData = res.values.filter((item) => item.group_id === currentListID.value);
-		knowledgeBaseList.value = filterDocData;
+
+		knowledgeBaseList.value = res.values ?? [];
+		showKnowledgeBaseList.value = filterDocData(knowledgeBaseList.value);
 	} else {
 		return ElMessage.error('鑾峰彇鍒楄〃绱㈠紩澶辫触' + (res?.json_msg ? `锛�${JSON.stringify(res.json_msg)}` : ''));
 	}
 };
+
+const filterDocData = (list) => {
+	const filterDocData = list.filter((item) => item.group_id === currentListID.value);
+	return filterDocData;
+};
+
 const deleteKnowledgeBase = async (row) => {
 	ElMessageBox.confirm(`纭畾鍒犻櫎褰撳墠鐨勭煡璇嗗簱锛氥��${row.title}銆�?`, '鎻愮ず', {
 		confirmButtonText: '纭畾',
@@ -208,9 +211,10 @@
 			knowlg_id: row.id,
 		});
 		if (res.json_ok) {
+			const foundIndex = knowledgeBaseList.value.findIndex((item) => item === row);
+			foundIndex > -1 && knowledgeBaseList.value.splice(foundIndex, 1);
+			showKnowledgeBaseList.value = filterDocData(knowledgeBaseList.value);
 			ElMessage.success('鍒犻櫎鐭ヨ瘑搴撴垚鍔�');
-			const index = knowledgeBaseList.value.findIndex((d) => d.id === row.id);
-			knowledgeBaseList.value.splice(index, 1);
 		}
 	});
 };
@@ -225,6 +229,7 @@
 			knowledge_desc: row.desc,
 			knowledge_prompt: row.prompt,
 			knowledge_scope: row.scope,
+			knowledge_publish: row.publish,
 		},
 	});
 };
@@ -254,8 +259,8 @@
 const knowledgeBaseForm = ref({
 	title: '',
 });
-const { resetQuery, handleQueryTable, displayTableData } = useQueryTable(knowledgeBaseList, knowledgeBaseForm, () => {
-	displayTableData.value = knowledgeBaseList.value;
+const { resetQuery, handleQueryTable, displayTableData } = useQueryTable(showKnowledgeBaseList, knowledgeBaseForm, () => {
+	displayTableData.value = showKnowledgeBaseList.value;
 });
 //#endregion
 //#region ====================== Chat 娴嬭瘯 ======================
@@ -301,10 +306,27 @@
 //#endregion
 onMounted(() => {
 	getListTreeData();
-	mittBus.on('addKnowledgeBaseObj', (obj) => {
-		knowledgeBaseList.value.push(obj);
+	mittBus.on('addEmptyKnowledge', (formValue) => {
+		knowledgeBaseList.value.push(formValue);
+		showKnowledgeBaseList.value = filterDocData(knowledgeBaseList.value);
 	});
+	//缂栬緫鍐呭
+	mittBus.on('updateKnowledgeBaseObj', cbUpdateKnowledgeBaseObj);
 });
+
+const cbUpdateKnowledgeBaseObj = (formValue) => {
+	knowledgeBaseList.value.forEach((item) => {
+		if (item.id == formValue.id) {
+			item.title = formValue.title;
+			item.prompt = formValue.prompt;
+			item.publish = formValue.publish;
+			item.create_time = formValue.create_time;
+			item.user_name = formValue.user_name;
+			item.scope = formValue.scope;
+		}
+	});
+	showKnowledgeBaseList.value = filterDocData(knowledgeBaseList.value);
+};
 </script>
 <style scoped lang="scss">
 .set_item_jel {
diff --git a/src/views/project/yw/lowCode/sqlAmis/SqlAmis.vue b/src/views/project/yw/lowCode/sqlAmis/SqlAmis.vue
index 0a2e4f3..9355cc4 100644
--- a/src/views/project/yw/lowCode/sqlAmis/SqlAmis.vue
+++ b/src/views/project/yw/lowCode/sqlAmis/SqlAmis.vue
@@ -8,7 +8,7 @@
 				ref="leftTreeRef"
 				:defaultProps="{
 					id: 'group_id',
-					label: 'group_name',
+					label: 'label',
 					children: 'children',
 				}"
 				:treedata="listTreeData"
@@ -25,7 +25,7 @@
 		<template #header>
 			<el-form ref="queryFormRef" :inline="true" :model="queryParams">
 				<el-form-item label="鏍囬" prop="title">
-					<el-input v-model="queryParams.title" style="width: 226.4px" placeholder="鏍囬" clearable @input="debounceQueryTable"/>
+					<el-input v-model="queryParams.title" style="width: 226.4px" placeholder="鏍囬" clearable @input="debounceQueryTable" />
 				</el-form-item>
 
 				<el-form-item>
@@ -107,6 +107,7 @@
 													deleteCurrentRow(scope.row, '椤甸潰', supervisorAdminApi.deleteSupervisor, () => {
 														const foundIndex = tableData.findIndex((item) => item === scope.row);
 														foundIndex > -1 && tableData.splice(foundIndex, 1);
+														setCurrentLen(-1);
 													});
 												}
 											"
@@ -198,7 +199,7 @@
 
 <script setup lang="ts">
 import { useDraggable } from '@vueuse/core';
-import { debounce, travelTree } from '/@/utils/util';
+import { debounce, deleteCurrentRow, travelTree } from '/@/utils/util';
 
 import { computed, onMounted, ref } from 'vue';
 import { usePageDisplay } from '/@/hooks/usePageDisplay';
@@ -393,6 +394,38 @@
 //#endregion
 
 //#region ====================== 琛ㄦ牸鏁版嵁锛宼able init ======================
+
+const setCurrentLen = (offset: 1 | -1) => {
+	currentNode.value.label = `${currentNode.value.group_name} (${tableData.value.length})`;
+	const pId = currentNode.value.p_group_id;
+	if (pId) {
+		travelTree(listTreeData.value, (value) => {
+			if (value.group_id === pId) {
+				value.len += offset;
+				value.label = `${value.group_name} (${value.len})`;
+				return true;
+			}
+		});
+	}
+	// 淇敼鍚嶇О鍚庯紝涓嶇煡閬撲负浠�涔堜細澶卞幓 current 閫変腑
+	setTimeout(() => {
+		leftTreeRef.value?.treeRef.setCurrentKey(currentListID.value);
+	}, 0);
+};
+const setListLen = () => {
+	travelTree(listTreeData.value, (value, index, array, parent) => {
+		const id = value.group_id;
+		const len = allTableData.value.filter(
+			(item) => item.group_id === id || value.children?.some((treeItem) => treeItem.group_id === item.group_id)
+		).length;
+		value.len = len;
+		value.label = `${value.group_name} (${len})`;
+	});
+	// 淇敼鍚嶇О鍚庯紝涓嶇煡閬撲负浠�涔堜細澶卞幓 current 閫変腑
+	setTimeout(() => {
+		leftTreeRef.value?.treeRef.setCurrentKey(currentListID.value);
+	}, 0);
+};
 const tableLoading = ref(false);
 const tableData = ref([]);
 const isDragStatus = ref(false);
@@ -406,8 +439,12 @@
 
 			return item;
 		});
+		setListLen();
 	}
-	tableData.value = allTableData.value.filter((item) => item.group_id === currentListID.value || currentNode.value.children?.some(treeItem=>treeItem.group_id===item.group_id));
+	tableData.value = allTableData.value.filter(
+		(item) =>
+			item.group_id === currentListID.value || currentNode.value.children?.some((treeItem) => treeItem.group_id === item.group_id)
+	);
 };
 //#endregion
 
@@ -419,7 +456,7 @@
 const { resetQuery, handleQueryTable, displayTableData } = useQueryTable(tableData, queryParams, () => {
 	displayTableData.value = tableData.value;
 });
-const debounceQueryTable = debounce(handleQueryTable,400)
+const debounceQueryTable = debounce(handleQueryTable, 400);
 //#endregion
 
 //#region ====================== 鏌ヨ蹇嵎閿� ======================
@@ -476,6 +513,9 @@
 
 const insertOpt = (newData) => {
 	tableData.value.unshift({ ...newData, published: SupervisorPublished.N });
+	allTableData.value.unshift({ ...newData, published: SupervisorPublished.N });
+
+	setCurrentLen(1);
 };
 //#endregion
 
diff --git a/src/views/project/yw/systemManage/chatLog/ChatLog.vue b/src/views/project/yw/systemManage/chatLog/ChatLog.vue
index f686efb..971a131 100644
--- a/src/views/project/yw/systemManage/chatLog/ChatLog.vue
+++ b/src/views/project/yw/systemManage/chatLog/ChatLog.vue
@@ -27,6 +27,19 @@
 						@input="debounceQueryTable"
 					/>
 				</el-form-item>
+
+				<el-form-item label="缁撴灉" prop="state">
+					<el-select
+						
+						v-model="queryParams.state"
+						style="width: 226.4px"
+						placeholder="缁撴灉"
+						clearable
+						@change="handleQueryTable"
+					>
+						<el-option v-for="item in resultList" :key="item" :value="item" :label="item"></el-option>
+					</el-select>
+				</el-form-item>
 				<el-form-item label="鎿嶄綔浜哄憳" prop="user">
 					<el-input v-model="queryParams.user" style="width: 226.4px" placeholder="鎿嶄綔浜哄憳" clearable @input="debounceQueryTable" />
 				</el-form-item>
@@ -47,7 +60,13 @@
 					<el-table-column prop="time" label="鏃堕棿" width="185" show-overflow-tooltip> </el-table-column>
 					<el-table-column label="涓氬姟鍦烘櫙" width="120" prop="group_type" show-overflow-tooltip> </el-table-column>
 					<el-table-column label="闂鍐呭" prop="question" show-overflow-tooltip> </el-table-column>
-					<el-table-column label="缁撴灉" width="80" prop="state" show-overflow-tooltip> </el-table-column>
+					<el-table-column label="缁撴灉" width="80" prop="state" show-overflow-tooltip>
+						<template #default="scope">
+							<span :class="{ 'text-red-500': scope.row.state === 'NG', 'font-bold': scope.row.state === 'NG' }">
+								{{ scope.row.state }}
+							</span>
+						</template>
+					</el-table-column>
 					<el-table-column width="120" label="鑺辫垂鏃堕棿(绉�)" prop="run_ms" show-overflow-tooltip> </el-table-column>
 					<el-table-column label="鎿嶄綔" width="180" fixed="right" show-overflow-tooltip>
 						<template #default="scope">
@@ -95,8 +114,10 @@
 	group_type: [],
 	user: '',
 	question: '',
+	state: '',
 });
 
+const resultList = ['OK', 'NG'];
 // groupType 鍒楄〃
 const groupTypeList = computed(() => Array.from(new Set(sceneGroupList.value.map((item) => item.group_type))));
 const sceneGroupList = ref([]);
@@ -115,6 +136,7 @@
 		group_type: queryParams.value.group_type.join(','),
 		user: queryParams.value.user,
 		question: queryParams.value.question,
+		state:queryParams.value.state
 	});
 
 	tableData.value = (res?.values ?? []).map((item) => {
diff --git a/src/views/project/yw/systemManage/departmentMgr/DepartmentMgr.vue b/src/views/project/yw/systemManage/departmentMgr/DepartmentMgr.vue
new file mode 100644
index 0000000..d93d5e0
--- /dev/null
+++ b/src/views/project/yw/systemManage/departmentMgr/DepartmentMgr.vue
@@ -0,0 +1,150 @@
+<template>
+	<HMContainer type="card">
+		<template #header>
+			<el-form ref="queryFormRef" :inline="true" :model="queryParams">
+				<el-form-item label="鍚嶇О" prop="name">
+					<el-input v-model="queryParams.name" style="width: 226.4px" placeholder="鍚嶇О" clearable @input="debounceQueryTable" />
+				</el-form-item>
+
+				<el-form-item>
+					<el-button icon="ele-Plus" @click="openOptDlg()" type="primary"> 娣诲姞 </el-button>
+				</el-form-item>
+			</el-form>
+		</template>
+		<template #main>
+			<div class="h-full" ref="chatDragContainerRef">
+				<el-table
+					v-loading="tableLoading"
+					ref="draggableTableRef"
+					class="h100"
+					row-key="id"
+					:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
+					:header-cell-style="{ textAlign: 'center' }"
+					border
+					:cell-style="tableCellCenterExceptColumn()"
+					:row-class-name="isDragStatus ? 'cursor-move' : 'cursor-pointer'"
+					:data="displayTableData"
+					highlight-current-row
+				>
+					<el-table-column label="閮ㄩ棬鍚嶇О" prop="name" show-overflow-tooltip fixed="left"> </el-table-column>
+					<el-table-column label="鍒涘缓浜�" prop="create_user" width="190" show-overflow-tooltip> </el-table-column>
+					<el-table-column label="鍒涘缓鏃堕棿" prop="create_time" show-overflow-tooltip> </el-table-column>
+					<el-table-column label="鎿嶄綔" width="80" fixed="right" show-overflow-tooltip>
+						<template #default="scope">
+							<div class="space-x-3 items-center flex">
+								<el-tooltip effect="dark" content="鍒犻櫎" placement="top">
+									<i class="ywifont ywicon-shanchu !text-[17px] text-red-400 cursor-pointer" @click="deleteCurrentRow(scope.row)"></i>
+								</el-tooltip>
+							</div>
+						</template>
+					</el-table-column>
+				</el-table>
+			</div>
+		</template>
+		<OptDlg
+			v-model="optDlgIsShow"
+			:item="optDlgMapRow"
+			@insert="insertOpt"
+			@update="updateOpt"
+			:departmentTreeList="tableTreeData"
+		></OptDlg>
+	</HMContainer>
+</template>
+
+<script setup lang="ts">
+import { ElMessage, ElMessageBox } from 'element-plus';
+import { computed, onMounted, ref } from 'vue';
+import OptDlg from './optDlg/OptDlg.vue';
+import * as departmentApi from '/@/api/department/index';
+import HMContainer from '/@/components/layout/HMContainer.vue';
+import { usePageDisplay } from '/@/hooks/usePageDisplay';
+import { useQueryTable } from '/@/hooks/useQueryTable';
+import { convertListToTree, debounce, tableCellCenterExceptColumn } from '/@/utils/util';
+//#region ====================== 琛ㄦ牸鏁版嵁锛宼able init ======================
+const tableLoading = ref(false);
+const tableData = ref([]);
+const isDragStatus = ref(false);
+const tableTreeData = computed(() =>
+	convertListToTree(tableData.value, {
+		ID: 'id',
+		ParentID: 'parent_id',
+		Children: 'children',
+	})
+);
+const getTableData = async () => {
+	const res = await departmentApi.get_department_list();
+	tableData.value = (res?.values ?? []).map((item) => ({
+		create_time: item.create_time?.slice(0, 10),
+		id: item.id,
+		parent_id: item.parent_id,
+		name: item.name,
+		create_user: item.create_user,
+	}));
+};
+//#endregion
+//#region ====================== 琛ㄦ牸鏌ヨ銆佹帓搴忥紝search form init ======================
+const queryParams = ref({
+	name: '',
+});
+const { resetQuery, handleQueryTable, displayTableData } = useQueryTable(tableTreeData, queryParams, () => {
+	displayTableData.value = tableTreeData.value;
+});
+const debounceQueryTable = debounce(handleQueryTable, 400);
+//#endregion
+//#region ====================== 鏌ヨ蹇嵎閿� ======================
+const queryFormRef = ref(null);
+const pressEnterSearch = (ev: KeyboardEvent) => {
+	if (ev.key === 'Enter') {
+		handleQueryTable();
+	}
+};
+usePageDisplay(
+	() => {
+		queryFormRef.value?.$el?.addEventListener('keypress', pressEnterSearch);
+	},
+	() => {
+		queryFormRef.value?.$el?.removeEventListener('keypress', pressEnterSearch);
+	}
+);
+//#endregion
+//#region ====================== 娣诲姞淇敼鎿嶄綔 ======================
+const optDlgIsShow = ref(false);
+const optDlgMapRow = ref(null);
+const openOptDlg = (row?: any) => {
+	optDlgMapRow.value = row;
+	optDlgIsShow.value = true;
+};
+const updateOpt = (formValue) => {
+	const foundIndex = tableData.value.findIndex((item) => item.id === formValue.id);
+	if (foundIndex > -1) {
+		tableData.value[foundIndex] = {
+			...tableData.value[foundIndex],
+			...formValue,
+		};
+	}
+};
+const insertOpt = () => {
+	getTableData();
+};
+//#endregion
+
+const deleteCurrentRow = (row: any) => {
+	ElMessageBox.confirm(`纭畾鍒犻櫎鐢ㄦ埛锛氥��${row.name}銆�?`, '鎻愮ず', {
+		confirmButtonText: '纭畾',
+		cancelButtonText: '鍙栨秷',
+		type: 'warning',
+	}).then(async () => {
+		const res = await departmentApi.delete_department({
+			id: row.id,
+		});
+		const foundIndex = tableData.value.findIndex((item) => item === row);
+		foundIndex > -1 && tableData.value.splice(foundIndex, 1);
+		ElMessage.success('鍒犻櫎鐢ㄦ埛鎴愬姛');
+	});
+};
+//#endregion
+onMounted(async () => {
+	getTableData();
+});
+</script>
+<style scoped lang="scss"></style>
diff --git a/src/views/project/yw/systemManage/departmentMgr/optDlg/OptDlg.vue b/src/views/project/yw/systemManage/departmentMgr/optDlg/OptDlg.vue
new file mode 100644
index 0000000..b6166fb
--- /dev/null
+++ b/src/views/project/yw/systemManage/departmentMgr/optDlg/OptDlg.vue
@@ -0,0 +1,129 @@
+<template>
+	<ywDialog
+		v-model="dialogIsShow"
+		:headerIcon="dialogHeaderIcon"
+		:title="dialogTitle"
+		width="380"
+		@dlgClosed="closeDialog"
+		@submit="submitFormValue"
+	>
+		<el-form :model="dialogFormValue" ref="dialogFormRef" :rules="dialogFormRules" label-width="80">
+			<el-row :gutter="35">
+				<el-col :span="24" class="mb20">
+					<el-form-item label="閮ㄩ棬鍚嶇О" prop="name">
+						<el-input v-model="dialogFormValue.name"></el-input>
+					</el-form-item>
+				</el-col>
+				<el-col :span="24" class="mb20"
+					><el-form-item label="鐖剁骇" prop="parent_id" auto-complete="new-password">
+						<el-tree-select
+							filterable
+							style="width: 100%"
+							v-model="dialogFormValue.parent_id"
+							:props="{
+								id: 'id',
+								label: 'name',
+								children: 'children',
+							}"
+							:data="tableTreeData"
+							node-key="id"
+							:clearable="true"
+							:accordion="true"
+							:expandNode="false"
+							:check-strictly="true"
+							placeholder="璇烽�夋嫨鐖剁骇"
+						>
+						</el-tree-select>
+					</el-form-item>
+				</el-col>
+			</el-row>
+		</el-form>
+	</ywDialog>
+</template>
+
+<script setup lang="ts">
+import type { FormInstance, FormRules } from 'element-plus';
+import { ElMessage } from 'element-plus';
+import { computed, ref, toRefs, watch } from 'vue';
+import * as departmentApi from '/@/api/department/index';
+import ywDialog from '/@/components/dialog/yw-dialog.vue';
+import { formatDate } from '/@/utils/formatTime';
+import { deepClone } from '/@/utils/other';
+const props = defineProps(['item', 'departmentTreeList']);
+const { departmentTreeList } = toRefs(props);
+const emit = defineEmits(['update', 'insert']);
+//#region ====================== 澧炲姞銆佷慨鏀硅褰曟搷浣�, dialog init======================
+const isEditDialog = ref(false);
+const dialogTitle = computed(() => {
+	return isEditDialog.value ? `淇敼閮ㄩ棬銆�${props.item?.name}銆慲 : `娣诲姞閮ㄩ棬`;
+});
+const dialogHeaderIcon = computed(() => {
+	return isEditDialog.value ? 'ele-Edit' : 'ele-Plus';
+});
+const dialogFormValue = ref(null);
+const dialogIsShow = defineModel({
+	type: Boolean,
+});
+const dialogFormRef = ref<FormInstance>(null);
+const dialogFormRules = ref<FormRules>({
+	name: [{ required: true, message: '璇疯緭鍏ラ儴闂ㄥ悕绉�', trigger: 'blur' }],
+});
+const openOperateDialog = (row?) => {
+	if (row) {
+		isEditDialog.value = true;
+		const { id, parent_id, name, create_user, create_time } = row;
+		dialogFormValue.value = deepClone({ id, parent_id, name, create_user, create_time });
+	} else {
+		isEditDialog.value = false;
+		dialogFormValue.value = {
+			name: '',
+			parent_id: '',
+		};
+	}
+};
+const closeDialog = () => {
+	dialogIsShow.value = false;
+	dialogFormRef.value.clearValidate();
+};
+
+const submitFormValue = async () => {
+	const valid = await dialogFormRef.value.validate().catch(() => {});
+	if (!valid) return;
+	const updateTime = formatDate(new Date());
+
+	if (isEditDialog.value) {
+		return;
+		const res = await departmentApi.updateUserInfoByPost(dialogFormValue.value);
+		emit('update', { ...dialogFormValue.value });
+
+		closeDialog();
+		ElMessage.success('淇敼閮ㄩ棬鎴愬姛');
+	} else {
+		dialogFormValue.value.parent_id = dialogFormValue.value.parent_id || '0';
+		const res = await departmentApi.add_department_info(dialogFormValue.value);
+		emit('insert');
+		// tableData.value.push(newData);
+		closeDialog();
+		ElMessage.success('娣诲姞閮ㄩ棬鎴愬姛');
+	}
+};
+
+//#endregion
+
+watch(
+	() => dialogIsShow.value,
+	(val) => {
+		if (!val) return;
+		openOperateDialog(props.item);
+	}
+);
+const tableTreeData = ref([]);
+watch(
+	() => departmentTreeList.value,
+	(val) => {
+		if (!val) return;
+		tableTreeData.value = val;
+	}
+);
+</script>
+<style scoped lang="scss"></style>
diff --git a/src/views/project/yw/systemManage/metricAgentMgr/MetricAgentMgr.vue b/src/views/project/yw/systemManage/metricAgentMgr/MetricAgentMgr.vue
index 04038e9..c866b04 100644
--- a/src/views/project/yw/systemManage/metricAgentMgr/MetricAgentMgr.vue
+++ b/src/views/project/yw/systemManage/metricAgentMgr/MetricAgentMgr.vue
@@ -36,13 +36,11 @@
 				<el-form-item>
 					<el-button icon="ele-Refresh" @click="resetQuery">閲嶇疆 </el-button>
 				</el-form-item>
-				
 			</el-form>
 		</template>
 		<template #main>
 			<div class="w100 h100">
-				<div class="h-full" >
-
+				<div class="h-full">
 					<el-table
 						v-loading="tableLoading"
 						ref="draggableTableRef"
@@ -129,10 +127,10 @@
 import LeftTreeByMgr from '/@/components/tree/leftTreeByMgr.vue';
 import { useQueryTable } from '/@/hooks/useQueryTable';
 import { useSearch } from '/@/hooks/useSearch';
-import { useCompRef } from '/@/utils/types';
-import { convertListToTree, debounce } from '/@/utils/util';
-import { OptClassificationMap, classificationEnum } from '/@/views/types/metrics';
 import { gotoRoute } from '/@/utils/route';
+import { useCompRef } from '/@/utils/types';
+import { convertListToTree, debounce, travelTree } from '/@/utils/util';
+import { OptClassificationMap, classificationEnum } from '/@/views/types/metrics';
 //#region ====================== 宸︿晶鏍戞暟鎹紝tree init ======================
 const leftTreeRef = useCompRef(LeftTreeByMgr);
 const treeLoading = ref(false);
@@ -181,6 +179,10 @@
 const isDragStatus = ref(false);
 const metricStatus = ref(false);
 const allTableData = ref(null);
+const getLenById = (data: any[], id: string, value: any) => {
+	return data.filter((item) => item.agent_group === id || value.children?.some((treeItem) => treeItem.group_id === item.agent_group))
+		.length;
+};
 const getTableData = async () => {
 	if (!allTableData.value) {
 		const res = await metricApi.getMetricAgentListByPost();
@@ -188,6 +190,10 @@
 			item.create_time = item.create_time?.slice(0, 10);
 			return item;
 		});
+		travelTree(listTreeData.value, (value, index, array, parent) => {
+			const len = getLenById(allTableData.value, value.group_id, value);
+			value.group_name = `${value.group_name} (${len})`;
+		});
 	}
 	tableData.value = allTableData.value;
 };
diff --git a/src/views/project/yw/systemManage/metricMgr/MetricDetail.vue b/src/views/project/yw/systemManage/metricMgr/MetricDetail.vue
index 8cb0472..c37c5dd 100644
--- a/src/views/project/yw/systemManage/metricMgr/MetricDetail.vue
+++ b/src/views/project/yw/systemManage/metricMgr/MetricDetail.vue
@@ -42,7 +42,7 @@
 									<el-divider />
 								</div>
 							</el-tab-pane>
-							<el-tab-pane label="鎸囨爣鎺㈢储" name="indicatorExploration" class="h-full">
+							<el-tab-pane label="鎸囨爣鍥捐氨" name="indicatorExploration" class="h-full">
 								<div class="h-full flex-column">
 									<el-form :model="dialogFormValue" class="flex-0" ref="dialogFormRef" :rules="dialogFormRules">
 										<el-form-item label="鏃ユ湡鍖洪棿锛�" prop="rangValue" v-if="currentMetrics?.is_time_values ?? true">
@@ -201,10 +201,10 @@
 import { eMetrics_Ops } from '/@/views/types/metrics';
 
 import { FormRules } from 'element-plus/es/components/form/src/types';
+import _, { debounce } from 'lodash';
 import { computed } from 'vue';
 import SummaryCom from './components/SummaryCom.vue';
 import { chatMetricsJsonByPost } from '/@/api/metrics';
-import _, { debounce } from 'lodash';
 import { useCompRef } from '/@/utils/types';
 const defaultTime = ref<[Date, Date]>([new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]);
 const router = useRouter();
@@ -274,7 +274,7 @@
 	});
 };
 //#endregion
-//#region ====================== 鎸囨爣鎺㈢储鏌ヨ ======================
+//#region ====================== 鎸囨爣鍥捐氨鏌ヨ ======================
 // 鏃堕棿闄愬埗
 const disablesDate = (time) => {
 	return time.getTime() > new Date().getTime();
@@ -412,7 +412,7 @@
 };
 //#endregion
 
-//#region ====================== 鎸囨爣鎺㈢储 ======================
+//#region ====================== 鎸囨爣鍥捐氨 ======================
 
 const filterDimList = computed(
 	() => currentMetrics?.value?.dimensions ?? [].filter((item) => item.filter_type === 'str_eq' && item.type === '瀛楃涓�')
diff --git a/src/views/project/yw/systemManage/questionMgr/RecommendQuestions.vue b/src/views/project/yw/systemManage/questionMgr/RecommendQuestions.vue
index e814883..c399695 100644
--- a/src/views/project/yw/systemManage/questionMgr/RecommendQuestions.vue
+++ b/src/views/project/yw/systemManage/questionMgr/RecommendQuestions.vue
@@ -11,7 +11,7 @@
 					label: 'group_name',
 					children: 'children',
 				}"
-				:treedata="listTreeData"
+				:treedata="listLeftData"
 				title-name="鍦烘櫙鍒楄〃"
 				:show-more-operate="false"
 				:show-add="false"
@@ -105,67 +105,71 @@
 //#region ====================== 宸︿晶鏍戞暟鎹紝tree init ======================
 const leftTreeRef = useCompRef(LeftTreeByMgr);
 const treeLoading = ref(false);
-const listData = ref([]);
+const listLeftData = ref([]);
 const currentListID = computed(() => currentNode.value?.group_id);
 const currentNode = ref(null);
-const listTreeData = computed(() => {
-	const byParentData = convertListToTree(listData.value, {
-		ID: 'group_id',
-		ParentID: 'p_group_id',
-		Children: 'children',
-	});
-	const result = [];
-	byParentData.forEach((item) => {
-		if (
-			item.group_type != OptClassificationMap[classificationEnum.Office] &&
-			item.group_type != OptClassificationMap[classificationEnum.Knowledge]
-		) {
-			result.push(item);
-		}
-	});
-	return result;
-});
 const handleClickNode = (data) => {
 	nextTick(() => {
 		leftTreeRef.value?.treeRef.setCurrentKey(data.group_id);
 	});
 	currentNode.value = data;
-	getTableData();
+	terminologyData.value = data.sampleList;
 };
-const getListTreeData = async () => {
-	const res = await agentGroupApi.getSceneGroupTreeByPost();
-	listData.value = res.groups || [];
-	const firstListTreeNode = listTreeData.value[0];
-	currentNode.value = firstListTreeNode;
-	getTableData();
-};
+
 //#endregion
 //#region ====================== 鎺ㄨ崘闂 ======================
-const terminologyData = ref([]);
+const terminologyData = ref([]); //鏄剧ず鐨勬暟鎹簮
 //鑾峰彇鍦烘櫙list
-const getTableData = async () => {
-	let selNode = currentNode.value;
-	let curGroupID = [];
-	if (selNode.children && selNode.children.length > 0) {
-		selNode.children.forEach((item) => {
-			curGroupID.push(item.group_id);
-		});
-	} else {
-		curGroupID.push(selNode.group_id);
-	}
-	const res = await get_scene_group_sample();
-	res.samples.forEach((sample, index) => {
-		sample.Icon = '/static/images/wave/ChatImg.png';
-		sample.BgColor = randomHexColor();
+const initData = async () => {
+	const [treeData, sampleData] = await Promise.all([agentGroupApi.getSceneGroupTreeByPost(), get_scene_group_sample()]);
+	const tree_Data = treeData.groups ?? [];
+	const sample_Data = sampleData.samples ?? [];
+	let result = [];
+	let new_tree_Data = [];
+	tree_Data.forEach((node, index) => {
+		if (
+			node.group_type != OptClassificationMap[classificationEnum.Office] &&
+			node.group_type != OptClassificationMap[classificationEnum.Knowledge]
+		) {
+			new_tree_Data.push(node);
+		}
 	});
-	let terminology_Data = [];
-	curGroupID.forEach((curItem) => {
-		res.samples.forEach((sample) => {
-			if (curItem == sample.group_id) terminology_Data.push(sample);
+
+	new_tree_Data.forEach((node, index) => {
+		node.sampleList = [];
+		sample_Data.forEach((sample, index) => {
+			sample.Icon = '/static/images/wave/ChatImg.png';
+			sample.BgColor = randomHexColor();
+			if (node.group_id == sample.group_id) {
+				node.sampleList.push(sample);
+			}
 		});
+		if (node.p_group_id) {
+			node.group_name = `${node.group_name} (${node.sampleList.length})`;
+		}
 	});
-	terminologyData.value = terminology_Data;
+
+	const byParentData = convertListToTree(new_tree_Data, {
+		ID: 'group_id',
+		ParentID: 'p_group_id',
+		Children: 'children',
+	});
+	byParentData.forEach((item) => {
+		if (item.children && item.children.length > 0) {
+			item.children.forEach((child_node) => {
+				item.sampleList = item.sampleList.concat(child_node.sampleList);
+			});
+		}
+		result.push(item);
+
+		item.group_name = `${item.group_name} (${item.sampleList.length})`;
+	});
+	listLeftData.value = byParentData;
+	const firstListTreeNode = byParentData[0];
+	terminologyData.value = firstListTreeNode.sampleList;
+	currentNode.value = firstListTreeNode;
 };
+
 //闅忔満鐢熸垚棰滆壊
 const randomHexColor = () => {
 	return `#${Math.floor(Math.random() * 16777215)
@@ -176,6 +180,7 @@
 const changeExample = (item) => {
 	openChatTest(item);
 };
+
 //#endregion
 //#region ====================== 琛ㄦ牸鏌ヨ銆佹帓搴忥紝search form init ======================
 const queryParams = ref({
@@ -240,8 +245,8 @@
 	return res;
 };
 //#endregion
-onMounted(() => {
-	getListTreeData();
+onMounted(async () => {
+	initData();
 });
 </script>
 <style scoped lang="scss">

--
Gitblit v1.9.3