|
@@ -8,19 +8,29 @@ import {
|
|
|
createTooltip,
|
|
createTooltip,
|
|
|
FONT_FAMILY,
|
|
FONT_FAMILY,
|
|
|
formatDateLabel,
|
|
formatDateLabel,
|
|
|
|
|
+ formatMonthLabel,
|
|
|
THEME
|
|
THEME
|
|
|
} from '@/utils/kb'
|
|
} from '@/utils/kb'
|
|
|
import { IotStatApi } from '@/api/pms/stat'
|
|
import { IotStatApi } from '@/api/pms/stat'
|
|
|
|
|
|
|
|
|
|
+type RateRange = 'week' | 'sixMonth'
|
|
|
|
|
+
|
|
|
const chartData = ref<ChartData>({
|
|
const chartData = ref<ChartData>({
|
|
|
xAxis: [],
|
|
xAxis: [],
|
|
|
series: []
|
|
series: []
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
const chartRef = ref<HTMLDivElement>()
|
|
const chartRef = ref<HTMLDivElement>()
|
|
|
|
|
+const activeRange = ref<RateRange>('week')
|
|
|
|
|
+const loading = ref(false)
|
|
|
|
|
+const rangeOptions: Array<{ label: string; value: RateRange }> = [
|
|
|
|
|
+ { label: '近一周', value: 'week' },
|
|
|
|
|
+ { label: '近六个月', value: 'sixMonth' }
|
|
|
|
|
+]
|
|
|
let chart: echarts.ECharts | null = null
|
|
let chart: echarts.ECharts | null = null
|
|
|
const router = useRouter()
|
|
const router = useRouter()
|
|
|
let chartClickBound = false
|
|
let chartClickBound = false
|
|
|
|
|
+let loadRequestId = 0
|
|
|
|
|
|
|
|
function formatRate(value: number) {
|
|
function formatRate(value: number) {
|
|
|
return `${Number(value || 0).toFixed(2)}%`
|
|
return `${Number(value || 0).toFixed(2)}%`
|
|
@@ -57,7 +67,7 @@ function getChartOption(data: ChartData): echarts.EChartsOption {
|
|
|
fontWeight: 500,
|
|
fontWeight: 500,
|
|
|
fontFamily: FONT_FAMILY,
|
|
fontFamily: FONT_FAMILY,
|
|
|
formatter(value: string) {
|
|
formatter(value: string) {
|
|
|
- return formatDateLabel(value)
|
|
|
|
|
|
|
+ return activeRange.value === 'sixMonth' ? formatMonthLabel(value) : formatDateLabel(value)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
@@ -152,9 +162,10 @@ function getChartDayRange() {
|
|
|
const endDate = dayjs(xAxis[xAxis.length - 1])
|
|
const endDate = dayjs(xAxis[xAxis.length - 1])
|
|
|
if (!startDate.isValid() || !endDate.isValid()) return null
|
|
if (!startDate.isValid() || !endDate.isValid()) return null
|
|
|
|
|
|
|
|
|
|
+ const rangeUnit = activeRange.value === 'sixMonth' ? 'month' : 'day'
|
|
|
return [
|
|
return [
|
|
|
- startDate.startOf('day').format('YYYY-MM-DD HH:mm:ss'),
|
|
|
|
|
- endDate.endOf('day').format('YYYY-MM-DD HH:mm:ss')
|
|
|
|
|
|
|
+ startDate.startOf(rangeUnit).format('YYYY-MM-DD HH:mm:ss'),
|
|
|
|
|
+ endDate.endOf(rangeUnit).format('YYYY-MM-DD HH:mm:ss')
|
|
|
]
|
|
]
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -191,9 +202,16 @@ function destroyChart() {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-async function loadChart() {
|
|
|
|
|
|
|
+async function loadChart(range: RateRange = activeRange.value) {
|
|
|
|
|
+ const requestId = ++loadRequestId
|
|
|
|
|
+ loading.value = true
|
|
|
try {
|
|
try {
|
|
|
- const res = await IotStatApi.getRhSevenDayUtilization()
|
|
|
|
|
|
|
+ const res =
|
|
|
|
|
+ range === 'sixMonth'
|
|
|
|
|
+ ? await IotStatApi.getRhSixMonthUtilization()
|
|
|
|
|
+ : await IotStatApi.getRhSevenDayUtilization()
|
|
|
|
|
+ if (requestId !== loadRequestId) return
|
|
|
|
|
+
|
|
|
chartData.value = {
|
|
chartData.value = {
|
|
|
xAxis: res.xAxis || [],
|
|
xAxis: res.xAxis || [],
|
|
|
series: (res.series || []).map((item) => ({
|
|
series: (res.series || []).map((item) => ({
|
|
@@ -203,15 +221,24 @@ async function loadChart() {
|
|
|
}
|
|
}
|
|
|
renderChart()
|
|
renderChart()
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
|
|
+ if (requestId !== loadRequestId) return
|
|
|
console.error('获取设备利用率失败:', error)
|
|
console.error('获取设备利用率失败:', error)
|
|
|
chartData.value = {
|
|
chartData.value = {
|
|
|
xAxis: [],
|
|
xAxis: [],
|
|
|
series: []
|
|
series: []
|
|
|
}
|
|
}
|
|
|
renderChart()
|
|
renderChart()
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ if (requestId === loadRequestId) {
|
|
|
|
|
+ loading.value = false
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+watch(activeRange, (range) => {
|
|
|
|
|
+ loadChart(range)
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
|
initChart()
|
|
initChart()
|
|
|
loadChart()
|
|
loadChart()
|
|
@@ -228,17 +255,50 @@ onUnmounted(() => {
|
|
|
|
|
|
|
|
<template>
|
|
<template>
|
|
|
<div class="panel flex flex-col">
|
|
<div class="panel flex flex-col">
|
|
|
- <div class="panel-title">
|
|
|
|
|
- <div class="icon-decorator">
|
|
|
|
|
- <span></span>
|
|
|
|
|
- <span></span>
|
|
|
|
|
|
|
+ <div class="panel-title flex items-center justify-between">
|
|
|
|
|
+ <div class="kb-panel-title-text flex items-center">
|
|
|
|
|
+ <div class="icon-decorator">
|
|
|
|
|
+ <span></span>
|
|
|
|
|
+ <span></span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ 设备利用率
|
|
|
</div>
|
|
</div>
|
|
|
- 设备利用率
|
|
|
|
|
|
|
+ <el-segmented
|
|
|
|
|
+ v-model="activeRange"
|
|
|
|
|
+ :options="rangeOptions"
|
|
|
|
|
+ size="small"
|
|
|
|
|
+ class="rate-range-switch" />
|
|
|
</div>
|
|
</div>
|
|
|
- <div ref="chartRef" class="flex-1 min-h-0"></div>
|
|
|
|
|
|
|
+ <div ref="chartRef" v-loading="loading" class="rate-chart flex-1 min-h-0"></div>
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|
|
|
@import url('@/styles/kb.scss');
|
|
@import url('@/styles/kb.scss');
|
|
|
|
|
+
|
|
|
|
|
+.rate-range-switch {
|
|
|
|
|
+ --el-segmented-item-selected-color: #03409b;
|
|
|
|
|
+ --el-segmented-item-selected-bg-color: rgb(255 255 255 / 86%);
|
|
|
|
|
+ --el-segmented-bg-color: rgb(31 91 184 / 10%);
|
|
|
|
|
+ --el-segmented-item-hover-bg-color: rgb(255 255 255 / 56%);
|
|
|
|
|
+
|
|
|
|
|
+ min-height: calc(26px * var(--kb-scale, 1));
|
|
|
|
|
+ padding: calc(2px * var(--kb-scale, 1));
|
|
|
|
|
+ border: 1px solid rgb(31 91 184 / 12%);
|
|
|
|
|
+ transform: translateY(calc(-2px * var(--kb-scale, 1)));
|
|
|
|
|
+
|
|
|
|
|
+ :deep(.el-segmented__item) {
|
|
|
|
|
+ min-height: calc(22px * var(--kb-scale, 1));
|
|
|
|
|
+ padding: 0 calc(7px * var(--kb-scale, 1));
|
|
|
|
|
+ font-size: calc(13px * var(--kb-scale, 1));
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ color: #29527f;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.rate-chart {
|
|
|
|
|
+ :deep(.el-loading-mask) {
|
|
|
|
|
+ background-color: rgb(221 233 251 / 42%);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
</style>
|
|
</style>
|