Browse Source

首页设备数量

master
xuhuajiao 1 month ago
parent
commit
44c97fc24a
  1. 425
      src/views/dashboard/PanelGroup-old.vue
  2. 175
      src/views/dashboard/PanelGroup.vue
  3. 57
      src/views/home.vue

425
src/views/dashboard/PanelGroup-old.vue

@ -0,0 +1,425 @@
<template>
<el-row :gutter="20" class="panel-group" type="flex" justify="space-between">
<el-col class="card-panel-col">
<div class="card-panel danganzongliang" @click="handleSetLineChartData('archives')">
<div class="card-panel-icon-wrapper icon-people">
<svg-icon icon-class="danganzongliang" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
<count-to :start-val="0" :end-val="archivesNum" :duration="3200" class="card-panel-num" />
</div>
档案总量
</div>
</div>
</el-col>
<el-col class="card-panel-col">
<div class="card-panel danganhezongliang" @click="handleSetLineChartData('case')">
<div class="card-panel-icon-wrapper icon-message">
<svg-icon icon-class="danganhezongliang" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
<count-to :start-val="0" :end-val="caseNum" :duration="3200" class="card-panel-num" />
</div>
档案盒总量
</div>
</div>
</el-col>
<el-col class="card-panel-col">
<div class="card-panel quanbushebei" @click="handleSetLineChartData('device')">
<div class="card-panel-icon-wrapper icon-money">
<svg-icon icon-class="quanbushebei" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
<count-to v-if="getDeviceFlag" :start-val="0" :end-val="totalDeviceNum" :duration="3200" class="card-panel-num" />
<div v-if="!getDeviceFlag" class="card-panel-text"><span class="card-panel-num">获取中...</span></div>
</div>
全部设备
</div>
</div>
</el-col>
<el-col class="card-panel-col">
<!-- @click="handleSetLineChartData('device')" -->
<div class="card-panel zaixianshebei" @click="getDeviceDetail('on')">
<div class="card-panel-icon-wrapper icon-shopping">
<svg-icon icon-class="zaixianshebei" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
<count-to v-if="getDeviceFlag" :start-val="0" :end-val="onlineDeviceNum" :duration="3200" class="card-panel-num" />
<div v-if="!getDeviceFlag" class="card-panel-text"><span class="card-panel-num">获取中...</span></div>
</div>
在线设备
</div>
</div>
</el-col>
<el-col class="card-panel-col">
<!-- @click="handleSetLineChartData('device')" -->
<div class="card-panel lixianshebei" @click="getDeviceDetail('off')">
<div class="card-panel-icon-wrapper icon-shopping">
<svg-icon icon-class="lixianshebei" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
<count-to v-if="getDeviceFlag" :start-val="0" :end-val="offlineDeviceNum" :duration="3200" class="card-panel-num" />
<div v-if="!getDeviceFlag" class="card-panel-text"><span class="card-panel-num">获取中...</span></div>
</div>
离线设备
</div>
</div>
</el-col>
<el-dialog :title="deviveTitle" :visible.sync="deviceVisible">
<span class="dialog-right-top" />
<span class="dialog-left-bottom" />
<div class="setting-dialog">
<el-table v-loading="tableLoading" :data="tableDeviceData" style="width: 100%" height="520px">
<el-table-column type="index" label="序号" align="center" width="60" />
<el-table-column align="center" prop="supplierId.name" label="品牌" width="100" show-overflow-tooltip />
<el-table-column prop="deviceName" label="设备名称" min-width="200" show-overflow-tooltip />
<el-table-column label="设备ID" min-width="140" show-overflow-tooltip>
<template slot-scope="scope">
<span v-if="scope.row.deviceId"> {{ scope.row.deviceId }} </span>
<span v-else></span>
</template>
</el-table-column>
<el-table-column align="center" label="接口IP" width="120" show-overflow-tooltip>
<template slot-scope="scope">
<span v-if="scope.row.deviceIp"> {{ scope.row.deviceIp }} </span>
<span v-else></span>
</template>
</el-table-column>
<el-table-column align="center" label="端口" min-width="90">
<template slot-scope="scope">
<span v-if="scope.row.devicePort"> {{ scope.row.devicePort }} </span>
<span v-else></span>
</template>
</el-table-column>
<el-table-column v-if="deviceType==='off'" align="center" label="状态" min-width="120">
<template slot-scope="scope">
<span v-if="scope.row.deviceId !== 'PDA001'">设备连接超时</span>
<span v-else>设备常离线</span>
</template>
</el-table-column>
<el-table-column v-if="deviceType==='off'" label="解决办法或说明" min-width="300">
<template slot-scope="scope">
<span v-if="scope.row.deviceId !== 'PDA001'">
1.请检查网络是否连通<br>
2.请检查设备是否正常开启<br>
3.以上2种情况都不存在请重启设备</span>
<span v-else>该设备采用离线工作模式无需检测</span>
</template>
</el-table-column>
</el-table>
</div>
</el-dialog>
</el-row>
</template>
<script>
import CountTo from 'vue-count-to'
import { FetchGetArchivesNum, FetchGetCaseNum } from '@/api/archivesManage/statistics'
import { getDeviceList } from '@/api/storeManage/deviceManage/device'
import { getOnlineDevice, getDeviceOnoff } from '@/api/home/device'
import { mapGetters } from 'vuex'
export default {
components: {
CountTo
},
data() {
return {
archivesNum: 0,
caseNum: 0,
getDeviceFlag: false,
totalDeviceNum: 0,
onlineDeviceNum: 0,
offlineDeviceNum: 0,
onlineDevice: [],
offDevice: [],
deviveTitle: '在线设备',
deviceVisible: false,
tableLoading: false,
tableDeviceData: [],
deviceType: 'on'
}
},
computed: {
...mapGetters([
'roles'
])
},
mounted() {
this.handleArchivesNum()
this.handleCaseNum()
this.getDevice()
// this.handleTotalDeviceNum()
},
methods: {
handleSetLineChartData(type) {
// this.$emit('handleSetLineChartData', type)
if (type === 'archives') {
if (this.roles.includes('archivesList:list') || this.roles.includes('admin')) {
this.$router.push({
name: 'ArchivesList'
})
} else {
this.$message({
message: '当前账号没有权限',
type: 'warning'
})
}
} else if (type === 'case') {
if (this.roles.includes('caseManage:list') || this.roles.includes('admin')) {
this.$router.push({
name: 'caseManage'
})
} else {
this.$message({
message: '当前账号没有权限',
type: 'warning'
})
}
} else if (type === 'device') {
if (this.roles.includes('deviceManage:list') || this.roles.includes('admin')) {
this.$router.push({
name: 'DeviceManage'
})
} else {
this.$message({
message: '当前账号没有权限',
type: 'warning'
})
}
}
},
getDevice() {
getDeviceOnoff().then(data => {
this.getDeviceFlag = true
this.totalDeviceNum = data.deviceall.length
this.onlineDeviceNum = data.online.length
this.offlineDeviceNum = data.offline.length
this.onlineDevice = data.online
this.offDevice = data.offline
})
},
getDeviceDetail(type) {
this.deviceType = type
this.deviceVisible = true
this.tableDeviceData = []
if (type === 'on') {
this.deviveTitle = '在线设备'
this.tableDeviceData = this.onlineDevice
} else {
this.deviveTitle = '离线设备'
this.tableDeviceData = this.offDevice
}
},
//
handleArchivesNum() {
FetchGetArchivesNum().then(data => {
this.archivesNum = data
})
},
//
handleCaseNum() {
FetchGetCaseNum().then(data => {
this.caseNum = data
})
},
// ,线,线
handleTotalDeviceNum() {
Promise.all([getDeviceList({ page: 0, size: 10 }), getOnlineDevice()]).then((result) => {
this.getDeviceFlag = true
this.totalDeviceNum = result[0].totalElements
this.onlineDeviceNum = result[1]
this.offlineDeviceNum = this.totalDeviceNum - this.onlineDeviceNum
})
}
}
}
</script>
<style lang="scss" scoped>
.panel-group {
.card-panel-col {
margin-bottom: 20px;
}
.card-panel {
cursor: pointer;
height: 100px;
// height: 108px;
// cursor: pointer;
font-size: 15px;
position: relative;
overflow: hidden;
opacity: 0.86;
// box-shadow: 4px 4px 40px rgba(0, 0, 0, .05);
// border-color: rgba(0, 0, 0, .05);
&.danganzongliang {
color: #21aae1;
background: linear-gradient(
180deg,
rgba(51, 159, 210, 0.5) 0%,
rgba(56, 158, 225, 0) 100%
);
border-top: 2px #21aae1 solid;
& span.card-panel-num {
background: linear-gradient(180deg, #ffffff 0%, #21aae1 100%);
}
}
&.danganhezongliang {
color: #793cba;
background: linear-gradient(
180deg,
rgba(121, 60, 186, 0.5) 0%,
rgba(121, 60, 186, 0) 100%
);
border-top: 2px #793cba solid;
& span.card-panel-num {
background: linear-gradient(180deg, #ffffff 0%, #793cba 100%);
}
}
&.quanbushebei {
color: #008e81;
background: linear-gradient(
180deg,
rgba(0, 142, 129, 0.5) 0%,
rgba(0, 142, 129, 0) 100%
);
border-top: 2px #008e81 solid;
& span.card-panel-num {
background: linear-gradient(180deg, #ffffff 0%, #008e81 100%);
}
}
&.zaixianshebei {
color: #c4c859;
background: linear-gradient(
180deg,
rgba(196, 200, 89, 0.5) 0%,
rgba(196, 200, 89, 0) 100%
);
border-top: 2px #c4c859 solid;
& span.card-panel-num {
background: linear-gradient(180deg, #ffffff 0%, #bfc458 100%);
}
}
&.lixianshebei {
color: #f65164;
background: linear-gradient(
180deg,
rgba(246, 81, 100, 0.5) 0%,
rgba(247, 80, 100, 0) 100%
);
border-top: 2px #f65164 solid;
& span.card-panel-num {
background: linear-gradient(180deg, #ffffff 0%, #f55164 100%);
}
}
// &:hover {
// .card-panel-icon-wrapper {
// color: #fff;
// }
// .icon-people {
// background: #40c9c6;
// }
// .icon-message {
// background: #36a3f7;
// }
// .icon-money {
// background: #f4516c;
// }
// .icon-shopping {
// background: #34bfa3
// }
// }
// .icon-danganzongliang {
// color: #21AAE1;
// }
// .icon-danganhezongliang {
// color: #793CBA;
// }
// .icon-quanbushebei {
// color: #008E81;
// }
// .icon-zaixianshebei {
// color: #C4C859
// }
// .icon-lixianshebei {
// color: #F65164
// }
.card-panel-icon-wrapper {
float: left;
margin: 0 10px 0 12px;
padding: 20px;
transition: all 0.38s ease-out;
border-radius: 6px;
}
.card-panel-icon {
float: left;
font-size: 60px;
}
.card-panel-description {
// float: right;
// font-weight: bold;
margin: 19px;
margin-left: 0px;
.card-panel-text {
line-height: 30px;
color: rgba(0, 0, 0, 0.45);
font-size: 28px;
margin-bottom: 11px;
& span {
// background: linear-gradient(180deg, #FFFFFF 0%, #21AAE1 100%);
-webkit-background-clip: text;
color: transparent;
font-weight: bold;
}
}
// .card-panel-num {
// font-size: 20px;
// }
}
}
}
@media (max-width: 550px) {
.card-panel-description {
display: none;
}
.card-panel-icon-wrapper {
float: none !important;
width: 100%;
height: 100%;
margin: 0 !important;
.svg-icon {
display: block;
margin: 14px auto !important;
float: none !important;
}
}
}
::v-deep .el-dialog {
width: 950px;
}
</style>

175
src/views/dashboard/PanelGroup.vue

@ -41,7 +41,6 @@
</div>
</el-col>
<el-col class="card-panel-col">
<!-- @click="handleSetLineChartData('device')" -->
<div class="card-panel zaixianshebei" @click="getDeviceDetail('on')">
<div class="card-panel-icon-wrapper icon-shopping">
<svg-icon icon-class="zaixianshebei" class-name="card-panel-icon" />
@ -56,7 +55,6 @@
</div>
</el-col>
<el-col class="card-panel-col">
<!-- @click="handleSetLineChartData('device')" -->
<div class="card-panel lixianshebei" @click="getDeviceDetail('off')">
<div class="card-panel-icon-wrapper icon-shopping">
<svg-icon icon-class="lixianshebei" class-name="card-panel-icon" />
@ -78,7 +76,13 @@
<el-table v-loading="tableLoading" :data="tableDeviceData" style="width: 100%" height="520px">
<el-table-column type="index" label="序号" align="center" width="60" />
<el-table-column align="center" prop="supplierId.name" label="品牌" width="100" show-overflow-tooltip />
<el-table-column prop="deviceName" label="设备名称" min-width="200" show-overflow-tooltip />
<el-table-column prop="deviceName" label="设备名称" min-width="200" show-overflow-tooltip>
<template slot-scope="scope">
<span v-if="scope.row.deviceName"> {{ scope.row.deviceName }} </span>
<span v-else-if="scope.row.Name"> {{ scope.row.Name }} </span>
<span v-else></span>
</template>
</el-table-column>
<el-table-column label="设备ID" min-width="140" show-overflow-tooltip>
<template slot-scope="scope">
<span v-if="scope.row.deviceId"> {{ scope.row.deviceId }} </span>
@ -88,6 +92,7 @@
<el-table-column align="center" label="接口IP" width="120" show-overflow-tooltip>
<template slot-scope="scope">
<span v-if="scope.row.deviceIp"> {{ scope.row.deviceIp }} </span>
<span v-else-if="scope.row.IP"> {{ scope.row.IP }} </span>
<span v-else></span>
</template>
</el-table-column>
@ -121,14 +126,20 @@
<script>
import CountTo from 'vue-count-to'
import { FetchGetArchivesNum, FetchGetCaseNum } from '@/api/archivesManage/statistics'
import { getDeviceList } from '@/api/storeManage/deviceManage/device'
import { getOnlineDevice, getDeviceOnoff } from '@/api/home/device'
import { getDeviceOnoff } from '@/api/home/device'
import { mapGetters } from 'vuex'
export default {
components: {
CountTo
},
//
props: {
deviceList: {
type: Array,
default: () => []
}
},
data() {
return {
archivesNum: 0,
@ -137,8 +148,8 @@ export default {
totalDeviceNum: 0,
onlineDeviceNum: 0,
offlineDeviceNum: 0,
onlineDevice: [],
offDevice: [],
onlineDevice: [], // 线
offDevice: [], // 线
deviveTitle: '在线设备',
deviceVisible: false,
tableLoading: false,
@ -151,15 +162,22 @@ export default {
'roles'
])
},
//
watch: {
deviceList: {
handler() {
this.mergeDeviceData()
},
immediate: true //
}
},
mounted() {
this.handleArchivesNum()
this.handleCaseNum()
this.getDevice()
// this.handleTotalDeviceNum()
this.getDevice() //
},
methods: {
handleSetLineChartData(type) {
// this.$emit('handleSetLineChartData', type)
if (type === 'archives') {
if (this.roles.includes('archivesList:list') || this.roles.includes('admin')) {
this.$router.push({
@ -195,16 +213,82 @@ export default {
}
}
},
/**
* 保留原有接口请求获取设备状态数据
*/
getDevice() {
getDeviceOnoff().then(data => {
//
this.$set(this, 'onlineDevice', data.online || [])
this.$set(this, 'offDevice', data.offline || [])
//
this.getDeviceFlag = true
//
this.mergeDeviceData()
}).catch(error => {
console.error('获取设备状态失败:', error)
this.getDeviceFlag = true
this.totalDeviceNum = data.deviceall.length
this.onlineDeviceNum = data.online.length
this.offlineDeviceNum = data.offline.length
this.onlineDevice = data.online
this.offDevice = data.offline
this.mergeDeviceData() // 使
})
},
/**
* 核心合并接口数据和父组件deviceList数据
*/
mergeDeviceData() {
// 1. deviceListIP
const validParentDevices = this.deviceList.filter(item => {
const ip = (item.IP || '').trim()
return !!ip
})
// 2. 线/线NetStatus:1=线0=线
const parentOnline = validParentDevices.filter(item => item.NetStatus === 1)
const parentOffline = validParentDevices.filter(item => item.NetStatus === 0)
// 3.
// IP/ID
const apiOnlineKeys = new Set(this.onlineDevice.map(item => item.deviceIp || item.IP || item.deviceId))
const apiOfflineKeys = new Set(this.offDevice.map(item => item.deviceIp || item.IP || item.deviceId))
// 线
const newParentOnline = parentOnline.filter(item => {
const key = item.IP || item.deviceId
return !apiOnlineKeys.has(key)
})
// 线
const newParentOffline = parentOffline.filter(item => {
const key = item.IP || item.deviceId
return !apiOfflineKeys.has(key)
})
// 4.
const finalOnline = [...this.onlineDevice, ...newParentOnline]
const finalOffline = [...this.offDevice, ...newParentOffline]
// 5.
this.totalDeviceNum = finalOnline.length + finalOffline.length
this.onlineDeviceNum = finalOnline.length
this.offlineDeviceNum = finalOffline.length
// 6.
this.onlineDevice = finalOnline
this.offDevice = finalOffline
console.log('设备数据合并完成:', {
接口在线数: this.onlineDevice.length - newParentOnline.length,
父组件新增在线数: newParentOnline.length,
最终在线数: this.onlineDeviceNum,
接口离线数: this.offDevice.length - newParentOffline.length,
父组件新增离线数: newParentOffline.length,
最终离线数: this.offlineDeviceNum,
总设备数: this.totalDeviceNum
})
},
/**
* 查看设备详情
* @param {String} type on=在线 off=离线
*/
getDeviceDetail(type) {
this.deviceType = type
this.deviceVisible = true
@ -228,15 +312,6 @@ export default {
FetchGetCaseNum().then(data => {
this.caseNum = data
})
},
// ,线,线
handleTotalDeviceNum() {
Promise.all([getDeviceList({ page: 0, size: 10 }), getOnlineDevice()]).then((result) => {
this.getDeviceFlag = true
this.totalDeviceNum = result[0].totalElements
this.onlineDeviceNum = result[1]
this.offlineDeviceNum = this.totalDeviceNum - this.onlineDeviceNum
})
}
}
}
@ -251,14 +326,10 @@ export default {
.card-panel {
cursor: pointer;
height: 100px;
// height: 108px;
// cursor: pointer;
font-size: 15px;
position: relative;
overflow: hidden;
opacity: 0.86;
// box-shadow: 4px 4px 40px rgba(0, 0, 0, .05);
// border-color: rgba(0, 0, 0, .05);
&.danganzongliang {
color: #21aae1;
background: linear-gradient(
@ -319,47 +390,6 @@ export default {
background: linear-gradient(180deg, #ffffff 0%, #f55164 100%);
}
}
// &:hover {
// .card-panel-icon-wrapper {
// color: #fff;
// }
// .icon-people {
// background: #40c9c6;
// }
// .icon-message {
// background: #36a3f7;
// }
// .icon-money {
// background: #f4516c;
// }
// .icon-shopping {
// background: #34bfa3
// }
// }
// .icon-danganzongliang {
// color: #21AAE1;
// }
// .icon-danganhezongliang {
// color: #793CBA;
// }
// .icon-quanbushebei {
// color: #008E81;
// }
// .icon-zaixianshebei {
// color: #C4C859
// }
// .icon-lixianshebei {
// color: #F65164
// }
.card-panel-icon-wrapper {
float: left;
@ -375,8 +405,6 @@ export default {
}
.card-panel-description {
// float: right;
// font-weight: bold;
margin: 19px;
margin-left: 0px;
@ -386,16 +414,11 @@ export default {
font-size: 28px;
margin-bottom: 11px;
& span {
// background: linear-gradient(180deg, #FFFFFF 0%, #21AAE1 100%);
-webkit-background-clip: text;
color: transparent;
font-weight: bold;
}
}
// .card-panel-num {
// font-size: 20px;
// }
}
}
}

57
src/views/home.vue

@ -1,7 +1,8 @@
<template>
<div class="dashboard-container">
<div class="dashboard-editor-container">
<panel-group />
<!-- <panel-group /> -->
<panel-group :device-list="allDisplayConfigData" />
<el-row :gutter="20" style="margin-bottom:20px;height: 152px;">
<el-col :xs="24" :sm="24" :lg="8">
<!-- search-area -->
@ -238,17 +239,17 @@ import { FetchWaitBorrower } from '@/api/archivesManage/lendManage'
import alarmApi from '@/api/home/alarm'
import { mapGetters } from 'vuex'
// import { allDeviceData, mockIpData } from '@/views/environmentalScreen/index.js'
import { allDeviceData, mockIpData } from '@/views/environmentalScreen/index.js'
// const mockFetchDataForIP = (params) => {
// return new Promise((resolve) => {
// setTimeout(() => {
// const ip = params.ip
// const result = mockIpData[ip] || { code: 200, message: '', data: [], timestamp: Date.now() }
// resolve(result.data)
// }, 500)
// })
// }
const mockFetchDataForIP = (params) => {
return new Promise((resolve) => {
setTimeout(() => {
const ip = params.ip
const result = mockIpData[ip] || { code: 200, message: '操作成功', data: [], timestamp: Date.now() }
resolve(result.data)
}, 500)
})
}
export default {
name: 'Dashboard',
@ -359,23 +360,23 @@ export default {
* 加载所有设备配置数据
*/
async loadAllDeviceConfig() {
// this.allDisplayConfigData = allDeviceData
// this.handleDeviceIpList()
try {
const data = await alarmApi.FetchYpGetSite()
if (data && data.length > 0) {
this.allDisplayConfigData = data
// IPIP
this.handleDeviceIpList()
} else {
this.allDisplayConfigData = []
this.allDeviceIds = []
}
} catch (error) {
console.error('加载设备配置失败:', error)
this.allDisplayConfigData = []
this.allDeviceIds = []
}
this.allDisplayConfigData = allDeviceData
this.handleDeviceIpList()
// try {
// const data = await alarmApi.FetchYpGetSite()
// if (data && data.length > 0) {
// this.allDisplayConfigData = data
// // IPIP
// this.handleDeviceIpList()
// } else {
// this.allDisplayConfigData = []
// this.allDeviceIds = []
// }
// } catch (error) {
// console.error('', error)
// this.allDisplayConfigData = []
// this.allDeviceIds = []
// }
},
/**

Loading…
Cancel
Save