|
|
@@ -13,6 +13,7 @@ interface Query {
|
|
|
createTime?: [string, string]
|
|
|
pageNo: number
|
|
|
pageSize: number
|
|
|
+ type?: string
|
|
|
}
|
|
|
|
|
|
// 选项配置数组
|
|
|
@@ -58,15 +59,18 @@ interface StatItem {
|
|
|
key: string
|
|
|
title: string
|
|
|
icon: string
|
|
|
+ type: string
|
|
|
class: { bg1: string; bg2: string; text: string }
|
|
|
value: number
|
|
|
- trend: number
|
|
|
+ tb: number
|
|
|
+ hb: number
|
|
|
}
|
|
|
|
|
|
const defaultStats: StatItem[] = [
|
|
|
{
|
|
|
key: 'repair',
|
|
|
- title: '维修成本',
|
|
|
+ title: '内部维修成本',
|
|
|
+ type: '维修',
|
|
|
icon: 'i-material-symbols:home-repair-service-outline',
|
|
|
class: {
|
|
|
bg1: 'bg-[var(--el-color-success-light-7)]',
|
|
|
@@ -74,11 +78,13 @@ const defaultStats: StatItem[] = [
|
|
|
text: 'text-[var(--el-color-success)]'
|
|
|
},
|
|
|
value: 0,
|
|
|
- trend: 0
|
|
|
+ tb: 0,
|
|
|
+ hb: 0
|
|
|
},
|
|
|
{
|
|
|
key: 'byFee',
|
|
|
title: '保养成本',
|
|
|
+ type: '保养',
|
|
|
icon: 'i-material-symbols:construction-rounded',
|
|
|
class: {
|
|
|
bg1: 'bg-[var(--el-color-primary-light-7)]',
|
|
|
@@ -86,11 +92,13 @@ const defaultStats: StatItem[] = [
|
|
|
text: 'text-[var(--el-color-primary)]'
|
|
|
},
|
|
|
value: 0,
|
|
|
- trend: 0
|
|
|
+ tb: 0,
|
|
|
+ hb: 0
|
|
|
},
|
|
|
{
|
|
|
key: 'out',
|
|
|
title: '委外维修',
|
|
|
+ type: '委外维修',
|
|
|
icon: 'i-material-symbols:work-outline',
|
|
|
class: {
|
|
|
bg1: 'bg-[var(--el-color-warning-light-7)]',
|
|
|
@@ -98,7 +106,8 @@ const defaultStats: StatItem[] = [
|
|
|
text: 'text-[var(--el-color-warning)]'
|
|
|
},
|
|
|
value: 0,
|
|
|
- trend: 0
|
|
|
+ tb: 0,
|
|
|
+ hb: 0
|
|
|
}
|
|
|
]
|
|
|
|
|
|
@@ -108,12 +117,23 @@ const dataLoading = ref(false)
|
|
|
const loadData = useDebounceFn(async function () {
|
|
|
dataLoading.value = true
|
|
|
try {
|
|
|
- const { pageNo, pageSize, ...other } = query.value
|
|
|
- const res = await IotReportApi.getCostsFee(other)
|
|
|
- statList.value.forEach((item) => {
|
|
|
- item.value = res[item.key] || 0
|
|
|
- item.trend = res[`${item.key}Trend`] || 0
|
|
|
- })
|
|
|
+ const { pageNo, pageSize, type, ...other } = query.value
|
|
|
+ const res = await IotReportApi.getCostsFee({ ...other, timeType: activeTimeType.value })
|
|
|
+ const repair = statList.value[0]!
|
|
|
+ const out = statList.value[2]!
|
|
|
+ const byFee = statList.value[1]!
|
|
|
+
|
|
|
+ out.value = res[out.key].total || 0
|
|
|
+ out.tb = Number(((res[out.key].tb || 0) * 100).toFixed(0))
|
|
|
+ out.hb = Number(((res[out.key].hb || 0) * 100).toFixed(0))
|
|
|
+
|
|
|
+ repair.value = (res[repair.key].total ?? 0) - out.value
|
|
|
+ repair.tb = Number(((res[repair.key].tb || 0) * 100).toFixed(0))
|
|
|
+ repair.hb = Number(((res[repair.key].hb || 0) * 100).toFixed(0))
|
|
|
+
|
|
|
+ byFee.value = res[byFee.key].total || 0
|
|
|
+ byFee.tb = Number(((res[byFee.key].tb || 0) * 100).toFixed(0))
|
|
|
+ byFee.hb = Number(((res[byFee.key].hb || 0) * 100).toFixed(0))
|
|
|
} catch (error) {
|
|
|
console.log('error :>> ', error)
|
|
|
} finally {
|
|
|
@@ -170,11 +190,17 @@ watch(
|
|
|
},
|
|
|
{ immediate: true }
|
|
|
)
|
|
|
+
|
|
|
+function selectType(type: string) {
|
|
|
+ query.value.type = type
|
|
|
+ query.value.pageNo = 1
|
|
|
+ loadList()
|
|
|
+}
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
<div
|
|
|
- class="grid grid-cols-[15%_1fr] grid-rows-[196px_1fr] gap-4 h-[calc(100vh-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))]"
|
|
|
+ class="grid grid-cols-[15%_1fr] grid-rows-[196px_1fr] gap-4 h-[calc(100vh-20px-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))]"
|
|
|
>
|
|
|
<div class="p-4 bg-white dark:bg-[#1d1e1f] shadow rounded-lg row-span-2">
|
|
|
<DeptTreeSelect
|
|
|
@@ -191,8 +217,9 @@ watch(
|
|
|
<section
|
|
|
v-for="item in statList"
|
|
|
:key="item.key"
|
|
|
- class="flex flex-col items-center gap-y-4 rounded-lg shadow p-4"
|
|
|
- :class="item.class.bg1"
|
|
|
+ class="flex flex-col items-center gap-y-4 rounded-lg shadow p-4 transition-transform hover:scale-105 duration-500"
|
|
|
+ :class="{ [item.class.bg1]: true, 'scale-105': item.type === query.type }"
|
|
|
+ @click="selectType(item.type)"
|
|
|
>
|
|
|
<!-- 头部:图标 + 标题 -->
|
|
|
<div class="flex items-center gap-x-3">
|
|
|
@@ -210,6 +237,8 @@ watch(
|
|
|
:start-val="0"
|
|
|
:end-val="item.value"
|
|
|
:decimals="2"
|
|
|
+ suffix="元"
|
|
|
+ :duration="1000"
|
|
|
>
|
|
|
<!-- 插槽内容:当数据为空或0时的显示 (根据 count-to 组件的具体实现决定是否显示) -->
|
|
|
<span class="text-xs leading-8 text-[var(--el-text-color-regular)]">暂无数据</span>
|
|
|
@@ -217,20 +246,41 @@ watch(
|
|
|
|
|
|
<!-- 底部:环比数据 -->
|
|
|
<!-- 根据 trend 正负动态改变图标和颜色 -->
|
|
|
- <div class="mt-2 flex items-center gap-x-1 text-xs font-medium" :class="item.class.text">
|
|
|
- <!-- 动态图标:大于等于0向上,小于0向下 -->
|
|
|
+ <div class="mt-2 flex items-center gap-x-4">
|
|
|
<div
|
|
|
- :class="
|
|
|
- item.trend >= 0
|
|
|
- ? 'i-material-symbols:arrow-warm-up-rounded'
|
|
|
- : 'i-material-symbols:arrow-cool-down-rounded'
|
|
|
- "
|
|
|
- ></div>
|
|
|
-
|
|
|
- <span class="vertical-middle">
|
|
|
- {{ item.trend > 0 ? '+' + item.trend : item.trend }}
|
|
|
- </span>
|
|
|
- <span>环比</span>
|
|
|
+ v-show="item.hb"
|
|
|
+ class="flex items-center gap-x-1 text-xs font-medium"
|
|
|
+ :class="item.class.text"
|
|
|
+ >
|
|
|
+ <!-- 动态图标:大于等于0向上,小于0向下 -->
|
|
|
+ <div
|
|
|
+ :class="
|
|
|
+ item.hb >= 0
|
|
|
+ ? 'i-material-symbols:arrow-warm-up-rounded'
|
|
|
+ : 'i-material-symbols:arrow-cool-down-rounded'
|
|
|
+ "
|
|
|
+ ></div>
|
|
|
+
|
|
|
+ <span class="vertical-middle"> {{ item.hb > 0 ? '+' + item.hb : item.hb }}% </span>
|
|
|
+ <span>环比</span>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ v-show="item.tb"
|
|
|
+ class="flex items-center gap-x-1 text-xs font-medium"
|
|
|
+ :class="item.class.text"
|
|
|
+ >
|
|
|
+ <!-- 动态图标:大于等于0向上,小于0向下 -->
|
|
|
+ <div
|
|
|
+ :class="
|
|
|
+ item.tb >= 0
|
|
|
+ ? 'i-material-symbols:arrow-warm-up-rounded'
|
|
|
+ : 'i-material-symbols:arrow-cool-down-rounded'
|
|
|
+ "
|
|
|
+ ></div>
|
|
|
+
|
|
|
+ <span class="vertical-middle"> {{ item.tb > 0 ? '+' + item.tb : item.tb }}% </span>
|
|
|
+ <span>同比</span>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</section>
|
|
|
</div>
|
|
|
@@ -265,7 +315,12 @@ watch(
|
|
|
<el-table-column label="类别" prop="type" align="center" />
|
|
|
<el-table-column label="设备编号" prop="deviceCode" align="center" />
|
|
|
<el-table-column label="设备名称" prop="deviceName" align="center" />
|
|
|
- <el-table-column label="成本" prop="cost" align="center" />
|
|
|
+ <el-table-column
|
|
|
+ label="成本"
|
|
|
+ prop="cost"
|
|
|
+ align="center"
|
|
|
+ :formatter="(row) => (row.cost ?? 0) + '元'"
|
|
|
+ />
|
|
|
</el-table>
|
|
|
</template>
|
|
|
</el-auto-resizer>
|