From c4004648da4014c8777e4f4bd887ca28cb7afd97 Mon Sep 17 00:00:00 2001 From: wujingjing <gersonwu@qq.com> Date: 星期一, 30 十二月 2024 15:02:35 +0800 Subject: [PATCH] 提示词放大编辑 --- src/views/project/yw/systemManage/metricMgr/MetricDetail.vue | 392 +++++++++++++++++++++++++++++++++++-------------------- 1 files changed, 249 insertions(+), 143 deletions(-) diff --git a/src/views/project/yw/systemManage/metricMgr/MetricDetail.vue b/src/views/project/yw/systemManage/metricMgr/MetricDetail.vue index dafaf37..0996496 100644 --- a/src/views/project/yw/systemManage/metricMgr/MetricDetail.vue +++ b/src/views/project/yw/systemManage/metricMgr/MetricDetail.vue @@ -1,117 +1,95 @@ <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="鎸囨爣淇℃伅" :column="2"> - <el-descriptions-item label="鎸囨爣鍚嶇О:">{{ - state.descriptionQuotaItems.title ? state.descriptionQuotaItems.title : '-' + <el-descriptions title="鎸囨爣淇℃伅"> + <el-descriptions-item label="鎸囨爣鍚嶇О:" :span="2">{{ + state.metricBasicInfo.descriptionQuotaItems.title ? state.metricBasicInfo.descriptionQuotaItems.title : '-' }}</el-descriptions-item> - <el-descriptions-item label="鎸囨爣鍏ㄧО:">{{ - state.descriptionQuotaItems.full_name ? state.descriptionQuotaItems.full_name : '-' + <el-descriptions-item label="鎸囨爣鍏ㄧО:" :span="2">{{ + state.metricBasicInfo.descriptionQuotaItems.full_name + ? state.metricBasicInfo.descriptionQuotaItems.full_name + : '-' }}</el-descriptions-item> - <el-descriptions-item label="鎸囨爣瀹氫箟:">{{ - state.descriptionQuotaItems.metrics_define ? state.descriptionQuotaItems.metrics_define : '-' + <el-descriptions-item label="鎸囨爣瀹氫箟:" :span="3">{{ + state.metricBasicInfo.descriptionQuotaItems.metrics_define + ? state.metricBasicInfo.descriptionQuotaItems.metrics_define + : '-' }}</el-descriptions-item> - <el-descriptions-item label="绫诲埆:"> + <el-descriptions-item label="绫诲埆:" :span="2"> {{ - state.descriptionQuotaItems.metrics_type ? state.descriptionQuotaItems.metrics_type : '-' + state.metricBasicInfo.descriptionQuotaItems.metrics_type + ? state.metricBasicInfo.descriptionQuotaItems.metrics_type + : '-' }}</el-descriptions-item > - <el-descriptions-item label="閲嶈鎬�:"> - <el-tag size="small" :style="{ backgroundColor: 'e6f4ff', color: '#0958d9', borderColor: '#91caff' }">{{ - eMetrics_Ops[state.descriptionQuotaItems.metrics_important] - }}</el-tag> + <el-descriptions-item label="閲嶈鎬�:" :span="2"> + {{ eMetrics_Ops[state.metricBasicInfo.descriptionQuotaItems.metrics_important] }} </el-descriptions-item> - <el-descriptions-item label="璁$畻鏂规硶:"> - {{ state.descriptionQuotaItems.calcu_method ? state.descriptionQuotaItems.calcu_method : '-' }} + <el-descriptions-item label="璁$畻鏂规硶:" :span="3"> + {{ + state.metricBasicInfo.descriptionQuotaItems.calcu_method + ? state.metricBasicInfo.descriptionQuotaItems.calcu_method + : '-' + }} </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" + <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" /> - </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.resultList" autocomplete="off" style="width: 126.4px; margin-right: 5px" clearable> - <el-option - v-for="(item, index) in state.resultList" - :key="index" - :value="item.department" - :label="item.department" - > - </el-option> - </el-select> - <el-button type="primary" @click="handleExplore" icon="ele-Search">鏌ヨ</el-button> + </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-form> - </div> - <div class="w100 h-[550px]"> - <div ref="chartExplorationRef" class="w100 h100"></div> - </div> + </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"> + <TreeGraph v-if="graphData" :data="graphData" class="h-full" :maxCount="maxCount" /></div + ></el-tab-pane> </el-tabs> </div> <div class="list_btn" @click="handleExitFlow"> @@ -135,10 +113,28 @@ <div class="set-detail"> <el-divider /> <div class="section___vePzi"> - <div class="item___txXyB" v-for="(item, index) in state.metricBasicInfo.visitNumData" :key="index"> - <div class="item_name">{{ item.name }}:</div> + <div class="item___txXyB"> + <div class="item_name">閲嶈鎬�:</div> + <div class="item_value">{{ eMetrics_Ops[state.metricBasicInfo.descriptionQuotaItems.metrics_important] }}</div> + </div> + <div class="item___txXyB"> + <div class="item_name">鎵�灞為鍩�:</div> <div class="item_value"> - {{ item.value }} + {{ + state.metricBasicInfo.descriptionQuotaItems.metrics_type + ? state.metricBasicInfo.descriptionQuotaItems.metrics_type + : '-' + }} + </div> + </div> + <div class="item___txXyB"> + <div class="item_name">鎻忚堪:</div> + <div class="item_value"> + {{ + state.metricBasicInfo.descriptionQuotaItems.metrics_define + ? state.metricBasicInfo.descriptionQuotaItems.metrics_define + : '-' + }} </div> </div> </div> @@ -148,10 +144,24 @@ <i class="ywifont ywicon-gongzuozongjie w-[18px] h-[18px] !text-[18px]"></i> <span>鍒涘缓淇℃伅</span> </div> - <div class="item___txXyB" v-for="(item, index) in state.metricBasicInfo.createInformation" :key="index"> - <div class="item_name">{{ item.name }}:</div> + <div class="item___txXyB"> + <div class="item_name">鍒涘缓浜�:</div> <div class="item_value"> - {{ item.value }} + {{ + state.metricBasicInfo.descriptionQuotaItems.create_user + ? state.metricBasicInfo.descriptionQuotaItems.create_user + : '-' + }} + </div> + </div> + <div class="item___txXyB"> + <div class="item_name">鍒涘缓鏃堕棿:</div> + <div class="item_value"> + {{ + state.metricBasicInfo.descriptionQuotaItems.create_time + ? state.metricBasicInfo.descriptionQuotaItems.create_time + : '-' + }} </div> </div> </div> @@ -167,7 +177,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> @@ -190,51 +200,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 { formatTime, getDefaultPeriod } from '/@/utils/istation/common.js'; import { eMetrics_Ops } from '/@/views/types/metrics'; -import { eDimensionFilter_Ops, eDrilling_Ops } from '/@/views/types/metrics/index'; +import TreeGraph from '/@/components/graph/treeGraph/TreeGraph.vue'; + +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 { useCompRef } from '/@/utils/types'; +import { OrgTreeItem } from '../agentGraph/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(); const route = useRoute(); // 瀹氫箟鍙橀噺鍐呭 + const state = reactive({ metricInfo: { name: '', id: '', } as any, activeMetricName: 'basicInformation', - descriptionQuotaItems: {} as any, metricBasicInfo: { - visitNumData: [ - { - name: '閲嶈鎬�', - value: '', - }, - { - name: '鎵�灞炴ā鍨�', - value: '', - }, - { - name: '鎻忚堪', - value: '', - }, - ], - createInformation: [ - { - name: '鍒涘缓浜�', - value: 'admin', - }, - { - name: '鍒涘缓鏃堕棿', - value: '2024-10-08 10:03:39', - }, - { - name: '鏇存柊鏃堕棿', - value: '2024-10-08 14:12:11', - }, - ], - applicationInformation: [], - }, + descriptionQuotaItems: {}, + } as any, exploreForm: { dateRangeExplore: '' as any, dimensionDrilling: 0, @@ -246,15 +237,19 @@ }, resultList: [ { + id: 1, department: 'HR', }, { + id: 2, department: 'marketing', }, { + id: 3, department: 'sales', }, { + id: 4, department: 'strategy', }, ], @@ -269,30 +264,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.descriptionQuotaItems = filterData[0]; - state.metricBasicInfo.visitNumData = [ - { - name: '閲嶈鎬�', - value: eMetrics_Ops[filterData[0].metrics_important], - }, - { - name: '鎵�灞炴ā鍨�', - value: '-', - }, - { - name: '鎻忚堪', - value: filterData[0].metrics_define, - }, - ]; - state.metricBasicInfo.applicationInformation = filterData[0].dimensions ?? []; + state.metricBasicInfo.descriptionQuotaItems = filterData[0]; //宸︿晶鎻忚堪鍐呭 + 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(); @@ -427,10 +415,128 @@ }); } state.activeMetricName = val; + if (val === 'metricGraph') { + if (!graphData.value) { + getGraphTreeData(); + } + } }; //#endregion + +//#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(() => { const { id } = route.query; + query(true); getTableData(id); }); </script> -- Gitblit v1.9.3