fix:代码优化-方法封装-拖拽保存-大小自适应
This commit is contained in:
@@ -1,44 +1,43 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import draggable from 'vuedraggable';
|
import draggable from 'vuedraggable';
|
||||||
|
|
||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
import { PageContainer } from 'antdv-pro-layout';
|
import { PageContainer } from 'antdv-pro-layout';
|
||||||
import { onMounted, reactive, ref, markRaw, nextTick, onUnmounted } from 'vue';
|
import { onMounted, reactive, ref, markRaw, nextTick, onUnmounted} from 'vue';
|
||||||
import {
|
import { RESULT_CODE_ERROR, RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
RESULT_CODE_ERROR,
|
|
||||||
RESULT_CODE_SUCCESS,
|
|
||||||
} from '@/constants/result-constants';
|
|
||||||
import { SizeType } from 'ant-design-vue/es/config-provider';
|
import { SizeType } from 'ant-design-vue/es/config-provider';
|
||||||
import { listKPIData, getKPITitle } from '@/api/perfManage/goldTarget';
|
import { listKPIData, getKPITitle } from '@/api/perfManage/goldTarget';
|
||||||
import useI18n from '@/hooks/useI18n';
|
import useI18n from '@/hooks/useI18n';
|
||||||
import { parseDateToStr } from '@/utils/date-utils';
|
import { parseDateToStr } from '@/utils/date-utils';
|
||||||
import dayjs, { Dayjs } from 'dayjs';
|
import dayjs, { Dayjs } from 'dayjs';
|
||||||
import useNeInfoStore from '@/store/modules/neinfo';
|
import useNeInfoStore from '@/store/modules/neinfo';
|
||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
import { ColumnsType } from 'ant-design-vue/es/table';
|
import { ColumnsType } from 'ant-design-vue/es/table';
|
||||||
import { generateColorRGBA } from '@/utils/generate-utils';
|
import { generateColorRGBA } from '@/utils/generate-utils';
|
||||||
import { LineSeriesOption } from 'echarts/charts';
|
import { LineSeriesOption } from 'echarts/charts';
|
||||||
import { OptionsType, WS } from '@/plugins/ws-websocket';
|
import { OptionsType, WS } from '@/plugins/ws-websocket';
|
||||||
import { Switch } from 'ant-design-vue';
|
import { Switch } from 'ant-design-vue';
|
||||||
|
const { t, currentLocale } = useI18n();
|
||||||
|
|
||||||
const { t, currentLocale } = useI18n();
|
|
||||||
const neInfoStore = useNeInfoStore();
|
const neInfoStore = useNeInfoStore();
|
||||||
|
|
||||||
//WebSocket连接
|
//WebSocket连接
|
||||||
//const ws = new WS();
|
|
||||||
const ws = ref<WS | null>(null);
|
const ws = ref<WS | null>(null);
|
||||||
|
|
||||||
//实时数据开关
|
|
||||||
const handleRealTimeSwitch = (checked: any, event: Event) => {
|
|
||||||
console.log('Switch toggled:', checked);
|
|
||||||
fnRealTimeSwitch(!!checked);
|
|
||||||
};
|
|
||||||
//添加实时数据开关状态
|
//添加实时数据开关状态
|
||||||
const realTimeEnabled = ref(false);
|
const realTimeEnabled = ref(false);
|
||||||
|
//实时数据开关
|
||||||
|
const handleRealTimeSwitch = (checked: any) => {
|
||||||
|
fnRealTimeSwitch(!!checked);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 网元数组
|
||||||
|
const networkElementTypes = ['udm', 'upf', 'amf', 'smf', 'ims','ausf'] as const;
|
||||||
|
// 定义 ChartType
|
||||||
|
type ChartType = typeof networkElementTypes[number];
|
||||||
|
|
||||||
// 定义图表类型
|
|
||||||
type ChartType = 'udm' | 'upf' | 'amf' | 'smf';
|
|
||||||
//构建响应式数组储存图表类型数据
|
//构建响应式数组储存图表类型数据
|
||||||
const chartOrder = ref(['udm', 'upf', 'amf', 'smf']);
|
const chartOrder = ref([...networkElementTypes]);
|
||||||
|
|
||||||
// 定义表格状态类型
|
// 定义表格状态类型
|
||||||
type TableStateType = {
|
type TableStateType = {
|
||||||
@@ -49,78 +48,59 @@ type TableStateType = {
|
|||||||
selectedRowKeys: (string | number)[];
|
selectedRowKeys: (string | number)[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// 创建可复用的状态
|
// 创建可复用的状态
|
||||||
const createChartState = () => ({
|
const createChartState = () => {
|
||||||
chartDom: ref<HTMLElement | null>(null),
|
const chartDom = ref<HTMLElement | null>(null);
|
||||||
chart: ref<echarts.ECharts | null>(null),
|
const chart = ref<echarts.ECharts | null>(null);
|
||||||
tableColumns: ref<ColumnsType>([]),
|
const observer = ref<ResizeObserver | null>(null);
|
||||||
tableState: reactive<TableStateType>({
|
|
||||||
loading: false,
|
return {
|
||||||
size: 'small',
|
chartDom,
|
||||||
seached: true,
|
chart,
|
||||||
data: [],
|
observer,
|
||||||
selectedRowKeys: [],
|
tableColumns: ref<ColumnsType>([]),
|
||||||
}),
|
tableState: reactive<TableStateType>({
|
||||||
chartLegendSelected: {} as Record<string, boolean>,
|
loading: false,
|
||||||
chartDataXAxisData: [] as string[],
|
size: 'small',
|
||||||
chartDataYSeriesData: [] as CustomSeriesOption[],
|
seached: true,
|
||||||
});
|
data: [],
|
||||||
|
selectedRowKeys: [],
|
||||||
|
}),
|
||||||
|
chartLegendSelected: {} as Record<string, boolean>,
|
||||||
|
chartDataXAxisData: [] as string[],
|
||||||
|
chartDataYSeriesData: [] as CustomSeriesOption[],
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
// 为每种图表类型创建状态
|
// 为每种图表类型创建状态
|
||||||
const chartStates: Record<ChartType, ReturnType<typeof createChartState>> = {
|
const chartStates: Record<ChartType, ReturnType<typeof createChartState>> = Object.fromEntries(
|
||||||
udm: createChartState(),
|
networkElementTypes.map(type => [type, createChartState()])
|
||||||
upf: createChartState(),
|
) as Record<ChartType, ReturnType<typeof createChartState>>;
|
||||||
amf: createChartState(),
|
|
||||||
smf: createChartState(),
|
|
||||||
};
|
|
||||||
|
|
||||||
//日期选择器
|
//日期选择器
|
||||||
interface RangePicker {
|
interface RangePicker {
|
||||||
udm: [string, string];
|
[key: string]: [string, string] | Record<string, [Dayjs, Dayjs]>;
|
||||||
upf: [string, string];
|
|
||||||
amf: [string, string];
|
|
||||||
smf: [string, string];
|
|
||||||
placeholder: [string, string];
|
placeholder: [string, string];
|
||||||
ranges: Record<string, [Dayjs, Dayjs]>;
|
ranges: Record<string, [Dayjs, Dayjs]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建日期选择器状态
|
// 创建日期选择器状态
|
||||||
const rangePicker = reactive<RangePicker>({
|
const rangePicker = reactive<RangePicker>({
|
||||||
udm: [
|
...Object.fromEntries(networkElementTypes.map(type => [
|
||||||
dayjs('2024-09-20 00:00:00').valueOf().toString(),
|
type,
|
||||||
dayjs('2024-09-20 23:59:59').valueOf().toString(),
|
[
|
||||||
],
|
dayjs('2024-09-20 00:00:00').valueOf().toString(),//模拟数据日期为9月20日数据
|
||||||
upf: [
|
dayjs('2024-09-20 23:59:59').valueOf().toString()
|
||||||
dayjs('2024-09-20 00:00:00').valueOf().toString(),
|
]
|
||||||
dayjs('2024-09-20 23:59:59').valueOf().toString(),
|
])),
|
||||||
],
|
placeholder: [t('views.monitor.monitor.startTime'), t('views.monitor.monitor.endTime')] as [string, string],
|
||||||
amf: [
|
|
||||||
dayjs('2024-09-20 00:00:00').valueOf().toString(),
|
|
||||||
dayjs('2024-09-20 23:59:59').valueOf().toString(),
|
|
||||||
],
|
|
||||||
smf: [
|
|
||||||
dayjs('2024-09-20 00:00:00').valueOf().toString(),
|
|
||||||
dayjs('2024-09-20 23:59:59').valueOf().toString(),
|
|
||||||
],
|
|
||||||
placeholder: [
|
|
||||||
t('views.monitor.monitor.startTime'),
|
|
||||||
t('views.monitor.monitor.endTime'),
|
|
||||||
] as [string, string],
|
|
||||||
ranges: {
|
ranges: {
|
||||||
[t('views.monitor.monitor.yesterday')]: [
|
[t('views.monitor.monitor.yesterday')]: [dayjs().subtract(1, 'day').startOf('day'), dayjs().subtract(1, 'day').endOf('day')],
|
||||||
dayjs().subtract(1, 'day').startOf('day'),
|
|
||||||
dayjs().subtract(1, 'day').endOf('day'),
|
|
||||||
],
|
|
||||||
[t('views.monitor.monitor.today')]: [dayjs().startOf('day'), dayjs()],
|
[t('views.monitor.monitor.today')]: [dayjs().startOf('day'), dayjs()],
|
||||||
[t('views.monitor.monitor.week')]: [
|
[t('views.monitor.monitor.week')]: [dayjs().startOf('week'), dayjs().endOf('week')],
|
||||||
dayjs().startOf('week'),
|
[t('views.monitor.monitor.month')]: [dayjs().startOf('month'), dayjs().endOf('month')],
|
||||||
dayjs().endOf('week'),
|
} as Record<string, [Dayjs, Dayjs]>,
|
||||||
],
|
|
||||||
[t('views.monitor.monitor.month')]: [
|
|
||||||
dayjs().startOf('month'),
|
|
||||||
dayjs().endOf('month'),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 创建可复用的图表初始化函数
|
// 创建可复用的图表初始化函数
|
||||||
@@ -129,11 +109,12 @@ const initChart = (type: ChartType) => {
|
|||||||
const state = chartStates[type];
|
const state = chartStates[type];
|
||||||
const container = state.chartDom.value;
|
const container = state.chartDom.value;
|
||||||
if (!container) return;
|
if (!container) return;
|
||||||
|
|
||||||
state.chart.value = markRaw(echarts.init(container, 'light'));
|
state.chart.value = markRaw(echarts.init(container, 'light'));
|
||||||
const option: echarts.EChartsOption = {
|
const option: echarts.EChartsOption = {
|
||||||
tooltip: {
|
tooltip: {
|
||||||
trigger: 'axis',
|
trigger: 'axis',
|
||||||
position: function (pt: any) {
|
position: function(pt: any) {
|
||||||
return [pt[0], '10%'];
|
return [pt[0], '10%'];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -176,29 +157,45 @@ const initChart = (type: ChartType) => {
|
|||||||
series: [],
|
series: [],
|
||||||
};
|
};
|
||||||
state.chart.value.setOption(option);
|
state.chart.value.setOption(option);
|
||||||
|
|
||||||
|
// 创建 ResizeObserver 实例
|
||||||
|
state.observer.value = new ResizeObserver(() => {
|
||||||
|
if (state.chart.value) {
|
||||||
|
state.chart.value.resize();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 开始观察图表容器
|
||||||
|
state.observer.value.observe(container);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
//结束拖拽事件
|
//结束拖拽事件
|
||||||
const onDragEnd = () => {
|
const onDragEnd = () => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
chartOrder.value.forEach(type => {
|
chartOrder.value.forEach((type) => {
|
||||||
const state = chartStates[type as ChartType];
|
const state = chartStates[type as ChartType];
|
||||||
if (state.chart.value) {
|
if (state.chart.value) {
|
||||||
state.chart.value.dispose(); // 销毁旧的图表实例
|
state.chart.value.resize(); // 调整图表大小
|
||||||
|
// 重新设置图表选项,保留原有数据
|
||||||
|
state.chart.value.setOption({
|
||||||
|
xAxis: { data: state.chartDataXAxisData },
|
||||||
|
series: state.chartDataYSeriesData,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
initChart(type as ChartType);
|
|
||||||
fetchData(type as ChartType); // 重新获取数据并渲染图表
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// 创建可复用的数据获取函数
|
// 创建可复用的数据获取函数
|
||||||
const fetchData = async (type: ChartType) => {
|
const fetchData = async (type: ChartType) => {
|
||||||
const state = chartStates[type];
|
const state = chartStates[type];
|
||||||
const neId = '001';
|
const neId = '001';
|
||||||
state.tableState.loading = true;
|
state.tableState.loading = true;
|
||||||
try {
|
try {
|
||||||
const [startTime, endTime] = rangePicker[type];
|
const dateRange = rangePicker[type] as [string, string];
|
||||||
|
const [startTime, endTime] = dateRange;
|
||||||
const res = await listKPIData({
|
const res = await listKPIData({
|
||||||
neType: type.toUpperCase(),
|
neType: type.toUpperCase(),
|
||||||
neId,
|
neId,
|
||||||
@@ -209,8 +206,9 @@ const fetchData = async (type: ChartType) => {
|
|||||||
interval: 5,
|
interval: 5,
|
||||||
});
|
});
|
||||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
||||||
|
|
||||||
state.tableState.data = res.data;
|
state.tableState.data = res.data;
|
||||||
nextTick(() => {
|
nextTick(()=> {
|
||||||
renderChart(type);
|
renderChart(type);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -224,11 +222,11 @@ const fetchData = async (type: ChartType) => {
|
|||||||
|
|
||||||
//建立实时数据连接
|
//建立实时数据连接
|
||||||
function fnRealTimeSwitch(bool: boolean) {
|
function fnRealTimeSwitch(bool: boolean) {
|
||||||
console.log('fnRealTimeSwitch called with:', bool);
|
|
||||||
realTimeEnabled.value = bool;
|
realTimeEnabled.value = bool;
|
||||||
if (bool) {
|
if (bool) {
|
||||||
if (!ws.value) {
|
if(!ws.value){
|
||||||
console.log('Creating new WS instance');
|
|
||||||
ws.value = new WS();
|
ws.value = new WS();
|
||||||
}
|
}
|
||||||
Object.values(chartStates).forEach(state => {
|
Object.values(chartStates).forEach(state => {
|
||||||
@@ -238,21 +236,15 @@ function fnRealTimeSwitch(bool: boolean) {
|
|||||||
const options: OptionsType = {
|
const options: OptionsType = {
|
||||||
url: '/ws',
|
url: '/ws',
|
||||||
params: {
|
params: {
|
||||||
subGroupID: Object.keys(chartStates)
|
subGroupID: networkElementTypes.map(type => `10_${type.toUpperCase()}_001`).join(','),
|
||||||
.map(type => `10_${type.toUpperCase()}_001`)
|
|
||||||
.join(','),
|
|
||||||
},
|
},
|
||||||
onmessage: wsMessage,
|
onmessage: wsMessage,
|
||||||
onerror: wsError,
|
onerror: wsError,
|
||||||
onopen: () => {
|
|
||||||
console.log('WebSocket connection established');
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
console.log('Attempting to connect with options:', options);
|
|
||||||
ws.value.connect(options);
|
ws.value.connect(options);
|
||||||
console.log('Connection attempt initiated');
|
} else if(ws.value){
|
||||||
} else if (ws.value) {
|
|
||||||
console.log('Closing WebSocket connection');
|
|
||||||
Object.values(chartStates).forEach(state => {
|
Object.values(chartStates).forEach(state => {
|
||||||
state.tableState.seached = true;
|
state.tableState.seached = true;
|
||||||
});
|
});
|
||||||
@@ -262,8 +254,8 @@ function fnRealTimeSwitch(bool: boolean) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 接收数据后错误回调
|
// 接收数据后错误回调
|
||||||
function wsError(ev: any) {
|
function wsError() {
|
||||||
console.error('WebSocket error:', ev);
|
|
||||||
message.error(t('common.websocketError'));
|
message.error(t('common.websocketError'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,9 +274,9 @@ function wsMessage(res: Record<string, any>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 处理四个图表的数据
|
// 处理四个图表的数据
|
||||||
(Object.keys(chartStates) as ChartType[]).forEach(type => {
|
networkElementTypes.forEach((type) => {
|
||||||
const state = chartStates[type];
|
const state = chartStates[type];
|
||||||
const kpiEvent = data.data[type.toUpperCase()];
|
const kpiEvent:any = data.data[type.toUpperCase()];
|
||||||
|
|
||||||
if (kpiEvent) {
|
if (kpiEvent) {
|
||||||
// 更新 X 轴数据
|
// 更新 X 轴数据
|
||||||
@@ -326,25 +318,22 @@ interface CustomSeriesOption extends Omit<LineSeriesOption, 'data'> {
|
|||||||
}
|
}
|
||||||
// 创建可复用的图表渲染函数
|
// 创建可复用的图表渲染函数
|
||||||
const renderChart = (type: ChartType) => {
|
const renderChart = (type: ChartType) => {
|
||||||
|
|
||||||
const state = chartStates[type];
|
const state = chartStates[type];
|
||||||
if (state.chart.value == null || state.tableState.data.length <= 0) {
|
if (state.chart.value == null ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重置数据
|
// 重置数据
|
||||||
state.chartLegendSelected = {};
|
state.chartLegendSelected = {};
|
||||||
state.chartDataXAxisData = [];
|
state.chartDataXAxisData = [];
|
||||||
state.chartDataYSeriesData = [];
|
state.chartDataYSeriesData = [];
|
||||||
|
|
||||||
// 处理数据
|
// 处理数据
|
||||||
for (const columns of state.tableColumns.value) {
|
for (const columns of state.tableColumns.value) {
|
||||||
if (['neName', 'startIndex', 'timeGroup'].includes(columns.key as string))
|
if (['neName', 'startIndex', 'timeGroup'].includes(columns.key as string)) continue;
|
||||||
continue;
|
|
||||||
const color = generateColorRGBA();
|
const color = generateColorRGBA();
|
||||||
state.chartDataYSeriesData.push({
|
state.chartDataYSeriesData.push({
|
||||||
name: columns.title as string,
|
name: columns.title as string,
|
||||||
customKey: columns.key as string,
|
customKey: columns.key as string,
|
||||||
//key: columns.key as string,
|
|
||||||
type: 'line',
|
type: 'line',
|
||||||
symbol: 'none',
|
symbol: 'none',
|
||||||
sampling: 'lttb',
|
sampling: 'lttb',
|
||||||
@@ -358,8 +347,6 @@ const renderChart = (type: ChartType) => {
|
|||||||
data: [],
|
data: [],
|
||||||
} as CustomSeriesOption);
|
} as CustomSeriesOption);
|
||||||
state.chartLegendSelected[columns.title as string] = true;
|
state.chartLegendSelected[columns.title as string] = true;
|
||||||
//});
|
|
||||||
//state.chartLegendSelected[columns.title as string] = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const orgData = [...state.tableState.data].reverse();
|
const orgData = [...state.tableState.data].reverse();
|
||||||
@@ -370,12 +357,14 @@ const renderChart = (type: ChartType) => {
|
|||||||
y.data.push(+item[y.customKey as string]);
|
y.data.push(+item[y.customKey as string]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新图表
|
// 更新图表
|
||||||
state.chart.value.setOption(
|
state.chart.value.setOption(
|
||||||
{
|
{
|
||||||
legend: { selected: state.chartLegendSelected },
|
legend: { selected: state.chartLegendSelected },
|
||||||
xAxis: { data: state.chartDataXAxisData },
|
xAxis: { data: state.chartDataXAxisData,
|
||||||
|
type: 'category',
|
||||||
|
boundaryGap: false,
|
||||||
|
},
|
||||||
series: state.chartDataYSeriesData,
|
series: state.chartDataYSeriesData,
|
||||||
dataZoom: [
|
dataZoom: [
|
||||||
{
|
{
|
||||||
@@ -393,12 +382,10 @@ const renderChart = (type: ChartType) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// 获取表头数据
|
// 获取表头数据
|
||||||
const fetchKPITitle = async (type: ChartType) => {
|
const fetchKPITitle = async (type: ChartType) => {
|
||||||
const language =
|
const language = currentLocale.value.split('_')[0] === 'zh' ? 'cn' : currentLocale.value.split('_')[0];
|
||||||
currentLocale.value.split('_')[0] === 'zh'
|
|
||||||
? 'cn'
|
|
||||||
: currentLocale.value.split('_')[0];
|
|
||||||
try {
|
try {
|
||||||
const res = await getKPITitle(type.toUpperCase());
|
const res = await getKPITitle(type.toUpperCase());
|
||||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
||||||
@@ -423,22 +410,26 @@ const fetchKPITitle = async (type: ChartType) => {
|
|||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
ws.value = new WS();
|
ws.value = new WS();
|
||||||
await neInfoStore.fnNelist();
|
await neInfoStore.fnNelist();
|
||||||
for (const type of Object.keys(chartStates) as ChartType[]) {
|
for (const type of networkElementTypes) {
|
||||||
await fetchKPITitle(type);
|
await fetchKPITitle(type);
|
||||||
initChart(type);
|
initChart(type);
|
||||||
fetchData(type);
|
fetchData(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 在组件卸载时销毁图表实例
|
// 在组件卸载时销毁图表实例
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
if (ws.value && ws.value.state() === WebSocket.OPEN) {
|
if(ws.value &&ws.value.state()===WebSocket.OPEN) {
|
||||||
ws.value.close();
|
ws.value.close();
|
||||||
}
|
}
|
||||||
Object.values(chartStates).forEach(state => {
|
Object.values(chartStates).forEach((state) => {
|
||||||
if (state.chart.value) {
|
if (state.chart.value) {
|
||||||
state.chart.value.dispose();
|
state.chart.value.dispose();
|
||||||
}
|
}
|
||||||
|
if (state.observer.value) {
|
||||||
|
state.observer.value.disconnect();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@@ -451,9 +442,7 @@ onUnmounted(() => {
|
|||||||
v-model:checked="realTimeEnabled"
|
v-model:checked="realTimeEnabled"
|
||||||
@change="handleRealTimeSwitch as any"
|
@change="handleRealTimeSwitch as any"
|
||||||
/>
|
/>
|
||||||
<span class="switch-label">{{
|
<span class="switch-label">{{ realTimeEnabled ? t('views.dashboard.cdr.realTimeDataStart') : t('views.dashboard.cdr.realTimeDataStop') }}</span>
|
||||||
realTimeEnabled ? '实时数据已开启' : '实时数据已关闭'
|
|
||||||
}}</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<draggable
|
<draggable
|
||||||
@@ -462,14 +451,12 @@ onUnmounted(() => {
|
|||||||
item-key="type"
|
item-key="type"
|
||||||
@end="onDragEnd"
|
@end="onDragEnd"
|
||||||
class="row"
|
class="row"
|
||||||
onscroll="false"
|
onscroll='false'
|
||||||
>
|
>
|
||||||
<template #item="{ element: type }">
|
<template #item="{element:type}">
|
||||||
|
|
||||||
<div class="col-lg-6 col-md=-6 col-xs-12">
|
<div class="col-lg-6 col-md=-6 col-xs-12">
|
||||||
<a-card
|
<a-card :bordered="false" :body-style="{ marginBottom: '24px', padding: '24px'}">
|
||||||
:bordered="false"
|
|
||||||
:body-style="{ marginBottom: '24px', padding: '24px' }"
|
|
||||||
>
|
|
||||||
<template #title>{{ type.toUpperCase() }}</template>
|
<template #title>{{ type.toUpperCase() }}</template>
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<a-range-picker
|
<a-range-picker
|
||||||
@@ -485,14 +472,12 @@ onUnmounted(() => {
|
|||||||
@change="() => fetchData(type)"
|
@change="() => fetchData(type)"
|
||||||
></a-range-picker>
|
></a-range-picker>
|
||||||
</template>
|
</template>
|
||||||
<div class="chart" style="padding: 12px">
|
<div class='chart' style="padding: 12px">
|
||||||
<div
|
<div :ref="el => { if (el) chartStates[type as ChartType].chartDom.value = el as HTMLElement }" style="height:400px;width:100%"></div>
|
||||||
:ref="el => { if (el) chartStates[type as ChartType].chartDom.value = el as HTMLElement }"
|
|
||||||
style="height: 400px; width: 100%"
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
</a-card>
|
</a-card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
</draggable>
|
</draggable>
|
||||||
</PageContainer>
|
</PageContainer>
|
||||||
@@ -503,6 +488,7 @@ onUnmounted(() => {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 450px;
|
height: 450px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sortable-ghost {
|
.sortable-ghost {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
background: #c8ebfb;
|
background: #c8ebfb;
|
||||||
@@ -512,30 +498,19 @@ onUnmounted(() => {
|
|||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
background: #f4f4f4;
|
background: #f4f4f4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.row {
|
.row {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
margin-right: -12px;
|
margin: -12px;
|
||||||
margin-left: -12px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.col-lg-6 {
|
.col-lg-6 {
|
||||||
flex: 0 0 50%;
|
flex: 0 0 50%;
|
||||||
max-width: 50%;
|
max-width: 50%;
|
||||||
padding-right: 12px;
|
padding: 12px;
|
||||||
padding-left: 12px;
|
|
||||||
}
|
|
||||||
@media (max-width: 991px) {
|
|
||||||
.col-md-6 {
|
|
||||||
flex: 0 0 50%;
|
|
||||||
max-width: 50%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media (max-width: 575px) {
|
|
||||||
.col-xs-12 {
|
|
||||||
flex: 0 0 100%;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.control-row {
|
.control-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
|
|||||||
Reference in New Issue
Block a user