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.

3447 lines
100 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.desc"
: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-item>
<el-button type="primary" @click="sendMsg">发送短信</el-button>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="editIccid">修改ICCID</el-button>
</el-form-item>
</el-form>
</div>
<div class="zzMsg">
<p class="total" v-if="showDiv">
<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>
<p class="total" v-else>
<el-popover
placement="top"
trigger="click"
popper-class="totalPopover"
>
<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
>
<el-button type="primary" slot="reference">数据统计</el-button>
</el-popover>
</p>
<el-dropdown @command="handleCommand">
<el-button type="primary" icon="el-icon-more" circle></el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="a">导出</el-dropdown-item>
<el-dropdown-item command="b">扩展列</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<!-- <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
:data-changes-scroll-top="false"
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].desc == '' || scope.row.list[0].desc == null
"
>{{ cmdCn[scope.row.list[0].name] }}</b
><b v-else>{{ scope.row.list[0].desc }}</b>
<b
v-if="
scope.row.list[0].estimatedPublishTime * 1000 - newupdatatime >
0
"
>
{{ remainingTime(scope.row.list[0]) }}
</b>
</span>
<span v-else>
{{
scope.row.mntnStatus.reportMap !== null &&
scope.row.mntnStatus.reportMap.hasOwnProperty("oid")
? scope.row.mntnStatus.reportMap.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="scope.row.onlinestatus == 1"
>在线</el-tag
>
<el-tag type="warning" v-if="scope.row.onlinestatus == 0"
>离线</el-tag
>
<el-tag type="danger" v-if="scope.row.onlinestatus == -1"
>异常</el-tag
>
</template>
</u-table-column>
<u-table-column
label="运维"
prop="mntnStatus.inMaintain"
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.mntnStatus.inMaintain"
:true-label="1"
:false-label="0"
@change="(val) => UpdateMaintainMode(val, scope.row)"
></el-checkbox>
</template>
</u-table-column>
<u-table-column
label="快心跳"
prop="mntnStatus.quickHb"
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.mntnStatus.quickHb"
:true-label="1"
:false-label="0"
@change="(val) => UpdateQuickHbMode(val, scope.row)"
></el-checkbox>
</template>
</u-table-column>
<u-table-column
prop="mntnStatus.rawReportTime"
label="最后心跳"
width="130"
:sortable="true"
class-name="hbClass"
>
<template slot-scope="scope">
<span
@click="handleMsgClick(scope.row)"
:title="formatLastHeartbeat(scope.row.mntnStatus.rawReportTime)"
>{{ formatLastHeartbeat(scope.row.mntnStatus.rawReportTime) }}</span
>
</template>
</u-table-column>
<u-table-column label="传图" key="ct">
<u-table-column
label="当天"
width="50"
class-name="picBg"
sortable
:sort-method="picSort"
>
<template slot-scope="scope">
{{
scope.row.mntnStatus.reportMap &&
scope.row.mntnStatus.reportMap.hasOwnProperty("uploads")
? Number(scope.row.mntnStatus.reportMap.uploads)
: 0
}}
</template>
</u-table-column>
<u-table-column
label="历史"
width="50"
class-name="picBg"
sortable
:sort-method="pichistorySort"
>
<template slot-scope="scope">
{{
scope.row.mntnStatus.reportMap &&
scope.row.mntnStatus.reportMap.hasOwnProperty("delayedUploads")
? Number(scope.row.mntnStatus.reportMap.delayedUploads)
: 0
}}
</template>
</u-table-column>
</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.mntnStatus.reportMap !== null &&
scope.row.mntnStatus.reportMap.hasOwnProperty('batteryVoltage') &&
scope.row.mntnStatus.reportMap.hasOwnProperty(
'batteryChargingVoltage'
) &&
scope.row.mntnStatus.reportMap.hasOwnProperty('batteryPower')
"
>
{{ scope.row.mntnStatus.reportMap.batteryVoltage }}V/{{
scope.row.mntnStatus.reportMap.batteryChargingVoltage
}}V/{{ scope.row.mntnStatus.reportMap.batteryPower }}
</span>
<span v-else>{{
scope.row.mntnStatus.reportMap !== null &&
scope.row.mntnStatus.reportMap.hasOwnProperty("battery")
? scope.row.mntnStatus.reportMap.battery
: ""
}}</span>
</template>
</u-table-column>
<u-table-column label="心跳信息" v-if="xtcheck" key="xt">
<u-table-column
label="次数"
min-width="48"
sortable
prop="mntnStatus.reportMap.numberOfHb"
:sort-method="sortnumberOfHb"
>
<template slot-scope="scope">
<span>
{{
scope.row.mntnStatus.reportMap &&
scope.row.mntnStatus.reportMap.hasOwnProperty("numberOfHb")
? Number(scope.row.mntnStatus.reportMap.numberOfHb)
: 0
}}
</span>
</template>
</u-table-column>
<u-table-column label="周期" min-width="48">
<template slot-scope="scope">
<span>{{
scope.row.mntnStatus.reportMap !== null &&
scope.row.mntnStatus.reportMap.hasOwnProperty("heartbeatDuration")
? scope.row.mntnStatus.reportMap.heartbeatDuration
: 0
}}</span>
</template>
</u-table-column>
<u-table-column label="CMA消息" min-width="48">
<template slot-scope="scope">
<span
v-if="
scope.row.mntnStatus.reportMap !== null &&
scope.row.mntnStatus.reportMap.hasOwnProperty('XyDev')
"
>
<el-tooltip class="item" effect="dark" placement="top">
<div slot="content">
lastHbTime
{{
$moment(
scope.row.mntnStatus.reportMap.lastHbTime * 1000
).format("YYYY-MM-DD HH:mm:ss")
}}
<br />
lastHbRespTime
{{
$moment(
scope.row.mntnStatus.reportMap.lastHbRespTime * 1000
).format("YYYY-MM-DD HH:mm:ss")
}}
</div>
<span>
{{
$moment(
scope.row.mntnStatus.reportMap.lastRecvTime * 1000
).format("HH:mm")
}}</span
>
</el-tooltip>
</span>
<span v-else> {{ scope.row.mntnStatus.reportMap.recv }}</span>
<!-- <span>{{
scope.row.mntnStatus.reportMap !== null &&
scope.row.mntnStatus.reportMap.hasOwnProperty("recv")
? scope.row.mntnStatus.reportMap.recv
: 0
}}</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>{{
scope.row.mntnStatus.reportMap !== null &&
scope.row.mntnStatus.reportMap.hasOwnProperty("photoTimes")
? scope.row.mntnStatus.reportMap.photoTimes
: 0
}}</span>
</template>
</u-table-column>
<u-table-column
label="成功"
min-width="48"
sortable
:sort-method="sortSuccess"
>
<template slot-scope="scope">
<span>{{
scope.row.mntnStatus.reportMap !== null &&
scope.row.mntnStatus.reportMap.hasOwnProperty("success")
? Number(scope.row.mntnStatus.reportMap.success)
: 0
}}</span>
</template>
</u-table-column>
<u-table-column
label="失败"
min-width="48"
sortable
:sort-method="sortFailure"
>
<template slot-scope="scope">
<span>{{
scope.row.mntnStatus.reportMap !== null &&
scope.row.mntnStatus.reportMap.hasOwnProperty("failure")
? Number(scope.row.mntnStatus.reportMap.failure)
: 0
}}</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">
<span
v-if="
scope.row.mntnStatus.reportMap !== null &&
scope.row.mntnStatus.reportMap.hasOwnProperty('XyDev')
"
>
{{ scope.row.mntnStatus.reportMap.signalLevel1 }}
</span>
<span v-else>
<el-tooltip
class="item"
effect="dark"
:content="
scope.row.mntnStatus.reportMap !== null &&
scope.row.mntnStatus.reportMap.hasOwnProperty('signature1')
? scope.row.mntnStatus.reportMap.signature1
: ''
"
placement="top"
>
<span>{{
scope.row.mntnStatus.reportMap !== null &&
scope.row.mntnStatus.reportMap.hasOwnProperty("signature1")
? scope.row.mntnStatus.reportMap.signature1.split("/")[0]
: ""
}}</span>
</el-tooltip>
</span>
</template>
</u-table-column>
<u-table-column label="卡2" min-width="60" prop="signature2">
<template slot-scope="scope">
<span
v-if="
scope.row.mntnStatus.reportMap !== null &&
scope.row.mntnStatus.reportMap.hasOwnProperty('XyDev')
"
>
{{ scope.row.mntnStatus.reportMap.signalLevel2 }}
</span>
<span v-else>
<el-tooltip
class="item"
effect="dark"
:content="
scope.row.mntnStatus.reportMap !== null &&
scope.row.mntnStatus.reportMap.hasOwnProperty('signature2')
? scope.row.mntnStatus.reportMap.signature2
: ''
"
placement="top"
>
<span>{{
scope.row.mntnStatus.reportMap !== null &&
scope.row.mntnStatus.reportMap.hasOwnProperty("signature2")
? scope.row.mntnStatus.reportMap.signature2.split("/")[0]
: ""
}}</span>
</el-tooltip>
</span>
</template>
</u-table-column>
<u-table-column
label="错误"
min-width="48"
prop="networkError"
sortable
:sort-method="sortNumbersErr"
>
<template slot-scope="scope">
<span>{{
scope.row.mntnStatus.reportMap !== null &&
scope.row.mntnStatus.reportMap.hasOwnProperty("networkError")
? Number(scope.row.mntnStatus.reportMap.networkError)
: 0
}}</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="sortRebootTimes"
>
<template slot-scope="scope">
<span>{{
scope.row.mntnStatus.reportMap !== null &&
scope.row.mntnStatus.reportMap.hasOwnProperty("rebootTimes")
? Number(scope.row.mntnStatus.reportMap.rebootTimes)
: 0
}}</span>
</template>
</u-table-column>
<u-table-column
label="I1"
min-width="48"
prop="i1RebootTimes"
sortable
:sort-method="sortI1Reb"
>
<template slot-scope="scope">
<span>{{
scope.row.mntnStatus.reportMap !== null &&
scope.row.mntnStatus.reportMap.hasOwnProperty("i1RebootTimes")
? Number(scope.row.mntnStatus.reportMap.i1RebootTimes)
: 0
}}</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 @dblclick="handleCopyClick1(scope.row.mntnStatus)">{{
scope.row.mntnStatus.reportMap !== null &&
scope.row.mntnStatus.reportMap.hasOwnProperty("simcard1")
? scope.row.mntnStatus.reportMap.simcard1
: ""
}}</span>
</template>
</u-table-column>
<u-table-column label="卡2ICCID" width="158" prop="simcard2">
<template slot-scope="scope">
<span @dblclick="handleCopyClick2(scope.row.mntnStatus)">{{
scope.row.mntnStatus.reportMap !== null &&
scope.row.mntnStatus.reportMap.hasOwnProperty("simcard2")
? scope.row.mntnStatus.reportMap.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>{{
scope.row.mntnStatus.reportMap !== null &&
scope.row.mntnStatus.reportMap.hasOwnProperty("freeROM")
? scope.row.mntnStatus.reportMap.freeROM
: ""
}}</span>
</template>
</u-table-column>
<u-table-column label="CMA服务器" v-if="cmacheck" width="140" key="cma">
<template slot-scope="scope">
<span>{{
scope.row.mntnStatus.reportMap !== null &&
scope.row.mntnStatus.reportMap.hasOwnProperty("cma")
? scope.row.mntnStatus.reportMap.cma
: ""
}}</span>
</template>
</u-table-column>
<u-table-column label="I1版本" v-if="i1check" min-width="192" key="I1">
<template slot-scope="scope">
<span>{{
scope.row.mntnStatus.reportMap !== null &&
scope.row.mntnStatus.reportMap.hasOwnProperty("i1Version")
? scope.row.mntnStatus.reportMap.i1Version
: ""
}}</span>
</template>
</u-table-column>
<u-table-column
label="运维版本"
v-if="ywbbcheck"
min-width="248 "
key="ywbb"
>
<template slot-scope="scope">
<span>{{
scope.row.mntnStatus.reportMap !== null &&
scope.row.mntnStatus.reportMap.hasOwnProperty("maintainVersion")
? scope.row.mntnStatus.reportMap.maintainVersion
: ""
}}</span>
</template>
</u-table-column>
<u-table-column
label="Camera版本"
v-if="Cameracheck"
min-width="80"
key="Camera"
>
<template slot-scope="scope">
<span>{{
scope.row.mntnStatus.reportMap !== null &&
scope.row.mntnStatus.reportMap.hasOwnProperty("cameraVersion")
? scope.row.mntnStatus.reportMap.cameraVersion
: ""
}}</span>
</template>
</u-table-column>
<u-table-column label="AI版本" v-if="AIcheck" min-width="80" key="AI">
<template slot-scope="scope">
<span>{{
scope.row.mntnStatus.reportMap !== null &&
scope.row.mntnStatus.reportMap.hasOwnProperty("aiVersion")
? scope.row.mntnStatus.reportMap.aiVersion
: ""
}}</span>
</template>
</u-table-column>
<u-table-column label="MCU版本" v-if="MCUcheck" min-width="210" key="MCU">
<template slot-scope="scope">
<span>{{
scope.row.mntnStatus.reportMap !== null &&
scope.row.mntnStatus.reportMap.hasOwnProperty("mcuVersion")
? scope.row.mntnStatus.reportMap.mcuVersion
: ""
}}</span>
</template>
</u-table-column>
<u-table-column label="固件版本" v-if="fwcheck" min-width="210" key="fw">
<template slot-scope="scope">
<span>{{
scope.row.mntnStatus.reportMap !== null &&
scope.row.mntnStatus.reportMap.hasOwnProperty("XyDev")
? scope.row.mntnStatus.reportMap.firmware
: ""
}}</span>
</template>
</u-table-column>
<u-table-column
label="装置IP"
v-if="lastIpcheck"
width="120"
key="lastIp"
>
<template slot-scope="scope">
<span> {{ scope.row.mntnStatus.lastIp }}</span>
</template>
</u-table-column>
<u-table-column label="算法" width="120">
<template slot-scope="scope">
<span> {{ scope.row.mntnStatus.reportMap.night415 }}</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.mntnStatus.comment"
@blur="handleCommentBlur(scope)"
placeholder="请输入备注"
></el-input>
<span v-else :title="scope.row.mntnStatus.comment">{{
scope.row.mntnStatus.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="fwcheck" @change="saveLocalStorage"
>固件版本</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="设置CMA服务器"
: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"
filterable
>
<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"
filterable
>
<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>
<!-- 删除文件 -->
<el-dialog
title="删除文件"
:visible.sync="deleteFileVisible"
:close-on-click-modal="false"
width="504px"
class="deleteDialog"
>
<el-form :model="delFileForm" ref="delFileFormref" :rules="delFileRules">
<el-form-item label="删除文件路径:" prop="delFile">
<el-input v-model="delFileForm.delFile"></el-input>
</el-form-item>
<ul>
<li
v-for="(item, index) in pullpathOption"
@click="handleDelPath(item)"
>
{{ item.desc }}{{ item.name }}
</li>
</ul>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="deleteFileVisible = false">取 消</el-button>
<el-button type="primary" @click="handleDelete">确 定</el-button>
</div>
</el-dialog>
<!-- 下载文件 -->
<el-dialog
title="拉取文件"
:visible.sync="pullFileVisible"
:close-on-click-modal="false"
width="504px"
class="pullBoxDialog"
>
<el-form
:model="pullFileForm"
ref="pullFileFormref"
:rules="pullFileRules"
>
<el-form-item label="文件路径:" prop="pullFile">
<el-input
type="textarea"
:autosize="{ minRows: 2, maxRows: 6 }"
v-model="pullFileForm.pullFile"
></el-input>
</el-form-item>
<!-- <el-checkbox-group
v-model="checkedName"
@change="handleCheckedCitiesChange"
>
<el-checkbox
v-for="(item, index) in pullpathOption"
:label="item.name"
:key="item.name"
>{{ item.desc }}{{ item.name }}</el-checkbox
>
</el-checkbox-group> -->
<ul>
<li
@click="handlepullPath(item)"
v-for="(item, index) in pullpathOption"
:key="item.name"
>
{{ item.desc }}{{ item.name }}
</li>
</ul>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="pullFileVisible = false">取 消</el-button>
<el-button type="primary" @click="handlePull">确 定</el-button>
</div>
</el-dialog>
<!-- 上传文件base64 -->
<el-dialog
class="pushBoxDialog"
title="推送文件"
:visible.sync="pushFileVisible"
:close-on-click-modal="false"
width="504px"
v-loading="pushLoading"
>
<el-form
:model="pushFileForm"
ref="pushFileFormref"
:rules="pushFileRules"
>
<el-form-item label="文件路径:" prop="name">
<el-input v-model="pushFileForm.name"></el-input>
</el-form-item>
<ul>
<li v-for="(item, index) in pathOption" @click="handlePath(item)">
{{ item.desc }}{{ item.name }}
</li>
</ul>
<el-form-item label="文件上传:">
<el-upload
class="upload-demo"
ref="upload"
action="#"
:before-upload="beforeUpload"
:auto-upload="false"
>
<el-button slot="trigger" size="small" type="primary"
>选取文件</el-button
>
</el-upload>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="pushFileVisible = false">取 消</el-button>
<el-button type="primary" @click="handlePush">确 定</el-button>
</div>
</el-dialog>
<!-- 上传大文件 -->
<el-dialog
class="configDialogBox"
title="请选择配置文件"
:visible.sync="configVisible"
:close-on-click-modal="false"
width="30%"
>
<el-form :model="configform" :rules="configRules" ref="configRuleForm">
<el-form-item label="文件路径:" prop="pathVal">
<el-input v-model="configform.pathVal"></el-input>
</el-form-item>
<ul>
<li
v-for="(item, index) in bigpathOption"
@click="handlebigPath(item)"
>
{{ item.desc }}{{ item.name }}
</li>
</ul>
<el-form-item label="文件名称" prop="upVal">
<el-select
v-model="configform.upVal"
placeholder="请选择文件"
@change="selectChangedconfig"
filterable
>
<el-option
v-for="item in configOptions"
: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="configVisible = false">取 消</el-button>
<el-button type="primary" @click="handleconfig">确 定</el-button>
</div>
</el-dialog>
<!-- 发送短信 -->
<el-dialog
title="发送短信"
:visible.sync="senMsgVisible"
:close-on-click-modal="false"
width="504px"
class="senMsgDialog"
>
<el-form :model="sendForm" ref="sendFormref">
<el-form-item label="输入短息内容:" prop="msginfo">
<el-input
type="textarea"
:autosize="{ minRows: 2, maxRows: 4 }"
placeholder="请输入内容"
v-model="sendForm.msginfo"
></el-input>
</el-form-item>
<ul>
<li v-for="(item, index) in sendOption" @click="handleSend(item)">
{{ item.name }}{{ item.value }}
</li>
</ul>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="senMsgVisible = false">取 消</el-button>
<el-button type="primary" @click="handlemsgSend">发送短信</el-button>
<el-button type="primary" @click="handlemsgList">查询短信</el-button>
</div>
</el-dialog>
<!-- 修改ICCID -->
<editIccid
ref="iccidRef"
:multipleSelection="multipleSelection"
></editIccid>
<!-- 短信接收记录 -->
<msgList
ref="msglistRef"
:msgtype="msgtype"
:msgListData="msgListData"
:msgCompany="msgCompany"
:multipleSelection="multipleSelection"
></msgList>
<!-- 修改配置文件 -->
<config ref="configRef" :multipleSelection="multipleSelection"></config>
<!-- -->
<el-dialog
title="列出目录下文件名"
:visible.sync="fileContentVisible"
:close-on-click-modal="false"
width="504px"
class="fileContentDialog"
>
<el-form
:model="fileContentForm"
ref="fileContentFormref"
:rules="fileContentRules"
>
<el-form-item label="目录路径:" prop="fileContent">
<el-input v-model="fileContentForm.fileContent"></el-input>
</el-form-item>
<el-form-item label="包含的字符串:" prop="filtername">
<el-input v-model="fileContentForm.filtername"></el-input>
</el-form-item>
<ul>
<li
v-for="(item, index) in filepathOption"
@click="handleFliePath(item)"
>
{{ item.desc }}{{ item.name }}
</li>
</ul>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="fileContentDialog = false">取 消</el-button>
<el-button type="primary" @click="handleFileDelete">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
cmdSendApi,
getCmdActionApi,
upgradeListApi,
updCommentApi,
sendMsgApi,
msglistApi,
} from "@/utils/api/index";
import rowMsgDialog from "./rowMsgDialog.vue";
import editIccid from "./editIccid.vue";
import msgList from "./msglist.vue";
import config from "./setConfig/config";
import htmlToExcel from "@/utils/htmlToExcel";
import { saveAs } from "file-saver";
import XLSX from "xlsx";
export default {
props: [
"tableData",
"onlineNum",
"offlineNum",
"noPicNum",
"freeNum",
"tableLoaidng",
"showDiv",
],
components: {
rowMsgDialog,
msgList,
config,
editIccid,
},
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: "升级",
yw_upd_ota: "Ota升级",
yw_cmd_start_frpc: "开启frpc",
yw_cmd_stop_frpc: "停止frpc",
i1_cmd_stop_aging_test: "停止老化测试",
del_file: "删除文件",
pull_files: "拉取文件",
push_file: "推送文件",
dl_file: "推送大文件",
},
taskdrawer: false,
drawer: false,
protocolMap: {
65280: "国网I1",
65296: "陕西",
65281: "安徽",
65282: "江苏",
65283: "湖南",
65284: "浙江",
65285: "河南全景",
65286: "河南郑州",
65290: "河南统一视频v2020",
65298: "宁夏",
2: "南网",
},
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,
fwcheck: false,
freecheck: false,
notecheck: false,
lastIpcheck: false,
//运维操作列表
operateOptions: [],
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: [],
//上传大文件
//升级
configVisible: false,
configform: {
upVal: "",
pathVal: "",
},
bigpathOption: [
{
name: "/sdcard/com.xypower.mpapp/data/recog/rp.dat",
desc: "AI识别文件",
},
{
name: "/sdcard/com.xypower.mpapp/data/recog/rb.dat",
desc: "AI识别文件",
},
],
selectconfigObj: {},
configRules: {
upVal: [
{ required: true, message: "请选择升级文件", trigger: "change" },
],
},
configOptions: [],
//设置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,
//设置删除文件
deleteFileVisible: false,
delFileForm: {
delFile: "",
},
delFileRules: {
delFile: [
{
required: true,
message: "请输入文件路径",
trigger: "blur",
},
],
},
//下载文件
pullFileVisible: false,
pullFileForm: {
pullFile: "",
},
pullFileRules: {
pullFile: [
{
required: true,
message: "请输入文件路径",
trigger: "blur",
},
],
},
pushLoading: false,
pathOption: [
{
name: "/sdcard/com.xypower.mpapp/data/App.json",
desc: "MpAPP全局配置",
},
{
name: "/sdcard/com.xypower.mpapp/data/recog.json",
desc: "AI全局配置",
},
{
name: "/sdcard/com.xypower.mpapp/data/bc.json",
desc: "电压电量配置",
},
{
name: "/sdcard/com.xypower.mpapp/data/channels/1.json",
desc: "通道拍照配置",
},
{
name: "/sdcard/com.xypower.mpapp/data/channels/2.json",
desc: "通道拍照配置",
},
{
name: "/sdcard/com.xypower.mpapp/data/imgparams/1",
desc: "图像参数配置",
},
{
name: "/sdcard/com.xypower.mpapp/data/imgparams/2",
desc: "图像参数配置",
},
{
name: "/sdcard/com.xypower.mpapp/data/videoparams/1",
desc: "短视频参数配置",
},
{
name: "/sdcard/com.xypower.mpapp/data/videoparams/2",
desc: "短视频参数配置",
},
{
name: "/sdcard/com.xypower.mpapp/data/videoparams/78",
desc: "采样配置",
},
{
name: "/sdcard/com.xypower.mpapp/data/recog/rp.dat",
desc: "AI识别文件",
},
{
name: "/sdcard/com.xypower.mpapp/data/recog/rb.dat",
desc: "AI识别文件",
},
{
name: "/sdcard/com.xypower.mpmaster/data/Master.json",
desc: "运维配置文件",
},
],
pullpathOption: [
{
name: "/sdcard/com.xypower.mpapp/data/App.json",
desc: "MpAPP全局配置",
},
{
name: "/sdcard/com.xypower.mpapp/data/recog.json",
desc: "AI全局配置",
},
{
name: "/sdcard/com.xypower.mpapp/data/bc.json",
desc: "电压电量配置",
},
{
name: "/sdcard/com.xypower.mpapp/data/channels/1.json",
desc: "通道拍照配置",
},
{
name: "/sdcard/com.xypower.mpapp/data/channels/2.json",
desc: "通道拍照配置",
},
{
name: "/sdcard/com.xypower.mpapp/data/imgparams/1",
desc: "图像参数配置",
},
{
name: "/sdcard/com.xypower.mpapp/data/imgparams/2",
desc: "图像参数配置",
},
{
name: "/sdcard/com.xypower.mpapp/data/videoparams/1",
desc: "短视频参数配置",
},
{
name: "/sdcard/com.xypower.mpapp/data/videoparams/2",
desc: "短视频参数配置",
},
{
name: "/sdcard/com.xypower.mpapp/data/videoparams/78",
desc: "采样配置",
},
{
name: "/sdcard/com.xypower.mpapp/data/recog/rp.dat",
desc: "AI识别文件",
},
{
name: "/sdcard/com.xypower.mpapp/data/recog/rb.dat",
desc: "AI识别文件",
},
{
name: "/sdcard/com.xypower.mpmaster/data/Master.json",
desc: "运维配置文件",
},
],
checkedName: [],
//上传文件base64
pushFileVisible: false,
fileList: [],
pushFileForm: {
name: "",
fileData: "",
},
pushFileRules: {
name: [
{
required: true,
message: "请输入文件路径",
trigger: "blur",
},
],
},
senMsgVisible: false,
sendForm: {
msginfo: "",
},
sendOption: [
{
name: "重启系统1",
value: "yw+at+stw21=1",
},
{
name: "重启系统2",
value: "at+stw21=1",
},
{
name: "重启MpApp",
value: "at+restart=mpapp",
},
{
name: "重启MpMaster格式",
value: "at+restart=mpmaster",
},
],
msgListData: [], //短信记录
msgCompany: "", //公司厂家
msgtype: "", //类型
companyMap: {
1: "大汉移动",
2: "公田移动rabchase",
3: "公田m2m10086",
4: "安徽",
},
//文件目录
fileContentVisible: false,
fileContentForm: {
fileContent: "",
filtername: "",
},
fileContentRules: {
fileContent: [
{
required: true,
message: "请输入文件路径",
trigger: "blur",
},
],
},
filepathOption: [
{
name: "/sdcard/com.xypower.mpapp/data/",
desc: "MpAPP配置目录",
},
{
name: "/sdcard/com.xypower.mpapp/photos/",
desc: "MpAPP照片目录",
},
{
name: "/sdcard/com.xypower.mpapp/sentPhotos/",
desc: "MpAPP已发送照片目录",
},
{
name: "/sdcard/com.xypower.mpapp/logs/",
desc: "MpAPP日志目录",
},
{
name: "/sdcard/com.xypower.mpmaster/data/",
desc: "运维配置目录",
},
{
name: "/sdcard/com.xypower.mpmaster/logs/",
desc: "运维日志目录",
},
{
name: "/data/system/dropbox/",
desc: "系统日志目录",
},
],
//iccid弹窗
iccidVisible: false,
};
},
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.$refs.ywMultipleTable.clearSelection();
this.$nextTick(() => {
this.startCountdown(); // 确保在 DOM 更新后执行
});
// this.startCountdown();
},
deep: true,
},
},
created() {
this.getCmdOptionsFun();
// this.multipleSelection = [];
// this.idArray = [];
},
methods: {
//复制
handleCopyClick1(row) {
console.log(row);
if (row.reportMap.hasOwnProperty("simcard1")) {
// alert(val);
var input = document.createElement("input"); // 创建input对象
input.value = row.reportMap.simcard1; // 设置复制内容
document.body.appendChild(input); // 添加临时实例
input.select(); // 选择实例内容
document.execCommand("Copy"); // 执行复制
document.body.removeChild(input); // 删除临时实例
//this.$message.success("复制成功!");
this.$message({
duration: 800,
showClose: true,
message: "复制成功!",
type: "success",
});
}
},
handleCopyClick2(row) {
console.log(row);
if (row.reportMap.hasOwnProperty("simcard2")) {
// alert(val);
var input = document.createElement("input"); // 创建input对象
input.value = row.reportMap.simcard2; // 设置复制内容
document.body.appendChild(input); // 添加临时实例
input.select(); // 选择实例内容
document.execCommand("Copy"); // 执行复制
document.body.removeChild(input); // 删除临时实例
//this.$message.success("复制成功!");
this.$message({
duration: 800,
showClose: true,
message: "复制成功!",
type: "success",
});
}
},
//获取命令列表
getCmdOptionsFun() {
getCmdActionApi()
.then((res) => {
console.log(res);
this.operateOptions = res.data;
})
.catch((err) => {});
},
formatLastHeartbeat(timestamp) {
return this.$moment(timestamp * 1000).format("YYYY-MM-DD HH:mm:ss");
},
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.mntnStatus ||
!row.mntnStatus.reportMap ||
!row.mntnStatus.reportMap.hasOwnProperty("freeROM")
) {
// 如果freeROM属性不存在返回默认类名
return "no-color";
}
const freeROMValue = row.mntnStatus.reportMap.freeROM;
const parsedValue = parseInt(freeROMValue, 10); // 使用基数10来确保解析为十进制数
if (parsedValue < 50) {
return "has-color";
}
},
//传图pic排序
picSort(a, b) {
// 确保 a 和 b 都有 mntnStatus.reportMap 对象
const aPic =
(a.mntnStatus.reportMap && a.mntnStatus.reportMap.uploads) || 0;
const bPic =
(b.mntnStatus.reportMap && b.mntnStatus.reportMap.uploads) || 0;
// 将 pic 转换为数字进行比较
const numA = Number(aPic);
const numB = Number(bPic);
// 根据需要进行升序或降序排序
// 这里假设你想要升序排序(从小到大)
return numA - numB;
// 如果你想要降序排序(从大到小),则返回 numB - numA
},
//历史传图
pichistorySort(a, b) {
// 确保 a 和 b 都有 mntnStatus.reportMap 对象
const aPic =
(a.mntnStatus.reportMap && a.mntnStatus.reportMap.delayedUploads) || 0;
const bPic =
(b.mntnStatus.reportMap && b.mntnStatus.reportMap.delayedUploads) || 0;
// 将 pic 转换为数字进行比较
const numA = Number(aPic);
const numB = Number(bPic);
// 根据需要进行升序或降序排序
// 这里假设你想要升序排序(从小到大)
return numA - numB;
// 如果你想要降序排序(从大到小),则返回 numB - numA
},
//心跳次数排序
sortnumberOfHb(a, b) {
const aNum =
(a.mntnStatus.reportMap && a.mntnStatus.reportMap.numberOfHb) || 0;
const bNum =
(b.mntnStatus.reportMap && b.mntnStatus.reportMap.numberOfHb) || 0;
const numA = Number(aNum);
const numB = Number(bNum);
return numA - numB;
},
//成功和失败
sortSuccess(a, b) {
const aNum =
(a.mntnStatus.reportMap && a.mntnStatus.reportMap.success) || 0;
const bNum =
(b.mntnStatus.reportMap && b.mntnStatus.reportMap.success) || 0;
const numA = Number(aNum);
const numB = Number(bNum);
return numA - numB;
},
sortFailure(a, b) {
const aNum =
(a.mntnStatus.reportMap && a.mntnStatus.reportMap.failure) || 0;
const bNum =
(b.mntnStatus.reportMap && b.mntnStatus.reportMap.failure) || 0;
const numA = Number(aNum);
const numB = Number(bNum);
return numA - numB;
},
//网络错误
sortNumbersErr(a, b) {
const aNum =
(a.mntnStatus.reportMap && a.mntnStatus.reportMap.networkError) || 0;
const bNum =
(b.mntnStatus.reportMap && b.mntnStatus.reportMap.networkError) || 0;
const numA = Number(aNum);
const numB = Number(bNum);
return numA - numB;
},
//重启次数
sortRebootTimes(a, b) {
const aNum =
(a.mntnStatus.reportMap && a.mntnStatus.reportMap.rebootTimes) || 0;
const bNum =
(b.mntnStatus.reportMap && b.mntnStatus.reportMap.rebootTimes) || 0;
const numA = Number(aNum);
const numB = Number(bNum);
return numA - numB;
},
//I1重启次数
sortI1Reb(a, b) {
const aNum =
(a.mntnStatus.reportMap && a.mntnStatus.reportMap.i1RebootTimes) || 0;
const bNum =
(b.mntnStatus.reportMap && b.mntnStatus.reportMap.i1RebootTimes) || 0;
const numA = Number(aNum);
const numB = Number(bNum);
return numA - numB;
},
sortfreeNumbers(a, b) {
// 确保 a 和 b 都有 mntnStatus.reportMap 对象,并且提取 pic 值
const aFree = a.mntnStatus.reportMap && a.mntnStatus.reportMap.freeROM;
const bFree = b.mntnStatus.reportMap && b.mntnStatus.reportMap.freeROM;
// 定义一个函数来将百分比字符串转换为数值,或者如果值为 null 或非百分比字符串,则返回 0
function parsePercentage(value) {
if (
value === null ||
typeof value !== "string" ||
!value.endsWith("%")
) {
return 0;
}
// 去除百分比符号,并将剩余的字符串转换为数值
const numberValue = parseFloat(value.slice(0, -1));
if (isNaN(numberValue)) {
return 0;
}
return numberValue;
}
// 转换 pic 值为数值进行比较
const numA = parsePercentage(aFree);
const numB = parsePercentage(bFree);
// 这里假设你想要升序排序(从小到大)
return numA - numB;
},
sortNote(a, b) {
// 确保 a和b都是字符串如果不是则转换为字符串
const aValue =
a.mntnStatus.comment === null ? "" : String(a.mntnStatus.comment);
const bValue =
b.mntnStatus.comment === null ? "" : String(b.mntnStatus.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",
});
},
//获取运维勾选和快心跳勾选个数
getNumber() {
console.log(this.tableData);
this.ywNumber = this.tableData.filter(
(item) => item.mntnStatus.inMaintain == 1
).length;
this.kxtNumber = this.tableData.filter(
(item) => item.mntnStatus.quickHb == 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() {
this.$parent.exportTable();
},
//更多功能
handleCommand(command) {
if (command == "a") {
this.handleExport();
}
if (command == "b") {
this.drawer = true;
}
},
// 保存选中的数据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);
cmdSendApi({
action: "mntn",
termIds: this.termidsArray,
mntnMode: 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);
cmdSendApi({
action: "mntn",
termIds: this.termidsArray,
mntnMode: 0,
})
.then((res) => {
console.log(res);
this.$parent.onSubmit();
})
.catch((err) => {});
}
},
//运维
UpdateMaintainMode(val, row) {
console.log("运维");
console.log(val, row);
cmdSendApi({
action: "mntn",
termIds: [row.id],
mntnMode: 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);
cmdSendApi({
action: "quickhb",
termIds: this.termidsArray,
quickHeartbeat: 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);
cmdSendApi({
action: "quickhb",
termIds: this.termidsArray,
quickHeartbeat: 0,
})
.then((res) => {
console.log(res);
this.$parent.onSubmit();
})
.catch((err) => {});
}
},
//快心跳
UpdateQuickHbMode(val, row) {
console.log("快心跳");
cmdSendApi({
action: "quickhb",
termIds: [row.id],
quickHeartbeat: 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 = {
action: "yw_cmd_android_reboot",
termIds: this.idArray,
};
this.changeIssue(params);
return;
case 2:
console.log("重启MCU");
var params = {
action: "yw_cmd_mcu_reboot",
termIds: this.idArray,
};
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("上传日志");
let logSetparam = JSON.parse(localStorage.getItem("logset"));
if (logSetparam !== null) {
console.log(logSetparam);
} else {
logSetparam = { noSpecData: 0, mTime: 0 };
}
var params = {
action: "yw_cmd_upload_i1_zip_log",
//url: "http://180.166.218.222:40101/upload/",
termIds: this.idArray,
noSpecData: Number(logSetparam.noSpecData),
mTime: Number(logSetparam.mTime),
};
this.changeIssue(params);
return;
case 7:
console.log("升级");
this.upgradationVisible = true;
this.getUpgradeList();
return;
case 8:
console.log("开启frpc");
this.frpcVisible = true;
if (JSON.parse(localStorage.getItem("frpcJson"))) {
this.frpcform = JSON.parse(localStorage.getItem("frpcJson"));
}
return;
case 9:
console.log("停止frpc");
var params = {
action: "yw_cmd_stop_frpc",
termIds: this.idArray,
};
this.changeIssue(params);
return;
case 10:
console.log("停止老化测试");
var params = {
action: "i1_cmd_stop_aging_test",
termIds: this.idArray,
};
this.changeIssue(params);
return;
case 11:
console.log("升级Ota");
this.upgradationVisibleOta = true;
this.getUpgradeOtaList();
return;
case 12:
console.log("删除文件");
this.deleteFileVisible = true;
return;
case 13:
console.log("上传文件base64");
this.pullFileVisible = true;
return;
case 14:
console.log("下载文件base64");
this.pushFileVisible = true;
return;
case 15:
console.log("修改配置文件");
// this.configVisible = true;
if (this.multipleSelection.length !== 1) {
this.$message({
duration: 1500,
showClose: true,
message: "只能选中一个设备",
type: "warning",
});
return;
}
this.$refs.configRef.display();
// this.getconfigList();
return;
case 16:
console.log("查看目录文件");
this.fileContentVisible = true;
return;
}
},
//下发短信
sendMsg() {
if (this.idArray.length !== 0) {
this.senMsgVisible = true;
} else {
this.$message({
duration: 1500,
showClose: true,
message: "最少选中一个设备",
type: "warning",
});
return;
}
},
//editIccid修改ICCICD
editIccid() {
if (this.idArray.length == 1) {
console.log(this.multipleSelection[0]);
this.$refs.iccidRef.display(this.multipleSelection[0]);
} else {
this.$message({
duration: 1500,
showClose: true,
message: "最多选中一个设备",
type: "warning",
});
return;
}
},
handleSend(item) {
console.log(item);
this.sendForm.msginfo = item.value;
},
//自定义输入
handlemsgSend() {
let params = {
termIdList: this.idArray,
content: this.sendForm.msginfo,
};
sendMsgApi(params)
.then((res) => {
console.log(res);
if (res.code == 200) {
this.$refs.ywMultipleTable.clearSelection();
this.$message({
duration: 1500,
showClose: true,
message: "短信下发成功",
type: "success",
});
this.senMsgVisible = false;
}
})
.catch((err) => {});
},
//查询短信
handlemsgList() {
msglistApi({
termId: this.idArray[0],
})
.then((res) => {
console.log(res);
if (res.code == 200) {
if (res.data !== null) {
this.msgListData = res.data.data;
this.msgCompany = this.companyMap[res.data.type];
this.msgtype = res.data.type;
this.$nextTick(() => {
this.$refs.msglistRef.display();
});
} else {
this.$message({
duration: 1500,
showClose: true,
message: this.companyMap[res.data.type] + "暂无短信记录",
type: "warning",
});
}
} else {
this.$message({
duration: 1500,
showClose: true,
message: res.msg,
type: "error",
});
}
})
.catch((err) => {});
},
//执行操作
changeIssue(params) {
cmdSendApi(params)
.then((res) => {
console.log(res);
if (res.code == 200) {
this.$refs.ywMultipleTable.clearSelection();
this.idArray = [];
console.log(this.multipleSelection);
console.log("我执行了命令");
this.$parent.fetchData();
this.pushLoading = false;
this.pushFileVisible = false;
}
})
.catch((err) => {});
},
//点击ie服务器确定
handleIeServe() {
console.log(this.$refs.ieRuleForm);
this.$refs.ieRuleForm.validate((valid) => {
if (valid) {
var params = {
action: "i1_cmd_set_i1_server_ip_port",
ip: this.ieform.ip,
port: this.ieform.port,
termIds: this.idArray,
};
this.changeIssue(params);
this.ieVisible = false;
}
});
},
//点击运维服务器确定
handleOperationServe() {
console.log(this.$refs.operationRuleForm);
this.$refs.operationRuleForm.validate((valid) => {
if (valid) {
var params = {
action: "i1_cmd_set_xy_yw_ip_port",
ip: this.operationform.ip,
port: this.operationform.port,
termIds: this.idArray,
};
this.changeIssue(params);
this.operationVisible = false;
}
});
},
//点击心跳设置确定
handleheartBeat() {
console.log(this.$refs.heartBeatRuleForm);
this.$refs.heartBeatRuleForm.validate((valid) => {
if (valid) {
var params = {
action: "i1_cmd_set_i1_heart_beat_time",
hb: this.heartBeatform.heart,
termIds: this.idArray,
};
this.changeIssue(params);
this.heartBeatVisible = false;
}
});
},
//获取升级apkList
getUpgradeList() {
upgradeListApi({ type: 0 })
.then((res) => {
console.log(res);
this.upOptions = res.data;
})
.catch((err) => {});
},
//获取Ota升级apkList
getUpgradeOtaList() {
upgradeListApi({ type: 1 })
.then((res) => {
console.log(res);
this.upOptionsOta = res.data;
})
.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 = {
action: "upgrade",
url: this.upgradationform.upVal,
md5: this.selectUpObj.md5,
fn: this.selectUpObj.fileName,
termIds: this.idArray,
};
this.changeIssue(params);
this.upgradationVisible = false;
}
});
},
//升级OTa确定阿
handleupgradationOta() {
this.$refs.upgradationRuleFormOta.validate((valid) => {
if (valid) {
var params = {
action: "yw_upd_ota",
url: this.upgradationformOta.upVal,
md5: this.selectUpObjOta.md5,
fn: this.selectUpObjOta.fileName,
termIds: this.idArray,
};
console.log(params);
this.changeIssue(params);
this.upgradationVisibleOta = false;
}
});
},
//点击模板
handleModelForm() {
this.frpcform = {
// ip: "",
// port: "",
//server_addr: "180.166.218.222",
server_addr: "61.169.135.146",
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) {
console.log(this.frpcform);
var params = {
action: "yw_cmd_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,
termId: this.idArray[0],
};
localStorage.setItem("frpcJson", JSON.stringify(this.frpcform));
this.changeIssue(params);
this.frpcVisible = false;
}
});
},
//删除文件
handleDelete() {
console.log(this.$refs.delFileFormref);
this.$refs.delFileFormref.validate((valid) => {
if (valid) {
var params = {
action: "del_file",
path: this.delFileForm.delFile,
termIds: this.idArray,
};
console.log(params);
this.changeIssue(params);
this.deleteFileVisible = false;
}
});
},
//查看目录文件
handleFileDelete() {
console.log(this.$refs.fileContentFormref);
this.$refs.fileContentFormref.validate((valid) => {
if (valid) {
var params = {
action: "list_files",
path: this.fileContentForm.fileContent,
filter: this.fileContentForm.filtername,
termIds: this.idArray,
};
console.log(params);
this.changeIssue(params);
this.fileContentVisible = false;
}
});
},
handleFliePath(row) {
this.fileContentForm.fileContent = row.name;
},
//下载文件
handlepullPath(item) {
console.log(item);
this.pullFileForm.pullFile += item.name + "\n";
console.log(this.pullFileForm.pullFile);
},
handlePull() {
console.log(this.$refs.pullFileFormref);
//选中的内容组成数组去重
let uniquePaths = [
...new Set(
this.pullFileForm.pullFile.split(/\r\n|\n|\r/).filter(Boolean)
),
];
this.$refs.pullFileFormref.validate((valid) => {
if (valid) {
var params = {
action: "pull_files",
paths: uniquePaths,
termIds: this.idArray,
};
console.log(params);
this.changeIssue(params);
this.pullFileVisible = false;
}
});
},
handlePath(row) {
console.log(row);
this.pushFileForm.name = row.name;
},
handleDelPath(row) {
this.delFileForm.delFile = row.name;
},
//上传文件
beforeUpload(file) {
console.log(file);
new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = (e) => {
console.log("asdasdad", e);
this.pushFileForm.fileData = e.target.result; // Base64 编码的数据
const base64Index = this.pushFileForm.fileData.indexOf("base64,");
if (base64Index > 0) {
// 提取base64编码部分
const base64Data = this.pushFileForm.fileData.substring(
base64Index + 7
); // 7 是 "base64," 的长度
this.pushFileForm.fileData = base64Data; // 保存Base64编码部分
this.sendToBackend(this.pushFileForm.fileData);
resolve(true);
} else {
// 如果找不到"base64,",则可能不是预期的格式
reject(new Error("Invalid data URL format"));
}
};
reader.onerror = (error) => {
reject(error);
};
});
return false;
},
sendToBackend(base64Data) {
this.$refs.pushFileFormref.validate((valid) => {
if (valid) {
var params = {
action: "push_file",
path: this.pushFileForm.name,
content: base64Data,
termIds: this.idArray,
};
console.log(params);
this.changeIssue(params);
// this.pushFileVisible = false;
}
});
},
handlePush() {
this.pushLoading = true;
this.$refs.upload.submit();
},
//上传大文件
selectChangedconfig(val) {
console.log(val);
// 找到选中项的整个object对象
this.selectconfigObj = this.configOptions.find((item) => {
return item["path"] === val;
});
console.log(this.selectconfigObj);
},
getconfigList() {
upgradeListApi({ type: 3 })
.then((res) => {
console.log(res);
this.configOptions = res.data;
})
.catch((err) => {});
},
handlebigPath(row) {
console.log(row);
this.configform.pathVal = row.name;
},
handleconfig() {
this.$refs.configRuleForm.validate((valid) => {
if (valid) {
var params = {
action: "dl_file",
url: this.configform.upVal,
path: this.configform.pathVal,
md5: this.selectconfigObj.md5,
termIds: this.idArray,
};
console.log(params);
this.changeIssue(params);
this.configVisible = 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("fwcheck", this.fwcheck);
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.fwcheck = localStorage.getItem("fwcheck")
? JSON.parse(localStorage.getItem("fwcheck"))
: 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);
updCommentApi({
termId: row.id,
comment: row.mntnStatus.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;
}
}
.totalPopover {
}
.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;
}
}
.pushBoxDialog {
.el-dialog__body {
height: auto;
ul {
li {
list-style: none;
font-size: 13px;
line-height: 22px;
cursor: pointer;
&:hover {
background-color: #b9e2dd;
}
}
}
}
.upload-demo {
position: absolute;
display: flex;
flex-direction: row-reverse;
margin-right: 65px;
top: 36px;
.el-upload-list {
width: 320px;
height: 32px;
line-height: 32px;
border: 1px solid #ddd;
margin-right: 12px;
border-radius: 4px;
.el-upload-list__item {
transition: none;
font-size: 14px;
color: #606266;
position: relative;
box-sizing: border-box;
border-radius: 4px;
width: 100%;
height: 32px;
line-height: 32px;
margin-top: 0px !important;
.el-icon-close {
top: 10px;
}
}
}
}
}
.pullBoxDialog {
.el-dialog__body {
padding: 12px 12px;
}
ul {
li {
list-style: none;
font-size: 13px;
line-height: 22px;
cursor: pointer;
&:hover {
background-color: #b9e2dd;
}
}
}
}
.deleteDialog {
.el-dialog__body {
height: auto;
ul {
li {
list-style: none;
font-size: 13px;
line-height: 22px;
cursor: pointer;
&:hover {
background-color: #b9e2dd;
}
}
}
}
}
.fileContentDialog {
.el-dialog__body {
height: auto;
ul {
li {
list-style: none;
font-size: 13px;
line-height: 22px;
cursor: pointer;
&:hover {
background-color: #b9e2dd;
}
}
}
}
}
.configDialogBox {
ul {
margin-bottom: 12px;
li {
list-style: none;
font-size: 13px;
line-height: 22px;
cursor: pointer;
&:hover {
background-color: #b9e2dd;
}
}
}
}
.senMsgDialog {
ul {
li {
list-style: none;
font-size: 13px;
line-height: 22px;
cursor: pointer;
&:hover {
background-color: #b9e2dd;
}
}
}
}
}
.contenBoxMsg {
p {
color: #333;
line-height: 24px;
font-size: 14px;
}
}
.el-select-dropdown__item {
i {
margin-left: 8px;
font-size: 12px;
font-style: normal;
}
}
.totalPopover {
display: flex;
span {
margin-right: 4px;
}
}
</style>