From b9fa2c53e0fb86718d976ee825102e43f3825a26 Mon Sep 17 00:00:00 2001
From: wujingjing <gersonwu@qq.com>
Date: 星期一, 06 一月 2025 09:51:58 +0800
Subject: [PATCH] 大模型管理修改

---
 src/views/project/yw/systemManage/metricMgr/MetricDetail.vue |  377 ++++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 253 insertions(+), 124 deletions(-)

diff --git a/src/views/project/yw/systemManage/metricMgr/MetricDetail.vue b/src/views/project/yw/systemManage/metricMgr/MetricDetail.vue
index 4bedfd8..152d9d8 100644
--- a/src/views/project/yw/systemManage/metricMgr/MetricDetail.vue
+++ b/src/views/project/yw/systemManage/metricMgr/MetricDetail.vue
@@ -1,130 +1,111 @@
 <template>
 	<div class="flex flex-col h100">
 		<el-row class="w100 h100">
-			<el-col :span="17">
+			<el-col :span="17" class="h-full">
 				<div class="h100 relative">
 					<div class="ml-6 h100">
 						<el-tabs v-model="state.activeMetricName" @tab-change="handleClick" class="h100">
-							<el-tab-pane label="鍩虹淇℃伅" name="basicInformation">
-								<div class="h100">
-									<el-descriptions title="鎸囨爣淇℃伅">
-										<el-descriptions-item label="鎸囨爣鍚嶇О:" :span="2">{{
-											state.metricBasicInfo.descriptionQuotaItems.title ? state.metricBasicInfo.descriptionQuotaItems.title : '-'
-										}}</el-descriptions-item>
-										<el-descriptions-item label="鎸囨爣鍏ㄧО:" :span="2">{{
-											state.metricBasicInfo.descriptionQuotaItems.full_name
-												? state.metricBasicInfo.descriptionQuotaItems.full_name
-												: '-'
-										}}</el-descriptions-item>
-										<el-descriptions-item label="鎸囨爣瀹氫箟:" :span="3">{{
-											state.metricBasicInfo.descriptionQuotaItems.metrics_define
-												? state.metricBasicInfo.descriptionQuotaItems.metrics_define
-												: '-'
-										}}</el-descriptions-item>
-										<el-descriptions-item label="绫诲埆:" :span="2">
-											{{
-												state.metricBasicInfo.descriptionQuotaItems.metrics_type
-													? state.metricBasicInfo.descriptionQuotaItems.metrics_type
+							<el-tab-pane label="鍩虹淇℃伅" name="basicInformation" class="h-full">
+								<div class="h100 flex flex-col">
+									<div class="flex-0">
+										<el-descriptions title="鎸囨爣淇℃伅">
+											<el-descriptions-item label="鎸囨爣缂栧彿:" :span="2">{{
+												state.metricBasicInfo.descriptionQuotaItems.id ? state.metricBasicInfo.descriptionQuotaItems.id : '-'
+											}}</el-descriptions-item>
+											<el-descriptions-item label="鎸囨爣鍚嶇О:" :span="2">{{
+												state.metricBasicInfo.descriptionQuotaItems.title ? state.metricBasicInfo.descriptionQuotaItems.title : '-'
+											}}</el-descriptions-item>
+											<el-descriptions-item label="涓婚鍩�:" :span="2">{{
+												state.metricBasicInfo.descriptionQuotaItems?.metrics_group
+													? themeDomainMap?.[state.metricBasicInfo.descriptionQuotaItems?.metrics_group]?.group_name
 													: '-'
-											}}</el-descriptions-item
-										>
-										<el-descriptions-item label="閲嶈鎬�:" :span="2">
-											{{ eMetrics_Ops[state.metricBasicInfo.descriptionQuotaItems.metrics_important] }}
-										</el-descriptions-item>
-										<el-descriptions-item label="璁$畻鏂规硶:" :span="3">
-											{{
-												state.metricBasicInfo.descriptionQuotaItems.calcu_method
-													? state.metricBasicInfo.descriptionQuotaItems.calcu_method
+											}}</el-descriptions-item>
+											<el-descriptions-item label="鍗曚綅:" :span="2">{{
+												state.metricBasicInfo.descriptionQuotaItems.metrics_unit
+													? state.metricBasicInfo.descriptionQuotaItems.metrics_unit
 													: '-'
-											}}
-										</el-descriptions-item>
-									</el-descriptions>
-									<el-divider />
-								</div>
-							</el-tab-pane>
-							<el-tab-pane label="鎸囨爣鎺㈢储" name="indicatorExploration">
-								<div class="h100">
-									<div class="set_explore">
-										<div class="set_explore_pad">
-											<el-form ref="exploreFormRef" :model="state.exploreForm" label-width="80px" label-position="left">
-												<el-form-item label="鏃ユ湡鍖洪棿:">
-													<div style="width: 300px">
-														<el-date-picker
-															v-model="state.exploreForm.dateRangeExplore"
-															type="daterange"
-															range-separator="~"
-															value-format="YYYY-MM-DD HH:mm:ss"
-															:default-time="defaultTime"
-															@change="getDateTime"
-															:disabled-date="disablesDate"
-														/>
-													</div>
-												</el-form-item>
-												<el-form-item label="缁村害涓嬮捇:">
-													<el-select v-model="state.exploreForm.dimensionDrilling" autocomplete="off" style="width: 226.4px" clearable>
-														<el-option
-															v-for="item in Object.keys(eDrilling_Ops)"
-															:key="item"
-															:value="parseInt(item)"
-															:label="eDrilling_Ops[item]"
-														>
-														</el-option>
-													</el-select>
-												</el-form-item>
-												<el-form-item label="缁村害绛涢��:">
-													<el-select
-														v-model="state.exploreForm.dimensionFiltering.user"
-														autocomplete="off"
-														style="width: 186.4px"
-														clearable
-														@change="handleDimensionFilteringChange"
-													>
-														<el-option
-															v-for="item in Object.keys(eDrilling_Ops)"
-															:key="item"
-															:value="parseInt(item)"
-															:label="eDrilling_Ops[item]"
-														>
-														</el-option>
-													</el-select>
-													<el-select
-														v-model="state.exploreForm.dimensionFiltering.unit"
-														autocomplete="off"
-														style="width: 126.4px; margin: 0 5px"
-														clearable
-													>
-														<el-option
-															v-for="item in Object.keys(eDimensionFilter_Ops)"
-															:key="item"
-															:value="parseInt(item)"
-															:label="eDimensionFilter_Ops[item]"
-														>
-														</el-option>
-													</el-select>
-													<el-select
-														v-model="state.exploreForm.dimensionFiltering.someone"
-														autocomplete="off"
-														style="width: 126.4px; margin-right: 5px"
-														clearable
-													>
-														<el-option
-															v-for="(item, index) in state.resultList"
-															:key="index"
-															:value="item.id"
-															:label="item.department"
-														>
-														</el-option>
-													</el-select>
-													<el-button type="primary" @click="handleExplore" icon="ele-Search">鏌ヨ</el-button>
-												</el-form-item>
-											</el-form>
-										</div>
-										<div class="w100 h-[550px]">
-											<div ref="chartExplorationRef" class="w100 h100"></div>
-										</div>
+											}}</el-descriptions-item>
+											<el-descriptions-item label="鎸囨爣鍏ㄧО:" :span="2">{{
+												state.metricBasicInfo.descriptionQuotaItems.full_name
+													? state.metricBasicInfo.descriptionQuotaItems.full_name
+													: '-'
+											}}</el-descriptions-item>
+											<el-descriptions-item label="鎸囨爣瀹氫箟:" :span="3">{{
+												state.metricBasicInfo.descriptionQuotaItems.metrics_define
+													? state.metricBasicInfo.descriptionQuotaItems.metrics_define
+													: '-'
+											}}</el-descriptions-item>
+											<el-descriptions-item label="绫诲埆:" :span="2">
+												{{
+													state.metricBasicInfo.descriptionQuotaItems.metrics_type
+														? state.metricBasicInfo.descriptionQuotaItems.metrics_type
+														: '-'
+												}}</el-descriptions-item
+											>
+											<el-descriptions-item label="閲嶈鎬�:" :span="2">
+												{{ eMetrics_Ops[state.metricBasicInfo.descriptionQuotaItems.metrics_important] }}
+											</el-descriptions-item>
+											<el-descriptions-item label="璁$畻鏂规硶:" :span="3">
+												{{
+													state.metricBasicInfo.descriptionQuotaItems.calcu_method
+														? state.metricBasicInfo.descriptionQuotaItems.calcu_method
+														: '-'
+												}}
+											</el-descriptions-item>
+										</el-descriptions>
+										<el-divider />
+									</div>
+									<div class="flex-auto flex flex-col">
+										<span class="flex-0 text-[16px] font-bold mb-[4px]">鎸囨爣鍥捐氨</span>
+										<TreeGraph v-if="graphData" class="flex-auto" :data="graphData" :maxCount="maxCount" />
 									</div>
 								</div>
 							</el-tab-pane>
