设备管理
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

277 lines
6.0 KiB

<template>
<div class="device-home">
<header class="device-status-blok">
<div
v-for="(item, idx) in summaryList"
:key="idx"
class="val-blok"
:style="{ backgroundColor: item.color }"
>
<div class="val">
<span>{{ item.label }}</span>
<span class="num">{{ item.value }}</span>
</div>
<Icon :icon="item.icon" :size="48" />
<!-- <img :src="item.icon" alt="" /> -->
</div>
</header>
<main>
<EdfsWrap title="库存数据" class="line">
<template #title-right>
<el-button-group size="small">
<template v-for="{ key, name } in filterData" :key="key">
<EdfsButton
:inner-text="name"
@click="onTimeSearch(key)"
:type="currentFilter === key ? 'success' : ''"
/>
</template>
</el-button-group>
</template>
<LineChart :data="lineChartData" :filterType="currentFilter" />
</EdfsWrap>
<EdfsWrap title="设备数据" class="pie">
<PieChart :data="pieData" />
</EdfsWrap>
</main>
<footer>
<EdfsWrap title="快捷入口" class="shortcut">
<div class="shortcut-list">
<template v-for="(item, idx) in shortcutList" :key="idx">
<div class="item" @click="onShortcutClick(item)">
<el-button :type="item.type as any" circle size="large">
<Icon :icon="item.icon" :size="24" />
</el-button>
<span>{{ item.title }}</span>
</div>
</template>
</div>
</EdfsWrap>
</footer>
</div>
</template>
<script setup lang="ts">
import EdfsWrap from '@/components/dashboard/Edfs-wrap.vue'
import { data } from './components/utils'
import LineChart from './components/line-chart.vue'
import PieChart from './components/pie-chart.vue'
import { Icon } from '@/components/dashboard/Icon/index'
import { useRouter } from 'vue-router'
import {
getDeviceStorageAndMaintainChart,
getDeviceSummary,
getDeviceSummaryByStatus,
} from '@/api/module/eam/device'
import dayjs from 'dayjs'
import { isResError } from '@/hooks/useMessage'
const router = useRouter()
const shortcutList = [
{
title: '设备管理',
icon: 'solar:server-square-linear',
type: 'primary',
path: '/device/data',
},
{
title: '设备库存',
icon: 'solar:box-outline',
type: 'success',
path: '/storage',
},
{
title: '测试计划',
icon: 'codicon:code-oss',
type: 'warning',
path: '/testSheet/plan',
},
]
function onShortcutClick(item: any) {
router.push(item.path)
}
const filterData = [
{
key: 0,
name: '本月',
},
{
key: 1,
name: '本年',
},
]
const summaryList = ref([
// {
// label: '设备总数',
// value: 0,
// icon: 'solar:server-square-linear',
// color: '#1E90FF',
// },
{
label: '积累入库',
value: 0,
icon: 'solar:inbox-in-broken',
key: 'storage',
color: '#4CAF50',
},
{
label: '积累出库',
value: 0,
key: 'outStorage',
icon: 'solar:inbox-out-outline',
color: '#2196F3',
},
{
label: '测试中设备',
value: 0,
icon: 'solar:document-add-outline',
key: 'testing',
color: '#FF9800',
},
{
label: '维修中',
icon: 'solar:minimalistic-magnifer-bug-outline',
value: 0,
key: 'repair',
color: '#F44336',
},
])
const currentFilter = ref(1)
function onTimeSearch(filter: number) {
currentFilter.value = filter
loadLineChartData()
}
const lineChartData = ref<any>([])
async function loadLineChartData() {
// 获取当前月
const curMonth = dayjs().month() + 1
const curYear = dayjs().year()
const res = await getDeviceStorageAndMaintainChart({
type: currentFilter.value,
year: curYear,
month: curMonth,
})
if (isResError(res)) return
lineChartData.value = res.data
}
const pieData = ref<any>([])
async function loadPieChartData() {
const res = await getDeviceSummaryByStatus()
if (isResError(res)) return
pieData.value = res.data.map((item: any) => {
return {
name: item.statusName,
6 months ago
value: item.count,
}
})
}
async function loadDeviceSummary() {
const res = await getDeviceSummary()
if (isResError(res)) return
const data = res.data
summaryList.value.forEach(item => {
item.value = !!data[item.key] ? data[item.key] : 0
})
}
onMounted(() => {
loadDeviceSummary()
loadLineChartData()
loadPieChartData()
})
</script>
<style scoped lang="scss">
.device-home {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
row-gap: 16px;
.device-status-blok {
box-sizing: border-box;
height: 110px;
display: flex;
user-select: none;
justify-content: space-between;
column-gap: 40px;
.val-blok {
display: flex;
font-size: 16px;
box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.2);
border-radius: 4px;
overflow: hidden;
background-color: var(--warp-bg);
height: 100%;
width: 33%;
padding: 0 30px;
align-items: center;
img {
width: 130px;
height: 100%;
}
.val {
display: flex;
justify-content: center;
flex-direction: column;
width: 100%;
row-gap: 6px;
height: 100%;
.num {
font-size: 30px;
font-weight: 600;
padding-right: 24px;
}
}
}
}
main {
flex: 1;
display: flex;
column-gap: 16px;
.line {
flex: 0.58;
}
.pie {
flex: 0.42;
}
}
footer {
height: 140px;
.shortcut-list {
display: flex;
align-items: center;
column-gap: 18px;
}
.item {
display: flex;
flex-direction: column;
align-items: center;
cursor: pointer;
span {
margin-top: 8px;
color: var(--label-color);
}
}
:deep(.wrap-body) {
padding-top: 0;
padding-left: 20px;
}
:deep(.el-button) {
width: 52px;
height: 52px;
}
}
}
</style>