This commit is contained in:
hh
2021-03-24 15:58:34 +08:00
parent 8e2126a20b
commit 4d8c510d4d
8 changed files with 365 additions and 152 deletions

View File

@ -21,4 +21,17 @@ export function OTAUpdates(data) {
method: 'post', method: 'post',
data data
}) })
} }
export function getNodeOTAHistory(params) {
return request({
url: '/system/device/node/getOTAHistory',
params
});
}
export function nodeOTAHistoryExport() {
return request({
url: '/ota/export',
});
}

View File

@ -65,4 +65,37 @@ export function importTemplate() {
return request({ return request({
url: '/system/device/importTemplate', url: '/system/device/importTemplate',
}) })
}
// 获取白名单列表
export function whiteList(params) {
return request({
url: '/system/device/whiteList',
method: 'get',
params
})
}
/**
* 批量添加白名单
* @param {Array} ids
*/
export function addWhiteDevice(ids) {
return request({
url: '/system/device/addWhiteDevice/',
method: 'post',
data: {ids}
})
}
/**
* 批量移除白名单
* @param {Array} ids
*/
export function delWhiteDevice(ids) {
return request({
url: '/system/device/delWhiteDevice',
method: 'post',
data: {ids}
})
} }

View File

@ -64,145 +64,11 @@ export default {
'3': '已回单', '3': '已回单',
}, },
myStyleJson: [ myStyleJson: [
{
"featureType": "water",
"elementType": "all",
"stylers": {
"color": "#021019"
}
},
{
"featureType": "highway",
"elementType": "geometry.fill",
"stylers": {
"color": "#000000"
}
},
{
"featureType": "highway",
"elementType": "geometry.stroke",
"stylers": {
"color": "#147a92"
}
},
{
"featureType": "arterial",
"elementType": "geometry.fill",
"stylers": {
"color": "#000000"
}
},
{
"featureType": "arterial",
"elementType": "geometry.stroke",
"stylers": {
"color": "#0b3d51"
}
},
{
"featureType": "local",
"elementType": "geometry",
"stylers": {
"color": "#000000"
}
},
{ {
"featureType": "land", "featureType": "land",
"elementType": "all",
"stylers": {
"color": "#08304b"
}
},
{
"featureType": "railway",
"elementType": "geometry.fill",
"stylers": {
"color": "#000000"
}
},
{
"featureType": "railway",
"elementType": "geometry.stroke",
"stylers": {
"color": "#08304b"
}
},
{
"featureType": "subway",
"elementType": "geometry", "elementType": "geometry",
"stylers": { "stylers": {
"lightness": -70 "color": "#f5f6f7ff"
}
},
{
"featureType": "building",
"elementType": "geometry.fill",
"stylers": {
"color": "#000000"
}
},
{
"featureType": "all",
"elementType": "labels.text.fill",
"stylers": {
"color": "#857f7f"
}
},
{
"featureType": "all",
"elementType": "labels.text.stroke",
"stylers": {
"color": "#000000"
}
},
{
"featureType": "building",
"elementType": "geometry",
"stylers": {
"color": "#022338"
}
},
{
"featureType": "green",
"elementType": "geometry",
"stylers": {
"color": "#062032"
}
},
{
"featureType": "boundary",
"elementType": "all",
"stylers": {
"color": "#1e1c1c"
}
},
{
"featureType": "manmade",
"elementType": "geometry",
"stylers": {
"color": "#022338"
}
},
{
"featureType": "poi",
"elementType": "all",
"stylers": {
"visibility": "off"
}
},
{
"featureType": "all",
"elementType": "labels.icon",
"stylers": {
"visibility": "off"
}
},
{
"featureType": "all",
"elementType": "labels.text.fill",
"stylers": {
"color": "#2da0c6",
"visibility": "on"
} }
} }
] ]
@ -210,8 +76,8 @@ export default {
}, },
computed: { computed: {
time() { time () {
return parseTime(this.date,'{h} : {i} : {s}') return parseTime(this.date, '{h} : {i} : {s}')
} }
}, },
mounted () { mounted () {
@ -638,7 +504,7 @@ export default {
<style> <style>
.ec-extension-bmap { .ec-extension-bmap {
background: #23375f !important; background: #a6c2df !important;
} }
.BMap_cpyCtrl, .BMap_cpyCtrl,
.anchorBL { .anchorBL {
@ -677,7 +543,7 @@ export default {
width: 30vw; width: 30vw;
right: 35vw; right: 35vw;
display: block; display: block;
color: white; color: black;
.tit { .tit {
padding-top: 20px; padding-top: 20px;
font-size: 40px; font-size: 40px;

View File

@ -3,6 +3,10 @@
<el-row> <el-row>
<el-col :span="24"> <el-col :span="24">
<el-form :size="size" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="90px"> <el-form :size="size" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="90px">
<el-form-item label="信号量">
<el-input v-model="queryParams.signalCode" placeholder="请输入信号量" clearable style="width: 200px"
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="故障名称"> <el-form-item label="故障名称">
<el-input v-model="queryParams.faultName" placeholder="请输入故障名称" clearable style="width: 200px" <el-input v-model="queryParams.faultName" placeholder="请输入故障名称" clearable style="width: 200px"
@keyup.enter.native="handleQuery" /> @keyup.enter.native="handleQuery" />

View File

@ -33,15 +33,21 @@
<el-form-item label="设备SN"> <el-form-item label="设备SN">
<el-input v-model="queryParams.deviceId" placeholder="请输入设备SN" @keyup.enter.native="handleQuery" /> <el-input v-model="queryParams.deviceId" placeholder="请输入设备SN" @keyup.enter.native="handleQuery" />
</el-form-item> </el-form-item>
<el-form-item label="当前软件版本">
<el-input v-model="queryParams.nowVersion" placeholder="请输入当前软件版本" @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item> <el-form-item>
<el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-row class="mb8"> <el-row :gutter="10" class="mb8">
<el-col :span="1.5"> <el-col :span="1.5">
<el-button size="mini" type="primary" icon="el-icon-set-up" @click="handleOTAUpdate">批量升级</el-button> <el-button size="mini" type="primary" icon="el-icon-set-up" @click="handleOTAUpdate">批量升级</el-button>
</el-col> </el-col>
<el-col :span="1.5">
<el-button size="mini" type="info" icon="el-icon-set-up" @click="nodeOTAHistoryExport">导出升级记录</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
<el-table ref="multipleTable" :data="tableData" tooltip-effect="dark" style="width: 100%" @selection-change="handleSelectionChange"> <el-table ref="multipleTable" :data="tableData" tooltip-effect="dark" style="width: 100%" @selection-change="handleSelectionChange">
@ -64,7 +70,7 @@
{{ scope.row.deviceType ? deviceTypeList.find(v=> v.value == scope.row.deviceType).label : '' }} {{ scope.row.deviceType ? deviceTypeList.find(v=> v.value == scope.row.deviceType).label : '' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" prop="nowVersion" label="当前软件版本"> <el-table-column align="center" prop="nowVersions" label="当前软件版本">
</el-table-column> </el-table-column>
<el-table-column align="center" prop="version" label="可升级软件版本"> <el-table-column align="center" prop="version" label="可升级软件版本">
</el-table-column> </el-table-column>
@ -78,6 +84,9 @@
<el-button v-if="scope.row.deviceType != 'tt'" size="mini" type="text" @click="handleOneOTAUpdate(scope.row)"> <el-button v-if="scope.row.deviceType != 'tt'" size="mini" type="text" @click="handleOneOTAUpdate(scope.row)">
升级 升级
</el-button> </el-button>
<el-button size="mini" type="text" @click="showHistory(scope.row)">
升级历史
</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -85,13 +94,23 @@
@pagination="getList" /> @pagination="getList" />
</el-col> </el-col>
</el-row> </el-row>
<el-dialog title="节点升级历史" :visible.sync="nodeOTAHistoryDialog">
<el-table :data="nodeOTAHistoryData">
<el-table-column align="center" prop="deviceId" label="设备SN"></el-table-column>
<el-table-column align="center" prop="nodeId" label="节点SN"></el-table-column>
<el-table-column align="center" prop="nowVersion" label="节点当前版本"></el-table-column>
<el-table-column align="center" prop="oldVersion" label="节点上次版本"></el-table-column>
<el-table-column align="center" prop="createTimeStr" label="升级时间"></el-table-column>
</el-table>
</el-dialog>
</section> </section>
</template> </template>
<script> <script>
import Region from "@/components/Region"; import Region from "@/components/Region";
import { list, OTAUpdate, OTAUpdates } from "@/api/firmware/firmwareupdate"; import { list, OTAUpdate, OTAUpdates, getNodeOTAHistory, nodeOTAHistoryExport } from "@/api/firmware/firmwareupdate";
import { select as projectSelect } from "@/api/hardware/project"; import { select as projectSelect } from "@/api/hardware/project";
import { select as productSelect } from "@/api/hardware/product"; import { select as productSelect } from "@/api/hardware/product";
import { productNodeList, productNodeSelect } from "@/api/hardware/productNode"; import { productNodeList, productNodeSelect } from "@/api/hardware/productNode";
@ -127,6 +146,8 @@ export default {
{ 'label': '锐能设备', 'value': 'rn', }, { 'label': '锐能设备', 'value': 'rn', },
{ 'label': '铁塔设备', 'value': 'tt', }, { 'label': '铁塔设备', 'value': 'tt', },
], ],
nodeOTAHistoryDialog: false,
nodeOTAHistoryData: [],
} }
}, },
created () { created () {
@ -147,6 +168,28 @@ export default {
this.getList(); this.getList();
}, },
methods: { methods: {
nodeOTAHistoryExport () {
this.$confirm('是否确认导出所有节点升级记录?', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function () {
return nodeOTAHistoryExport();
}).then(response => {
this.download(response.msg);
})
},
showHistory ({ id }) {
this.nodeOTAHistoryDialog = true;
getNodeOTAHistory({ id }).then(({ rows, msg, code }) => {
if (code == 200) {
this.nodeOTAHistoryData = rows;
} else {
this.$message.error(msg);
}
})
},
queryProductIdChange (productId) { queryProductIdChange (productId) {
delete this.queryParams.nodeId; delete this.queryParams.nodeId;
productNodeSelect({ productId }).then(({ code, msg, select }) => { productNodeSelect({ productId }).then(({ code, msg, select }) => {
@ -223,7 +266,7 @@ export default {
}) })
}, },
OTAUpdates (deviceNode) { OTAUpdates (deviceNode) {
OTAUpdates(deviceNode).then(({code, msg}) => { OTAUpdates(deviceNode).then(({ code, msg }) => {
if (200 == code) { if (200 == code) {
this.msgSuccess(msg) this.msgSuccess(msg)
} else { } else {

View File

@ -43,10 +43,6 @@
<el-button type="danger" icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete" <el-button type="danger" icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete"
v-hasPermi="['system:device:remove']">批量删除</el-button> v-hasPermi="['system:device:remove']">批量删除</el-button>
</el-col> </el-col>
<!-- <el-col :span="1.5">
<el-button type="danger" icon="el-icon-delete" size="mini" @click="handleClean" v-hasPermi="['monitor:job:remove']">清空
</el-button>
</el-col> -->
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="info" icon="el-icon-upload2" size="mini" @click="handleImport" v-hasPermi="['system:device:import']">导入 <el-button type="info" icon="el-icon-upload2" size="mini" @click="handleImport" v-hasPermi="['system:device:import']">导入
</el-button> </el-button>
@ -55,6 +51,10 @@
<el-button type="warning" icon="el-icon-download" size="mini" @click="handleExport" v-hasPermi="['system:device:export']">导出 <el-button type="warning" icon="el-icon-download" size="mini" @click="handleExport" v-hasPermi="['system:device:export']">导出
</el-button> </el-button>
</el-col> </el-col>
<el-col :span="1.5">
<el-button type="warning" icon="el-icon-plus" size="mini" :disabled="!canAddWhiteDevice" @click="addWhiteDevice" v-hasPermi="['system:device:addWhiteDevice']">加入白名单
</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
@ -255,7 +255,8 @@ import {
del, del,
saveDeviceFirmware, saveDeviceFirmware,
exportEquipment, exportEquipment,
importTemplate importTemplate,
addWhiteDevice,
} from "@/api/hardware/device"; } from "@/api/hardware/device";
// import { nodeList, addNode, nodeInfo, delNode, nodeSelect } from "@/api/system/device/node"; // import { nodeList, addNode, nodeInfo, delNode, nodeSelect } from "@/api/system/device/node";
import { select as productSelect } from "@/api/hardware/product"; import { select as productSelect } from "@/api/hardware/product";
@ -381,6 +382,23 @@ export default {
} }
}; };
}, },
computed: {
canAddWhiteDevice() {
let bool = true;
if(this.ids.length > 0) {
for (let i = 0; i < this.ids.length; i++) {
const ele = this.ids[i];
const device = this.tableData.find(e => e.id == ele);
if(device && device.deviceType !== 'tt') {
bool = false;
}
}
} else {
bool = false;
}
return bool
}
},
created () { created () {
productSelect().then(({ code, msg, select }) => { productSelect().then(({ code, msg, select }) => {
if (code == 200) { if (code == 200) {
@ -415,6 +433,21 @@ export default {
this.getList(); this.getList();
}, },
methods: { methods: {
addWhiteDevice() {
this.$confirm('是否确认移入白名单?', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
return addWhiteDevice(this.ids);
}).catch(() => { }).then(res => {
if (200 == res.code) {
this.msgSuccess("加入成功");
} else {
this.msgError(res.msg);
}
}).catch(res => { })
},
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport () { handleExport () {
const queryParams = this.queryParams; const queryParams = this.queryParams;

View File

@ -0,0 +1,220 @@
<template>
<section class="app-container">
<el-row>
<el-col :span="4">
<region @selectdRegionCode="selectdRegionCode" :currentNodeKey.sync="queryParams.provinceCode"></region>
</el-col>
<el-col :span="20">
<el-form :size="size" :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="产品">
<el-select v-model="queryParams.productId" clearable placeholder="请选择产品SN">
<el-option v-for="item in queryProductSelectList" :key="item.id" :label="item.productName" :value="item.productId">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="项目" prop="projectId">
<el-select v-model="queryParams.projectId" clearable placeholder="请选择项目SN">
<el-option v-for="item in queryProjectSelectList" :key="item.id" :label="item.projectName" :value="item.projectId">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="设备名称">
<el-input v-model="queryParams.deviceName" placeholder="请输入设备名称或SN" clearable style="width: 240px"
@keyup.enter.native="handleQuery" />
</el-form-item>
<!-- <el-form-item label="设备类型">
<el-select v-model="queryParams.deviceType" clearable placeholder="请选择">
<el-option v-for="item in deviceTypeList" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item> -->
<el-form-item>
<el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="danger" icon="el-icon-delete" size="mini" @click="delWhiteDevice" v-hasPermi="['system:device:delWhiteDevice']">移除白名单
</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table :data="tableData" style="width: 100%" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center">
</el-table-column>
<el-table-column prop="deviceId" align="center" label="设备SN" min-width="200">
</el-table-column>
<el-table-column prop="deviceName" align="center" label="设备名称" min-width="150">
<template slot-scope="scope">
<el-link type="primary" :href="'./detail?id=' + scope.row.id " target="_blank">{{scope.row.deviceName}}</el-link>
</template>
</el-table-column>
<el-table-column prop="projectName" align="center" label="项目名称" min-width="150">
</el-table-column>
<el-table-column prop="deviceType" align="center" label="类型">
<template slot-scope="scope">{{getDeviceTypeLabel(scope.row.deviceType)}}</template>
<!-- <template slot-scope="scope">{{scope.row.deviceType}}</template> -->
<!-- <template slot-scope="scope">{{deviceTypeList.find(v=> v.value == scope.row.deviceType).label}}</template> -->
</el-table-column>
<el-table-column prop="productName" align="center" label="产品SN" min-width="200">
</el-table-column>
<!-- <el-table-column prop="deviceCode" align="center" label="设备编码">
</el-table-column>
<el-table-column prop="deviceType" align="center" label="类型">
</el-table-column>
<el-table-column prop="deviceModel" align="center" label="装置模型">
</el-table-column> -->
<el-table-column prop="proName" align="center" label="省份" min-width="80">
</el-table-column>
<el-table-column prop="cityName" align="center" label="市" min-width="80">
</el-table-column>
<el-table-column prop="disName" align="center" label="区" min-width="80">
</el-table-column>
<!-- <el-table-column prop="status" align="center" label="在线状态">
</el-table-column> -->
<!-- <el-table-column label="操作" align="center" class-name="small-padding fixed-width" min-width="250">
<template slot-scope="scope">
</template>
</el-table-column> -->
</el-table>
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
@pagination="getList" />
</el-col>
</el-row>
</section>
</template>
<script>
import Region from "@/components/Region";
import {
whiteList as list,
delWhiteDevice,
} from "@/api/hardware/device";
// import { nodeList, addNode, nodeInfo, delNode, nodeSelect } from "@/api/system/device/node";
import { select as productSelect } from "@/api/hardware/product";
import { select as projectSelect } from "@/api/hardware/project";
export default {
name: "DeviceList",
components: {
Region,
},
data () {
return {
// 产品下拉列表
queryProductSelectList: [],
queryProjectSelectList: [],
deviceTypeList: [
{ 'label': '锐能设备', 'value': 'rn', },
{ 'label': '铁塔设备', 'value': 'tt', },
],
// 选中数组
ids: [],
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 表格数据
tableData: [],
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
},
};
},
created () {
productSelect().then(({ code, msg, select }) => {
if (code == 200) {
this.queryProductSelectList = select;
} else {
this.$message.error(msg);
}
})
projectSelect().then(({code,select})=>{
if (code == 200) {
this.queryProjectSelectList = select;
} else {
this.$message.error(msg);
}
})
this.getList();
},
methods: {
delWhiteDevice() {
this.$confirm('是否确认移出白名单?', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
return delWhiteDevice(this.ids);
}).catch(() => { }).then(res => {
if (200 == res.code) {
this.getList();
this.msgSuccess("移出成功");
} else {
this.msgError(res.msg);
}
}).catch(res => { })
},
getDeviceTypeLabel (deviceType) {
let snap = '';
this.deviceTypeList.map(v => {
if (v.value == deviceType) {
snap = v.label;
}
})
return snap;
},
selectdRegionCode ({ code }) {
this.queryParams.provinceCode = code;
this.handleQuery();
},
/** 搜索按钮操作 */
handleQuery () {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery () {
this.queryParams = {
pageNum: 1,
pageSize: 10
};
this.resetForm("queryForm");
this.handleQuery();
},
// 获取设备数据列表
getList () {
list({...this.queryParams,userId:this.$store.getters.userId}).then((response) => {
this.tableData = response.rows;
this.total = response.total;
});
},
// 多选框选中数据
handleSelectionChange (selection) {
this.ids = selection.map((item) => item.id);
this.multiple = !selection.length;
},
// 页码尺寸改变
handleSizeChange (val) {
this.queryForm.pagesize = val;
this.getList();
},
// 页码改变
handleCurrentChange (val) {
this.queryForm.page = val;
this.getList();
},
},
};
</script>
<style></style>

View File

@ -133,8 +133,8 @@
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item v-if="form.userId == undefined" label="用户名称" prop="userName"> <el-form-item v-if="form.userId == undefined" label="用户账号" prop="userName">
<el-input v-model="form.userName" placeholder="请输入用户名称" /> <el-input v-model="form.userName" placeholder="请输入用户账号" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
@ -449,7 +449,8 @@ export default {
this.roleOptions = response.roles; this.roleOptions = response.roles;
this.open = true; this.open = true;
this.title = "添加用户"; this.title = "添加用户";
this.form.password = this.initPassword; // set init password
// this.form.password = this.initPassword;
}); });
}, },
/** 修改按钮操作 */ /** 修改按钮操作 */