+							<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">
+											<TimeRange v-model="dialogFormValue.rangValue" @change="query(false)" />
+										</el-form-item>
+										<el-row :gutter="35">
+											<el-col :span="12" class="mb20">
+												<el-form-item label="鍒嗙粍缁村害锛�" prop="rangValue">
+													<el-select v-model="dialogFormValue.groupDimList" multiple @change="query(false)">
+														<el-option
+															v-for="item in currentMetrics?.dimensions ?? []"
+															:key="item.id"
+															:label="item.title"
+															:value="item.id"
+														/>
+													</el-select>
+												</el-form-item>
+											</el-col>
+											<el-col :span="12" class="mb20" v-for="item in filterDimList" :key="item.id"
+												><el-form-item :label="`${item.title}锛歚" :prop="`${item.id}`">
+													<el-input v-model="dialogFormValue[item.id]" @input="(val) => filterDimInput(val, item)"> </el-input>
+												</el-form-item>
+											</el-col>
+										</el-row>
+									</el-form>
+									<div class="flex-auto mt-4">
+										<SummaryCom
+											v-loading="queryLoading"
+											ref="summaryComRef"
+											:data="querySummaryData"
+											:origin-data="{
+												content: {
+													origin: {
+														summary: querySummaryData,
+													},
+												},
+											}"
+										/>
+										<!-- <RecordSet v-bind="recordSetProps" class="h-full" /> -->
+										<!-- <RecordSetTable v-bind="recordSetTableProps" class="h-full"/> -->
+									</div>
+								</div>
+							</el-tab-pane>
+							<!-- <el-tab-pane label="鎸囨爣鍥捐氨" name="metricGraph" class="h-full"> <div class="h-full"></div></el-tab-pane> -->
 						</el-tabs>
 					</div>
 					<div class="list_btn" @click="handleExitFlow">
