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

2321 lines
68 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="tableContain">
<div class="headTitle">
<div class="xfMl">
<el-form :inline="true" :model="formIssue" class="demo-form-inline">
<el-form-item label="运维操作">
<el-select v-model="formIssue.operate" placeholder="请输入运维操作">
<el-option
v-for="item in operateOptions"
:key="item.id"
:label="item.name"
:value="item.id"
></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onIssue">下发命令</el-button>
</el-form-item>
</el-form>
</div>
<div class="zzMsg">
<p class="total">
<span
>已选中:<el-tag type="primary">{{
multipleSelection.length
}}</el-tag></span
>
<span
>运维:<el-tag type="primary">{{ ywNumber }}</el-tag></span
>
<span
>快心跳:<el-tag type="primary">{{ kxtNumber }}</el-tag></span
>
<span
>在线:<el-tag type="success">{{ onlineNum }}</el-tag></span
>
<span
>离线:<el-tag type="danger">{{ offlineNum }}</el-tag></span
>
<span
>未上传图片:<el-tag type="danger">{{ noPicNum }}</el-tag></span
>
<span
>磁盘异常数量:<el-tag type="danger">{{ freeNum }}</el-tag></span
>
<span
>装置总数:<el-tag type="info">{{ tableData.length }}</el-tag></span
>
</p>
<el-tooltip class="item" effect="dark" content="导出" placement="top">
<el-button
type="primary"
icon="el-icon-tickets"
@click="handleExport"
></el-button>
</el-tooltip>
<el-tooltip class="item" effect="dark" content="扩展列" placement="top">
<el-button
class="drawBox"
size="small"
type="primary"
icon="el-icon-s-operation"
@click="drawer = true"
></el-button>
</el-tooltip>
</div>
</div>
<u-table
v-loading="tableLoaidng"
id="ywTable"
ref="ywMultipleTable"
:data="tableData"
border
:row-style="isRed"
:row-key="getRowKey"
style="width: 100%"
@selection-change="handleSelectionChange"
:default-sort="{ order: 'descending' }"
:row-class-name="tableRowSetting"
use-virtual
:height="tableHeight"
:row-height="32"
>
<u-table-column
type="selection"
:reserve-selection="true"
width="30"
fixed
>
</u-table-column>
<u-table-column type="index" width="40" label="序号" fixed>
</u-table-column>
<u-table-column prop="oid" label="出厂ID" width="134" sortable fixed>
<template slot-scope="scope">
<span
class="redMlxf"
v-if="
scope.row.list &&
scope.row.list[0].estimatedPublishTime * 1000 - newupdatatime > 0
"
>
<b v-if="scope.row.list[0].cmdDesc == ''">{{
cmdCn[scope.row.list[0].cmdName]
}}</b
><b v-else>{{ scope.row.list[0].cmdDesc }}</b>
<b
v-if="
scope.row.list[0].estimatedPublishTime * 1000 - newupdatatime >
0
"
>
{{ remainingTime(scope.row.list[0]) }}
</b>
</span>
<span v-else>
{{
scope.row.raw_report.hasOwnProperty("oid")
? scope.row.raw_report.oid
: ""
}}
</span>
</template>
</u-table-column>
<u-table-column prop="cmdid" label="装置编号" width="136" sortable fixed>
</u-table-column>
<u-table-column label="状态" width="54" fixed>
<template slot-scope="scope">
<el-tag
type="success"
v-if="nowTime - scope.row.last_heartbeat_ts <= 720"
>在线</el-tag
>
<el-tag type="danger" v-else>离线</el-tag>
</template>
</u-table-column>
<u-table-column label="运维" prop="in_maintain" width="68" sortable fixed>
<template slot="header" slot-scope="scope">
<p :class="ywNumber != 0 ? 'redClass' : 'noClass'">
{{ ywNumber }}<span> / {{ tableData.length }}</span>
</p>
<span @click.stop>
<el-checkbox
v-model="checkAllYW"
@change="handlecheckAllYW"
:class="
(ywNumber == tableData.length && tableData.length != 0) ||
ywNumber == 0
? ''
: 'is-indeterminate'
"
></el-checkbox>
运维
</span>
</template>
<template slot-scope="scope">
<el-checkbox
v-model="scope.row.in_maintain"
:true-label="'1'"
:false-label="'0'"
@change="(val) => UpdateMaintainMode(val, scope.row)"
></el-checkbox>
</template>
</u-table-column>
<u-table-column label="快心跳" prop="quick_hb" width="90" sortable fixed>
<template slot="header" slot-scope="scope">
<p :class="kxtNumber != 0 ? 'redClass' : 'noClass'">
{{ kxtNumber }}<span> / {{ tableData.length }}</span>
</p>
<span @click.stop>
<el-checkbox
v-model="checkAllKXT"
@change="handlecheckAllKXT"
:class="
(kxtNumber == tableData.length && tableData.length != 0) ||
kxtNumber == 0
? ''
: 'is-indeterminate'
"
></el-checkbox>
快心跳
</span>
</template>
<template slot-scope="scope">
<el-checkbox
v-model="scope.row.quick_hb"
:true-label="'1'"
:false-label="'0'"
@change="(val) => UpdateQuickHbMode(val, scope.row)"
></el-checkbox>
</template>
</u-table-column>
<u-table-column
prop="last_heartbeat"
label="最后心跳"
width="130"
sortable
class-name="hbClass"
>
<template slot-scope="scope">
<span
@click="handleMsgClick(scope.row)"
:title="scope.row.last_heartbeat"
>{{ scope.row.last_heartbeat }}</span
>
</template>
</u-table-column>
<u-table-column
label="传图"
prop="raw_report.pic"
width="50"
class-name="picBg"
sortable
>
<template slot-scope="scope">
{{ scope.row.raw_report.pic }}
</template>
</u-table-column>
<u-table-column
prop="protocol"
label="规约"
width="120"
v-if="gycheck"
sortable
key="gy"
>
<template slot-scope="scope">
{{ protocolMap[scope.row.protocol] }}
</template>
</u-table-column>
<u-table-column label="电池状态" width="126" key="dc" v-if="dccheck">
<template slot-scope="scope">
<span v-if="scope.row.raw_report.hasOwnProperty('XyDev')">{{
scope.row.raw_report.battary
}}</span>
<span v-else>{{
scope.row.raw_report.hasOwnProperty("msgs")
? scope.row.raw_report.msgs.battery
: ""
}}</span>
</template>
</u-table-column>
<u-table-column label="心跳信息" v-if="xtcheck" key="xt">
<u-table-column
label="次数"
min-width="48"
sortable
:sort-method="sortnumberOfHb"
>
<template slot-scope="scope">
<span v-if="scope.row.raw_report.hasOwnProperty('XyDev')">{{
scope.row.raw_report.numberOfHb
}}</span>
<span v-else>{{
scope.row.raw_report.msgs.hasOwnProperty("numberOfHb")
? Number(scope.row.raw_report.msgs.numberOfHb)
: ""
}}</span>
</template>
</u-table-column>
<u-table-column label="周期" min-width="48">
<template slot-scope="scope">
<span v-if="scope.row.raw_report.hasOwnProperty('XyDev')">{{
scope.row.raw_report.heartbeatDuration
}}</span>
<span v-else>{{
scope.row.raw_report.hasOwnProperty("msgs")
? scope.row.raw_report.msgs.heartbeatDuration
: ""
}}</span>
</template>
</u-table-column>
<u-table-column label="CMA消息" min-width="48">
<template slot-scope="scope">
<span v-if="scope.row.raw_report.hasOwnProperty('XyDev')">{{
scope.row.raw_report.recv
}}</span>
<span v-else>{{
scope.row.raw_report.hasOwnProperty("msgs")
? scope.row.raw_report.msgs.recv
: ""
}}</span>
</template>
</u-table-column>
</u-table-column>
<u-table-column label="拍照" v-if="pzcheck" key="pz">
<u-table-column label="计划/实际" min-width="48">
<template slot-scope="scope">
<span v-if="scope.row.raw_report.hasOwnProperty('XyDev')">{{
scope.row.raw_report.photoTimes
}}</span>
<span v-else>{{
scope.row.raw_report.hasOwnProperty("msgs")
? scope.row.raw_report.msgs.photoTimes
: ""
}}</span>
</template>
</u-table-column>
<u-table-column
label="成功"
min-width="48"
sortable
:sort-method="sortSuccess"
>
<template slot-scope="scope">
<span v-if="scope.row.raw_report.hasOwnProperty('XyDev')">{{
scope.row.raw_report.success
}}</span>
<span v-else>{{
scope.row.raw_report.msgs.hasOwnProperty("success")
? Number(scope.row.raw_report.msgs.success)
: ""
}}</span>
</template>
</u-table-column>
<u-table-column
label="失败"
min-width="48"
sortable
:sort-method="sortFailure"
>
<template slot-scope="scope">
<span v-if="scope.row.raw_report.hasOwnProperty('XyDev')">{{
scope.row.raw_report.failure
}}</span>
<span v-else>{{
scope.row.raw_report.msgs.hasOwnProperty("failure")
? Number(scope.row.raw_report.msgs.failure)
: ""
}}</span>
</template>
</u-table-column>
</u-table-column>
<u-table-column label="网络信号" v-if="wlcheck" key="wl">
<u-table-column label="卡1" min-width="60" prop="signature1">
<template slot-scope="scope">
<el-tooltip
class="item"
effect="dark"
:content="scope.row.raw_report.msgs.signature1"
placement="top"
>
<span>{{
scope.row.raw_report.msgs.hasOwnProperty("signature1")
? scope.row.raw_report.msgs.signature1.split("/")[0]
: ""
}}</span>
</el-tooltip>
</template>
</u-table-column>
<u-table-column label="卡2" min-width="60" prop="signature2">
<template slot-scope="scope">
<span v-if="scope.row.raw_report.hasOwnProperty('XyDev')">
<el-tooltip
class="item"
effect="dark"
:content="scope.row.raw_report.msgs.signature2"
placement="top"
><span>{{
scope.row.raw_report.msgs.signature2
}}</span></el-tooltip
></span
>
<span v-else>
<el-tooltip
class="item"
effect="dark"
:content="scope.row.raw_report.msgs.signature2"
placement="top"
>
<span>{{
scope.row.raw_report.msgs.hasOwnProperty("signature2")
? scope.row.raw_report.msgs.signature2.split("/")[0]
: ""
}}</span>
</el-tooltip>
</span>
<!-- {{
scope.row.raw_report.msgs.hasOwnProperty("signature2")
? scope.row.raw_report.msgs.signature2.split("/")[0]
: ""
}} -->
</template>
</u-table-column>
<u-table-column
label="错误"
min-width="48"
prop="networkError"
sortable
:sort-method="sortNumbersErr"
>
<template slot-scope="scope">
<span v-if="scope.row.raw_report.hasOwnProperty('XyDev')">{{
scope.row.raw_report.networkError
}}</span>
<span v-else>{{
scope.row.raw_report.msgs.hasOwnProperty("networkError")
? Number(scope.row.raw_report.msgs.networkError)
: ""
}}</span>
</template>
</u-table-column>
</u-table-column>
<u-table-column label="重启次数" v-if="cqcheck" key="cq">
<u-table-column
label="系统"
min-width="48"
prop="rebootTimes"
sortable
:sort-method="sortNumbers"
>
<template slot-scope="scope">
<span v-if="scope.row.raw_report.hasOwnProperty('XyDev')">{{
scope.row.raw_report.rebootTimes
}}</span>
<span v-else>{{
scope.row.raw_report.msgs.hasOwnProperty("rebootTimes")
? Number(scope.row.raw_report.msgs.rebootTimes)
: ""
}}</span>
</template>
</u-table-column>
<u-table-column
label="I1"
min-width="48"
prop="i1RebootTimes"
sortable
:sort-method="sortNumbers2"
>
<template slot-scope="scope">
<span v-if="scope.row.raw_report.hasOwnProperty('XyDev')">{{
scope.row.raw_report.i1RebootTimes
}}</span>
<span v-else>{{
scope.row.raw_report.msgs.hasOwnProperty("i1RebootTimes")
? Number(scope.row.raw_report.msgs.i1RebootTimes)
: ""
}}</span>
</template>
</u-table-column>
</u-table-column>
<u-table-column label="SIM卡" v-if="simcheck" min-width="160" key="sim">
<u-table-column label="卡1ICCID" width="158" prop="simcard1">
<template slot-scope="scope">
<span v-if="scope.row.raw_report.hasOwnProperty('XyDev')">
{{ scope.row.raw_report.simcard1 }}</span
>
<span v-else>
{{
scope.row.raw_report.msgs.hasOwnProperty("simcard1")
? scope.row.raw_report.msgs.simcard1
: ""
}}</span
>
</template>
</u-table-column>
<u-table-column label="卡2ICCID" width="158" prop="simcard2">
<template slot-scope="scope">
<span v-if="scope.row.raw_report.hasOwnProperty('XyDev')">
{{ scope.row.raw_report.simcard2 }}</span
>
<span v-else>
{{
scope.row.raw_report.msgs.hasOwnProperty("simcard2")
? scope.row.raw_report.msgs.simcard2
: ""
}}</span
>
</template>
</u-table-column>
</u-table-column>
<u-table-column
label="磁盘剩余空间"
v-if="freecheck"
min-width="66"
key="free"
sortable
:sort-method="sortfreeNumbers"
>
<template slot-scope="scope">
<span v-if="scope.row.raw_report.hasOwnProperty('XyDev')">
{{ scope.row.raw_report.freeROM }}</span
>
<span v-else>{{
scope.row.raw_report.msgs.hasOwnProperty("freeROM")
? scope.row.raw_report.msgs.freeROM
: ""
}}</span>
</template>
</u-table-column>
<u-table-column label="CMA服务器" v-if="cmacheck" width="140" key="cma">
<template slot-scope="scope">
<span v-if="scope.row.raw_report.hasOwnProperty('XyDev')">
{{ scope.row.raw_report.cma }}</span
>
<span v-else>{{
scope.row.raw_report.hasOwnProperty("msgs")
? scope.row.raw_report.msgs.cma
: ""
}}</span>
</template>
</u-table-column>
<u-table-column label="I1版本" v-if="i1check" min-width="192" key="I1">
<template slot-scope="scope">
<span v-if="scope.row.raw_report.hasOwnProperty('XyDev')">{{
scope.row.raw_report.i1Version
}}</span>
<span v-else>{{
scope.row.raw_report.msgs.hasOwnProperty("i1Version")
? scope.row.raw_report.msgs.i1Version
: ""
}}</span>
</template>
</u-table-column>
<u-table-column
label="运维版本"
v-if="ywbbcheck"
min-width="248 "
key="ywbb"
>
<template slot-scope="scope">
<span v-if="scope.row.raw_report.hasOwnProperty('XyDev')">{{
scope.row.raw_report.maintainVersion
}}</span>
<span v-else>
{{
scope.row.raw_report.msgs.hasOwnProperty("maintainVersion")
? scope.row.raw_report.msgs.maintainVersion
: ""
}}</span
>
</template>
</u-table-column>
<u-table-column
label="Camera版本"
v-if="Cameracheck"
min-width="80"
key="Camera"
>
<template slot-scope="scope">
{{
scope.row.raw_report.msgs.hasOwnProperty("cameraService")
? scope.row.raw_report.msgs.cameraService
: ""
}}
</template>
</u-table-column>
<u-table-column label="AI版本" v-if="AIcheck" min-width="80" key="AI">
<template slot-scope="scope">
{{
scope.row.raw_report.msgs.hasOwnProperty("aiVersion")
? scope.row.raw_report.msgs.aiVersion
: ""
}}
</template>
</u-table-column>
<u-table-column label="MCU版本" v-if="MCUcheck" min-width="210" key="MCU">
<template slot-scope="scope">
{{
scope.row.raw_report.msgs.hasOwnProperty("mcu")
? scope.row.raw_report.msgs.mcu
: ""
}}
</template>
</u-table-column>
<u-table-column
label="装置IP"
v-if="lastIpcheck"
width="120"
key="lastIp"
>
<template slot-scope="scope">
<span> {{ scope.row.last_ip }}</span>
</template>
</u-table-column>
<u-table-column
label="备注"
v-if="notecheck"
min-width="210"
key="note"
sortable
:sort-method="sortNote"
>
<template slot-scope="scope">
<div
@click="handlecolEditClick(scope)"
style="height: 22px; cursor: pointer"
>
<el-input
class="noteclass"
v-if="scope.$index == cellIndex"
v-model="scope.row.comment"
@blur="handleCommentBlur(scope)"
placeholder="请输入备注"
></el-input>
<span v-else :title="scope.row.comment">{{
scope.row.comment
}}</span>
</div>
</template>
</u-table-column>
</u-table>
<el-drawer
class="drawerBox"
:visible.sync="drawer"
direction="rtl"
:with-header="false"
>
<div class="drawerSelect">
<h3>表格列配置</h3>
<div class="selectBox">
<el-checkbox v-model="gycheck" @change="saveLocalStorage"
>规约</el-checkbox
>
<el-checkbox v-model="dccheck" @change="saveLocalStorage"
>电池状态</el-checkbox
>
<el-checkbox v-model="xtcheck" @change="saveLocalStorage"
>心跳信息</el-checkbox
>
<!-- <el-checkbox v-model="xtcs" @change="saveLocalStorage"
>心跳次数</el-checkbox
>
<el-checkbox v-model="xtzq" @change="saveLocalStorage"
>心跳周期</el-checkbox
> -->
<el-checkbox v-model="pzcheck" @change="saveLocalStorage"
>拍照</el-checkbox
>
<el-checkbox v-model="wlcheck" @change="saveLocalStorage"
>网络信号</el-checkbox
>
<el-checkbox v-model="cqcheck" @change="saveLocalStorage"
>重启次数</el-checkbox
>
<el-checkbox v-model="simcheck" @change="saveLocalStorage"
>SIM卡</el-checkbox
>
<el-checkbox v-model="freecheck" @change="saveLocalStorage"
>磁盘剩余空间</el-checkbox
>
<el-checkbox v-model="cmacheck" @change="saveLocalStorage"
>CMA服务器</el-checkbox
>
<el-checkbox v-model="i1check" @change="saveLocalStorage"
>I1版本</el-checkbox
>
<el-checkbox v-model="ywbbcheck" @change="saveLocalStorage"
>运维版本</el-checkbox
>
<el-checkbox v-model="Cameracheck" @change="saveLocalStorage"
>Camera版本</el-checkbox
>
<el-checkbox v-model="AIcheck" @change="saveLocalStorage"
>AI版本</el-checkbox
>
<el-checkbox v-model="MCUcheck" @change="saveLocalStorage"
>MCU版本</el-checkbox
>
<el-checkbox v-model="lastIpcheck" @change="saveLocalStorage"
>装置IP</el-checkbox
>
<el-checkbox v-model="notecheck" @change="saveLocalStorage"
>备注</el-checkbox
>
</div>
</div>
</el-drawer>
<!-- 设置ie服务器 -->
<el-dialog
title="设置ie服务器"
:visible.sync="ieVisible"
width="30%"
:close-on-click-modal="false"
>
<el-form :model="ieform" ref="ieRuleForm" :rules="ieRules">
<el-form-item label="CMA IP" prop="ip">
<el-input v-model="ieform.ip" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="CMA Port" prop="port">
<el-input v-model.number="ieform.port" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="ieVisible = false">取 消</el-button>
<el-button type="primary" @click="handleIeServe">确 定</el-button>
</div>
</el-dialog>
<!-- 设置运维服务器 -->
<el-dialog
title="设置运维服务器"
:visible.sync="operationVisible"
:close-on-click-modal="false"
width="30%"
>
<el-form
:model="operationform"
ref="operationRuleForm"
:rules="operationRules"
>
<el-form-item label="运维服务器IP" prop="ip">
<el-input v-model="operationform.ip" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="运维服务器Port" prop="port">
<el-input
v-model.number="operationform.port"
autocomplete="off"
></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="ieVisible = false">取 消</el-button>
<el-button type="primary" @click="handleOperationServe"
>确 定</el-button
>
</div>
</el-dialog>
<!-- 设置心跳周期 -->
<el-dialog
title="设置运维服务器"
:visible.sync="heartBeatVisible"
:close-on-click-modal="false"
width="30%"
>
<el-form
:model="heartBeatform"
ref="heartBeatRuleForm"
:rules="heartBeatRules"
>
<el-form-item label="心跳周期:(分钟)" prop="heart">
<el-input
v-model.number="heartBeatform.heart"
autocomplete="off"
></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="heartBeatVisible = false">取 消</el-button>
<el-button type="primary" @click="handleheartBeat">确 定</el-button>
</div>
</el-dialog>
<!-- 升级 -->
<el-dialog
class="upDialogBox"
title="请选择升级文件"
:visible.sync="upgradationVisible"
:close-on-click-modal="false"
width="30%"
>
<el-form
:model="upgradationform"
:rules="upgradationRules"
ref="upgradationRuleForm"
>
<el-form-item label="文件名称" prop="upVal">
<el-select
v-model="upgradationform.upVal"
placeholder="请选择升级文件"
@change="selectChanged"
>
<el-option
v-for="item in upOptions"
:key="item.id"
:label="item.fileName"
:value="item.path"
:title="item.title"
>
{{ item.fileName }}
<i class="title">{{ item.title }}</i
><i class="time">{{ item.createTime }}</i>
</el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="upgradationVisible = false">取 消</el-button>
<el-button type="primary" @click="handleupgradation">确 定</el-button>
</div>
</el-dialog>
<!-- 升级 -->
<el-dialog
class="upDialogBox"
title="请选择OTA升级文件"
:visible.sync="upgradationVisibleOta"
:close-on-click-modal="false"
width="30%"
>
<el-form
:model="upgradationformOta"
:rules="upgradationRulesOta"
ref="upgradationRuleFormOta"
>
<el-form-item label="文件名称" prop="upVal">
<el-select
v-model="upgradationformOta.upVal"
placeholder="请选择升级文件"
@change="selectChangedOta"
>
<el-option
v-for="item in upOptionsOta"
:key="item.id"
:label="item.fileName"
:value="item.path"
:title="item.title"
>
{{ item.fileName }}
<i class="title">{{ item.title }}</i
><i class="time">{{ item.createTime }}</i>
</el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="upgradationVisibleOta = false">取 消</el-button>
<el-button type="primary" @click="handleupgradationOta">确 定</el-button>
</div>
</el-dialog>
<!-- 开启frpc服务器 -->
<el-dialog
title="设置frpc"
:visible.sync="frpcVisible"
:close-on-click-modal="false"
width="40%"
class="frpcDialogBox"
>
<el-button type="primary" @click="handleModelForm">模板一</el-button>
<el-form
:model="frpcform"
ref="frpcRuleForm"
:rules="frpcRules"
label-width="132px"
>
<el-form-item label="服务器IP" prop="server_addr">
<el-input
v-model="frpcform.server_addr"
autocomplete="off"
></el-input>
</el-form-item>
<el-form-item label="服务器端口:" prop="server_port">
<el-input
v-model.number="frpcform.server_port"
autocomplete="off"
></el-input>
</el-form-item>
<el-form-item label="FRPC类型">
<el-select v-model="frpcform.frpc_type" placeholder="请选择">
<el-option
v-for="item in frpc_typeOption"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="网络类型:">
<el-select v-model="frpcform.type" placeholder="请选择">
<el-option
v-for="item in typeOption"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="本地IP" prop="local_ip">
<el-input v-model="frpcform.local_ip" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="本地端口:" prop="local_port">
<el-input
v-model.number="frpcform.local_port"
autocomplete="off"
></el-input>
</el-form-item>
<el-form-item label="远程端口:" prop="remote_port">
<el-input
v-model.number="frpcform.remote_port"
autocomplete="off"
></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="frpcVisible = false">取 消</el-button>
<el-button type="primary" @click="handleFrpc">确 定</el-button>
</div>
</el-dialog>
<!-- 装置详细信息 -->
<rowMsgDialog ref="rowMsgDialogref"></rowMsgDialog>
</div>
</template>
<script>
import {
getdoActionApi,
getqueryUpgradesApi,
updComment,
} from "@/utils/api/index";
import rowMsgDialog from "./rowMsgDialog.vue";
import htmlToExcel from "@/utils/htmlToExcel";
import { saveAs } from "file-saver";
import XLSX from "xlsx";
export default {
props: [
"tableData",
"onlineNum",
"offlineNum",
"noPicNum",
"freeNum",
"tableLoaidng",
],
components: {
rowMsgDialog,
},
data() {
//判断ip
let validateIPAddress = (rule, value, callback) => {
let regexp =
/^((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}$/;
let valdata = value.split(",");
let isCorrect = true;
if (valdata.length) {
for (let i = 0; i < valdata.length; i++) {
if (regexp.test(valdata[i]) == false) {
isCorrect = false;
}
}
}
if (value == "") {
return callback(new Error("请输入iP地址"));
} else if (!isCorrect) {
callback(new Error("请输入正确对ip地址"));
} else {
callback();
}
};
return {
tableHeight: 0,
screenHeight: 0,
showFlag: true,
newupdatatime: null,
cmdCn: {
yw_cmd_android_reboot: "重启设备",
yw_cmd_mcu_reboot: "MCU单片机重启",
i1_cmd_set_i1_server_ip_port: "设置I1服务器",
i1_cmd_set_xy_yw_ip_port: "设置运维服务器",
i1_cmd_set_i1_heart_beat_time: "设置心跳周期",
yw_cmd_upload_i1_zip_log: "上传日志",
upgrade: "升级",
updOta: "Ota升级",
yw_cmd_start_frpc: "开启frpc",
yw_cmd_stop_frpc: "停止frpc",
i1_cmd_stop_aging_test: "停止老化测试",
},
taskdrawer: false,
drawer: false,
protocolMap: {
65280: "国网I1",
65296: "陕西",
65281: "安徽",
65282: "江苏",
65283: "湖南",
65284: "浙江",
65285: "河南全景",
65286: "河南郑州",
65290: "河南统一视频v2020",
},
multipleSelection: [],
checkAllYW: false,
checkAllKXT: false,
ywNumber: 0,
kxtNumber: 0,
nowTime: new Date().getTime() / 1000,
gycheck: true,
dccheck: false,
xtcheck: false,
// xtcs: false,
// xtzq: false,
pzcheck: false,
wlcheck: false,
cqcheck: false,
simcheck: false,
cmacheck: true,
// bbcheck: true,
i1check: true,
ywbbcheck: true,
Cameracheck: false,
AIcheck: false,
MCUcheck: false,
freecheck: false,
notecheck: false,
lastIpcheck: false,
//运维操作列表
operateOptions: [
{ id: 1, name: "重启设备" },
{ id: 2, name: "MCU单片机重启" },
{ id: 3, name: "设置I1服务器" },
// { id: 4, name: "设置运维服务器" },
{ id: 5, name: "设置心跳周期" },
{ id: 6, name: "上传日志" },
{ id: 7, name: "升级" },
{ id: 11, name: "OTA升级" },
{ id: 8, name: "开启frpc" },
{ id: 9, name: "停止frpc" },
{ id: 10, name: "停止老化测试" },
],
formIssue: {
operate: "",
}, //运维操作
idArray: [], //选中的数组 id
//设置ie服务器
ieVisible: false,
ieform: {
ip: "",
port: "",
},
ieRules: {
ip: [{ required: true, validator: validateIPAddress, trigger: "blur" }],
port: [
{
required: true,
type: "number",
message: "请输入端口号(必须为数字)",
trigger: "blur",
},
],
},
//设置运维服务器
operationVisible: false,
operationform: {
ip: "",
port: "",
},
operationRules: {
ip: [{ required: true, validator: validateIPAddress, trigger: "blur" }],
port: [
{
required: true,
type: "number",
message: "请输入端口号(必须为数字)",
trigger: "blur",
},
],
},
//设置心跳周期
heartBeatVisible: false,
heartBeatform: {
heart: "",
},
heartBeatRules: {
heart: [
{
required: true,
type: "number",
message: "请输入心跳周期(必须为数字)",
trigger: "blur",
},
],
},
//升级
upgradationVisible: false,
upgradationform: {
upVal: "",
},
selectUpObj: {},
upgradationRules: {
upVal: [
{ required: true, message: "请选择升级文件", trigger: "change" },
],
},
upOptions: [],
upgradationVisibleOta: false,
upgradationformOta: {
upVal: "",
},
upgradationRulesOta: {
upVal: [
{ required: true, message: "请选择升级文件", trigger: "change" },
],
},
selectUpObjOta: {},
upOptionsOta: [],
//设置frpc服务器
frpcVisible: false,
frpcform: {
// ip: "",
// port: "",
server_addr: "",
server_port: "",
frpc_type: "adb",
type: "tcp",
local_ip: "",
local_port: "",
remote_port: "",
},
frpc_typeOption: [
{
value: "ssh",
label: "SSH",
},
{
value: "adb",
label: "ADB",
},
],
typeOption: [
{
value: "tcp",
label: "TCP",
},
{
value: "udp",
label: "UDP",
},
],
frpcRules: {
server_addr: [
{ required: true, validator: validateIPAddress, trigger: "blur" },
],
server_port: [
{
required: true,
type: "number",
message: "请输入端口号(必须为数字)",
trigger: "blur",
},
],
local_ip: [
{ required: true, validator: validateIPAddress, trigger: "blur" },
],
local_port: [
{
required: true,
type: "number",
message: "请输入端口号(必须为数字)",
trigger: "blur",
},
],
remote_port: [
{
required: true,
type: "number",
message: "请输入端口号(必须为数字)",
trigger: "blur",
},
],
},
newupdatatime: null,
cellIndex: null,
};
},
mounted() {
this.loadLocalStorage();
this.calculateHeight(this.showFlag);
window.addEventListener("resize", this.calculateHeight(this.showFlag));
},
computed: {
// 使用计算属性来扩展数据,为每个项目添加 isEditing 字段
// tableDataWithEditing() {
// console.log(this.tableData);
// return this.tableData.map((row) => ({
// ...row, // 复制原始行的所有属性
// isEditing: false, // 添加 isEditing 字段并初始化为 false
// }));
// },
},
watch: {
tableData: {
handler(newVal) {
// 数据发生变化时的处理逻辑
console.log("数据已更新:", newVal);
this.getNumber();
this.startCountdown();
},
deep: true,
},
},
created() {},
methods: {
calculateHeight(val) {
console.log(val);
this.showFlag = val;
this.screenHeight = window.innerHeight; // 获取屏幕高度
if (val) {
this.tableHeight = this.screenHeight - 230; // 假设你想从屏幕高度中减去270px
} else {
this.tableHeight = this.screenHeight - 150; // 假设你想从屏幕高度中减去190px
}
// 根据你的需求计算高度,这里只是一个简单的示例
console.log(this.tableHeight);
},
tableRowSetting({ row }) {
if (row.raw_report.msgs.hasOwnProperty("freeROM")) {
// console.log(row.raw_report.msgs.freeROM);
// console.log(parseInt(row.raw_report.msgs.freeROM));
if (parseInt(row.raw_report.msgs.freeROM) < 50) {
return "has-color";
}
}
// 根据if条件定义到该行
// if (row.rank === 1) {
// return "has-color";
// }
// return "";
},
sortNumbers(a, b) {
return (
Number(a.raw_report.msgs.rebootTimes) -
Number(b.raw_report.msgs.rebootTimes)
);
},
sortNumbers2(a, b) {
return (
Number(a.raw_report.msgs.i1RebootTimes) -
Number(b.raw_report.msgs.i1RebootTimes)
);
},
sortNumbersErr(a, b) {
return (
Number(a.raw_report.msgs.networkError) -
Number(b.raw_report.msgs.networkError)
);
},
sortSuccess(a, b) {
return (
Number(a.raw_report.msgs.success) - Number(b.raw_report.msgs.success)
);
},
sortFailure(a, b) {
return (
Number(a.raw_report.msgs.failure) - Number(b.raw_report.msgs.failure)
);
},
sortnumberOfHb(a, b) {
return (
Number(a.raw_report.msgs.numberOfHb) -
Number(b.raw_report.msgs.numberOfHb)
);
},
sortfreeNumbers(a, b) {
return (
parseInt(a.raw_report.msgs.freeROM) -
parseInt(b.raw_report.msgs.freeROM)
);
},
sortNote(a, b) {
// 确保 a和b都是字符串如果不是则转换为字符串
const aValue = a.comment === null ? "" : String(a.comment);
const bValue = b.comment === null ? "" : String(b.comment);
// const aValue = typeof a === "string" ? a : String(a);
// const bValue = typeof b === "string" ? b : String(b);
// 处理null值将它们视为最低优先级
if (aValue === "" || bValue === "") {
return aValue === "" ? 1 : -1; // 空字符串排在非空字符串后面
}
console.log(aValue, bValue);
// 使用localeCompare进行中文排序
return aValue.localeCompare(bValue, "zh-Hans-CN", {
sensitivity: "base",
});
},
// sortSignature1(a, b) {
// return (
// Number(a.raw_report.msgs.signature1.split("/")[0]) -
// Number(b.raw_report.msgs.signature1.split("/")[0])
// );
// },
// sortSignature2(a, b) {
// return (
// Number(a.raw_report.msgs.signature2.split("/")[0]) -
// Number(b.raw_report.msgs.signature2.split("/")[0])
// );
// },
//获取运维勾选和快心跳勾选个数
getNumber() {
console.log(this.tableData);
this.ywNumber = this.tableData.filter(
(item) => item.in_maintain == 1
).length;
this.kxtNumber = this.tableData.filter(
(item) => item.quick_hb == 1
).length;
console.log("我这里是运维和快心跳的数据");
console.log(this.ywNumber, this.kxtNumber);
if (
this.ywNumber == this.tableData.length &&
this.tableData.length !== 0
) {
this.checkAllYW = true;
} else {
this.checkAllYW = false;
}
if (
this.kxtNumber == this.tableData.length &&
this.tableData.length !== 0
) {
this.checkAllKXT = true;
} else {
this.checkAllKXT = false;
}
// this.freeNum =
// this.$refs.ywMultipleTable.$el.getElementsByClassName(
// "has-color"
// ).length;
},
//导出表格
// handleExport() {
// htmlToExcel.getExcel("#ywTable", "设备运维信息");
// },
//导出表格
handleExport() {
// 准备 CSV 文件的头部信息
const headers = [
"出厂ID",
"装置编号",
"状态",
"最后心跳时间",
"传图",
"规约",
"电池状态",
"心跳次数",
"心跳周期",
"CMA消息",
"拍照计划/实际",
"拍照成功",
"拍照失败",
"卡1信号",
"卡2信号",
"网络错误",
"系统重启",
"I1重启",
"SIM卡1",
"SIM卡2",
"CMA服务器",
"磁盘剩余空间",
"I1版本",
"运维版本",
"camera版本",
"AI版本",
"MCU版本",
];
// 准备 CSV 文件的内容数据
//let csvContent = headers.join(",") + "\n";
let csvContent = headers.map((header) => `"${header}"`).join(",") + "\n"; // 对所有头部使用双引号
this.tableData.forEach((item) => {
const rawReport = item.raw_report;
const msgs = item.raw_report.msgs;
// 处理 raw_report 数据
const rawReportData = [
item.oid,
item.cmdid,
this.nowTime - item.last_heartbeat_ts <= 720 ? "在线" : "离线",
item.last_heartbeat,
rawReport.pic || "",
this.protocolMap[item.protocol],
msgs.battery || "",
msgs.numberOfHb || "",
msgs.heartbeatDuration || "",
msgs.recv || "",
//msgs.photoTimes || "",
String(msgs.photoTimes + "," || ""), // 确保是字符串
msgs.success || "",
msgs.failure || "",
msgs.signature1 || "",
msgs.signature2 || "",
msgs.networkError || "",
msgs.rebootTimes || "",
msgs.i1RebootTimes || "",
// msgs.simcard1 || "",
// msgs.simcard2 || "",
String(msgs.simcard1 + "," || ""), // 确保是字符串
String(msgs.simcard2 + "," || ""), // 确保是字符串
msgs.freeROM || "",
msgs.cma || "",
msgs.i1Version || "",
msgs.maintainVersion || "",
msgs.cameraService || "",
msgs.aiVersion || "",
msgs.mcu || "",
];
// 如果需要处理 msgs 数据,可以在这里添加逻辑
// 将数据添加到 CSV 内容中
//csvContent += rawReportData.join(",") + "\n";
csvContent +=
rawReportData.map((value) => `"${value}"`).join(",") + "\n"; // 对每个值使用双引号
});
// 获取当前时间并格式化
const now = this.$moment(new Date());
const formattedTime = now.format("YYYY年MM月DD日HH时mm分"); // 格式化时间字符串,例如 "2023-04-01_15_30_00"
console.log(formattedTime);
// 创建CSV文件的Blob对象
const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8" });
// 使用FileSaver.js保存文件文件名后加上当前时间
saveAs(blob, `运维数据报表_${formattedTime}.csv`);
},
// 保存选中的数据id,row-key就是要指定一个key标识这一行的数据
getRowKey(row) {
return row.id;
},
handleSelectionChange(val) {
this.multipleSelection = val;
console.log(this.multipleSelection);
this.idArray = [];
for (let i = 0; i < this.multipleSelection.length; i++) {
this.idArray.push(this.multipleSelection[i].id);
}
this.idArray = [...new Set(this.idArray)];
console.log("1", this.idArray);
},
isRed({ row }) {
const checkIdList = this.multipleSelection.map((item) => item.id);
if (checkIdList.includes(row.id)) {
return {
background: "#d0ece8!important",
};
}
},
// 点击装置名称
handleMsgClick(val) {
console.log(val);
this.$refs.rowMsgDialogref.display(val);
},
handlecheckAllYW(val) {
console.log(val);
if (val) {
console.log("我全选了了运维了");
console.log(this.tableData);
this.termidsArray = [];
for (let i = 0; i < this.tableData.length; i++) {
this.termidsArray.push(this.tableData[i].id);
}
this.termidsArray = [...new Set(this.termidsArray)];
console.log(this.termidsArray);
getdoActionApi({
act: "mntn",
termIds: this.termidsArray.join("-"),
mntn: 1,
})
.then((res) => {
console.log(res);
this.$parent.onSubmit();
})
.catch((err) => {});
} else {
console.log("我取消了运维全选了");
console.log(this.tableData);
this.termidsArray = [];
for (let i = 0; i < this.tableData.length; i++) {
this.termidsArray.push(this.tableData[i].id);
}
this.termidsArray = [...new Set(this.termidsArray)];
console.log(this.termidsArray);
getdoActionApi({
act: "mntn",
termIds: this.termidsArray.join("-"),
mntn: 0,
})
.then((res) => {
console.log(res);
this.$parent.onSubmit();
})
.catch((err) => {});
}
},
//运维
UpdateMaintainMode(val, row) {
console.log("运维");
console.log(val, row);
getdoActionApi({
act: "mntn",
termId: row.id,
mntn: val,
})
.then((res) => {
console.log(res);
})
.catch((err) => {});
},
//快心跳
handlecheckAllKXT(val) {
console.log(val);
if (val) {
console.log("我全选了快心跳了");
console.log(this.tableData);
this.termidsArray = [];
for (let i = 0; i < this.tableData.length; i++) {
this.termidsArray.push(this.tableData[i].id);
}
this.termidsArray = [...new Set(this.termidsArray)];
console.log(this.termidsArray);
getdoActionApi({
act: "quickhb",
termIds: this.termidsArray.join("-"),
quickhb: 1,
})
.then((res) => {
console.log(res);
this.$parent.onSubmit();
})
.catch((err) => {});
} else {
console.log("我取消了运维全选了");
console.log(this.tableData);
this.termidsArray = [];
for (let i = 0; i < this.tableData.length; i++) {
this.termidsArray.push(this.tableData[i].id);
}
this.termidsArray = [...new Set(this.termidsArray)];
console.log(this.termidsArray);
getdoActionApi({
act: "quickhb",
termIds: this.termidsArray.join("-"),
quickhb: 0,
})
.then((res) => {
console.log(res);
this.$parent.onSubmit();
})
.catch((err) => {});
}
},
//快心跳
UpdateQuickHbMode(val, row) {
console.log("快心跳");
getdoActionApi({
act: "quickhb",
termId: row.id,
quickhb: val,
})
.then((res) => {
console.log(res);
})
.catch((err) => {});
},
//下发命令
onIssue() {
console.log(this.formIssue.operate);
console.log(this.multipleSelection);
if (this.formIssue.operate == "") {
this.$message({
duration: 1500,
showClose: true,
message: "请选择运维操作",
type: "warning",
});
return;
}
if (this.multipleSelection.length == 0) {
this.$message({
duration: 1500,
showClose: true,
message: "至少选中一个设备",
type: "warning",
});
return;
}
this.$parent.fetchData();
switch (this.formIssue.operate) {
case 1:
console.log("重启");
var params = {
act: "reset",
termIds: this.idArray.join("-"),
};
this.changeIssue(params);
return;
case 2:
console.log("重启MCU");
var params = {
act: "reset-mcu",
termIds: this.idArray.join("-"),
};
this.changeIssue(params);
return;
case 3:
console.log("设置I1服务器");
this.ieVisible = true;
return;
case 4:
console.log("设置运维服务器");
this.operationVisible = true;
return;
case 5:
console.log("设置心跳周期");
this.heartBeatVisible = true;
return;
case 6:
console.log("上传日志");
var params = {
act: "upload-logs",
url: "http://180.166.218.222:40101/upload/",
termIds: this.idArray.join("-"),
};
this.changeIssue(params);
return;
case 7:
console.log("升级");
this.upgradationVisible = true;
this.getUpgradeList();
return;
case 8:
console.log("开启frpc");
this.frpcVisible = true;
return;
case 9:
console.log("停止frpc");
var params = {
act: "stop-frpc",
termIds: this.idArray.join("-"),
};
this.changeIssue(params);
return;
case 10:
console.log("停止老化测试");
var params = {
act: "stop-aging-test",
termIds: this.idArray.join("-"),
};
this.changeIssue(params);
return;
case 11:
console.log("升级Ota");
this.upgradationVisibleOta = true;
this.getUpgradeOtaList();
return;
}
},
//执行操作
changeIssue(params) {
getdoActionApi(params)
.then((res) => {
console.log(res);
this.$refs.ywMultipleTable.clearSelection();
this.idArray = [];
console.log(this.multipleSelection);
})
.catch((err) => {});
},
//点击ie服务器确定
handleIeServe() {
console.log(this.$refs.ieRuleForm);
this.$refs.ieRuleForm.validate((valid) => {
if (valid) {
var params = {
act: "set-cma",
ip: this.ieform.ip,
port: this.ieform.port,
termIds: this.idArray.join("-"),
};
this.changeIssue(params);
this.ieVisible = false;
}
});
},
//点击运维服务器确定
handleOperationServe() {
console.log(this.$refs.operationRuleForm);
this.$refs.operationRuleForm.validate((valid) => {
if (valid) {
var params = {
act: "set-mntn",
ip: this.operationform.ip,
port: this.operationform.port,
termIds: this.idArray.join("-"),
};
this.changeIssue(params);
this.operationVisible = false;
}
});
},
//点击运维服务器确定
handleheartBeat() {
console.log(this.$refs.heartBeatRuleForm);
this.$refs.heartBeatRuleForm.validate((valid) => {
if (valid) {
var params = {
act: "set-hb",
hb: this.heartBeatform.heart,
termIds: this.idArray.join("-"),
};
this.changeIssue(params);
this.heartBeatVisible = false;
}
});
},
//获取升级apkList
getUpgradeList() {
getqueryUpgradesApi()
.then((res) => {
console.log(res);
this.upOptions = res.data.filter(item => item.type === "0");
})
.catch((err) => {});
},
//获取Ota升级apkList
getUpgradeOtaList() {
getqueryUpgradesApi()
.then((res) => {
console.log(res);
this.upOptionsOta = res.data.filter(item => item.type === "1");
})
.catch((err) => {});
},
selectChanged(val) {
console.log(val);
// 找到选中项的整个object对象
this.selectUpObj = this.upOptions.find((item) => {
return item["path"] === val;
});
console.log(this.selectUpObj);
},
selectChangedOta(val) {
console.log(val);
// 找到选中项的整个object对象
this.selectUpObjOta = this.upOptionsOta.find((item) => {
return item["path"] === val;
});
console.log(this.selectUpObj);
},
//升级确定阿
handleupgradation() {
this.$refs.upgradationRuleForm.validate((valid) => {
if (valid) {
var params = {
act: "upgrade",
url: this.upgradationform.upVal,
md5: this.selectUpObj.md5,
fn: this.selectUpObj.fileName,
termIds: this.idArray.join("-"),
};
this.changeIssue(params);
this.upgradationVisible = false;
}
});
},
//升级OTa确定阿
handleupgradationOta() {
this.$refs.upgradationRuleFormOta.validate((valid) => {
if (valid) {
var params = {
act: "upd-ota",
url: this.upgradationformOta.upVal,
md5: this.selectUpObjOta.md5,
fn: this.selectUpObjOta.fileName,
termIds: this.idArray.join("-"),
};
this.changeIssue(params);
this.upgradationVisibleOta = false;
}
});
},
//点击模板
handleModelForm() {
this.frpcform = {
// ip: "",
// port: "",
server_addr: "180.166.218.222",
server_port: 40204,
frpc_type: "adb",
type: "tcp",
local_ip: "127.0.0.1",
local_port: 5555,
remote_port: 40205,
};
},
//开启frpc
handleFrpc() {
console.log(this.$refs.frpcRuleForm);
this.$refs.frpcRuleForm.validate((valid) => {
if (valid) {
var params = {
act: "start-frpc",
server_addr: this.frpcform.server_addr,
server_port: this.frpcform.server_port,
local_ip: this.frpcform.local_ip,
local_port: this.frpcform.local_port,
remote_port: this.frpcform.remote_port,
frpc_type: this.frpcform.frpc_type,
type: this.frpcform.type,
termIds: this.idArray.join("-"),
};
this.changeIssue(params);
this.frpcVisible = false;
}
});
},
saveLocalStorage() {
localStorage.setItem("gycheck", this.gycheck);
localStorage.setItem("dccheck", this.dccheck);
localStorage.setItem("xtcheck", this.xtcheck);
// localStorage.setItem("xtcs", this.xtcs);
// localStorage.setItem("xtzq", this.xtzq);
localStorage.setItem("pzcheck", this.pzcheck);
localStorage.setItem("wlcheck", this.wlcheck);
localStorage.setItem("cqcheck", this.cqcheck);
localStorage.setItem("cmacheck", this.cmacheck);
localStorage.setItem("simcheck", this.simcheck);
localStorage.setItem("i1check", this.i1check);
localStorage.setItem("ywbbcheck", this.ywbbcheck);
localStorage.setItem("Cameracheck", this.Cameracheck);
localStorage.setItem("AIcheck", this.AIcheck);
localStorage.setItem("MCUcheck", this.MCUcheck);
localStorage.setItem("freecheck", this.freecheck);
localStorage.setItem("notecheck", this.notecheck);
localStorage.setItem("lastIpcheck", this.lastIpcheck);
this.adjustTableHeight();
},
loadLocalStorage() {
this.checkAllKXT = localStorage.getItem("checkAllKXT", this.checkAllKXT)
? JSON.parse(localStorage.getItem("checkAllKXT"))
: false;
this.checkAllYW = localStorage.getItem("checkAllYW", this.checkAllYW)
? JSON.parse(localStorage.getItem("checkAllYW"))
: false;
this.gycheck = localStorage.getItem("gycheck")
? JSON.parse(localStorage.getItem("gycheck"))
: true;
this.dccheck = localStorage.getItem("dccheck")
? JSON.parse(localStorage.getItem("dccheck"))
: false;
this.xtcheck = localStorage.getItem("xtcheck")
? JSON.parse(localStorage.getItem("xtcheck"))
: false;
// this.xtcs = localStorage.getItem("xtcs")
// ? JSON.parse(localStorage.getItem("xtcs"))
// : false;
// this.xtzq = localStorage.getItem("xtzq")
// ? JSON.parse(localStorage.getItem("xtzq"))
// : false;
this.pzcheck = localStorage.getItem("pzcheck")
? JSON.parse(localStorage.getItem("pzcheck"))
: false;
this.wlcheck = localStorage.getItem("wlcheck")
? JSON.parse(localStorage.getItem("wlcheck"))
: false;
this.cqcheck = localStorage.getItem("cqcheck")
? JSON.parse(localStorage.getItem("cqcheck"))
: false;
this.simcheck = localStorage.getItem("simcheck")
? JSON.parse(localStorage.getItem("simcheck"))
: false;
this.cmacheck = localStorage.getItem("cmacheck")
? JSON.parse(localStorage.getItem("cmacheck"))
: true;
this.i1check = localStorage.getItem("i1check")
? JSON.parse(localStorage.getItem("i1check"))
: true;
this.ywbbcheck = localStorage.getItem("ywbbcheck")
? JSON.parse(localStorage.getItem("ywbbcheck"))
: true;
this.Cameracheck = localStorage.getItem("Cameracheck")
? JSON.parse(localStorage.getItem("Cameracheck"))
: false;
this.AIcheck = localStorage.getItem("AIcheck")
? JSON.parse(localStorage.getItem("AIcheck"))
: false;
this.MCUcheck = localStorage.getItem("MCUcheck")
? JSON.parse(localStorage.getItem("MCUcheck"))
: false;
this.freecheck = localStorage.getItem("freecheck")
? JSON.parse(localStorage.getItem("freecheck"))
: false;
this.notecheck = localStorage.getItem("notecheck")
? JSON.parse(localStorage.getItem("notecheck"))
: false;
this.lastIpcheck = localStorage.getItem("lastIpcheck")
? JSON.parse(localStorage.getItem("lastIpcheck"))
: false;
console.log(
"规约:" + this.gycheck,
"电池:" + this.dccheck,
"心跳:" + this.xtcheck,
"拍照:" + this.pzcheck,
"网络信号:" + this.wlcheck,
"重启次数:" + this.cqcheck,
"sim卡" + this.simcheck,
"cma服务器" + this.cmacheck,
"版本:" + this.ywbbcheck
);
},
adjustTableHeight() {
// 通过调用 window.resize 事件重新触发表格布局和渲染
const resizeEvent = new Event("resize");
window.dispatchEvent(resizeEvent);
// 或者使用 Vue 的 nextTick 方法来确保 DOM 更新完成后再执行调整操作
this.$nextTick(() => {
this.$refs.ywMultipleTable.doLayout(); // 调用 el-table 的 doLayout 方法重新布局
});
},
startCountdown() {
this.newupdatatime = new Date().getTime(); // 更新当前时间
// 清空之前可能存在的定时器
if (this.intervalId) {
clearInterval(this.intervalId);
}
// 开始倒计时每秒执行一次remainingTime方法
this.intervalId = setInterval(() => {
this.newupdatatime = new Date().getTime(); // 更新当前时间
this.tableData.forEach((item) => {
//console.log(item);
if (item.list) {
this.remainingTime(item.list[0]);
}
// let params = item.list[0];
// this.remainingTime(params); // 重新计算每个项目的剩余时间
});
}, 1000); // 每秒执行一次
},
remainingTime(item) {
if (!this.newupdatatime) {
// 更新时间尚未设置,返回默认的倒计时时间或者不执行任何操作
return "计算中...";
}
const estimatedPublishTime = item.estimatedPublishTime * 1000;
const difference = estimatedPublishTime - this.newupdatatime;
const minutes = Math.floor(difference / 60000);
const seconds = Math.floor((difference % 60000) / 1000);
if (minutes == 0 && seconds == 0) {
this.$parent.fetchData();
return `命令已下发`;
} else {
if (minutes < 10 && seconds < 10) {
return ` 0${minutes} : 0${seconds} `;
} else if (minutes < 10) {
return ` 0${minutes} : ${seconds} `;
} else if (seconds < 10) {
return ` ${minutes} : 0${seconds} `;
} else {
return ` ${minutes} : ${seconds} `;
}
}
},
//更新备注
handlecolEditClick({ $index, row }) {
this.cellIndex = $index;
},
handleCommentBlur({ row }) {
console.log(row);
updComment({
id: row.id,
comment: row.comment,
})
.then((res) => {
if (res.data) {
this.cellIndex = null;
} else {
this.$message({
duration: 1500,
showClose: true,
message: res.errorMsg,
type: "error",
});
}
})
.catch((err) => {});
},
},
beforeDestroy() {
window.removeEventListener("resize", this.calculateHeight);
},
};
</script>
<style lang="less">
.tableContain {
width: 100%;
height: 100%;
.headTitle {
display: flex;
align-items: center;
margin-bottom: 8px;
.xfMl {
.el-form-item--small.el-form-item {
margin-bottom: 0px;
}
.el-select {
width: 158px;
}
}
.zzMsg {
display: flex;
margin-left: auto;
margin-right: 44px;
.total {
margin-left: 8px;
//width: 100%;
height: 32px;
line-height: 32px;
font-size: 14px;
color: #333;
span {
margin-right: 4px;
}
.el-tag--info {
color: #333;
}
}
.drawBox {
//margin-left: auto;
}
}
}
#ywTable {
.el-input--small .el-input__inner {
height: 20px;
line-height: 20px;
}
}
.plTableBox {
/* */
// ::-webkit-scrollbar {
// height: 12px; /* */
// }
.el-table {
thead {
color: #333;
th {
background: #d3d3d3;
}
}
td {
text-align: center;
}
th {
padding: 0px;
}
th > .cell {
text-align: center;
}
.cell {
padding-left: 4px !important;
padding-right: 4px !important;
}
}
.hbClass {
.cell {
cursor: pointer;
&:hover {
color: #169e8c;
text-decoration: underline;
}
}
}
.has-color {
background: #ffb8b8;
}
.has-color td.el-table__cell {
background: #ffb8b8 !important;
}
.el-table__fixed::before {
height: 0px;
}
}
.ywTableBox {
color: #333;
.el-table__cell {
text-align: center;
.cell {
padding: 0px;
}
}
.bbStyle {
text-align: left;
.cell {
display: flex;
p {
display: inline;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
b {
margin-left: 4px;
}
}
}
}
.el-table--scrollable-y .el-table__body-wrapper {
height: calc(100% - 40px) !important;
}
.el-table__row .picBg {
background: #169e8c !important;
color: #fff;
}
th.el-table__cell {
background: #d3d3d3;
}
.noClass {
color: #333;
font-size: 12px;
line-height: 12px;
}
.redClass {
color: red;
font-weight: 700;
line-height: 12px;
span {
color: #333;
}
}
thead.is-group th.el-table__cell {
background: #d3d3d3;
}
tr {
background: #fff;
}
.el-table--striped
.el-table__body
tr.el-table__row--striped
td.el-table__cell {
background: #e9e9e8;
}
.el-table__body tr:hover > td.el-table__cell {
background: #e9e9e9;
}
thead {
color: #333;
}
.el-table--scrollable-y .el-table__body-wrapper {
height: 100% !important;
}
}
.el-table--small .el-table__cell {
padding: 4px 0px;
}
.el-table .caret-wrapper {
height: 24px;
width: 10px;
margin-left: 4px;
}
.el-table .sort-caret.ascending {
border-bottom-color: #666;
top: 0px;
left: 0px;
}
.el-table .ascending .sort-caret.ascending {
border-bottom-color: #169e8c;
}
.el-table .sort-caret.descending {
border-top-color: #666;
bottom: 2px;
left: 0px;
}
.el-table .descending .sort-caret.descending {
border-top-color: #169e8c;
}
//半选
.is-indeterminate .el-checkbox__input .el-checkbox__inner {
background-color: #169e8c;
border-color: #169e8c;
}
.is-indeterminate .el-checkbox__input .el-checkbox__inner:before {
content: "";
position: absolute;
display: block;
background-color: #fff;
height: 2px;
transform: scale(0.5);
left: 0;
right: 0;
top: 5px;
}
.drawerBox {
.el-drawer {
width: 240px !important;
.el-drawer__body {
padding: 16px;
color: #333;
.drawerSelect {
h3 {
font-size: 14px;
color: #333;
//font-weight: normal;
margin-bottom: 12px;
}
.selectBox {
display: flex;
flex-direction: column;
height: 32px;
line-height: 32px;
}
}
}
}
}
.upDialogBox {
.el-dialog {
.el-select {
width: 100%;
}
}
}
.frpcDialogBox {
.el-dialog__body {
.el-button--small {
padding: 5px 15px;
}
.el-form {
margin-top: 12px;
}
}
.el-select {
width: 100%;
}
}
.taskMask {
position: fixed;
bottom: 50%;
right: 0px;
z-index: 2;
.el-button {
border-radius: 50%;
padding: 10px;
}
}
.taskDrawDialog {
.commandList {
width: 100%;
height: calc(100% - 32px);
//background: #fcc;
overflow: auto;
p {
background: #fdf6ec;
margin-bottom: 8px;
line-height: 24px;
color: #333;
font-size: 14px;
padding: 6px;
cursor: pointer;
display: flex;
align-items: center;
&:hover {
background: #faecd8;
}
.indexClass {
padding: 4px;
font-size: 14px;
color: #000;
background: #d3d3d3;
min-width: 18px;
text-align: center;
margin-right: 8px;
}
.normalClass {
background: #d3d3d3;
}
.cancelClass {
background: #fde2e2;
}
.comMsg {
display: flex;
flex-wrap: wrap;
b {
font-weight: normal;
margin-right: 12px;
}
}
}
}
}
.redMlxf {
color: #f00;
b {
font-size: 12px;
font-weight: normal;
}
}
}
.contenBoxMsg {
p {
color: #333;
line-height: 24px;
font-size: 14px;
}
}
.el-select-dropdown__item {
i {
margin-left: 8px;
font-size: 12px;
font-style: normal;
}
}
</style>