From 671c80972e35d358d4413ddecb9b0906b9df8322 Mon Sep 17 00:00:00 2001 From: zhongzm Date: Fri, 18 Oct 2024 10:32:55 +0800 Subject: [PATCH] =?UTF-8?q?fix:=E5=A4=9A=E9=80=89=E6=94=B9checkbox?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/perfManage/goldTarget/index.vue | 39 +++--- src/views/perfManage/kpiKeyTarget/index.vue | 146 ++++++++++++-------- 2 files changed, 111 insertions(+), 74 deletions(-) diff --git a/src/views/perfManage/goldTarget/index.vue b/src/views/perfManage/goldTarget/index.vue index 5aaf1bd9..d4aadbe5 100644 --- a/src/views/perfManage/goldTarget/index.vue +++ b/src/views/perfManage/goldTarget/index.vue @@ -251,14 +251,14 @@ function fnGetListTitle() { // 获取表头文字 getKPITitle(state.neType[0]) - .then(res => { - if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) { - tableColumns.value = []; - const columns: ColumnsType = []; - for (const item of res.data) { - const kpiDisplay = item[`${language}Title`]; + .then(res => {//处理getKPITitle返回的结果 + if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {//检查值 + tableColumns.value = [];//设为空数组 + const columns: ColumnsType = [];//初始化,构建新表头 + for (const item of res.data) {//遍历res.data + const kpiDisplay = item[`${language}Title`];//提取标题kpiDisplay和ID标识kpiValue const kpiValue = item[`kpiId`]; - columns.push({ + columns.push({// title: kpiDisplay, dataIndex: kpiValue, align: 'left', @@ -297,7 +297,7 @@ function fnGetListTitle() { return false; } }) - .then(result => { + .then(result => {//result是前一个.then返回的值(true or false) result && fnGetList(); }); } @@ -334,27 +334,27 @@ function fnChangShowType() { /**绘制图表 */ function fnRanderChart() { - const container: HTMLElement | undefined = kpiChartDom.value; - if (!container) return; + const container: HTMLElement | undefined = kpiChartDom.value;//获取图表容器DOM元素 + if (!container) return;//若没有,则退出函数 kpiChart.value = markRaw(echarts.init(container, 'light')); - - const option: EChartsOption = { +//初始化Echarts图表实例,应用light主题,并赋值给kpiChart.value,markRaw是vue函数,用于标记对象为不可响应 + const option: EChartsOption = {//定义图表的配置对象,tooltip的出发方式为axis tooltip: { trigger: 'axis', position: function (pt: any) { return [pt[0], '10%']; }, }, - xAxis: { + xAxis: {//x类别轴 type: 'category', boundaryGap: false, data: [], // 数据x轴 }, - yAxis: { + yAxis: {//y类别轴 type: 'value', boundaryGap: [0, '100%'], }, - legend: { + legend: {//图例垂直滚动 type: 'scroll', orient: 'vertical', top: 40, @@ -367,13 +367,13 @@ function fnRanderChart() { icon: 'circle', selected: {}, }, - grid: { + grid: {//网格区域边距 left: '10%', right: '30%', bottom: '20%', }, dataZoom: [ - { + {//启用图表的数据缩放,范围90%-100% type: 'inside', start: 90, end: 100, @@ -385,9 +385,9 @@ function fnRanderChart() { ], series: [], // 数据y轴 }; - kpiChart.value.setOption(option); + kpiChart.value.setOption(option);//设置图表配置项,应用到kpiChart实例上 - // 创建 ResizeObserver 实例 + // 创建 ResizeObserver 实例 监听图表容器大小变化,并在变化时调整图表大小 var observer = new ResizeObserver(entries => { if (kpiChart.value) { kpiChart.value.resize(); @@ -452,6 +452,7 @@ function fnRanderChartData() { // 用降序就反转 let orgData = tableState.data; + console.log(orgData); if (queryParams.sortOrder === 'desc') { orgData = orgData.toReversed(); } diff --git a/src/views/perfManage/kpiKeyTarget/index.vue b/src/views/perfManage/kpiKeyTarget/index.vue index 1e7ea9ab..1e6ed330 100644 --- a/src/views/perfManage/kpiKeyTarget/index.vue +++ b/src/views/perfManage/kpiKeyTarget/index.vue @@ -16,11 +16,15 @@ import { ColumnsType } from 'ant-design-vue/es/table'; import { generateColorRGBA } from '@/utils/generate-utils'; import { LineSeriesOption } from 'echarts/charts'; import { OptionsType, WS } from '@/plugins/ws-websocket'; +import { Select } from 'ant-design-vue'; import { useDebounceFn } from '@vueuse/core'; const { t, currentLocale } = useI18n(); + const neInfoStore = useNeInfoStore(); + //WebSocket连接 const ws = ref(null); + //添加实时数据开关状态 const realTimeEnabled = ref(false); //实时数据开关 @@ -28,20 +32,27 @@ const handleRealTimeSwitch = (checked: any) => { fnRealTimeSwitch(!!checked); }; + // 定义所有可能的网元类型 const ALL_NE_TYPES = ['ims', 'amf', 'udm', 'smf', 'pcf','upf','mme','mocngw','smsc','cbc','ausf'] as const; type AllChartType = typeof ALL_NE_TYPES[number]; +// 在 ALL_NE_TYPES 定义之后添加 +const neTypeOptions = ALL_NE_TYPES.map(type => ({ + label: type.toUpperCase(), + value: type +})); + // 使用 ref 来使 networkElementTypes 变为响应式,并使用 ALL_NE_TYPES 初始化 const networkElementTypes = ref([...ALL_NE_TYPES]); -// 添加选择的网元类型,也使用 ALL_NE_TYPES 初始化 -const selectedNeTypes = ref([...ALL_NE_TYPES]); +// 添加选择的网元类型 +const selectedNeTypes = ref([]); -// 临时状态 存储最新的选择 +// 添加一个临时状态来存储最新的选择 const latestSelectedTypes = ref([]); -// watch 函数 +// 修改 watch 函数 watch(selectedNeTypes, (newTypes) => { console.log('Selected types changed:', newTypes); // 立即更新 UI @@ -52,11 +63,11 @@ watch(selectedNeTypes, (newTypes) => { debouncedUpdateCharts(); }, { deep: true }); -// 防抖函数 +// 修改防抖函数 const debouncedUpdateCharts = useDebounceFn(() => { // 比较当前选择和最新选择 if (JSON.stringify(latestSelectedTypes.value) !== JSON.stringify(selectedNeTypes.value)) { - // 如果不一致,以最新选择为准 + // 如果不致,以最新选择为准 selectedNeTypes.value = latestSelectedTypes.value; } @@ -92,7 +103,7 @@ const debouncedUpdateCharts = useDebounceFn(() => { }); }, 300); -// initCharts 函数 +// 修改 initCharts 函数 const initCharts = async () => { console.log('Initializing charts for:', networkElementTypes.value); @@ -132,7 +143,7 @@ const initCharts = async () => { localStorage.setItem('chartOrder', JSON.stringify(chartOrder.value)); }; -// 类型定义 +// 添加类型定义 interface LayoutItem { x: number; y: number; @@ -148,7 +159,7 @@ const chartOrder = ref( JSON.parse(localStorage.getItem('chartOrder') || 'null') || networkElementTypes.value.map((type, index) => ({ x: index % 2 * 6, // 每行两个图表,宽度为6 - y: Math.floor(index / 2) * 4, // 每个图表占据 4 个单位高度 + y: Math.floor(index / 2) * 4, // 每个图表据 4 个单位高度 w: 6, // 宽度为6单位 h: 4, // 高度为4个单位 i: type, // 使用网元类型作为唯一标识 @@ -238,7 +249,7 @@ const rangePicker = reactive({ // dayjs('2024-09-20 23:59:59').valueOf().toString() // ] [ - dayjs().startOf('day').valueOf().toString(), // 当天 0 点 0 分 0 秒 + dayjs().startOf('day').valueOf().toString(), // 天 0 点 0 分 0 秒 dayjs().valueOf().toString() // 当前时间 ] ])) as Record, @@ -334,7 +345,7 @@ const initChart = (type: AllChartType) => { } }); - // 观察图表容器 + // 开始观察图表容器 state.observer.value.observe(container); }); }; @@ -408,13 +419,13 @@ function fnRealTimeSwitch(bool: boolean) { } } -// 接收数据后错误回调 +// 接收数据后错误回 function wsError() { message.error(t('common.websocketError')); } -// wsMessage 数据回调 +// 修改 wsMessage 数 function wsMessage(res: Record) { const { code, data } = res; if (code === RESULT_CODE_ERROR) { @@ -573,7 +584,7 @@ onMounted(async () => { ws.value = new WS(); await neInfoStore.fnNelist(); - // 从本地存储中读取选中的网类型 + // 从本地存储中读取选中的网元类型 const savedSelectedNeTypes = localStorage.getItem('selectedNeTypes'); if (savedSelectedNeTypes) { const parsedSelectedNeTypes = JSON.parse(savedSelectedNeTypes) as AllChartType[]; @@ -625,6 +636,8 @@ onUnmounted(() => { state.observer.value.disconnect(); } }); + + // 不需要显式取消防抖函数 }); @@ -642,16 +655,7 @@ onUnmounted(() => { {{ realTimeEnabled ? t('views.dashboard.cdr.realTimeDataStart') : t('views.dashboard.cdr.realTimeDataStop') }} - - - {{ type.toUpperCase() }} - - + @@ -682,31 +686,31 @@ onUnmounted(() => { :min-h="3" :is-draggable="true" :is-resizable="true" - :resizable-handles="['ne']" - drag-allow-from=".drag-handle" + :resizable-handles="['se']" + drag-allow-from=".ant-card-head" drag-ignore-from=".no-drag" class="grid-item" > -
- +
+
-
@@ -732,12 +736,37 @@ onUnmounted(() => { position: relative; } +.date-picker-wrapper { + position: absolute; + top: -40px; + left: 0; + right: 0; + z-index: 1; +} + .card-container { height: 100%; display: flex; flex-direction: column; } +.card-title { + display: flex; + align-items: center; + cursor: move; + + .anticon { + margin-right: 8px; + font-size: 16px; + color: #1890ff; + } + + span { + font-size: 16px; + font-weight: 500; + } +} + .chart { flex: 1; min-height: 0; @@ -756,28 +785,31 @@ onUnmounted(() => { } .drag-handle { - position: absolute; - top: 0; - right: 0; - width: 24px; - height: 24px; display: flex; align-items: center; - justify-content: center; - background-color: rgba(24, 144, 255, 0.1); - border-radius: 4px; cursor: move; - z-index: 100; - transition: background-color 0.3s; - &:hover { - background-color: rgba(24, 144, 255, 0.2); + .anticon { + margin-right: 8px; + font-size: 16px; + color: #1890ff; + } + + span { + font-size: 16px; + font-weight: 500; } } .ne-type-select { flex-grow: 1; max-width: 100%; + + :deep(.ant-checkbox-group) { + display: flex; + flex-wrap: wrap; + gap: 8px; + } } :deep { @@ -806,5 +838,9 @@ onUnmounted(() => { .ant-select { min-width: 200px; } + + .ant-card-head { + cursor: move; + } }