@@ -142,12 +123,17 @@
 					<div class="mb-[5px]">
 						<div class="set-visit">
 							<i class="ywifont ywicon-fenshu_an w-[18px] h-[18px] text-yellow-300 !text-[20px]"></i>
-							<div>璁块棶娆℃暟</div>
+							<div>鍏抽敭淇℃伅</div>
 						</div>
 					</div>
 					<div class="set-detail">
 						<el-divider />
 						<div class="section___vePzi">
+						
+							<div class="item___txXyB">
+								<div class="item_name">鎸囨爣鍚嶇О:</div>
+								<div class="item_value">{{state.metricBasicInfo.descriptionQuotaItems.title ? state.metricBasicInfo.descriptionQuotaItems.title : '-'}}</div>
+							</div>
 							<div class="item___txXyB">
 								<div class="item_name">閲嶈鎬�:</div>
 								<div class="item_value">{{ eMetrics_Ops[state.metricBasicInfo.descriptionQuotaItems.metrics_important] }}</div>
@@ -212,7 +198,7 @@
 										<div class="subTitle___zya5g">涓嬮捇缁村害</div>
 										<div class="ml-0 mt-[20px]">
 											<div class="flex flex-wrap gap-[5px] items-center">
-												<div v-for="item in state.metricBasicInfo.applicationInformation" :key="item.id">
+												<div v-for="item in currentMetrics?.dimensions ?? []" :key="item.id">
 													<el-tag :style="{ backgroundColor: 'e6f4ff', color: '#0958d9', borderColor: '#91caff' }">{{
 														item.title
 													}}</el-tag>
