fix:多选改checkbox
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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<WS | null>(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<AllChartType[]>([...ALL_NE_TYPES]);
|
||||
|
||||
// 添加选择的网元类型,也使用 ALL_NE_TYPES 初始化
|
||||
const selectedNeTypes = ref<AllChartType[]>([...ALL_NE_TYPES]);
|
||||
// 添加选择的网元类型
|
||||
const selectedNeTypes = ref<AllChartType[]>([]);
|
||||
|
||||
// 临时状态 存储最新的选择
|
||||
// 添加一个临时状态来存储最新的选择
|
||||
const latestSelectedTypes = ref<AllChartType[]>([]);
|
||||
|
||||
// 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<Layout>(
|
||||
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<RangePicker>({
|
||||
// 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<AllChartType, [string, string]>,
|
||||
@@ -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<string, any>) {
|
||||
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();
|
||||
}
|
||||
});
|
||||
|
||||
// 不需要显式取消防抖函数
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -642,16 +655,7 @@ onUnmounted(() => {
|
||||
<span class="switch-label">{{ realTimeEnabled ? t('views.dashboard.cdr.realTimeDataStart') : t('views.dashboard.cdr.realTimeDataStop') }}</span>
|
||||
</a-form-item>
|
||||
<a-form-item :label="t('views.ne.common.neType')" class="ne-type-select">
|
||||
<a-select
|
||||
v-model:value="selectedNeTypes"
|
||||
mode="multiple"
|
||||
style="min-width: 200px; width: 100%"
|
||||
:placeholder="t('common.selectPlease')"
|
||||
>
|
||||
<a-select-option v-for="type in ALL_NE_TYPES" :key="type" :value="type">
|
||||
{{ type.toUpperCase() }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
<a-checkbox-group v-model:value="selectedNeTypes" :options="neTypeOptions" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-card>
|
||||
@@ -682,19 +686,12 @@ 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"
|
||||
>
|
||||
<div class="drag-handle">
|
||||
<DragOutlined />
|
||||
</div>
|
||||
<a-card :bordered="false" class="card-container">
|
||||
<template #title>
|
||||
<span class="no-drag">{{ item.i.toUpperCase() }}</span>
|
||||
</template>
|
||||
<template #extra>
|
||||
<div class="date-picker-wrapper">
|
||||
<a-range-picker
|
||||
v-model:value="rangePicker[item.i]"
|
||||
:allow-clear="false"
|
||||
@@ -707,6 +704,13 @@ onUnmounted(() => {
|
||||
style="width: 100%"
|
||||
@change="() => fetchData(item.i)"
|
||||
></a-range-picker>
|
||||
</div>
|
||||
<a-card :bordered="false" class="card-container">
|
||||
<template #title>
|
||||
<div class="card-title">
|
||||
<DragOutlined />
|
||||
<span>{{ item.i.toUpperCase() }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class='chart'>
|
||||
<div :ref="el => { if (el && chartStates[item.i]) chartStates[item.i].chartDom.value = el as HTMLElement }"></div>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user