<template>
|
<basic-main-content>
|
<avue-crud :option="option" :table-loading="loading" :data="data" v-model:page="page" ref="crud" @row-del="rowDel"
|
v-model="form" :permission="permissionList" @row-update="rowUpdate" @row-save="rowSave" :before-open="beforeOpen"
|
@search-change="searchChange" @search-reset="searchReset" @selection-change="selectionChange"
|
@current-change="currentChange" @size-change="sizeChange" @refresh-change="refreshChange" @on-load="onLoad"
|
@tree-load="treeLoad">
|
<template #menu-left>
|
<el-button type="danger" icon="el-icon-delete" plain v-if="permission.device_delete" @click="handleDelete">删 除
|
</el-button>
|
</template>
|
<template #dept_name="{ row }">
|
<el-tag>{{ row.dept_name }}</el-tag>
|
</template>
|
<template #status="{ row }">
|
<div v-if="row.status == true" class="onlineStatus">
|
<div class="onlineStatus-dot"></div>
|
<span class="online">在线</span>
|
</div>
|
<div v-if="row.status == false" class="onlineStatus">
|
<div class="onlineStatus-dot1"></div>
|
<span class="online">离线</span>
|
</div>
|
</template>
|
<template #firmware_status="{ row }">
|
<div v-if="row.firmware_status == 1" class="onlineStatus1">
|
<el-tag type="info">无需升级</el-tag>
|
<el-tag type="primary" effect="dark" class="active-element" @click="rollFirmware(row)">版本管理</el-tag>
|
<!-- <div style="background-color: #f1f1f1; border-radius: 4px">无需升级</div> -->
|
</div>
|
<div v-if="row.firmware_status == 2" class="onlineStatus1">
|
<!-- <el-tag type="success" effect="dark" class="active-element" @click="updateFirmware(row)"
|
>升级固件</el-tag
|
> -->
|
<el-tag type="primary" effect="dark" class="active-element" @click="rollFirmware(row)">版本管理</el-tag>
|
<!-- <div @click="updateFirmware(row)" class="firmware_status">升级固件</div> -->
|
</div>
|
<div v-if="row.firmware_status == 3" class="onlineStatus">
|
<el-tag type="success" effect="dark" class="active-element" @click="updateFirmware(row)">一致性升级</el-tag>
|
<!-- <div @click="updateFirmware(row)" class="firmware_status">一致性升级</div> -->
|
</div>
|
<div v-if="row.firmware_status == 4" class="onlineStatus">
|
<el-tag effect="dark" class="active-element" @click="updateFirmware(row)">升级中</el-tag>
|
<el-progress v-if="row.firmware_progress > 0 && row.firmware_progress < 100"
|
:percentage="row.firmware_progress"></el-progress>
|
</div>
|
</template>
|
<template #mode_code="{ row }">
|
<span class="text" v-if="row.domain == 3" :style="row.mode_code != '-1' ? 'color: #00ee8b' : 'color: #de5e5e'">
|
{{ getDockModeText(row.mode_code) }}
|
</span>
|
</template>
|
<template #menu="scope">
|
<el-button type="primary" text icon="el-icon-paperclip" v-if="permission.oss_set"
|
@click.stop="handleOpenOssSet(scope.row, scope.index)">存储配置
|
</el-button>
|
<el-button type="primary" text icon="el-icon-share" v-if="permission.per_share && scope.row.domain == 3"
|
@click.stop="handleOpenDevicePerShare(scope.row, scope.index)">机场授权
|
</el-button>
|
|
<el-button type="primary" text icon="el-icon-position" :disabled="!scope.row.status"
|
v-if="permission.rang_con && scope.row.domain == 3"
|
@click.stop="handleOpenRemoteDebugging(scope.row, scope.index)">远程调试
|
</el-button>
|
</template>
|
<!-- 添加行政区划显示模板 -->
|
<template #area_code="{ row }">
|
<span>{{ row.area_name }}</span>
|
</template>
|
</avue-crud>
|
|
<el-dialog title="固件升级" append-to-body v-model="firmwareBox" width="455px">
|
<div>升级固件版本:{{ firmwareVersion }}</div>
|
<template #footer>
|
<span class="dialog-footer">
|
<el-button @click="firmwareBox = false">取 消</el-button>
|
<el-button type="primary" @click="updateFirmwareConfirm">确 定</el-button>
|
</span>
|
</template>
|
</el-dialog>
|
|
<el-dialog title="存储配置" append-to-body v-model="ossSetBox" @close="handleOssSetClose" width="600px">
|
<div class="onlineStatus">
|
存储对象配置:
|
<el-select v-model="ossEnd" clearable placeholder="请选择存储对象" style="width: 450px">
|
<el-option v-for="item in ossList" :key="item.id" :label="item.name + ': ' + item.endpoint" :value="item.id">
|
<span style="float: left">{{ item.name + ': ' + item.endpoint }}</span>
|
<span v-if="item.status == 1" class="status1">{{ item.categoryName }}</span>
|
<span v-if="item.status == 2" class="status2">{{ item.categoryName }}</span>
|
</el-option>
|
</el-select>
|
</div>
|
<template #footer>
|
<span class="dialog-footer">
|
<el-button @click="cancelOssSet">取 消</el-button>
|
<el-button type="danger" @click="cancelOssSetConfirm">取消配置</el-button>
|
<el-button type="primary" @click="ossSetConfirm">配置</el-button>
|
</span>
|
</template>
|
</el-dialog>
|
|
<el-dialog title="固件版本管理" append-to-body v-model="rollFirmwareBox" width="455px">
|
<div class="onlineStatus">
|
固件版本升级/回退:
|
<el-select v-model="rollFirmVersion" clearable placeholder="请选择固件版本" style="width: 240px">
|
<el-option v-for="item in firmList" :key="item.firmware_version" :label="item.firmware_version"
|
:value="item.firmware_version" />
|
</el-select>
|
</div>
|
<template #footer>
|
<span class="dialog-footer">
|
<el-button @click="rollFirmwareBox = false">取 消</el-button>
|
<el-button type="primary" @click="rollFirmwareConfirm">确 定</el-button>
|
</span>
|
</template>
|
</el-dialog>
|
|
<el-drawer title="机场授权管理" size="60%" append-to-body v-model="devicePerShareVisible" :direction="'rtl'">
|
<DevicePerShare ref="devicePerShare" />
|
</el-drawer>
|
|
<el-drawer :title="operateTitle" append-to-body v-model="remoteDebuggingShow" size="40%">
|
<DockControlPanel v-if="remoteDebuggingShow" :sn="curDeviceInfo.device_sn" :deviceInfo="curDeviceInfo">
|
</DockControlPanel>
|
</el-drawer>
|
</basic-main-content>
|
</template>
|
|
<script>
|
import {
|
getList,
|
remove,
|
update,
|
add,
|
getDetail,
|
getDeviceUpgradeInfo,
|
ota,
|
getDeviceFirmwareList,
|
getDevices,
|
} from '@/api/device/device'
|
import { deleteByOssId, addOrUpdate as addOrUpdateOssBind } from '@/api/device/ossBind'
|
import { getListPage as getOssList } from '@/api/resource/oss'
|
import { getLazyTree } from '@/api/base/region'
|
import { EDockModeText, EDockModeCode } from '@/types/device'
|
import { mapGetters } from 'vuex'
|
import FirmwareManage from './components/firmwareManage.vue'
|
import DevicePerShare from './components/devicePerShare.vue'
|
import DockControlPanel from './components/DockControlPanel.vue'
|
import { getWebsocketUrl } from '@/websocket/util/config'
|
import ConnectWebSocket from '@/websocket'
|
export default {
|
components: {
|
FirmwareManage,
|
DevicePerShare,
|
DockControlPanel,
|
},
|
data () {
|
return {
|
bindOssId: null,
|
deviceSn: '',
|
ossSetBox: false,
|
ossList: [],
|
ossEnd: '',
|
operateTitle: '',
|
rollFirmVersion: '',
|
firmList: [],
|
rollFirmwareBox: false,
|
// 用于记录已经创建的websocket,防止重复创建
|
webSocketIdSet: new Set(),
|
// 用于保存多组websocket
|
websocketMap: new Map(),
|
scheduleNum: 0,
|
webSocket: '',
|
devicePerShareVisible: false,
|
remoteDebuggingShow: false,
|
curDeviceInfo: {},
|
firmwareManageVisible: false,
|
percentageNum: 0,
|
firmwareBox: false,
|
firmwareInfo: {},
|
form: {},
|
query: {},
|
firmwareVersion: '',
|
loading: true,
|
page: {
|
pageSize: 10,
|
currentPage: 1,
|
total: 0,
|
},
|
selectionList: [],
|
option: {
|
lazy: true,
|
tree: true,
|
|
dialogWidth: 1050,
|
tip: false,
|
searchShow: true,
|
searchMenuSpan: 6,
|
border: true,
|
index: true,
|
viewBtn: true,
|
selection: true,
|
excelBtn: false,
|
addBtn: false,
|
dialogClickModal: false,
|
grid: false,
|
|
height: 'auto',
|
calcHeight: 180,
|
|
column: [
|
{
|
label: '设备型号',
|
prop: 'device_name',
|
editDisabled: true,
|
search: true,
|
searchSpan: 4,
|
labelWidth: 130,
|
rules: [
|
{
|
required: true,
|
message: '请输入设备型号',
|
trigger: 'blur',
|
},
|
],
|
},
|
{
|
label: '设备SN',
|
prop: 'device_sn',
|
labelWidth: 130,
|
search: true,
|
searchSpan: 4,
|
editDisabled: true,
|
rules: [
|
{
|
required: true,
|
message: '请输入设备SN',
|
trigger: 'blur',
|
},
|
],
|
},
|
{
|
label: '机巢编号',
|
prop: 'machine_nest_sn',
|
labelWidth: 130,
|
editDisabled: true,
|
rules: [
|
{
|
required: false,
|
message: '请输入机巢编号',
|
trigger: 'blur',
|
},
|
],
|
},
|
{
|
label: '设备组织名称',
|
prop: 'nickname',
|
labelWidth: 130,
|
rules: [
|
{
|
required: true,
|
message: '请输入设备组织名称',
|
trigger: 'blur',
|
},
|
],
|
},
|
{
|
label: '固件版本',
|
prop: 'firmware_version',
|
labelWidth: 130,
|
width: 100,
|
editDisabled: true,
|
rules: [
|
{
|
required: true,
|
message: '请输入固件版本',
|
trigger: 'blur',
|
},
|
],
|
},
|
{
|
label: '固件升级',
|
prop: 'firmware_status',
|
labelWidth: 130,
|
width: 100,
|
viewDisabled: true,
|
addDisabled: true,
|
editDisabled: true,
|
addDisplay: false,
|
editDisplay: false,
|
viewDisplay: false,
|
rules: [
|
{
|
required: true,
|
message: '请输入固件升级',
|
trigger: 'blur',
|
},
|
],
|
},
|
{
|
label: '所属单位',
|
prop: 'dept_name',
|
addDisplay: false,
|
editDisplay: false,
|
viewDisplay: false,
|
labelWidth: 130,
|
rules: [
|
{
|
required: true,
|
message: '请输入所属单位',
|
trigger: 'blur',
|
},
|
],
|
},
|
{
|
label: '所属单位',
|
prop: 'dept_id',
|
hide: true,
|
type: 'tree',
|
defaultExpandAll: true,
|
labelWidth: 130,
|
dicUrl: '/blade-system/dept/getTree',
|
props: {
|
label: 'name',
|
value: 'id',
|
},
|
rules: [
|
{
|
required: true,
|
message: '请输入所属单位',
|
trigger: 'blur',
|
},
|
],
|
},
|
{
|
label: '加入组织时间',
|
prop: 'bound_time',
|
addDisplay: false,
|
editDisplay: false,
|
type: 'date',
|
labelWidth: 130,
|
width: 160,
|
format: 'YYYY-MM-DD HH:mm:ss',
|
// valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
rules: [
|
{
|
required: true,
|
message: '请输入在线状态',
|
trigger: 'blur',
|
},
|
],
|
},
|
{
|
label: '行政区划',
|
prop: 'area_code',
|
type: 'cascader',
|
labelWidth: 130,
|
hide: true,
|
props: {
|
label: 'title',
|
value: 'value',
|
emitPath: false,
|
checkStrictly: true,
|
multiple: false,
|
expandTrigger: 'hover',
|
},
|
dataType: 'string',
|
rules: [
|
{
|
required: true,
|
message: '请选择行政区划',
|
trigger: 'change',
|
},
|
],
|
change: ({ value }) => {
|
if (!value) {
|
this.form.area_code = null
|
} else {
|
if (typeof value === 'string' && value.includes(',')) {
|
const codes = value.split(',')
|
this.form.area_code = codes[codes.length - 1]
|
} else {
|
this.form.area_code = value
|
}
|
}
|
},
|
lazy: true,
|
lazyLoad (node, resolve) {
|
let level = node.level
|
let list = []
|
let callback = () => {
|
resolve(
|
(list || []).map(ele => ({
|
...ele,
|
value: ele.value,
|
leaf: level >= 2,
|
}))
|
)
|
}
|
|
if (level === 0) {
|
getLazyTree('000000000000').then(res => {
|
list = res.data.data
|
callback()
|
})
|
} else if (level === 1) {
|
getLazyTree(node.value).then(res => {
|
list = res.data.data
|
callback()
|
})
|
} else if (level === 2) {
|
getLazyTree(node.value).then(res => {
|
list = res.data.data
|
callback()
|
})
|
} else {
|
callback()
|
}
|
},
|
},
|
|
{
|
hide: true,
|
label: '保险有效期',
|
prop: 'duration_of_insurance',
|
labelWidth: 130,
|
type: "daterange",
|
format: 'YYYY-MM-DD',
|
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
startPlaceholder: '保险开始日期',
|
endPlaceholder: '保险结束日期',
|
rules: [
|
{
|
required: true,
|
message: '请选择保险有效期',
|
trigger: 'blur',
|
},
|
],
|
},
|
|
{
|
label: '在线时间',
|
prop: 'login_time',
|
type: 'date',
|
addDisplay: false,
|
editDisplay: false,
|
labelWidth: 130,
|
width: 160,
|
format: 'YYYY-MM-DD HH:mm:ss',
|
// valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
startPlaceholder: '任务开始时间',
|
rules: [
|
{
|
required: true,
|
message: '请输入在线时间',
|
trigger: 'blur',
|
},
|
],
|
},
|
{
|
label: '在线状态',
|
prop: 'status',
|
addDisplay: false,
|
editDisplay: false,
|
labelWidth: 130,
|
slot: true,
|
width: 100,
|
rules: [
|
{
|
required: true,
|
message: '请输入在线状态',
|
trigger: 'blur',
|
},
|
],
|
},
|
{
|
label: '机场状态',
|
prop: 'mode_code',
|
addDisplay: false,
|
editDisplay: false,
|
labelWidth: 130,
|
slot: true,
|
width: 100,
|
rules: [
|
{
|
required: true,
|
message: '请输入机场状态',
|
trigger: 'blur',
|
},
|
],
|
},
|
],
|
},
|
data: [],
|
DeviceFirmwareTypeEnum: {
|
// 普通升级
|
ToUpgraded: 3,
|
// 一致性升级
|
ConsistencyUpgrade: 2,
|
},
|
DeviceFirmwareStatusEnum: {
|
None: 1, // 无需升级
|
ToUpgraded: 2, // 待升级
|
ConsistencyUpgrade: 3, // 一致性升级
|
DuringUpgrade: 4, // 升级中
|
},
|
}
|
},
|
computed: {
|
...mapGetters(['permission']),
|
permissionList () {
|
return {
|
addBtn: this.validData(this.permission.airport_add, true),
|
viewBtn: this.validData(this.permission.airport_view, true),
|
delBtn: this.validData(this.permission.airport_delete, true),
|
editBtn: this.validData(this.permission.airport_edit, true),
|
}
|
},
|
ids () {
|
let ids = []
|
this.selectionList.forEach(ele => {
|
ids.push(ele.id)
|
})
|
return ids.join(',')
|
},
|
},
|
destroyed () {
|
this.websocketMap.forEach((k, v) => {
|
if (null != v) {
|
v.close()
|
this.websocketMap.delete(k)
|
this.webSocketIdSet.delete(k)
|
}
|
})
|
},
|
methods: {
|
getDockModeText (value) {
|
return EDockModeText[value] || ''
|
},
|
// 关闭所有的webscoket
|
closeAllWebsoket () {
|
this.websocketMap.forEach((k, v) => {
|
if (null != v) {
|
v.close()
|
this.websocketMap.delete(k)
|
this.webSocketIdSet.delete(k)
|
}
|
})
|
},
|
// 连接webSocket
|
connectWebSocket (data) {
|
const webSocketId = data.workspace_id
|
if (!this.webSocketIdSet.has(webSocketId)) {
|
// 防止重复连接
|
this.webSocketIdSet.add(webSocketId)
|
const webSorketUrl = getWebsocketUrl() + '&workspace-id=' + data.workspace_id
|
// 监听ws 消息
|
this.useConnectWebSocket(webSocketId, webSorketUrl)
|
}
|
},
|
useConnectWebSocket (webSocketId, url) {
|
const websocket = new ConnectWebSocket(url)
|
// 加入 webscoket map
|
this.websocketMap.set(webSocketId, websocket)
|
websocket?.registerMessageHandler(this.messageHandler)
|
websocket?.initSocket()
|
},
|
async messageHandler (payload) {
|
if (!payload) {
|
return
|
}
|
if (payload.biz_code != 'ota_progress') {
|
return
|
}
|
var data = payload.data
|
this.data.forEach(e => {
|
if (e.device_sn == data.sn && data.output.status == 'in_progress') {
|
e.firmware_progress = data.output.progress.percent
|
}
|
|
if (e.device_sn == data.sn && data.output.status == 'ok') {
|
// 升级完成修改状态
|
e.firmware_status = 1
|
const webscoket = this.websocketMap.get(e.workspace_id)
|
// 关闭
|
webscoket?.close()
|
//删除对应的webscoket
|
this.websocketMap.delete(e.workspace_id)
|
this.webSocketIdSet.delete(e.workspace_id)
|
}
|
})
|
},
|
init () {
|
(this.page = {
|
pageSize: 10,
|
currentPage: 1,
|
total: 0,
|
}),
|
this.onLoad(this.page)
|
},
|
// 打开权限分享页面
|
handleOpenDevicePerShare (row) {
|
var that = this
|
this.devicePerShareVisible = true
|
this.$nextTick(() => {
|
that.$refs.devicePerShare.init(row)
|
})
|
},
|
// 打开远程调试
|
handleOpenRemoteDebugging (row) {
|
this.curDeviceInfo = row
|
this.remoteDebuggingShow = true
|
this.operateTitle = row.nickname + ' - ' + row.device_sn
|
},
|
// 打开存储对象配置页面
|
handleOpenOssSet (row) {
|
var that = this
|
this.deviceSn = row.device_sn
|
this.ossSetBox = true
|
this.bindOssId = row.oss_id
|
this.ossEnd = row.oss_id
|
// 查询下拉列表
|
const param = {
|
categoryKeys: '1,3,6',
|
}
|
getOssList(1, 50, param).then(res => {
|
const data = res.data.data
|
that.ossList = data.records
|
})
|
},
|
// 打开固件管理页面
|
handleOpenFirmwarm (row) {
|
var that = this
|
this.firmwareManageVisible = true
|
this.$nextTick(() => {
|
that.$refs.firmwareManage.init(row)
|
})
|
},
|
// 版本回退点击事件
|
rollFirmware (row) {
|
if (row.status == 0) {
|
this.$message({
|
type: 'warning',
|
message: '设备不在线!',
|
})
|
return
|
}
|
// 如果是机场,查询飞机对应的信息
|
if (row.domain === 3) {
|
// 查询子设备名称
|
getDevices(row.workspace_id, row.child_sn).then(res => {
|
const data = res.data.data
|
that.firmwareInfo['child_device_name'] = data.device_name
|
that.firmwareInfo['child_version'] = data.firmware_version
|
that.firmwareInfo['child_status'] = data.status
|
})
|
}
|
var that = this
|
this.rollFirmwareBox = true
|
const param = {
|
device_name: row.device_name,
|
}
|
// 获取固件最新版本信息
|
getDeviceFirmwareList(1, 20, param).then(res => {
|
that.firmList = []
|
const data = res.data.data.records
|
if (data.length === 0) {
|
return
|
}
|
data.forEach(e => {
|
if (e.firmware_version != row.firmware_version) {
|
that.firmList.push(e)
|
}
|
})
|
that.firmwareInfo['device_name'] = row.device_name
|
that.firmwareInfo['sn'] = row.device_sn
|
// 3-普通升级,2-一致性升级;
|
that.firmwareInfo['firmware_upgrade_type'] = 3
|
that.firmwareInfo['workspaceId'] = row.workspace_id
|
that.firmwareInfo['firmware_version'] = row.firmware_version
|
that.firmwareInfo['status'] = row.status
|
// domain 0:飞机 3:机场
|
that.firmwareInfo['domain'] = row.domain
|
that.firmwareInfo['child_sn'] = row.child_sn
|
that.firmwareInfo['now_version'] = row.firmware_version
|
})
|
},
|
// 比较版本大小
|
compare (version1, version2) {
|
let arr1 = version1.split('.')
|
let arr2 = version2.split('.')
|
let length = Math.max(arr1.length, arr2.length)
|
for (let i = 0; i < length; i++) {
|
const n1 = Number(arr1[i] || 0)
|
const n2 = Number(arr2[i] || 0)
|
// version1 > version2 返回1,如果 version1 < version2 返回-1,不然返回0
|
if (n1 > n2) return 1
|
if (n1 < n2) return -1
|
}
|
return 0
|
},
|
// 版本回退
|
rollFirmwareConfirm () {
|
// 无人机升级/回滚
|
if (this.rollFirmVersion == '') {
|
this.$message({
|
type: 'warning',
|
message: '请先选择回退的固件版本!',
|
})
|
return
|
}
|
var that = this
|
var arr = []
|
that.firmwareInfo['product_version'] = this.rollFirmVersion
|
// 机场信息设置
|
arr.push(that.firmwareInfo)
|
// 判断是机场升级还是飞机升级,如果是机场升级则把无人机信息一起带过去
|
if (that.firmwareInfo.domain === 3) {
|
// 判断当前机场和无人机固件版本是否一致
|
var dockFlag = this.compare(
|
this.firmwareInfo.firmware_version,
|
this.firmwareInfo.child_version
|
)
|
// 机场和无人机版本一致情况
|
if (dockFlag == 0) {
|
if (!this.firmwareInfo.status || !this.firmwareInfo.child_status) {
|
this.$message({
|
type: 'warning',
|
message: '请先更新无人机固件版本后再进行机场固件版本更新!',
|
})
|
return
|
}
|
// 只有同时在线并且是升级才能操作
|
// 判断升级还是降级,不能降级
|
var upDownFlag = this.compare(this.rollFirmVersion, this.firmwareInfo.firmware_version)
|
if (upDownFlag == -1) {
|
this.$message({
|
type: 'warning',
|
message: '请先回滚无人机固件版本后再进行机场固件版本更新!',
|
})
|
return
|
}
|
// 同时升级操作
|
// 无人机信息设置
|
arr.push({
|
device_name: that.firmwareInfo.child_device_name,
|
sn: that.firmwareInfo.child_sn,
|
product_version: this.rollFirmVersion,
|
firmware_upgrade_type: 3,
|
})
|
} else {
|
// 版本不一致情况
|
// 比对需要改变的版本号和无人机版本号是否一致,不一致提示不能操作
|
var verFlag = this.compare(this.rollFirmVersion, this.firmwareInfo.child_version)
|
if (verFlag == -1 || verFlag == 1) {
|
this.$message({
|
type: 'warning',
|
message: '更新版本与当前无人机固件版本不一致,请更新和无人机一致的版本!',
|
})
|
return
|
}
|
// 需要改变的版本号和无人机版本号如果是一致,进行单独的机场升级/回滚操作
|
}
|
}
|
ota(that.firmwareInfo.workspaceId, arr).then(res => {
|
that.firmwareVersion = ''
|
that.firmwareInfo = {}
|
that.rollFirmwareBox = false
|
this.$message({
|
type: 'success',
|
message: '操作成功!',
|
})
|
this.onLoad(this.page)
|
done()
|
})
|
},
|
// 升级固件按钮事件
|
updateFirmware (row) {
|
if (row.status == 0) {
|
this.$message({
|
type: 'warning',
|
message: '设备不在线!',
|
})
|
return
|
}
|
var that = this
|
this.firmwareBox = true
|
const param = {
|
device_name: row.device_name,
|
}
|
// 获取固件最新版本信息
|
getDeviceUpgradeInfo(param).then(res => {
|
const data = res.data.data
|
if (data.length === 0) {
|
return
|
}
|
that.firmwareVersion = data[0].product_version
|
that.firmwareInfo['device_name'] = row.device_name
|
that.firmwareInfo['sn'] = row.device_sn
|
that.firmwareInfo['product_version'] = data[0].product_version
|
// 3-普通升级,2-一致性升级;
|
that.firmwareInfo['firmware_upgrade_type'] =
|
row.firmware_status === that.DeviceFirmwareStatusEnum.ToUpgraded
|
? that.DeviceFirmwareTypeEnum.ToUpgraded
|
: that.DeviceFirmwareTypeEnum.ConsistencyUpgrade
|
that.firmwareInfo['workspaceId'] = row.workspace_id
|
})
|
},
|
// 确定升级固件版本
|
updateFirmwareConfirm () {
|
var that = this
|
var arr = []
|
arr.push(that.firmwareInfo)
|
ota(that.firmwareInfo.workspaceId, arr).then(res => {
|
that.firmwareVersion = ''
|
that.firmwareInfo = {}
|
that.firmwareBox = false
|
this.$message({
|
type: 'success',
|
message: '操作成功!',
|
})
|
this.onLoad(this.page)
|
done()
|
})
|
},
|
handleOssSetClose () {
|
this.ossEnd = ''
|
this.deviceSn = ''
|
this.bindOssId = null
|
},
|
// 存储对象配置确定
|
ossSetConfirm () {
|
var that = this
|
// 判断是否已选择
|
if (!this.ossEnd) {
|
this.$message({
|
type: 'warning',
|
message: '请选择对于的存储对象!',
|
})
|
return
|
}
|
// 新增或者修改操作
|
const data = {
|
oss_id: this.ossEnd,
|
sn: this.deviceSn,
|
}
|
// 新增
|
addOrUpdateOssBind(data).then(res => {
|
this.$message({
|
type: 'success',
|
message: '操作成功!',
|
})
|
that.ossSetBox = false
|
this.onLoad(this.page)
|
done()
|
})
|
},
|
// 取消配置
|
cancelOssSetConfirm () {
|
var that = this
|
// 判断是否已有配置
|
if (!this.bindOssId) {
|
this.$message({
|
type: 'warning',
|
message: '当前机场尚未配置存储对象信息!',
|
})
|
return
|
}
|
deleteByOssId(this.bindOssId).then(() => {
|
that.ossSetBox = false
|
this.onLoad(this.page)
|
this.$message({
|
type: 'success',
|
message: '操作成功!',
|
})
|
})
|
},
|
// 取消按钮 oss
|
cancelOssSet () {
|
this.ossEnd = ''
|
this.deviceSn = ''
|
this.bindOssId = null
|
this.ossSetBox = false
|
},
|
rowSave (row, done, loading) {
|
let areaCode = row.area_code
|
if (Array.isArray(areaCode)) {
|
areaCode = areaCode[areaCode.length - 1]
|
} else if (typeof areaCode === 'string' && areaCode.includes(',')) {
|
const codes = areaCode.split(',')
|
areaCode = codes[codes.length - 1]
|
}
|
row.area_code = areaCode || null
|
|
add(row).then(
|
() => {
|
this.onLoad(this.page)
|
this.$message({
|
type: 'success',
|
message: '操作成功!',
|
})
|
done()
|
},
|
error => {
|
window.console.log(error)
|
loading()
|
}
|
)
|
},
|
rowUpdate (row, index, done, loading) {
|
const submitData = {
|
...row,
|
area_code: row.area_code.split(',').pop(),
|
insure_start_time: row.duration_of_insurance[0],
|
insure_expired_time: row.duration_of_insurance[1],
|
}
|
|
delete submitData.duration_of_insurance
|
|
update(submitData).then(
|
() => {
|
this.onLoad(this.page)
|
this.$message({
|
type: 'success',
|
message: '操作成功!',
|
})
|
done()
|
},
|
error => {
|
window.console.log(error)
|
loading()
|
}
|
)
|
},
|
rowDel (row) {
|
this.$confirm('确定将选择数据删除?', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning',
|
})
|
.then(() => {
|
return remove(row.id)
|
})
|
.then(() => {
|
this.onLoad(this.page)
|
this.$message({
|
type: 'success',
|
message: '操作成功!',
|
})
|
})
|
},
|
searchReset () {
|
this.query = {}
|
this.onLoad(this.page)
|
},
|
searchChange (params, done) {
|
this.query = params
|
this.page.currentPage = 1
|
this.onLoad(this.page, params)
|
done()
|
},
|
selectionChange (list) {
|
this.selectionList = list
|
},
|
selectionClear () {
|
this.selectionList = []
|
this.$refs.crud.toggleSelection()
|
},
|
handleDelete () {
|
if (this.selectionList.length === 0) {
|
this.$message.warning('请选择至少一条数据')
|
return
|
}
|
this.$confirm('确定将选择数据删除?', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning',
|
})
|
.then(() => {
|
return remove(this.ids)
|
})
|
.then(() => {
|
this.onLoad(this.page)
|
this.$message({
|
type: 'success',
|
message: '操作成功!',
|
})
|
this.$refs.crud.toggleSelection()
|
})
|
},
|
getFullAreaCode (areaCode) {
|
if (!areaCode) return ''
|
|
const code = areaCode.toString()
|
|
if (code.includes(',')) return code
|
|
if (code.endsWith('0000000000')) {
|
return code
|
} else if (code.endsWith('00000000') && !code.endsWith('0000000000')) {
|
const provinceCode = code.substring(0, 2) + '0000000000'
|
return `${provinceCode},${code}`
|
} else {
|
const provinceCode = code.substring(0, 2) + '0000000000'
|
const cityCode = code.substring(0, 4) + '00000000'
|
return `${provinceCode},${cityCode},${code}`
|
}
|
},
|
beforeOpen (done, type) {
|
if (['edit', 'view'].includes(type)) {
|
getDetail(this.form.id).then(res => {
|
const data = res.data.data
|
|
this.form = {
|
...data,
|
area_code: this.getFullAreaCode(data.area_code),
|
duration_of_insurance: [data?.insure_start_time || '', data?.insure_expired_time || '']
|
}
|
|
done()
|
})
|
}
|
},
|
currentChange (currentPage) {
|
this.page.currentPage = currentPage
|
},
|
sizeChange (pageSize) {
|
this.page.pageSize = pageSize
|
},
|
refreshChange () {
|
this.onLoad(this.page, this.query)
|
},
|
onLoad (page, params = {}) {
|
// this.closeAllWebsoket();
|
const { releaseTimeRange } = this.query
|
let values = {
|
...params,
|
...this.query,
|
}
|
if (releaseTimeRange) {
|
values = {
|
...values,
|
releaseTime_datege: releaseTimeRange[0],
|
releaseTime_datelt: releaseTimeRange[1],
|
}
|
values.releaseTimeRange = null
|
}
|
values['type'] = 1
|
this.loading = true
|
getList(page.currentPage, page.pageSize, values).then(res => {
|
const data = res.data.data
|
this.page.total = data.total
|
data.records.forEach(e => {
|
e['hasChildren'] = e.has_children
|
if (e.firmware_status == 4) {
|
this.connectWebSocket(e)
|
}
|
})
|
this.data = data.records
|
this.loading = false
|
this.selectionClear()
|
})
|
},
|
treeLoad (tree, treeNode, resolve) {
|
var params = {
|
childSn: tree.child_sn,
|
}
|
getList(1, 10, params).then(res => {
|
const data = res.data.data.records
|
resolve(data)
|
})
|
},
|
},
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
.status2 {
|
float: right;
|
color: #40cb8b;
|
font-size: 13px;
|
}
|
|
.status1 {
|
float: right;
|
color: #8492a6;
|
font-size: 13px;
|
}
|
|
.online {
|
margin-left: 5px;
|
}
|
|
.onlineStatus1 {
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
}
|
|
.onlineStatus {
|
display: flex;
|
flex-direction: row;
|
align-items: center;
|
}
|
|
.onlineStatus-dot {
|
width: 15px;
|
height: 15px;
|
background-color: #40cb8b;
|
border-radius: 50%;
|
}
|
|
.onlineStatus-dot1 {
|
width: 15px;
|
height: 15px;
|
background-color: #de5e5e;
|
border-radius: 50%;
|
}
|
|
.firmware_status {
|
background-color: aqua;
|
border-radius: 4px;
|
}
|
|
.firmware_status:hover {
|
cursor: pointer;
|
/* color: aqua; */
|
}
|
|
.active-element {
|
cursor: pointer;
|
|
&:hover {
|
background-color: #409eff;
|
border-color: #409eff;
|
}
|
}
|
</style>
|