@@ -235,12 +221,32 @@
 import { nextTick, onMounted, reactive, ref } from 'vue';
 import { useRoute, useRouter } from 'vue-router';
 import * as metricApi from '/@/api/metrics';
+import TimeRange from '/@/components/chat/chatComponents/summaryCom/components/recordSet/components/TimeRange.vue';
+import TreeGraph from '/@/components/graph/treeGraph/TreeGraph.vue';
 import { formatTime, getDefaultPeriod } from '/@/utils/istation/common.js';
-import { eDimensionFilter_Ops, eDrilling_Ops, eMetrics_Ops } from '/@/views/types/metrics';
+import { eMetrics_Ops } from '/@/views/types/metrics';
+
+import type { FormRules } from 'element-plus/es/components/form/src/types';
+import _, { debounce } from 'lodash';
+import { computed } from 'vue';
+import type { OrgTreeItem } from '../agentGraph/types';
+import SummaryCom from './components/SummaryCom.vue';
+import { chatMetricsJsonByPost } from '/@/api/metrics';
+import { getSceneGroupTreeByPost } from '/@/api/scene';
+import { useCompRef } from '/@/utils/types';
+import { getItemMap } from '/@/utils/util';
 const defaultTime = ref<[Date, Date]>([new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]);
 const router = useRouter();
 const route = useRoute();
 // 瀹氫箟鍙橀噺鍐呭
