feat:语音仪表盘增加新指标显示
This commit is contained in:
@@ -134,3 +134,11 @@ export function updateKPITitle(data: Record<string, any>) {
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
//忙时呼叫
|
||||
export async function getbusyhour(query: Record<string, any>) {
|
||||
return request({
|
||||
url: '/neData/ims/kpi/busy-hour',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -88,6 +88,42 @@
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="[16, 16]" style="margin-top: 16px;">
|
||||
<a-col :xs="24" :sm="24" :lg="12">
|
||||
<a-card bordered class="metric-card">
|
||||
<div class="card-title">Call Attempts <span class="main-icon phone">📞</span></div>
|
||||
<div class="card-content">
|
||||
<div class="trend-chart">
|
||||
<div class="mini-chart" ref="callAttemptsChartRef"></div>
|
||||
</div>
|
||||
<div class="metric-info">
|
||||
<div class="metric-value">
|
||||
{{ calculateCallAttemptsValue() }}
|
||||
<span class="main-arrow" :class="calculateCallAttemptsArrowDirection()">{{ calculateCallAttemptsArrow() }}</span>
|
||||
</div>
|
||||
<div class="metric-change">{{ calculateCallAttemptsChange() }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :xs="24" :sm="24" :lg="12">
|
||||
<a-card bordered class="metric-card">
|
||||
<div class="card-title">Call Completions <span class="main-icon phone">📞</span></div>
|
||||
<div class="card-content">
|
||||
<div class="trend-chart">
|
||||
<div class="mini-chart" ref="callCompletionsChartRef"></div>
|
||||
</div>
|
||||
<div class="metric-info">
|
||||
<div class="metric-value">
|
||||
{{ calculateCallCompletionsValue() }}
|
||||
<span class="main-arrow" :class="calculateCallCompletionsArrowDirection()">{{ calculateCallCompletionsArrow() }}</span>
|
||||
</div>
|
||||
<div class="metric-change">{{ calculateCallCompletionsChange() }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<div class="row-title" style="margin-top: 48px;">{{ t('views.perfManage.voiceOverView.registration') }}</div>
|
||||
<a-row :gutter="[16, 16]">
|
||||
<a-col :xs="24" :sm="24" :lg="8">
|
||||
@@ -147,7 +183,7 @@ import { GridComponent } from 'echarts/components'
|
||||
import { CanvasRenderer } from 'echarts/renderers'
|
||||
import useNeInfoStore from '@/store/modules/neinfo'
|
||||
import { WS } from '@/plugins/ws-websocket'
|
||||
import { listKPIData } from '@/api/perfManage/goldTarget'
|
||||
import { listKPIData ,getbusyhour} from '@/api/perfManage/goldTarget'
|
||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'
|
||||
import useI18n from '@/hooks/useI18n';
|
||||
const { t } = useI18n();
|
||||
@@ -156,6 +192,8 @@ echarts.use([LineChart, GridComponent, CanvasRenderer])
|
||||
const callsChartRef = ref<HTMLDivElement | null>(null)
|
||||
const mosChartRef = ref<HTMLDivElement | null>(null)
|
||||
const failedCallsChartRef = ref<HTMLDivElement | null>(null)
|
||||
const callAttemptsChartRef = ref<HTMLDivElement | null>(null)
|
||||
const callCompletionsChartRef = ref<HTMLDivElement | null>(null)
|
||||
const regChartRef = ref<HTMLDivElement | null>(null)
|
||||
const failedRegChartRef = ref<HTMLDivElement | null>(null)
|
||||
|
||||
@@ -167,6 +205,8 @@ const selectedImsNeId = ref('')
|
||||
const imsWs = ref<any>(null)
|
||||
// IMS实时原始数据(只存储当前选中网元)
|
||||
const imsRealtimeRawData = ref<any[]>([])
|
||||
// Busy Hour数据(用于Call Attempts和Call Completions)
|
||||
const busyHourData = ref<any>(null)
|
||||
// WebSocket连接状态
|
||||
const wsStatus = ref('no connection')
|
||||
|
||||
@@ -185,8 +225,9 @@ onMounted(async () => {
|
||||
selectedImsNeId.value = imsNeList.value[0].neId
|
||||
// console.log('默认选中第一个IMS网元:', selectedImsNeId.value) // 调试信息
|
||||
|
||||
// 先获取历史数据,再订阅实时数据
|
||||
// 先获取历史数据和Busy Hour数据,再订阅实时数据
|
||||
await fetchHistoryData(selectedImsNeId.value)
|
||||
await fetchBusyHourData(selectedImsNeId.value)
|
||||
subscribeImsRealtime(selectedImsNeId.value)
|
||||
} else {
|
||||
// console.warn('没有找到IMS类型的网元') // 调试信息
|
||||
@@ -252,6 +293,44 @@ async function fetchHistoryData(neId: string) {
|
||||
}
|
||||
}
|
||||
|
||||
// 获取Busy Hour数据
|
||||
async function fetchBusyHourData(neId: string) {
|
||||
if (!neId) return
|
||||
|
||||
try {
|
||||
// 获取当天日期的时间戳
|
||||
const today = new Date()
|
||||
today.setHours(0, 0, 0, 0) // 设置为当天00:00:00
|
||||
const timestamp = today.getTime()
|
||||
|
||||
// 构建请求参数
|
||||
const params = {
|
||||
neId: neId,
|
||||
timestamp: timestamp
|
||||
}
|
||||
|
||||
console.log('获取Busy Hour数据参数:', params)
|
||||
|
||||
const res = await getbusyhour(params)
|
||||
console.log('Busy Hour数据响应:', res)
|
||||
|
||||
if (res.code === 1 && Array.isArray(res.data)) {
|
||||
busyHourData.value = res.data
|
||||
console.log('Busy Hour数据加载完成:', busyHourData.value)
|
||||
|
||||
// 更新Call Attempts和Call Completions图表
|
||||
updateCallAttemptsChart()
|
||||
updateCallCompletionsChart()
|
||||
} else {
|
||||
console.warn('获取Busy Hour数据失败或数据为空')
|
||||
busyHourData.value = null
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取Busy Hour数据出错:', error)
|
||||
busyHourData.value = null
|
||||
}
|
||||
}
|
||||
|
||||
// 切换IMS网元时,重新订阅
|
||||
async function onImsNeChange() {
|
||||
// console.log('切换IMS网元,新的网元ID:', selectedImsNeId.value) // 调试信息
|
||||
@@ -268,8 +347,9 @@ async function onImsNeChange() {
|
||||
updateActiveRegistrationsChart()
|
||||
updateFailedRegistrationsChart()
|
||||
|
||||
// 先获取历史数据,再订阅实时数据
|
||||
// 先获取历史数据和Busy Hour数据,再订阅实时数据
|
||||
await fetchHistoryData(selectedImsNeId.value)
|
||||
await fetchBusyHourData(selectedImsNeId.value)
|
||||
subscribeImsRealtime(selectedImsNeId.value)
|
||||
}
|
||||
|
||||
@@ -998,6 +1078,300 @@ function updateFailedRegistrationsChart() {
|
||||
}
|
||||
}
|
||||
|
||||
// 更新Call Attempts图表
|
||||
function updateCallAttemptsChart() {
|
||||
if (!callAttemptsChartRef.value) return
|
||||
|
||||
// 获取图表实例
|
||||
let chart = echarts.getInstanceByDom(callAttemptsChartRef.value)
|
||||
if (!chart) {
|
||||
chart = echarts.init(callAttemptsChartRef.value)
|
||||
}
|
||||
|
||||
// 如果没有Busy Hour数据,显示默认的平直线
|
||||
if (!busyHourData.value) {
|
||||
const defaultData = [0, 0, 0, 0, 0] // 5个默认数据点,值为0
|
||||
const xAxisData = [1, 2, 3, 4, 5]
|
||||
|
||||
chart.setOption({
|
||||
grid: { left: 0, right: 30, top: 10, bottom: 10 },
|
||||
xAxis: { type: 'category', show: false, data: xAxisData },
|
||||
yAxis: { type: 'value', show: false },
|
||||
series: [{
|
||||
data: defaultData,
|
||||
type: 'line', symbol: 'none',
|
||||
lineStyle: { width: 2, color: '#d9d9d9' },
|
||||
areaStyle: { color: 'rgba(217,217,217,0.1)' }
|
||||
}]
|
||||
})
|
||||
|
||||
// 清除所有旧标注
|
||||
const chartContainer = callAttemptsChartRef.value
|
||||
if (chartContainer) {
|
||||
const existingLabels = chartContainer.querySelectorAll('.chart-label')
|
||||
existingLabels.forEach(label => label.remove())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 从Busy Hour数据中提取Call Attempts数据
|
||||
const chartData = busyHourData.value.map((item: any) => Number(item.callAttempts) || 0)
|
||||
|
||||
// 生成时间轴数据
|
||||
const xAxisData = Array.from({ length: chartData.length }, (_, i) => i + 1)
|
||||
|
||||
// 计算最大值、最小值、最新值
|
||||
const maxValue = Math.max(...chartData)
|
||||
const minValue = Math.min(...chartData)
|
||||
const latestValue = chartData[chartData.length - 1]
|
||||
|
||||
chart.setOption({
|
||||
grid: { left: 0, right: 30, top: 10, bottom: 10 },
|
||||
xAxis: { type: 'category', show: false, data: xAxisData },
|
||||
yAxis: { type: 'value', show: false },
|
||||
series: [{
|
||||
data: chartData,
|
||||
type: 'line', symbol: 'none',
|
||||
lineStyle: { width: 2, color: '#52c41a' }, // 绿色线条
|
||||
areaStyle: { color: 'rgba(82,196,26,0.1)' } // 淡绿色填充
|
||||
}]
|
||||
})
|
||||
|
||||
// 在图表容器中添加数值标注
|
||||
const chartContainer = callAttemptsChartRef.value
|
||||
if (chartContainer) {
|
||||
// 清除之前的标注
|
||||
const existingLabels = chartContainer.querySelectorAll('.chart-label')
|
||||
existingLabels.forEach(label => label.remove())
|
||||
|
||||
// 添加右侧数值标注
|
||||
const maxLabel = document.createElement('div')
|
||||
maxLabel.className = 'chart-label'
|
||||
maxLabel.style.cssText = `
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
top: 8px;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
color: #666;
|
||||
pointer-events: none;
|
||||
z-index: 10;
|
||||
`
|
||||
maxLabel.textContent = maxValue.toString()
|
||||
|
||||
const latestLabel = document.createElement('div')
|
||||
latestLabel.className = 'chart-label'
|
||||
latestLabel.style.cssText = `
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
color: #52c41a;
|
||||
pointer-events: none;
|
||||
z-index: 10;
|
||||
`
|
||||
latestLabel.textContent = latestValue.toString()
|
||||
|
||||
const minLabel = document.createElement('div')
|
||||
minLabel.className = 'chart-label'
|
||||
minLabel.style.cssText = `
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
bottom: 8px;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
color: #666;
|
||||
pointer-events: none;
|
||||
z-index: 10;
|
||||
`
|
||||
minLabel.textContent = minValue.toString()
|
||||
|
||||
// 添加底部时间标注
|
||||
const oldestTimeLabel = document.createElement('div')
|
||||
oldestTimeLabel.className = 'chart-label'
|
||||
oldestTimeLabel.style.cssText = `
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
bottom: -20px;
|
||||
font-size: 11px;
|
||||
color: #999;
|
||||
pointer-events: none;
|
||||
z-index: 10;
|
||||
`
|
||||
// 使用第一个数据点的时间戳计算相对时间
|
||||
const oldestTime = Number(busyHourData.value[0]?.timeGroup) || Date.now()
|
||||
oldestTimeLabel.textContent = calculateRelativeTime(oldestTime)
|
||||
|
||||
const nowTimeLabel = document.createElement('div')
|
||||
nowTimeLabel.className = 'chart-label'
|
||||
nowTimeLabel.style.cssText = `
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
bottom: -20px;
|
||||
font-size: 11px;
|
||||
color: #999;
|
||||
pointer-events: none;
|
||||
z-index: 10;
|
||||
`
|
||||
nowTimeLabel.textContent = t('views.perfManage.voiceOverView.now')
|
||||
|
||||
chartContainer.appendChild(maxLabel)
|
||||
chartContainer.appendChild(latestLabel)
|
||||
chartContainer.appendChild(minLabel)
|
||||
chartContainer.appendChild(oldestTimeLabel)
|
||||
chartContainer.appendChild(nowTimeLabel)
|
||||
}
|
||||
}
|
||||
|
||||
// 更新Call Completions图表
|
||||
function updateCallCompletionsChart() {
|
||||
if (!callCompletionsChartRef.value) return
|
||||
|
||||
// 获取图表实例
|
||||
let chart = echarts.getInstanceByDom(callCompletionsChartRef.value)
|
||||
if (!chart) {
|
||||
chart = echarts.init(callCompletionsChartRef.value)
|
||||
}
|
||||
|
||||
// 如果没有Busy Hour数据,显示默认的平直线
|
||||
if (!busyHourData.value) {
|
||||
const defaultData = [0, 0, 0, 0, 0] // 5个默认数据点,值为0
|
||||
const xAxisData = [1, 2, 3, 4, 5]
|
||||
|
||||
chart.setOption({
|
||||
grid: { left: 0, right: 30, top: 10, bottom: 10 },
|
||||
xAxis: { type: 'category', show: false, data: xAxisData },
|
||||
yAxis: { type: 'value', show: false },
|
||||
series: [{
|
||||
data: defaultData,
|
||||
type: 'line', symbol: 'none',
|
||||
lineStyle: { width: 2, color: '#d9d9d9' },
|
||||
areaStyle: { color: 'rgba(217,217,217,0.1)' }
|
||||
}]
|
||||
})
|
||||
|
||||
// 清除所有旧标注
|
||||
const chartContainer = callCompletionsChartRef.value
|
||||
if (chartContainer) {
|
||||
const existingLabels = chartContainer.querySelectorAll('.chart-label')
|
||||
existingLabels.forEach(label => label.remove())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 从Busy Hour数据中提取Call Completions数据
|
||||
const chartData = busyHourData.value.map((item: any) => Number(item.callCompletions) || 0)
|
||||
|
||||
// 生成时间轴数据
|
||||
const xAxisData = Array.from({ length: chartData.length }, (_, i) => i + 1)
|
||||
|
||||
// 计算最大值、最小值、最新值
|
||||
const maxValue = Math.max(...chartData)
|
||||
const minValue = Math.min(...chartData)
|
||||
const latestValue = chartData[chartData.length - 1]
|
||||
|
||||
chart.setOption({
|
||||
grid: { left: 0, right: 30, top: 10, bottom: 10 },
|
||||
xAxis: { type: 'category', show: false, data: xAxisData },
|
||||
yAxis: { type: 'value', show: false },
|
||||
series: [{
|
||||
data: chartData,
|
||||
type: 'line', symbol: 'none',
|
||||
lineStyle: { width: 2, color: '#722ed1' }, // 紫色线条
|
||||
areaStyle: { color: 'rgba(114,46,209,0.1)' } // 淡紫色填充
|
||||
}]
|
||||
})
|
||||
|
||||
// 在图表容器中添加数值标注
|
||||
const chartContainer = callCompletionsChartRef.value
|
||||
if (chartContainer) {
|
||||
// 清除之前的标注
|
||||
const existingLabels = chartContainer.querySelectorAll('.chart-label')
|
||||
existingLabels.forEach(label => label.remove())
|
||||
|
||||
// 添加右侧数值标注
|
||||
const maxLabel = document.createElement('div')
|
||||
maxLabel.className = 'chart-label'
|
||||
maxLabel.style.cssText = `
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
top: 8px;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
color: #666;
|
||||
pointer-events: none;
|
||||
z-index: 10;
|
||||
`
|
||||
maxLabel.textContent = maxValue.toString()
|
||||
|
||||
const latestLabel = document.createElement('div')
|
||||
latestLabel.className = 'chart-label'
|
||||
latestLabel.style.cssText = `
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
color: #722ed1;
|
||||
pointer-events: none;
|
||||
z-index: 10;
|
||||
`
|
||||
latestLabel.textContent = latestValue.toString()
|
||||
|
||||
const minLabel = document.createElement('div')
|
||||
minLabel.className = 'chart-label'
|
||||
minLabel.style.cssText = `
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
bottom: 8px;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
color: #666;
|
||||
pointer-events: none;
|
||||
z-index: 10;
|
||||
`
|
||||
minLabel.textContent = minValue.toString()
|
||||
|
||||
// 添加底部时间标注
|
||||
const oldestTimeLabel = document.createElement('div')
|
||||
oldestTimeLabel.className = 'chart-label'
|
||||
oldestTimeLabel.style.cssText = `
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
bottom: -20px;
|
||||
font-size: 11px;
|
||||
color: #999;
|
||||
pointer-events: none;
|
||||
z-index: 10;
|
||||
`
|
||||
// 使用第一个数据点的时间戳计算相对时间
|
||||
const oldestTime = Number(busyHourData.value[0]?.timeGroup) || Date.now()
|
||||
oldestTimeLabel.textContent = calculateRelativeTime(oldestTime)
|
||||
|
||||
const nowTimeLabel = document.createElement('div')
|
||||
nowTimeLabel.className = 'chart-label'
|
||||
nowTimeLabel.style.cssText = `
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
bottom: -20px;
|
||||
font-size: 11px;
|
||||
color: #999;
|
||||
pointer-events: none;
|
||||
z-index: 10;
|
||||
`
|
||||
nowTimeLabel.textContent = t('views.perfManage.voiceOverView.now')
|
||||
|
||||
chartContainer.appendChild(maxLabel)
|
||||
chartContainer.appendChild(latestLabel)
|
||||
chartContainer.appendChild(minLabel)
|
||||
chartContainer.appendChild(oldestTimeLabel)
|
||||
chartContainer.appendChild(nowTimeLabel)
|
||||
}
|
||||
}
|
||||
|
||||
// 处理IMS实时数据(只存储当前选中网元)
|
||||
function handleIMSRealtimeData(res: any) {
|
||||
//console.log('收到实时数据:', res) // 调试信息
|
||||
@@ -1152,6 +1526,18 @@ onMounted(() => {
|
||||
chart.setOption(defaultChartOption)
|
||||
}
|
||||
|
||||
// call attempts
|
||||
if (callAttemptsChartRef.value) {
|
||||
const chart = echarts.init(callAttemptsChartRef.value)
|
||||
chart.setOption(defaultChartOption)
|
||||
}
|
||||
|
||||
// call completions
|
||||
if (callCompletionsChartRef.value) {
|
||||
const chart = echarts.init(callCompletionsChartRef.value)
|
||||
chart.setOption(defaultChartOption)
|
||||
}
|
||||
|
||||
// active registrations
|
||||
if (regChartRef.value) {
|
||||
const chart = echarts.init(regChartRef.value)
|
||||
@@ -1790,8 +2176,103 @@ function calculateFailedRegistrationsChange() {
|
||||
// 计算时间差
|
||||
const timeDiff = calculateTimeDifference(latestData, previousData)
|
||||
|
||||
return `${changeText} ${+t('views.perfManage.voiceOverView.last')} ${timeDiff}`
|
||||
return `${changeText} ${t('views.perfManage.voiceOverView.last')} ${timeDiff}`
|
||||
}
|
||||
|
||||
// Call Attempts相关计算函数
|
||||
function calculateCallAttemptsValue() {
|
||||
if (!busyHourData.value || busyHourData.value.length === 0) return '-'
|
||||
|
||||
// 获取最新的Call Attempts值(数组最后一个元素)
|
||||
const latestData = busyHourData.value[busyHourData.value.length - 1]
|
||||
const callAttempts = Number(latestData.callAttempts) || 0
|
||||
return callAttempts.toString()
|
||||
}
|
||||
|
||||
function calculateCallAttemptsArrowDirection() {
|
||||
if (!busyHourData.value || busyHourData.value.length < 2) return 'up'
|
||||
|
||||
const latestValue = Number(busyHourData.value[busyHourData.value.length - 1].callAttempts) || 0
|
||||
const previousValue = Number(busyHourData.value[busyHourData.value.length - 2].callAttempts) || 0
|
||||
|
||||
const change = latestValue - previousValue
|
||||
if (change > 0) return 'up'
|
||||
if (change < 0) return 'down'
|
||||
return 'up'
|
||||
}
|
||||
|
||||
function calculateCallAttemptsArrow() {
|
||||
if (!busyHourData.value || busyHourData.value.length < 2) return '→'
|
||||
|
||||
const latestValue = Number(busyHourData.value[busyHourData.value.length - 1].callAttempts) || 0
|
||||
const previousValue = Number(busyHourData.value[busyHourData.value.length - 2].callAttempts) || 0
|
||||
|
||||
const change = latestValue - previousValue
|
||||
if (change > 0) return '↗'
|
||||
if (change < 0) return '↘'
|
||||
return '→'
|
||||
}
|
||||
|
||||
function calculateCallAttemptsChange() {
|
||||
if (!busyHourData.value || busyHourData.value.length < 2) return '±0 ' + t('views.perfManage.voiceOverView.last') + ' 1h'
|
||||
|
||||
const latestValue = Number(busyHourData.value[busyHourData.value.length - 1].callAttempts) || 0
|
||||
const previousValue = Number(busyHourData.value[busyHourData.value.length - 2].callAttempts) || 0
|
||||
|
||||
const change = latestValue - previousValue
|
||||
if (change === 0) return '±0 ' + t('views.perfManage.voiceOverView.last') + ' 1h'
|
||||
|
||||
const changeText = change > 0 ? `+${change}` : `${change}`
|
||||
return `${changeText} ` + t('views.perfManage.voiceOverView.last') + ' 1h'
|
||||
}
|
||||
|
||||
// Call Completions相关计算函数
|
||||
function calculateCallCompletionsValue() {
|
||||
if (!busyHourData.value || busyHourData.value.length === 0) return '-'
|
||||
|
||||
// 获取最新的Call Completions值(数组最后一个元素)
|
||||
const latestData = busyHourData.value[busyHourData.value.length - 1]
|
||||
const callCompletions = Number(latestData.callCompletions) || 0
|
||||
return callCompletions.toString()
|
||||
}
|
||||
|
||||
function calculateCallCompletionsArrowDirection() {
|
||||
if (!busyHourData.value || busyHourData.value.length < 2) return 'up'
|
||||
|
||||
const latestValue = Number(busyHourData.value[busyHourData.value.length - 1].callCompletions) || 0
|
||||
const previousValue = Number(busyHourData.value[busyHourData.value.length - 2].callCompletions) || 0
|
||||
|
||||
const change = latestValue - previousValue
|
||||
if (change > 0) return 'up'
|
||||
if (change < 0) return 'down'
|
||||
return 'up'
|
||||
}
|
||||
|
||||
function calculateCallCompletionsArrow() {
|
||||
if (!busyHourData.value || busyHourData.value.length < 2) return '→'
|
||||
|
||||
const latestValue = Number(busyHourData.value[busyHourData.value.length - 1].callCompletions) || 0
|
||||
const previousValue = Number(busyHourData.value[busyHourData.value.length - 2].callCompletions) || 0
|
||||
|
||||
const change = latestValue - previousValue
|
||||
if (change > 0) return '↗'
|
||||
if (change < 0) return '↘'
|
||||
return '→'
|
||||
}
|
||||
|
||||
function calculateCallCompletionsChange() {
|
||||
if (!busyHourData.value || busyHourData.value.length < 2) return '±0 ' + t('views.perfManage.voiceOverView.last') + ' 1h'
|
||||
|
||||
const latestValue = Number(busyHourData.value[busyHourData.value.length - 1].callCompletions) || 0
|
||||
const previousValue = Number(busyHourData.value[busyHourData.value.length - 2].callCompletions) || 0
|
||||
|
||||
const change = latestValue - previousValue
|
||||
if (change === 0) return '±0 ' + t('views.perfManage.voiceOverView.last') + ' 1h'
|
||||
|
||||
const changeText = change > 0 ? `+${change}` : `${change}`
|
||||
return `${changeText} ` + t('views.perfManage.voiceOverView.last') + ' 1h'
|
||||
}
|
||||
|
||||
// 测试数据更新
|
||||
// function testDataUpdate() {
|
||||
// console.log('测试数据更新')
|
||||
@@ -1854,8 +2335,6 @@ function calculateFailedRegistrationsChange() {
|
||||
.trend-chart {
|
||||
flex: 2;
|
||||
height: 60px;
|
||||
min-width: 140px;
|
||||
max-width: 220px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
@@ -1879,6 +2358,7 @@ function calculateFailedRegistrationsChange() {
|
||||
}
|
||||
.metric-info {
|
||||
flex: 1;
|
||||
margin-right: 8px;
|
||||
margin-left: 16px;
|
||||
text-align: right;
|
||||
min-width: 90px;
|
||||
|
||||
Reference in New Issue
Block a user