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.
287 lines
6.3 KiB
287 lines
6.3 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' : 'default'" |
|
/> |
|
</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 :color="item.color" circle size="large"> |
|
<Icon :icon="item.icon" :size="36" /> |
|
</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', |
|
color: '#1E90FF', |
|
path: '/device/data', |
|
}, |
|
{ |
|
title: '设备添加', |
|
icon: 'solar:add-circle-linear', |
|
color: '#619925', |
|
path: 'device/deviceOperation?action=create', |
|
}, |
|
{ |
|
title: '设备库存', |
|
icon: 'solar:box-outline', |
|
color: '#909399', |
|
path: '/storage', |
|
}, |
|
{ |
|
title: '测试计划', |
|
icon: 'codicon:code-oss', |
|
color: '#FF9800', |
|
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, |
|
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%; |
|
color: #fff; |
|
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: 180px; |
|
.shortcut-list { |
|
display: flex; |
|
align-items: center; |
|
column-gap: 40px; |
|
} |
|
.item { |
|
display: flex; |
|
flex-direction: column; |
|
align-items: center; |
|
cursor: pointer; |
|
span { |
|
margin-top: 10px; |
|
font-size: 16px; |
|
color: var(--label-color); |
|
} |
|
:deep(.el-icon) { |
|
color: #fff; |
|
} |
|
} |
|
:deep(.wrap-body) { |
|
// padding-top: 0; |
|
padding-left: 20px; |
|
} |
|
:deep(.el-button) { |
|
width: 78px; |
|
height: 78px; |
|
} |
|
} |
|
} |
|
</style>
|
|
|