+const themeDomainData = ref([]);
+const initThemeDomainData = async () => {
+	const res = await getSceneGroupTreeByPost();
+	themeDomainData.value = res.groups || [];
+};
+const themeDomainMap = computed(() => {
+	return getItemMap(themeDomainData.value, 'group_id');
+});
 const state = reactive({
 	metricInfo: {
 		name: '',
@@ -249,7 +255,6 @@
 	activeMetricName: 'basicInformation',
 	metricBasicInfo: {
 		descriptionQuotaItems: {},
-		applicationInformation: [],
 	} as any,
 	exploreForm: {
 		dateRangeExplore: '' as any,
@@ -289,16 +294,23 @@
 
 //#endregion
 //#region ====================== 鍩虹淇℃伅 ======================
+const currentMetrics = ref(null);
 const tableData = ref([]);
 const getTableData = async (id) => {
 	const res = await metricApi.getMetricNameListByPost();
 	const data = res?.values ?? [];
 	const filterData = data.filter((item) => item.id == id);
 	state.metricBasicInfo.descriptionQuotaItems = filterData[0]; //宸︿晶鎻忚堪鍐呭
-	state.metricBasicInfo.applicationInformation = filterData[0].dimensions ?? [];
+	currentMetrics.value = filterData[0];
+	filterDimList.value.forEach((item) => {
+		if (!dialogFormValue.value) {
+			dialogFormValue.value = {} as any;
+		}
+		dialogFormValue.value[item.id] = '';
+	});
 };
 //#endregion
-//#region ====================== 鎸囨爣鎺㈢储鏌ヨ ======================
+//#region ====================== 鎸囨爣鍥捐氨鏌ヨ ======================
 // 鏃堕棿闄愬埗
 const disablesDate = (time) => {
 	return time.getTime() > new Date().getTime();
@@ -432,12 +444,129 @@
 			state.chartStatus = true;
 		});
 	}
+
 	state.activeMetricName = val;
 };
 //#endregion
-onMounted(() => {
+
+//#region ====================== 鎸囨爣鍥捐氨 ======================
+
+const filterDimList = computed(
+	() => currentMetrics?.value?.dimensions ?? [].filter((item) => item.filter_type === 'str_eq' && item.type === '瀛楃涓�')
+);
+const dialogFormRules = ref<FormRules>({
+	title: [{ required: true, message: '璇疯緭鍏ユ爣棰�', trigger: 'blur' }],
+	prompt: [{ required: true, message: '璇疯緭鍏ユ彁绀鸿瘝', trigger: 'blur' }],
+});
+
+const summaryComRef = useCompRef(SummaryCom);
+const dialogFormValue = ref({
+	rangValue: ['2024-10-21 00:00:00', '2024-10-23 23:59:59'],
+	groupDimList: [],
+});
+
+const currentMetricsId = computed(() => router.currentRoute.value.query.id as string);
+const querySummaryData = ref([]);
+const queryLoading = ref(false);
+/**
+ * 鎸夋煡璇㈡潯浠舵煡鎵�
+ */
+const query = async (isFirst: boolean) => {
+	if (!currentMetricsId.value) return;
+	const groupDimStr = dialogFormValue.value.groupDimList.join(',');
+	const sendGroupDims = groupDimStr || undefined;
+	queryLoading.value = true;
+	const res = await chatMetricsJsonByPost(
+		{
+			metrics_id: currentMetricsId.value,
+			start_time: dialogFormValue.value.rangValue[0],
+			end_time: dialogFormValue.value.rangValue[1],
+			group_dims: sendGroupDims,
+			filter_dims: JSON.stringify(_.omit(dialogFormValue.value, ['groupDimList', 'rangValue'])),
+		},
+		{
+			loading: false,
+		}
+	).finally(() => {
+		queryLoading.value = false;
+	});
+	querySummaryData.value = res?.summary ?? [];
+	if (!isFirst) {
+		nextTick(() => {
+			nextTick(() => {
+				summaryComRef.value.updateSummary();
+			});
+		});
+	}
+};
+const debounceQuery = debounce(query, 600);
+const filterDimInput = (val, dim) => {
+	debounceQuery(false);
+};
+
+//#endregion
+
+//#region ====================== 鎸囨爣鍥捐氨 ======================
+
+const maxCount = ref(null);
+const graphData = ref(null);
+const convertOrgTreeToTreeNode = (orgTreeData: OrgTreeItem) => {
+	const treeData = {
+		id: orgTreeData.treeId,
+		label: orgTreeData.label,
+		data: orgTreeData,
+		children: orgTreeData.children?.length > 0 ? orgTreeData.children.map((item) => convertOrgTreeToTreeNode(item)) : [],
+	};
+	return treeData;
+};
+const getGraphTreeData = () => {
+	if (!currentMetricsId.value) return;
+	/** @description 缁村害鏁伴噺 */
+	let dimensionCount = 0;
+	/** @description 鎸囨爣鏁伴噺 */
+	let metricsCount = 1;
+
+	const metricsTreeId = `metrics-${currentMetricsId.value}`;
+	const dimensionList = currentMetrics.value.dimensions ?? [];
+	dimensionCount = dimensionList.length;
+	let logicTree: OrgTreeItem = {
+		treeId: metricsTreeId,
+		logicId: currentMetricsId.value,
+		type: 'metrics',
+
+		model: currentMetrics.value,
+		get label() {
+			return this.model.title;
+		},
+		level: 0,
+		children: dimensionList.map((item) => {
+			const dimensionTreeId = `${metricsTreeId}-dimension-${item.id}`;
+			return {
+				treeId: dimensionTreeId,
+				logicId: item.id,
+				type: 'dimension',
+				model: item,
+				get label() {
+					return this.model.title;
+				},
+				level: 1,
+			};
+		}),
+	};
+	const resData = logicTree;
+	maxCount.value = Math.max(dimensionCount, metricsCount);
+	graphData.value = convertOrgTreeToTreeNode(resData);
+};
+//#endregion
+
+onMounted(async () => {
 	const { id } = route.query;
-	getTableData(id);
+	query(true);
+	initThemeDomainData();
+	await getTableData(id);
+	if (!graphData.value) {
+		getGraphTreeData();
+	}
 });
 </script>
 <style scoped lang="scss">

--
Gitblit v1.9.3