监控大屏 V3;
设备批次号;
硬件数据库;
个性自定义主体1 等代码
This commit is contained in:
23688nl 2022-01-21 11:44:28 +08:00
parent d9d52747b9
commit d1119b7829
52 changed files with 5304 additions and 120 deletions

View File

@ -8,7 +8,7 @@
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<link rel="stylesheet" href="<%= BASE_URL %>cdn/iconfont/1.0.0/index.css">
<link rel="stylesheet" href="<%= BASE_URL %>cdn/iconfont/1.0.0/iconfont.css">
<link rel="stylesheet" href="//at.alicdn.com/t/font_2506643_eumy2msqof4.css">
<link rel="stylesheet" href="//at.alicdn.com/t/font_2506643_9w119og75cs.css">
<script type="text/javascript" src="http://webapi.amap.com/maps?v=1.4.15&key=aabc97a5e095102787d405719847ecf0"></script>

53
src/api/iot/batch.js Normal file
View File

@ -0,0 +1,53 @@
import request from '@/utils/request'
// 查询设备批次号列表
export function listBatch(query) {
return request({
url: '/iot/batch/list',
method: 'get',
params: query
})
}
// 查询设备批次号详细
export function getBatch(batchId) {
return request({
url: '/iot/batch/' + batchId,
method: 'get'
})
}
// 新增设备批次号
export function addBatch(data) {
return request({
url: '/iot/batch',
method: 'post',
data: data
})
}
// 修改设备批次号
export function updateBatch(data) {
return request({
url: '/iot/batch',
method: 'put',
data: data
})
}
// 删除设备批次号
export function delBatch(batchId) {
return request({
url: '/iot/batch/' + batchId,
method: 'delete'
})
}
// 导出设备批次号
export function exportBatch(query) {
return request({
url: '/iot/batch/export',
method: 'get',
params: query
})
}

61
src/api/iot/library.js Normal file
View File

@ -0,0 +1,61 @@
import request from '@/utils/request'
// 查询硬件数据库列表
export function listLibrary(query) {
return request({
url: '/iot/library/list',
method: 'get',
params: query
})
}
// 查询硬件数据库详细
export function getLibrary(devId) {
return request({
url: '/iot/library/' + devId,
method: 'get'
})
}
// 新增硬件数据库
export function addLibrary(data) {
return request({
url: '/iot/library',
method: 'post',
data: data
})
}
// 修改硬件数据库
export function updateLibrary(data) {
return request({
url: '/iot/library',
method: 'put',
data: data
})
}
// 删除硬件数据库
export function delLibrary(devId) {
return request({
url: '/iot/library/' + devId,
method: 'delete'
})
}
// 导出硬件数据库
export function exportLibrary(query) {
return request({
url: '/iot/library/export',
method: 'get',
params: query
})
}
// 下载用户导入模板
export function importTemplate() {
return request({
url: '/iot/library/importTemplate',
method: 'get'
})
}

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1642564409794" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6179" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M531 958.9H64.3V903h405.9c17.6 21.3 38.1 40 60.8 55.9z m-97.3-111.8H176.1V534c0-166.4 135.4-301.8 301.7-301.8 121.9 0 227.5 70.2 279.2 172.1-16.3-2.7-32.9-4.4-49.9-4.4-5.6 0-11.2 0.6-16.8 0.8C644 332.8 566 288.1 477.8 288.1 342.3 288.2 232 398.4 232 534v257.2h111.8V511.7h55.9v279.5h11.9c5.6 19.5 13 38.2 22.1 55.9z m77.8-670.7h-55.9V64.6h55.9v111.8z m-253.8 65.4l-79-79 39.5-39.5 79 79-39.5 39.5z m407.6 0l-39.5-39.5 79-79 39.5 39.5-79 79z m38.9 206.1c-136.1 0-246.4 110.3-246.4 246.4 0 136.1 110.3 246.4 246.4 246.4 136.1 0 246.4-110.3 246.4-246.4 0-136-110.3-246.4-246.4-246.4z m0 453.2c-114.2 0-206.7-92.6-206.7-206.7 0-114.2 92.6-206.7 206.7-206.7 114.2 0 206.7 92.6 206.7 206.7s-92.5 206.7-206.7 206.7zM797.9 587h-56.1c-5.5-15.6-20.2-26.8-37.7-26.8-17.5 0-32.2 11.3-37.7 26.8h-56.1c-14.8 0-26.8 12-26.8 26.8v187.7c0 14.8 12 26.8 26.8 26.8H798c14.8 0 26.8-12 26.8-26.8V613.9c-0.1-14.9-12.1-26.9-26.9-26.9z m-93.9 0c7.4 0 13.4 6 13.4 13.4s-6 13.4-13.4 13.4-13.4-6-13.4-13.4 6-13.4 13.4-13.4z m26.8 187.7H637v-26.8h93.8v26.8z m40.2-53.6H637v-26.8h134v26.8z m0-53.6H637v-26.8h134v26.8z m0 0" p-id="6180" fill="#bfcbd9"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1642564298941" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4902" width="64" height="64" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M950.840889 841.159111v109.681778H146.261333v-109.681778h804.579556z m-402.261333-768c189.667556 0 344.803556 148.081778 344.803555 329.102222v329.159111c0 32.938667-22.983111 54.840889-57.457778 54.840889H261.233778c-34.474667 0-57.457778-21.902222-57.457778-54.840889V402.261333c0-181.020444 155.136-329.102222 344.746667-329.102222z m114.915555 219.420445H462.392889l-86.243556 213.902222h114.915556l-57.457778 170.097778 287.345778-263.338667h-114.915556l57.457778-120.661333z" fill="#bfcbd9" p-id="4903"></path></svg>

After

Width:  |  Height:  |  Size: 897 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -87,6 +87,7 @@
& .nest-menu .el-submenu>.el-submenu__title,
& .el-submenu .el-menu-item {
min-width: $sideBarWidth !important;
background-color: $subMenuBg !important;
&:hover {
background-color: rgba(0, 0, 0, 0.06) !important;
@ -101,6 +102,19 @@
background-color: $subMenuHover !important;
}
}
& .theme-N1 .is-active > .el-submenu__title {
color: $subMenuActiveText !important;
}
& .theme-N1 .nest-menu .el-submenu>.el-submenu__title,
& .theme-N1 .el-submenu .el-menu-item {
background-color: $subMenuBg !important;
&:hover {
background-color: $subMenuHover !important;
}
}
}
.hideSidebar {
@ -201,7 +215,7 @@
.el-menu-item {
&:hover {
// you can use $subMenuHover
background-color: rgba(0, 0, 0, 0.06) !important;
// background-color: rgba(0, 0, 0, 0.06) !important;
}
}

View File

@ -21,8 +21,13 @@ $menuLightBg:#ffffff;
$menuLightHover:#f0f1f5;
$sidebarLightTitle: #001529;
$subMenuBg:#1f2d3d;
$subMenuHover:#001528;
$menuN1Bg:#07204b;
$menuN1Hover:#051249;
$sidebarN1Title: #ffffff;
$subMenuBg:#050d2f;
$subMenuHover:#003083;
$sideBarWidth: 200px;
@ -36,6 +41,11 @@ $sideBarWidth: 200px;
menuHover: $menuHover;
menuLightBg: $menuLightBg;
menuLightHover: $menuLightHover;
//
menuN1Bg:$menuN1Bg;
menuN1Hover:$menuN1Hover;
sidebarN1Title:$sidebarN1Title;
//
subMenuBg: $subMenuBg;
subMenuHover: $subMenuHover;
sideBarWidth: $sideBarWidth;

View File

@ -0,0 +1,415 @@
<template>
<div class="amap-bigsc-location">
<div id="container" style="width:100%; height:100%"></div>
</div>
</template>
<script>
import AMap from "AMap";
import markerIcon from "@/assets/images/big/marker_noalarm.png";
import markerAlarmIcon from "@/assets/images/big/marker_alarm.png";
import infoTopIcon from "@/assets/images/big/map_top.png";
import infoBotIcon from "@/assets/images/big/map_bottom.png";
import infoAlarmIcon from "@/assets/images/big/map_alarm.png";
import infoDeviceIcon from "@/assets/images/big/device_1.png";
import infoCloseIcon from "@/assets/images/big/clors_map.png";
export default {
name: "ShopLcation",
props: {
mapCenter: {
type: Object,
default: {
lng: 116.397428,
lat: 39.90923,
address: ""
}
},
zoom: {
type: [String, Number],
default: 10
},
draggable: {
type: Boolean,
default: false
},
projectList: {
type: Array,
default: []
}
},
data() {
return {
aMap: null,
pointResult: {
lng: 119.275254,
lat: 26.028928,
address: ""
},
theme: "",
infoWindow: null
};
},
mounted() {
this.initMap();
},
watch: {
projectList: {
handler: function(list, oldVal) {
//
if (this.aMap) {
this.aMap.clearMap();
}
this.createMarker();
// console.log("map_projectList: ", list);
// this.textFu();
},
deep: true
}
},
methods: {
overview() {
if (this.aMap) {
this.aMap.setFitView();
}
},
initMap() {
this.pointResult["lng"] = this.mapCenter.lng;
this.pointResult["lat"] = this.mapCenter.lat;
this.aMap = new AMap.Map("container", {
center: [this.mapCenter.lng, this.mapCenter.lat],
resizeEnable: true,
// zoom: this.zoom,
mapStyle: "amap://styles/" + this.theme
});
this.createMarker();
// this.textFu();
},
//
createInfoWindowO() {
//marker
this.infoWindow = new AMap.InfoWindow({
isCustom: true, //使
content: "",
offset: new AMap.Pixel(-3, -9)
});
},
//
markerClick(e) {
// console.log("");
if (!this.infoWindow) {
this.createInfoWindowO();
}
this.infoWindow.setContent(e.target.content);
this.infoWindow.open(this.aMap, e.target.getPosition());
},
//
textFu() {
let marker = new AMap.Marker({
position: [116.4224009776628, 39.93482727239599],
icon: markerIcon,
offset: new AMap.Pixel(-13, -30)
});
var content = [];
content.push(
`<div class="info-block">
<span class="info-title">报警提醒</span>
<img class="info-close" src="${infoCloseIcon}"/>
<img class="info-top" src="${infoTopIcon}" />
<div class="info-wrap">
<div class="info-item"><span class="info-lable">项目</span><span class="info-value">智慧园区项目</span></div>
<div class="info-item"><span class="info-lable">地址</span><span class="info-value">智慧园区项目</span></div>
<div class="info-item"><span class="info-lable">报警总数</span><span class="info-value">智慧园区项目</span></div>
<div class="alarm-icon-block">
<img class="alarm-icon" src="${infoAlarmIcon}"/>
</div>
<div class="list-device">
<div class="item-device"><img class="d-img" src="${infoDeviceIcon}" /> <span class="device-info">设备名称设备名称设备名称设备名</span> </div>
<div class="item-device"><img class="d-img" src="${infoDeviceIcon}" /> <span class="device-info">设备名称设备名称设备名称设备名</span></div>
<div class="item-device"><img class="d-img" src="${infoDeviceIcon}" /> <span class="device-info">设备名称设备名称设备名称设备名</span></div>
<div class="item-device"><img class="d-img" src="${infoDeviceIcon}" /> <span class="device-info">设备名称设备名称设备名称设备名</span></div>
</div>
</div>
<img class="info-bottom" src="${infoBotIcon}">
</div>`
);
const contentStr = this.createInfoWindow(content.join("<br/>"));
if (!this.infoWindow) {
this.createInfoWindowO();
}
this.infoWindow.setContent(contentStr);
this.infoWindow.open(this.aMap, [116.4224009776628, 39.93482727239599]);
this.aMap.add(marker);
this.aMap.setFitView();
},
//
createMarker() {
var markerList = [];
var _this = this;
for (var i = 0; i < this.projectList.length; i++) {
if (this.projectList[i].projectLat && this.projectList[i].projectLng) {
let marker = new AMap.Marker({
position: [
this.projectList[i].projectLng,
this.projectList[i].projectLat
],
// map: this.aMap,
icon: this.projectList[i].tenantIndexVo['unProcessed'] > 0 ? markerAlarmIcon : markerIcon,
offset: new AMap.Pixel(-13, -30)
});
var content = [];
window['amapObj'] = this.aMap;
content.push(
`<div class="info-block">
<span class="info-title">报警提醒</span>
<img name="closeImg" class="info-close" onclick="window['amapObj'].clearInfoWindow()" src="${infoCloseIcon}"/>
<img class="info-top" src="${infoTopIcon}" />
<div class="info-wrap">
<div class="info-item"><span class="info-lable">项目</span>
<span class="info-value">${this.projectList[i].projectName}</span></div>
<div class="info-item"><span class="info-lable">地址</span>
<marquee style="margin: 0; width:calc(100% - 80px);" behavior="alternate" scrollamount="1" width="calc(100% - 40px)">
<span class="info-value">${this.projectList[i].projectAddress}</span>
</marquee>
</div>
<div class="info-item"><span class="info-lable">报警总数</span>
<span class="info-value" style="color: #ff3739;font-size: 24px;font-weight: 500;">${this.projectList[i].tenantIndexVo?.unProcessed}</span></div>
<div class="alarm-icon-block">
<img class="alarm-icon" src="${infoAlarmIcon}"/>
</div>
<div class="list-device">
${this.resultDeviceListStr(this.projectList[i].deviceAlarmSimpleVoList || [])}
</div>
</div>
<img class="info-bottom" src="${infoBotIcon}">
</div>`
);
marker.content = _this.createInfoWindow(content.join("<br/>"));
marker.on("click", _this.markerClick);
markerList.push(marker);
}
}
this.aMap.add(markerList);
this.aMap.setFitView();
},
resultDeviceListStr(list) {
var resultStr = '';
var _this = this;
window['_this'] = this;
if (list && list.length > 0) {
list.forEach(v => {
// if (v.unProcessAlarmTotal > 0) {
resultStr = resultStr + `
<div class="item-device">
<img class="d-img" src="${infoDeviceIcon}" />
<span class="device-info" name="${v.deviceId}"
onclick="window['_this'].$router.push({ name:'systemDevice', params: { 'deviceId': ${v.deviceId}, 'tempType': 'details' } })"
style="${v.unProcessAlarmTotal > 0 ? 'color: #ff3739;':''}">${v.deviceName}</span>
</div>
`
// }
});
}
return resultStr;
},
//
createInfoWindow(content) {
var info = document.createElement("div");
info.className = "custom-info input-card content-window-card";
//
var middle = document.createElement("div");
middle.className = "info-middle";
middle.style.backgroundColor = "#ff2f6000";
middle.innerHTML = content;
info.appendChild(middle);
return info;
},
//
closeInfoWindow() {
this.aMap.clearInfoWindow();
},
getPositionByLonLats(lng, lat) {
var _this = this;
// console.log(""+lng+""+lat);
var lnglatXY = [lng, lat]; //
AMap.service("AMap.Geocoder", function() {
//
var geocoder = new AMap.Geocoder({});
geocoder.getAddress(lnglatXY, function(status, result) {
if (status === "complete" && result.info === "OK") {
// console.log(result.regeocode.formattedAddress);
var address = result.regeocode.formattedAddress;
_this.pointResult.address = address;
}
_this.$emit("mapEvent", _this.pointResult);
});
});
},
showInfoOut(e) {
// return
this.getPositionByLonLats(
this.pointResult["lng"],
this.pointResult["lat"]
);
// this.$emit("")
},
showInfoM(e) {
this.pointResult["lat"] = e.lnglat.lat;
this.pointResult["lng"] = e.lnglat.lng;
}
}
};
</script>
<style lang="scss">
.amap-bigsc-location {
width: 100%;
height: 100%;
.amap-marker:first-child .amap-icon img {
width: 25px;
height: 34px;
}
div.info-middle {
padding: 20px;
// background: #ff2f6000 !important;
}
div.info-block {
background-image: url("../../../../assets/images/big/mapbj_c_1.png");
background-size: cover;
display: flex;
padding: 12px;
font-size: 14px;
font-family: "Microsoft YaHei";
font-weight: 400;
padding-left: 5px;
// border: 1px solid red;
width: 350px;
// height: 280px;
flex-wrap: wrap;
}
img.info-top {
height: 40px;
width: 100%;
position: relative;
// top: -20px;
}
img.info-bottom {
height: 40px;
width: calc(100%);
position: relative;
// top: 20px;
}
div.info-wrap {
min-height: 220px;
width: 100%;
background-image: url("../../../../assets/images/big/mapbj_c_1.png");
background-size: contain;
display: flex;
flex-wrap: wrap;
}
div.info-lable {
color: #07beff;
margin-right: 8px;
margin-left: 8px;
letter-spacing: 7px;
width: 50px;
}
div.info-value {
width: calc(100% - 60px);
text-overflow: ellipsis;
overflow: hidden;
}
span.tt {
margin-left: -6px;
}
div.input-card {
background-color: #ff2f6000;
box-shadow: 0;
}
div.info-item {
width: 100%;
display: flex;
padding-left: 30px;
height: 30px;
}
span.info-title {
position: relative;
top: 30px;
left: 140px;
font-size: 16px;
font-family: "Microsoft YaHei";
font-weight: 400;
color: #07b3f2;
line-height: 24px;
z-index: 1;
}
span.info-lable {
font-size: 14px;
font-family: "Microsoft YaHei";
font-weight: 400;
color: #07beff;
line-height: 28px;
}
span.info-value {
font-size: 14px;
font-family: "Microsoft YaHei";
font-weight: 400;
color: #ffffff;
line-height: 28px;
}
div.alarm-icon-block {
width: 100%;
height: 50px;
display: flex;
justify-content: center;
align-items: center;
}
div.list-device {
width: 100%;
padding-left: 30px;
display: flex;
flex-wrap: wrap;
height: auto;
padding-right: 30px;
max-height: 150px;
overflow: auto;
// justify-content: space-between;
// align-items: flex-start;
}
div.item-device {
background: rgba(1, 112, 255, 0);
height: 35px;
// border: 1px solid #00c0ff;
border-top: 1px solid #00c0ff75;
border-radius: 3px;
display: flex;
justify-content: left;
align-items: center;
padding: 0px 10px;
margin-bottom: 5px;
margin-right: 5px;
width: 100%;
}
img.d-img {
margin-right: 10px;
}
span.device-info {
display: block;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
width: calc(100% - 35px);
}
span.device-info:hover {
color: #00c0ff;
}
img.info-close {
position: relative;
left: 250px;
top: 25px;
z-index: 1;
}
}
</style>

View File

@ -0,0 +1,55 @@
<template>
<div class="app-container dialog-bit">
<el-dialog class="eldialog-wrap-t" :title="title" :visible.sync="visible" :width="width">
<slot name="dialog-center"></slot>
<div slot="footer" class="dialog-footer">
<slot name="dialog-footer"></slot>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
name: 'dialogTemplate',
props: {
title: {
type: String
},
visible: {
type: Boolean
},
width: {
type: String,
default() {
return '450px'
}
}
}
}
</script>
<style lang="scss" >
.dialog-bit {
.eldialog-wrap-t {
.el-dialog__header {
border-bottom: 1px solid #747373;
}
.el-dialog__body {
padding: 10px;
}
.el-dialog__footer {
height: 60px;
border-top: 1px solid #747373;
text-align: right;
width: 100%;
padding: 0px;
padding-top: 15px;
.el-button + .el-button {
margin-right: 10px;
}
.el-button {
padding-top: 8px;
}
}
}
}
</style>

View File

@ -18,7 +18,7 @@
</i>
</div>
</div>
<div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-light')">
<!-- <div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-light')">
<img src="@/assets/images/light.svg" alt="light">
<div v-if="sideTheme === 'theme-light'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
<i aria-label="图标: check" class="anticon anticon-check">
@ -29,6 +29,19 @@
</svg>
</i>
</div>
</div> -->
<div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-N1')">
<img src="@/assets/images/light.svg" alt="N1">
<div v-if="sideTheme === 'theme-N1'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
<i aria-label="图标: check" class="anticon anticon-check">
<svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true"
focusable="false" class="">
<path
d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"/>
</svg>
</i>
</div>
</div>
</div>

View File

@ -1,13 +1,13 @@
<template>
<div class="sidebar-logo-container" :class="{'collapse':collapse}" :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBg : variables.menuLightBg }">
<div class="sidebar-logo-container" :class="{'collapse':collapse}" :style="{ backgroundColor: this.themeMenuBg() }">
<transition name="sidebarLogoFade">
<router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
<!-- <img v-if="logo" :src="logo" class="sidebar-logo"> -->
<h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.sidebarTitle : variables.sidebarLightTitle }">{{ title }} </h1>
<h1 class="sidebar-title" :style="{ color: this.themeTextColor()}">{{ title }} </h1>
</router-link>
<router-link v-else key="expand" class="sidebar-logo-link" to="/">
<!-- <img v-if="logo" :src="logo" class="sidebar-logo"> -->
<h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.sidebarTitle : variables.sidebarLightTitle }">{{ title }} </h1>
<h1 class="sidebar-title" :style="{ color: this.themeTextColor() }">{{ title }} </h1>
</router-link>
</transition>
</div>
@ -38,7 +38,29 @@ export default {
title: '智慧能源综合管理系统',
logo: logoImg
}
}
},
methods: {
themeMenuBg() {
switch (this.sideTheme) {
case "theme-dark":
return variables["menuBg"];
case "theme-light":
return variables["menuLightBg"];
case "theme-N1":
return variables["menuN1Bg"];
}
},
themeTextColor() {
switch (this.sideTheme) {
case "theme-dark":
return variables["sidebarTitle"];
case "theme-light":
return variables['sidebarLightTitle'];
case "theme-N1":
return variables["sidebarN1Title"];
}
},
},
}
</script>

View File

@ -1,26 +1,30 @@
<template>
<div :class="{'has-logo':showLogo}" :style="{ backgroundColor: settings.sideTheme === 'theme-dark' ? variables.menuBg : variables.menuLightBg }">
<logo v-if="showLogo" :collapse="isCollapse" />
<el-scrollbar :class="settings.sideTheme" wrap-class="scrollbar-wrapper">
<el-menu
:default-active="activeMenu"
:collapse="isCollapse"
:background-color="settings.sideTheme === 'theme-dark' ? variables.menuBg : variables.menuLightBg"
:text-color="settings.sideTheme === 'theme-dark' ? variables.menuText : 'rgba(0,0,0,.65)'"
:unique-opened="true"
:active-text-color="settings.theme"
:collapse-transition="false"
mode="vertical"
>
<sidebar-item
v-for="(route, index) in sidebarRouters"
:key="route.path + index"
:item="route"
:base-path="route.path"
/>
</el-menu>
</el-scrollbar>
</div>
<div
:class="{ 'has-logo': showLogo }"
:style="{ backgroundColor: this.themeMenuBg() }"
>
<logo v-if="showLogo" :collapse="isCollapse" />
<el-scrollbar :class="settings.sideTheme" wrap-class="scrollbar-wrapper">
<el-menu
:default-active="activeMenu"
:collapse="isCollapse"
:background-color="this.themeMenuBg()"
:text-color="this.themeTextColor()
"
:unique-opened="true"
:active-text-color="settings.theme"
:collapse-transition="false"
mode="vertical"
>
<sidebar-item
v-for="(route, index) in sidebarRouters"
:key="route.path + index"
:item="route"
:base-path="route.path"
/>
</el-menu>
</el-scrollbar>
</div>
</template>
<script>
@ -30,28 +34,51 @@ import SidebarItem from "./SidebarItem";
import variables from "@/assets/styles/variables.scss";
export default {
components: { SidebarItem, Logo },
computed: {
...mapState(["settings"]),
...mapGetters(["sidebarRouters", "sidebar"]),
activeMenu() {
const route = this.$route;
const { meta, path } = route;
// if set path, the sidebar will highlight the path you set
if (meta.activeMenu) {
return meta.activeMenu;
}
return path;
},
showLogo() {
return this.$store.state.settings.sidebarLogo;
},
variables() {
return variables;
},
isCollapse() {
return !this.sidebar.opened;
}
}
components: { SidebarItem, Logo },
computed: {
...mapState(["settings"]),
...mapGetters(["sidebarRouters", "sidebar"]),
activeMenu() {
const route = this.$route;
const { meta, path } = route;
// if set path, the sidebar will highlight the path you set
if (meta.activeMenu) {
return meta.activeMenu;
}
return path;
},
showLogo() {
return this.$store.state.settings.sidebarLogo;
},
variables() {
return variables;
},
isCollapse() {
return !this.sidebar.opened;
},
},
methods: {
themeMenuBg() {
switch (this.settings.sideTheme) {
case "theme-dark":
return variables["menuBg"];
case "theme-light":
return variables["menuLightBg"];
case "theme-N1":
console.log(variables["menuN1Bg"])
return variables["menuN1Bg"];
}
},
themeTextColor() {
switch (this.settings.sideTheme) {
case "theme-dark":
return variables["menuText"];
case "theme-light":
return "rgba(0,0,0,.65)";
case "theme-N1":
return variables["menuText"];
}
},
},
};
</script>

View File

@ -1,7 +1,7 @@
<template>
<div :class="classObj" class="app-wrapper" :style="{'--current-color': theme}">
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
<sidebar class="sidebar-container" :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBg : variables.menuLightBg }" />
<sidebar class="sidebar-container" :style="{ backgroundColor: this.themeMenuItemColor() }" />
<div :class="{hasTagsView:needTagsView}" class="main-container">
<div :class="{'fixed-header':fixedHeader}" id="navbar-top" :style="navbarShow() ? 'display: none;' : ''">
<navbar />
@ -44,6 +44,12 @@ export default {
fixedHeader: state => state.settings.fixedHeader
}),
classObj() {
console.log({
hideSidebar: !this.sidebar.opened,
openSidebar: this.sidebar.opened,
withoutAnimation: this.sidebar.withoutAnimation,
mobile: this.device === 'mobile'
})
return {
hideSidebar: !this.sidebar.opened,
openSidebar: this.sidebar.opened,
@ -56,6 +62,16 @@ export default {
}
},
methods: {
themeMenuItemColor() {
switch (this.sideTheme) {
case "theme-dark":
return variables["menuBg"];
case "theme-light":
return variables["menuLightBg"];
case "theme-N1":
return variables["menuN1Bg"];
}
},
navbarShow() {
return this.$route.path === '/index'
},

View File

@ -60,10 +60,10 @@ export const constantRoutes = [
children: [
{
path: '/index',
component: (resolve) => require(['@/views/bigScreen/v2/index'], resolve),
component: (resolve) => require(['@/views/bigScreen/v3/index'], resolve),
name: 'BigScreen',
meta: {
title: '数据总览', icon: 'dashboard', noCache: true, affix: true
title: '监控大屏', icon: 'dashboard', noCache: true, affix: true
},
params: {
showNav: false
@ -108,12 +108,12 @@ export const constantRoutes = [
component: Layout,
redirect: 'srcindex',
children: [
{
path: '/srcindex',
component: (resolve) => require(['@/views/index'], resolve),
name: '系统概览',
meta: { title: '系统概览', icon: 'button', noCache: true, affix: false }
},
// {
// path: '/srcindex',
// component: (resolve) => require(['@/views/index'], resolve),
// name: '系统概览',
// meta: { title: '系统概览', icon: 'button', noCache: true, affix: false }
// },
{
path: '/news',
component: (resolve) => require(['@/views/bashboardcom/newsTable'], resolve),

View File

@ -2,9 +2,9 @@ module.exports = {
title: '智慧能源综合管理系统', // 智慧用电管理系统
/**
* 侧边栏主题 深色主题theme-dark浅色主题theme-light
* 侧边栏主题 深色主题theme-dark浅色主题theme-light, 自定义主题theme-N1
*/
sideTheme: 'theme-dark',
sideTheme: 'theme-N1',
/**
* 是否系统布局配置

View File

@ -0,0 +1,301 @@
<template>
<div
class="big-v1-wrap"
id="big-v1-wrap-id"
ref="big-v1-wrap-id"
:style="{
transformOrigin: 'center top',
transform: `scale(${scalseNum})`,
opacity: 1,
transition: `all 0.5s ease 0s`,
}"
>
<div class="main-block">
<head-wrap
ref="mainHead"
:handelTile="title"
:projectList="projectList"
@eventFullscreen="eventFullscreen"
@eventProjectId="eventProjectId"
@eventRegionalismId="eventRegionalismId"
></head-wrap>
<div class="count-wrap">
<div class="count-left">
<div class="left-block-1">
<device-proportion-wrap
:projectId="projectId"
></device-proportion-wrap>
<today-ratio-wrap
:result="resultInfo.warningAnalysisStatisticsVo || []"
></today-ratio-wrap>
</div>
<div
class="map-block-1"
:style="userLoginType !== 'PERSONAL' ? '' : ''"
>
<map-wrap
v-if="userLoginType !== 'PERSONAL'"
tempUserType="userLoginType"
:fullscreen="fullscreen"
:countResult="alarmInfoResult"
@eventFullscreen="eventFullscreenMap"
:projectList="projectList"
></map-wrap>
<map-wrap-personal
v-else
:fullscreen="fullscreen"
tempUserType="userLoginType"
:countResult="alarmInfoResult"
@eventFullscreen="eventFullscreenMap"
:projectList="projectList"
></map-wrap-personal>
</div>
<div class="bottom-block-1">
<alarm-table-list-wrap
:result="alarmInfoResult"
style="margin-top: -5px;"
:projectId="projectId"
></alarm-table-list-wrap>
</div>
</div>
<div class="right-block-1">
<wraring-info-wrap :result="alarmInfoResult"></wraring-info-wrap>
<trend-wrap :result="resultInfo.alarmChartDataVo || []"></trend-wrap>
<type-distribution-wrap
style="margin-top: -5px;"
:result="resultInfo.alarmCategoriesList || []"
></type-distribution-wrap>
</div>
</div>
</div>
</div>
</template>
<script>
import HeadWrap from "./profile/head";
import DeviceProportionWrap from "./profile/deviceProportion";
import WraringInfoWrap from "./profile/wraringInfo";
import AlarmTableListWrap from "./profile/alarmTableList";
import TodayRatioWrap from "./profile/todayRatio";
import TypeDistributionWrap from "./profile/typeDistribution";
import trendWrap from "./profile/trend";
import MapWrap from "./profile/mapWrap";
import MapWrapPersonal from "./profile/personalCenter";
import { iotWebSocketAlarmBaseUrl } from "@/config/env";
import { getWarningAnalysis, homeCount, appProjectList } from "@/api/app";
export default {
name: "Device_oneself",
components: {
HeadWrap,
DeviceProportionWrap,
WraringInfoWrap,
AlarmTableListWrap,
TodayRatioWrap,
TypeDistributionWrap,
trendWrap,
MapWrap,
MapWrapPersonal,
},
data() {
return {
title: "智慧能源综合管理系统",
scalseNum: 1,
resultInfo: {},
alarmInfoResult: {},
projectList: [],
projectId: null,
regionalismId: null,
fullscreen: false,
thisScrollTopY: 0,
userLoginType: "",
stompClient: null,
socket_flag: true,
};
},
mounted() {
//
this.resize_window();
this.userLoginType = this.$store.getters.userType;
this.thisScrollTopY = document.getElementById("con_lf_top_div").scrollTop;
document.getElementById("con_lf_top_div").style.background = "#010e45";
document.getElementById("con_lf_top_div").style.height =
"calc(100vh - 0px)";
document.getElementById("con_lf_top_div").style.minHeight =
"calc(100vh - 0px)";
document.getElementById("con_lf_top_div").style.overflow = "hidden";
document.getElementById("con_lf_top_div").scrollTop = 0;
window.addEventListener("resize", () => {
this.resize_window();
});
},
watch: {
$route(to, from) {
if (from.fullPath === "/index") {
document.getElementById("con_lf_top_div").style.background = "#fff";
} else if (to.fullPath === "/index") {
document.getElementById("con_lf_top_div").style.background = "#010e45";
}
},
},
created() {
document.getElementById("app").style.background = "#010e45";
this.getProjectList();
this.warningAnalysisList();
this.homeCount();
// this.connection();
},
methods: {
// ws
connection() {
if (this.stompClient) {
return;
}
if (!iotWebSocketAlarmBaseUrl) {
return;
}
this.stompClient = new WebSocket(`${iotWebSocketAlarmBaseUrl}`);
this.stompClient.onmessage = this.socket_onmsg;
this.stompClient.onclose = this.socket_onclose;
},
socket_onmsg(evt) {
console.log("wsljcg:=", evt);
},
socket_onclose(e) {
this.stompClient = null;
if (this.socket_flag) {
this.socket_flag = false;
let _this = this;
setTimeout(function () {
_this.socket_flag = true;
_this.connection();
}, 10000);
}
},
//
eventFullscreenMap(data) {
this.fullscreen = data.value;
this.$refs.mainHead["fullscreen"] = data.value;
},
//
eventFullscreen(data) {
this.fullscreen = data.value;
},
eventProjectId(data) {
this.projectId = data;
this.homeCount();
this.warningAnalysisList();
},
eventRegionalismId(data) {
this.regionalismId = data;
this.getProjectList();
},
resize_window() {
if (this.fullscreen) {
this.scalseNum = Math.min( Number(document.documentElement.clientHeight / 1080), Number(document.documentElement.clientWidth / 1920 )
);
} else {
this.scalseNum = Math.min( Number(document.documentElement.clientHeight / 1080), Number(document.documentElement.clientWidth / 1920 ))
}
},
//
getProjectList() {
if (this.$store.getters.userType !== "PERSONAL") {
appProjectList({
regionalismId: this.regionalismId,
}).then((response) => {
this.projectList = response.data;
});
}
},
//
homeCount() {
homeCount({
alarmDivide: "ALARM",
projectId: this.projectId,
}).then((res) => {
this.alarmInfoResult = res.data;
});
},
//
warningAnalysisList() {
getWarningAnalysis({
projectId: this.projectId,
}).then((res) => {
this.resultInfo = res.data;
});
},
},
destroyed() {
document.getElementById("app").style.background = "#fff";
document.getElementById("con_lf_top_div").style.background = "#fff";
document.getElementById("con_lf_top_div").style.overflow = "auto";
document.getElementById("con_lf_top_div").scrollTop = this.thisScrollTopY;
},
};
</script>
<style lang="scss">
.big-v1-wrap {
width: 100%;
height: calc(100vh - 0px);
display: flex;
justify-content: center;
background-image: url("../../../assets/images/big/v3/bg.jpg");
cursor: default;
.main-block {
width: 100%;
height: 100%;
display: flex;
flex-wrap: wrap;
.count-wrap {
width: 100%;
height: calc(100% - 65px);
display: flex;
flex-wrap: wrap;
color: #fff;
background: #1531f508;
padding: 0px 20px;
.count-left {
display: flex;
flex-wrap: wrap;
width: calc(100% - 400px);
height: calc(100%);
// padding-left: 20px;
.left-block-1 {
width: 400px;
height: calc(100% - 300px);
}
.map-block-1 {
width: calc(100% - 405px);
height: calc(100% - 320px);
}
.bottom-block-1 {
width: calc(100% - 5px);
height: 300px;
}
}
.right-block-1 {
width: 400px;
height: calc(100%);
position: relative;
}
}
}
}
.app-main {
width: 100%;
height: calc(100vh - 0);
// background: #021c80;
}
.big-v1-wrap {
width: 1920px;
height: 1080px;
transform-origin: center top 0px;
position: relative;
left: 50%;
margin-left: -960px;
}
</style>

View File

@ -0,0 +1,379 @@
<template>
<div class="big-alarm-table-list-wrap">
<nav-temp htmlType="t2" :title="title">
<div class="center-wrap" slot="mk-center">
<div class="query-right-div">
<div class="alarm-census-wrap">
<div class="census-block">
<img src="@/assets/images/big/v3/iconG.png" />
已处理
<span style="color: #0cff00">{{result['processed']}}</span>
</div>
<div class="census-block image-twinkle">
<img src="@/assets/images/big/v3/iconR.png" />
未处理
<span style="color: red">{{result['unProcessed']}}</span>
</div>
</div>
<el-checkbox-group v-model="queryCheckbox">
<el-checkbox label="warning">包含预警</el-checkbox>
<el-checkbox label="off">只显示离线报警</el-checkbox>
</el-checkbox-group>
</div>
<el-table
:data="list"
class="alarm-table alarm-table-tr"
height="190"
style="margin-top: 4px"
:highlight-pageNum-row="true"
>
<el-table-column
prop="projectName"
label="项目"
v-if="userLoginType !== 'PERSONAL'"
align="center"
width="350"
>
<template slot-scope="scope">
<div style="display: flex; align-items: center">
<div :class="returnStartImg(scope.row.processStatus)">
</div>
<span
style="margin-left: 10px"
v-text="scope.row.projectName"
></span>
</div>
</template>
</el-table-column>
<el-table-column prop="deviceName" label="线路" v-else align="center">
<template slot-scope="scope">
<div style="display: flex; align-items: center">
<div :class="returnStartImg(scope.row.processStatus)">
</div>
<span
style="margin-left: 10px"
v-text="scope.row.deviceName"
></span>
</div>
</template>
</el-table-column>
<el-table-column
prop="projectAddress"
label="地址"
v-if="userLoginType !== 'PERSONAL'"
align="left"
></el-table-column>
<el-table-column
prop="deviceName"
label="线路"
align="center"
v-if="userLoginType !== 'PERSONAL'"
width="100"
>
<template slot-scope="scope">
<span
style="
width: 100px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
"
>
{{ scope.row.deviceName }}
</span>
</template>
</el-table-column>
<el-table-column
prop="alarmDivide"
label="划分"
align="center"
width="100"
:formatter="alarmTypeFormatter"
></el-table-column>
<el-table-column
prop="typeName"
label="报警类型"
align="center"
:width="userLoginType !== 'PERSONAL' ? 120 : ''"
></el-table-column>
<el-table-column
prop="alarmTime"
label="报警时间"
align="center"
:width="userLoginType !== 'PERSONAL' ? 160 : ''"
></el-table-column>
<!-- <el-table-column prop="t6" label="耗时" align="center" width="150"></el-table-column> -->
<el-table-column
prop="processStatus"
label="状态"
align="center"
width="120"
>
<template slot-scope="scope">
<span
v-if="scope.row.processStatus === 'UNPROCESS'"
:style="'color: #FF2F60;'"
>未处理</span
>
<span
v-if="scope.row.processStatus === 'PROCESSED'"
:style="'color: #25F094;'"
>已处理</span
>
<span
v-if="scope.row.processStatus === 'IGNORE'"
:style="'color: #c0c4cc;'"
>忽略</span
>
</template>
</el-table-column>
</el-table>
</div>
</nav-temp>
</div>
</template>
<script>
import { appAlarmRecordList } from "@/api/app";
import NavTemp from "./navTemp";
export default {
name: "alarmTableList",
components: {
NavTemp,
},
props: ["projectId", 'result'],
data() {
return {
title: "实时报警列表",
queryCheckbox: [],
list: [],
userLoginType: "",
};
},
created() {
this.userLoginType = this.$store.getters.userType;
this.getAlarmRecrdList();
},
watch: {
projectId(val, oldval) {
this.getAlarmRecrdList();
},
queryCheckbox(val, oldVal) {
this.getAlarmRecrdList();
},
},
methods: {
returnStartImg(val) {
switch (val) {
case "UNPROCESS":
return "table-start-w bj-a";
break;
case "IGNORE":
return "table-start-w bj-jj";
break;
case "PROCESSED":
return "table-start-w bj-jc";
break;
}
},
alarmTypeFormatter(row) {
if (row.alarmDivide === "ALARM") {
return "报警";
} else if (row.alarmDivide === "WARNING") {
return "预警";
}
},
getAlarmRecrdList() {
appAlarmRecordList({
alarmDivide:
this.queryCheckbox.indexOf("warning") < 0 ? "ALARM" : undefined,
deviceState:
this.queryCheckbox.indexOf("off") >= 0 ? "OFFLINE" : undefined,
projectId: this.projectId || undefined,
pageNum: 1,
pageSize: 20,
}).then((res) => {
this.list = res.rows;
});
},
},
};
</script>
<style lang="scss">
.big-alarm-table-list-wrap {
width: 100%;
height: 280px;
display: flex;
flex-wrap: wrap;
.center-wrap {
width: 100%;
height: calc(100% - 75px);
justify-content: center;
padding-top: 10px;
background-size: contain;
display: flex;
flex-wrap: wrap;
width: 100%;
height: calc(100%);
// height: calc(100% - 75px);
padding: 0;
.query-right-div {
width: calc(100%);
display: flex;
justify-content: flex-end;
align-items: center;
padding-right: 40px;
height: 30px;
margin-top: -25px;
justify-content: space-between;
padding-left: 20px;
.el-checkbox__label {
color: #fff;
}
.alarm-census-wrap {
display: flex;
width: 600px;
color: #fff;
.census-block {
// width: 50%;
display: flex;
align-items: end;
justify-content: flex-start;
flex-wrap: nowrap;
font-size: 16px;
letter-spacing: 1px;
margin-right: 10px;
> img {
margin-right: 5px;
}
> span {
font-size: 18px;
font-family: Source Han Sans CN;
font-weight: bold;
color: #0cff00;
line-height: 26px;
}
}
.image-twinkle {
> img {
animation-name: light;
animation-duration: 1.25s;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-direction: alternate;
}
}
}
}
.alarm-table {
width: calc(100% - 20px);
margin-left: 20px;
.el-table__header-wrapper th,
.el-table .el-table__fixed-header-wrapper th {
// background-color: #0124a9;
background-color: #072d81;
color: #fff;
height: 50px;
border: 0 !important;
font-size: 16px;
letter-spacing: 2px;
}
.el-table__empty-block {
background: #0124a600;
}
tr {
background: #0124a600;
color: #fff;
}
.el-table__body-wrapper {
background: #0124a600;
}
.el-table__body tr:hover > td {
background-color: #0124a600 !important;
}
.el-table__body tr.current-row > td {
background-color: #0124a9 !important;
}
.el-table__body-wrapper::-webkit-scrollbar {
width: 6px;
height: 6px;
}
/*滚动条滑块*/
.el-table__body-wrapper::-webkit-scrollbar-thumb {
background-color: #114f9d;
}
.has-gutter > tr {
color: #909399;
font-weight: 500;
}
.el-table__header-wrapper tr th {
font-size: 14px;
font-family: "Source Han Sans CN";
font-weight: 400;
color: #00feff;
line-height: 16px;
background: #072d81;
height: 35px !important;
}
}
.el-table {
background-color: #ffffff00;
td {
border-bottom: 1px solid #06459f;
padding: 3px 0;
}
}
.el-table::before {
height: 0px;
}
.table-start-w {
width: 88px;
height: 41px;
margin-right: 30px;
display: flex;
justify-content: space-evenly;
font-size: 15px;
font-family: "Adobe Heiti Std";
font-weight: normal;
color: #ffc000;
line-height: 25px;
align-items: center;
.big-wraring-svg {
font-size: 22px;
}
}
.bj-a {
background-image: url("../../../../assets/images/big/v3/btnR.png");
}
.bj-jc {
background-image: url("../../../../assets/images/big/v3/btnG.png");
}
.bj-jj {
background-image: url("../../../../assets/images/big/biao_03.png");
}
}
.alarm-table-tr {
.el-table__body-wrapper tbody tr {
background: #0124a600;
color: #fff;
background-size: cover;
width: 100%;
height: 50px;
margin-bottom: 10px;
}
}
@keyframes light {
from {
opacity: 1;
}
to {
opacity: 0.2;
}
}
}
</style>

View File

@ -0,0 +1,73 @@
<template>
<div class="census-temp-a" :style="`color: ${icolor};`">
<span class="census-top">{{ value }}</span>
<div class="census-cneter">
<icon :class="`iconfont ${icons} icon-t`"></icon>
</div>
<div class="census-title">{{ title }}</div>
</div>
</template>
<script>
export default {
name: "CensusTmepA",
props: {
icolor: {
type: String,
},
icons: {
type: String,
},
title: {
type: String,
},
value: {
type: String,
},
},
};
</script>
<style lang="scss" scoped>
.census-temp-a {
width: 105px;
height: 80px;
display: flex;
flex-wrap: wrap;
.census-cneter {
width: 100%;
background-image: url("../../../../assets/images/big/v3/censusTempA.png");
height: 80px;
display: flex;
justify-content: center;
align-items: center;
background-size: cover;
font-size: 48px;
.icon-t {
font-size: 45px;
margin-top: 12px;
}
}
.census-top {
font-size: 20px;
font-family: "Source Han Sans CN";
font-weight: bold;
width: 100%;
display: flex;
justify-content: center;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
position: relative;
top: 10px;
}
.census-title {
width: 100%;
height: 15px;
font-size: 14px;
font-family: "Source Han Sans CN";
font-weight: 500;
color: #ffffff;
display: flex;
justify-content: center;
}
}
</style>

View File

@ -0,0 +1,90 @@
<template>
<div class="big-device-proportion-wrap">
<nav-temp htmlType="t1" :title="title">
<echarts-radar-wrap
slot="mk-center"
class="count-info"
:styles="'width: 100%; height: 240px;'"
eId="echartsGaugeDP"
:option="radarOption"
/>
</nav-temp>
</div>
</template>
<script>
import titleImg from "@/assets/images/big/b.png";
import EchartsRadarWrap from "./echartsRadar";
import { appDeviceStatistics } from "@/api/app";
import NavTemp from "./navTemp";
export default {
name: "DeviceProportionWrap",
components: {
EchartsRadarWrap,
NavTemp,
},
props: ["projectId"],
data() {
return {
list: [],
titleImg,
title: "所有设备占比分析",
radarOption: {
indicator: [
{ name: "物联网断路器", max: 100 },
{ name: "智能摄像机", max: 100 },
{ name: "智能电表", max: 100 },
{ name: "烟雾传感器", max: 100 },
{ name: "智能气表", max: 100 },
{ name: "智能电表", max: 100 },
{ name: "智能电表", max: 100 },
{ name: "智能水表", max: 100 },
],
seriesList: [
{
value: [],
name: "预算分配Allocated Budget",
},
],
},
};
},
watch: {
projectId(val) {
this.getDeviceProportionList();
},
},
created() {
this.getDeviceProportionList();
},
methods: {
getDeviceProportionList() {
appDeviceStatistics({ projectId: this.projectId }).then((res) => {
const list = res.data;
this.radarOption.indicator = [];
this.radarOption.seriesList = [];
var _this = this;
for (var i = 0; i < list.length; i++) {
_this.radarOption.indicator.push({
name: list[i].deviceTypeName,
max: list[i].total <= 0 ? 1 : list[i].total,
});
_this.radarOption.seriesList.push(list[i].thisTotal);
}
});
},
},
};
</script>
<style lang="scss">
.big-device-proportion-wrap {
width: 100%;
height: 300px;
.count-info {
width: 100%;
height: 240px;
// background-image: url("../../../../assets/images/big/boxleft-center.png");
// background-size: contain;
padding-top: 10px;
}
}
</style>

View File

@ -0,0 +1,149 @@
<template>
<div class="bigscreen-echarts-bar">
<div id="chartBar" :style="styles"></div>
</div>
</template>
<script>
import * as echarts from "echarts";
export default {
name: "echartsBar",
props: {
styles: {
type: String
},
colorList: {
type: [Array, String],
default: ""
},
option: {
stype: Array,
default: []
}
},
data() {
return {
chart: null
};
},
created() {
this.chart = null;
},
mounted() {
this.drawLine();
},
methods: {
drawLine() {
if (!this.chart) {
this.chart = echarts.init(document.getElementById("chartBar"));
}
const option = {
color: ["#3398DB"],
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow"
}
},
grid: {
left: "20",
right: "20",
bottom: "25",
top: 15,
containLabel: true
},
toolbox: {
show: false,
feature: {
mark: { show: true },
dataView: { show: true, readOnly: false },
magicType: { show: true, type: ["line", "bar"] },
restore: { show: true },
saveAsImage: { show: true }
}
},
xAxis: [
{
type: "category",
data: ["报警总数", "未处理", "已处理"],
axisTick: {
alignWithLabel: false
},
axisLabel: {
interval: 0,
margin: 10,
textStyle: {
color: "#fff"
}
},
splitLine: {
show: false,
lineStyle: {
color: ["#1d2c65"],
width: 1,
type: "solid"
}
}
}
],
yAxis: [
{
type: "value",
axisLabel: {
interval: 0,
margin: 10,
textStyle: {
color: "#fff"
}
},
splitLine: {
show: true,
lineStyle: {
color: ["#1d2c65"],
width: 1,
type: "solid"
}
}
}
],
series: [
{
name: "数量:",
type: "bar",
barWidth: "40%",
data: this.option,
itemStyle: {
//
normal: {
//colorListcolorList使
color: function(params) {
var colorList = ["#00FCFF", "#FF2F60", "#25F094"];
return colorList[params.dataIndex];
}
},
//
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: "rgba(0, 0, 0, 0.5)"
}
}
}
]
};
this.chart.setOption(option);
}
},
watch: {
option(val, oldVal) {
this.chart = null;
this.drawLine();
}
}
};
</script>
<style lang="scss">
.bigscreen-echarts-bar {
height: 100%;
}
</style>

View File

@ -0,0 +1,128 @@
<template>
<div class="bigscreen-echarts-gauge">
<div :id="eId" :style="styles"></div>
</div>
</template>
<script>
import * as echarts from "echarts/core";
import { GaugeChart } from "echarts/charts";
import { CanvasRenderer } from "echarts/renderers";
export default {
name: "echartsRadarWrap",
props: {
eId: {
type: String
},
styles: {
type: String
},
colorList: {
type: [Array, String],
default: ["#27d0ec"]
},
option: {
stype: Number,
default: 0
}
},
data() {
return {
chart: null
};
},
created() {
this.chart = null;
echarts.use([GaugeChart, CanvasRenderer]);
},
mounted() {
this.drawLine();
},
methods: {
drawLine() {
if (!this.chart) {
this.chart = echarts.init(document.getElementById(this.eId));
}
const options = {
series: [
{
type: "gauge",
color: this.colorList,
progress: {
show: true,
width: 15
},
// axisLine: {
// lineStyle: {
// width: 15
// }
// },
axisTick: {
show: false
},
splitLine: {
length: 15,
show: false,
lineStyle: {
width: 2,
color: "#004299a3"
}
},
axisLabel: {
distance: 25,
show: false,
color: "#999",
fontSize: 10
},
anchor: {
show: false,
showAbove: true,
size: 5,
itemStyle: {
borderWidth: 2
}
},
title: {
text: "今日报警"
},
axisLine: {
// 线
lineStyle: {
// lineStyle线
width: 15,
color: [
[1, "#1A3F81"]
]
}
},
detail: {
valueAnimation: true,
fontSize: 15,
color: this.colorList[0] || "#27d0ec",
offsetCenter: [0, "80%"]
},
data: [
{
value: this.option
}
]
}
]
};
this.chart.setOption(options);
}
},
watch: {
option(val, oldVal) {
this.chart = null;
this.drawLine();
}
}
};
</script>
<style lang="scss">
.bigscreen-echarts-gauge {
height: calc(100% - 30px);
width: 100%;
}
</style>

View File

@ -0,0 +1,66 @@
<template>
<div class="bigscreen-echarts-pie-t">
<div :id="eId" :style="styles"></div>
</div>
</template>
<script>
import * as echarts from "echarts";
export default {
name: "echartsRadarWrap",
props: {
eId: {
type: String
},
styles: {
type: String
},
colorList: {
type: [Array, String],
default: ""
},
option: {
stype: Object,
default: {}
}
},
data() {
return {
chart: null
};
},
created() {
this.chart = null;
},
mounted() {
this.drawLine();
},
methods: {
updateEchart() {
if (this.chart) {
this.chart = null;
}
this.drawLine();
},
drawLine() {
if (!this.chart) {
this.chart = echarts.init(document.getElementById(this.eId));
}
this.chart.setOption(this.option);
}
},
watch: {
option(val, oldVal) {
this.chart = null;
this.drawLine();
}
}
};
</script>
<style lang="scss">
.bigscreen-echarts-pie-t {
position: relative;
height: 100%;
top: 0px;
width: 95%;
}
</style>

View File

@ -0,0 +1,122 @@
<template>
<div class="bigscreen-echarts-pie">
<div :id="eId" :style="styles"></div>
<!-- <div v-else>暂无数据</div> -->
</div>
</template>
<script>
import * as echarts from "echarts";
export default {
name: "echartsRadarWrap",
props: {
eId: {
type: String,
},
styles: {
type: String,
},
colorList: {
type: [Array, String],
default: "",
},
option: {
stype: Object,
default: [],
},
},
data() {
return {
chart: null,
};
},
created() {
this.chart = null;
},
mounted() {
this.drawLine();
},
methods: {
updateEchart() {
if (this.chart) {
this.chart = null;
}
this.drawLine();
},
drawLine() {
if (!this.chart) {
this.chart = echarts.init(document.getElementById(this.eId));
}
const option = {
color: this.colorList,
// legend: {
// top: "5",
// right: "10",
// type: "scroll",
// // itemWidth: 10, // legend
// orient: "vertical",
// pageIconColor: "#6495ed", //
// pageIconInactiveColor: "#aaa", //
// pageIconSize: 10, //
// pageButtonItemGap: 1, //
// textStyle: {
// color: "#fff",
// fontSize: 16,
// },
// formatter: function (name) {
// return name.length > 7 ? name.substr(0, 7) + "..." : name;
// },
// },
toolbox: {
show: false,
feature: {
mark: { show: true },
dataView: { show: true, readOnly: false },
restore: { show: true },
saveAsImage: { show: true },
},
},
series: [
{
name: "",
type: "pie",
radius: ["40%", "70%"],
center: ["50%", "50%"],
itemStyle: {
borderRadius: 10,
borderColor: "#fff",
borderWidth: 2,
},
emphasis: {
label: {
show: false,
},
},
label: {
show: false,
},
itemStyle: {
borderRadius: 1,
},
data: this.option,
},
],
};
this.chart.setOption(option);
},
},
watch: {
option(val, oldVal) {
this.chart = null;
this.drawLine();
},
},
};
</script>
<style lang="scss">
.bigscreen-echarts-pie {
position: relative;
height: 100%;
top: 0px;
width: 50%;
}
</style>

View File

@ -0,0 +1,129 @@
<template>
<div class="bigscreen-echarts-radar">
<div :id="eId" :style="styles"></div>
</div>
</template>
<script>
import * as echarts from "echarts";
export default {
name: "echartsRadarWrap",
props: {
eId: {
type: String
},
styles: {
type: String
},
colorList: {
type: [Array, String],
default: ""
},
option: {
stype: Object,
default: {}
}
},
data() {
return {
chart: null
};
},
created() {
this.chart = null;
},
mounted() {
this.drawLine();
},
methods: {
drawLine() {
if (!this.chart) {
this.chart = echarts.init(document.getElementById(this.eId));
}
const option = {
title: {
text: ""
},
color: this.colorList,
tooltip: {},
legend: {
data: []
},
radar: {
nameGap: 5,
name: {
textStyle: {
color: "#fff",
backgroundColor: "#99999900",
borderRadius: 2,
padding: [1, 1]
}
},
splitArea: {
show: true,
areaStyle: {
color: ["#515a6e00"] //
}
},
axisLabel: {
// axis.axisLabel
show: false,
textStyle: {
color: "#247bd7" //
}
},
splitLine: {
show: true,
lineStyle: {
width: 1,
color: "#0865da" // 线
}
},
indicator: this.option.indicator
},
series: [
{
name: "预算 vs 开销Budget vs spending",
type: "radar",
symbol: "none",
itemStyle: {
normal: {
color: "rgba(46, 255, 233, 1)", // 线
lineStyle: {
color: "rgba(30, 238, 255, 1)" // 线
},
areaStyle: {
type: "default"
}
}
},
data: [
{
value: this.option.seriesList,
name: ""
}
]
}
]
};
// console.log('radar',this.option, this.chart)
this.chart.setOption(option);
}
},
watch: {
option: {
handler: function (val, oldVal) {
this.chart = null;
this.drawLine();
},
deep: true
}
}
};
</script>
<style lang="scss">
.bigscreen-echarts-radar {
position: relative;
height: 100%;
top: 0px;
}
</style>

View File

@ -0,0 +1,224 @@
<template>
<div class="big-head-wrap">
<div class="left-wrap">
<!-- <i class="el-icon-map-location"></i>
<span class="span-info">全国</span>-->
<!-- <el-cascader :options="treeList" :props="{ checkStrictly: true }" clearable></el-cascader> -->
<treeselect
class="tree-select-wrap"
v-model="treeValue"
:options="treeList"
placeholder="全国"
v-show="tempUserType !== 'PERSONAL'"
/>
<el-select
v-show="tempUserType !== 'PERSONAL'"
v-model="inputValue"
size="small"
filterable
placeholder="项目名称"
clearable
>
<el-option
v-for="item in projectList"
:key="item.projectId"
:label="item.projectName"
:value="item.projectId"
></el-option>
</el-select>
</div>
<div class="title-wrap">{{handelTile}}</div>
<div class="right-wrap">
<span>{{days}}</span>
<span>{{weeks}}</span>
<span>{{time}}</span>
<!-- <el-button type="text" @click="signOut" title="退出大屏" plain icon="iconfont icontuichu"></el-button> -->
<el-button
type="text"
@click="fullScreen"
:title="fullscreen ? '退出全屏':'全屏' "
plain
:icon="fullscreen ? 'iconfont iconshousuo':'iconfont iconquanping1'"
></el-button>
</div>
</div>
</template>
<script>
import { treeListRegionalism } from "@/api/system/regionalism";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
export default {
name: "bigHeadWrap",
props: ["handelTile", "projectList"],
components: {
Treeselect
},
data() {
return {
inputValue: "",
days: "",
weeks: "",
time: "",
treeList: [],
treeValue: null,
tempUserType: null,
fullscreen: false
};
},
mounted() {
setInterval(this.getDate, 1000);
},
created() {
this.tempUserType = this.$store.getters.userType;
this.treeListRegionalism();
this.getDate();
},
watch: {
inputValue(val) {
this.$emit("eventProjectId", val);
},
treeValue(val) {
this.$emit("eventRegionalismId", val);
}
},
methods: {
// 退
signOut() {
this.$router.push("/");
},
fullScreen() {
// let element = document.getElementsByClassName("big-head-wrap"); // id==con_lf_top_div
let element = document.getElementById("con_lf_top_div"); // id==con_lf_top_div
if (this.fullscreen) {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
} else {
if (element.requestFullscreen) {
element.requestFullscreen();
} else if (element.webkitRequestFullScreen) {
element.webkitRequestFullScreen();
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen();
} else if (element.msRequestFullscreen) {
// IE11
element.msRequestFullscreen();
}
}
this.fullscreen = !this.fullscreen;
this.$emit("eventFullscreen", { value: this.fullscreen });
},
treeListRegionalism() {
treeListRegionalism({}).then(res => {
this.treeList = res.data;
});
},
getDate() {
this.weeks = this.parseTime(new Date(), "星期{a}");
this.days = this.parseTime(new Date(), "{y}-{m}-{d}");
this.time = this.parseTime(new Date(), "{h}:{i}:{s}");
}
}
};
</script>
<style lang="scss">
.big-head-wrap {
height: 72px;
width: 100%;
display: flex;
background-image: url("../../../../assets/images/big/head_v2.png");
background-size: cover;
.left-wrap {
width: 20%;
height: 100%;
display: flex;
// color: #fff;
font-size: 14px;
align-items: flex-end;
justify-content: left;
padding-left: 30px;
display: flex;
align-items: center;
padding-top: 20px;
> i {
line-height: 1.5;
}
.span-info {
display: block;
width: 70px;
margin-left: 5px;
}
.el-input {
min-width: 150px;
}
.el-input--small .el-input__inner {
// line-height: 36px;
background: #ff000000;
border-color: #007598;
border-color: #153678;
color: #fff;
margin-left: 10px;
}
.el-input__prefix {
top: -4px;
}
.tree-select-wrap {
height: 32px;
.vue-treeselect__control {
background: #fff0;
border-color: #007598;
border-color: #153678;
height: 32px;
}
.vue-treeselect__single-value {
color: #fff;
}
}
}
.title-wrap {
color: #fff;
width: calc(100% - 40%);
display: flex;
font-size: 36px;
font-family: "Source Han Sans CN";
font-weight: 500;
letter-spacing: 2px;
justify-content: center;
align-items: center;
}
.right-wrap {
width: 20%;
display: flex;
color: #fff;
font-size: 20px;
justify-content: space-around;
align-items: flex-end;
font-family: "Source Han Sans CN";
font-weight: 400;
display: flex;
align-items: center;
padding-top: 20px;
margin-right: 30px;
.el-button--text {
border: 1px solid;
width: 30px;
height: 30px;
border-radius: 5px 0;
padding-top: 6px;
font-size: 16px;
.el-icon-setting {
font-weight: 600;
}
}
.el-button--texthover {
background: transparent;
}
}
}
</style>

View File

@ -0,0 +1,310 @@
<template>
<div class="big-map-wrap">
<nav-temp htmlType="t3" title="">
<div class="center-wrap" slot="mk-center">
<amap-wrap
:mapCenter="{
lng: 116.397428,
lat: 39.90923,
address: '',
}"
ref="bigscLocationMap"
:projectList="projectList"
></amap-wrap>
</div>
</nav-temp>
</div>
</template>
<script>
import amapWrap from "@/components/Amap/components/bigscLocation/indexV_3";
import imgs from "@/assets/images/big/maptp_v1.png";
import { appProjectDeviceList } from "@/api/app";
import NavTemp from "./navTemp.vue";
export default {
name: "mapWrap",
components: {
amapWrap,
NavTemp,
},
props: ["countResult", "projectList", "fullscreen"],
data() {
return {
imgs,
labelList: [
{
guid: "1",
label: "项目总数",
valueKeys: "projectTotal",
image: imgs,
routerKeys: "project",
color: "#97B1FC",
},
{
guid: "2",
label: "设备总数",
valueKeys: "deviceTotal",
image: imgs,
routerKeys: "device",
color: "#00C0FF",
},
{
guid: "3",
label: "在线设备",
valueKeys: "onlineTotal",
image: imgs,
routerKeys: "device",
color: "#00FF06",
},
{
guid: "2",
label: "报警总数",
valueKeys: "alarmTotal",
image: imgs,
routerKeys: "alarm",
color: "#E8512E",
},
{
guid: "4",
label: "今日报警",
valueKeys: "todayAlarmTotal",
image: imgs,
routerKeys: "alarm",
color: "#FFC659",
},
],
deviceList: [],
tempUserType: null,
isFold: true,
};
},
created() {
this.tempUserType = this.$store.getters.userType;
},
methods: {
closeFullScreen() {
let element = document.getElementById("con_lf_top_div");
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
this.$emit("eventFullscreen", { value: false });
},
routerTokeys(keys) {
if (this.fullscreen) {
this.closeFullScreen();
}
var routerPath = "";
switch (keys) {
case "projectTotal":
routerPath = "/project/project";
if (this.$store.getters.userType === "TENANT") {
routerPath = "/project_tenant/project_tenant";
}
break;
case "deviceTotal":
routerPath = "/device/device";
if (this.$store.getters.userType === "TENANT") {
routerPath = "/device_tenant/device_tenant";
} else if (this.$store.getters.userType === "PERSONAL") {
routerPath = "/device_oneself/device_oneself";
}
break;
case "onlineTotal":
routerPath = "/device/device";
if (this.$store.getters.userType === "TENANT") {
routerPath = "/device_tenant/device_tenant";
} else if (this.$store.getters.userType === "PERSONAL") {
routerPath = "/device_oneself/device_oneself";
}
break;
case "todayAlarmTotal":
routerPath = "/alarm/record";
if (this.$store.getters.userType === "TENANT") {
routerPath = "/alarm_tenant/alarm_tenant";
} else if (this.$store.getters.userType === "PERSONAL") {
routerPath = "/alarm_oneself/alarm_oneself";
}
break;
case "alarmTotal":
routerPath = "/alarm/record";
if (this.$store.getters.userType === "TENANT") {
routerPath = "/alarm_tenant/alarm_tenant";
} else if (this.$store.getters.userType === "PERSONAL") {
routerPath = "/alarm_oneself/alarm_oneself";
}
break;
}
this.$router.push({ path: routerPath });
},
overview() {
this.$refs.bigscLocationMap.overview();
},
},
watch: {},
};
</script>
<style lang="scss">
.big-map-wrap {
height: 100%;
width: 100%;
.center-wrap {
width: 100%;
height: 637px;
padding: 0px 20px;
.map-top {
width: 570px;
height: 134px;
background: #0000004d;
position: fixed;
top: 101px;
// left: -1px;
margin-right: 1px;
display: flex;
justify-content: space-evenly;
padding-top: 10px;
.for-i-block {
width: 109px;
height: 35px;
background: #142ea780;
.i-title {
width: 109px;
height: 35px;
background: #142ea780;
font-size: 16px;
font-family: "Source Han Sans CN";
font-weight: 400;
color: #ffffff;
display: flex;
justify-content: center;
align-items: center;
}
.i-value {
width: 109px;
height: 79px;
background: #3a4ead80;
font-size: 40px;
font-family: "Agency FB";
font-weight: 400;
color: #97b1fc;
display: flex;
justify-content: center;
align-items: center;
}
}
}
}
.botton-top-wrap-1 {
position: fixed;
width: calc(58% + 4px);
top: 66px;
height: 230px;
background: linear-gradient(
rgba(1, 18, 145, 0.65) 0%,
rgba(3, 63, 99, 0.5) 100%
);
box-shadow: 0px 1px 3px #033f6380;
.top-wrap-1 {
width: 100%;
height: 200px;
// position: relative;
// top: -743px;
display: flex;
align-items: center;
justify-content: space-around;
// pointer-events: none;
> div {
width: 150px;
height: 150px;
display: "-webkit-box";
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
align-items: center;
justify-content: center;
.item-value {
width: 100%;
display: flex;
justify-content: center;
height: 45px;
font-size: 28px;
font-family: "Source Han Sans CN";
font-weight: 600;
color: #f7f2ea;
background: linear-gradient(180deg, #fbcf34 0%, #ff9b58 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
pointer-events: none;
position: relative;
top: 22px;
font-size: 32px;
}
.item-label {
width: 100%;
height: 16px;
font-size: 16px;
font-family: "Microsoft YaHei";
font-weight: 400;
color: #ffffff;
line-height: 8px;
text-align: center;
}
.item-label:hover {
color: #fbcf34;
}
}
}
.fold-wrap {
height: 30px;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
font-size: 30px;
color: #32bcdd;
}
.fold-wrap:hover {
color: #fff;
background: linear-gradient(180deg, #9c9c9c0d 0%, #f3a0698a 100%);
}
}
.bottom-wrap-1 {
position: relative;
top: -280px;
top: -50px;
left: 90%;
> div {
margin-bottom: 5px;
font-size: 14px;
font-family: "Source Han Sans CN";
font-weight: 400;
color: #07beff;
line-height: 20px;
}
.mapButton {
padding: 5px;
width: 26px;
height: 26px;
background: #00629866;
border: 1px solid #008ee3;
border-radius: 2px;
color: #05bcff;
margin-right: 5px;
}
}
.amap-logo {
display: none;
opacity: 0 !important;
}
.amap-copyright {
opacity: 0;
}
}
</style>

View File

@ -0,0 +1,150 @@
<template>
<div class="big-nav-temp" :style="htmlType === 't2' ? 'margin-top: 10px;' : ''">
<div :class="htmlTop">{{ title }}</div>
<div :class="htmlCenter">
<slot name="mk-center"></slot>
</div>
<div :class="htmlBottom"></div>
</div>
</template>
<script>
export default {
name: "todayRatio",
props: {
title: {
type: String,
defautl: "",
},
htmlType: {
type: String,
default: "t1",
},
},
data() {
return {
htmlTop: "",
htmlCenter: "",
htmlBottom: "",
};
},
created() {
this.returnType();
},
methods: {
returnType() {
switch (this.htmlType) {
case "t1":
this.htmlTop = "mk-top mk-top-t1";
this.htmlCenter = "mk-center-t1";
this.htmlBottom = "mk-bottom-t1";
break;
case "t2":
this.htmlTop = "mk-top mk-top-t2";
this.htmlCenter = "mk-center-t2";
this.htmlBottom = "mk-bottom-t2";
break;
case "t3":
this.htmlTop = "mk-top mk-top-t3";
this.htmlCenter = "mk-center-t3";
this.htmlBottom = "mk-bottom-t3";
break;
}
},
},
watch: {},
};
</script>
<style lang="scss">
.big-nav-temp {
width: 100%;
height: 100%;
display: flex;
flex-wrap: wrap;
margin-top: 15px;
.mk-top {
height: 35px;
width: 100%;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
font-size: 16px;
font-family: "Source Han Sans CN";
font-weight: 400;
color: #02d9fd;
padding-left: 0;
-webkit-box-align: end;
-ms-flex-align: end;
padding-bottom: 0px;
letter-spacing: 1px;
background-size: cover;
padding-top: 5px;
align-items: center;
background-size: 100% 100%;
}
.mk-top-t1 {
background-image: url("../../../../assets/images/big/v3/boxleft-top.png");
}
.mk-top-t2 {
background-image: url("../../../../assets/images/big/v3/boxgao-t.png");
}
.mk-top-t3 {
height: 28px;
background-image: url("../../../../assets/images/big/v3/boxmap-t.png");
}
.mk-center-t1 {
width: 100%;
background-image: url("../../../../assets/images/big/v3/boxleft-center.png");
background-size: contain;
padding-top: 10px;
padding: 5px;
display: flex;
padding: 0 20px;
background-size: 100% 100%;
}
.mk-center-t2 {
width: 100%;
background-image: url("../../../../assets/images/big/v3/boxgao-c.png");
background-size: contain;
padding-top: 10px;
padding: 5px;
display: flex;
}
.mk-center-t3 {
width: 100%;
background-image: url("../../../../assets/images/big/v3/boxmap-c.png");
background-size: contain;
padding-top: 10px;
padding: 5px;
display: flex;
padding: 0 20px;
padding: 0;
height: calc(100% - 56px);
}
.mk-bottom-t1 {
height: 35px;
width: 100%;
background-image: url("../../../../assets/images/big/v3/boxleft-bottom.png");
background-size: 100% 100%;
}
.mk-bottom-t2 {
height: 35px;
width: 100%;
background-image: url("../../../../assets/images/big/v3/boxgao-b.png");
background-size: 100% 100%;
}
.mk-bottom-t3 {
height: 35px;
height: 28px;
width: 100%;
background-image: url("../../../../assets/images/big/v3/boxmap-b.png");
background-size: 100% 100%;
}
}
</style>

View File

@ -0,0 +1,208 @@
<template>
<div class="bigscreen-personal-center">
<nav-temp htmlType="t3" title="">
<div class="conter-blokc" slot="mk-center">
<div v-for="item in list" :key="item.deviceKey" class="info-crad">
<div class="info-title">
<img :src="titleImg" />
{{ item.deviceName }}
</div>
<div class="info-block">
<div class="device-info">
<img :src="deviceImg" />
<div
class="info-state-wrap"
:style="item.unProcessAlarmTotal > 0 ? 'color: red;' : ''"
v-text="item.unProcessAlarmTotal > 0 ? '报警' : '正常'"
></div>
<div class="info-lable">设备状态</div>
</div>
<div class="alarm-info" style="font-size: 20px; padding-right: 6px">
<img :src="alarmImg" />
<div class="info-alarm-num">{{ item.unProcessAlarmTotal }}</div>
<div class="info-lable">报警总数</div>
</div>
<el-button
type="text"
class="big-el-button"
@click="toDeviceDetails(item)"
icon="el-icon-search"
>查看详情</el-button
>
</div>
</div>
</div>
</nav-temp>
</div>
</template>
<script>
import titleImg from "@/assets/images/big/z_title.png";
import deviceImg from "@/assets/images/big/device_1.png";
import alarmImg from "@/assets/images/big/alarm1.png";
import { listDevice } from "@/api/personal/device";
import NavTemp from './navTemp';
export default {
name: "personalCenter",
components: {
NavTemp
},
props: [""],
data() {
return {
titleImg,
deviceImg,
alarmImg,
list: []
};
},
created() {
this.getDeviceList();
},
methods: {
getDeviceList() {
listDevice({
pageNum: 1,
pageSize: 9999
}).then(response => {
this.list = response.rows;
});
},
toDeviceDetails(row) {
this.$router.push({
name: "Device_oneself",
params: { deviceId: row.deviceId, tempType: "details" }
});
}
}
};
</script>
<style lang="scss" scoped>
.bigscreen-personal-center {
width: 100%;
height: 100%;
// overflow: auto;
-ms-flex-wrap: wrap;
// padding-top: 10px;
float: left;
.conter-blokc {
width: 100%;
height: calc(100% - 60px);
display: flex;
flex-wrap: wrap;
justify-content: center;
padding-top: 10px;
background-size: contain;
justify-content: start;
padding: 0 20px;
.info-crad {
width: 358px;
height: 243px;
width: 333px;
background: rgba(0, 36, 125, 0.5);
/* -webkit-box-shadow: 0px 0px 18px 3px rgb(73 94 255 / 70%); */
box-shadow: 0px 0px 18px 6px #495effb3;
margin: 4px;
float: left;
display: flex;
flex-wrap: wrap;
// background-image: url("../../../../assets/images/big/info_bg.png");
.info-title {
width: 100%;
height: 70px;
display: flex;
padding-left: 30px;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: flex-end;
font-size: 18px;
font-family: "Source Han Sans CN";
font-weight: 400;
color: #ffffff;
line-height: 20px;
align-items: center;
> img {
margin-right: 5px;
}
}
.info-block {
height: calc(100% - 70px);
width: 100%;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
justify-content: flex-end;
}
.device-info {
width: 50%;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
height: 80px;
> img {
margin-right: 10px;
margin-left: 20px;
width: 28px;
}
.info-state-wrap {
width: calc(100% - 80px);
height: 45px;
font-size: 24px;
font-family: "Source Han Sans CN";
font-weight: 400;
color: #04fefe;
line-height: 42px;
}
.info-lable {
font-size: 16px;
font-family: " Source Han Sans CN";
font-weight: 400;
color: #ffffff;
line-height: 22px;
padding-left: 20px;
height: 25px;
}
}
.alarm-info {
width: 50%;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
height: 80px;
> img {
margin-right: 10px;
margin-left: 20px;
width: 28px;
}
.info-alarm-num {
font-size: 30px;
font-family: "ShiShangZhongHeiJianTi";
font-weight: 400;
color: #fab03c;
line-height: 42px;
width: 80px;
overflow: hidden;
}
.info-lable {
font-size: 16px;
font-family: " Source Han Sans CN";
font-weight: 400;
color: #ffffff;
line-height: 22px;
padding-left: 20px;
height: 25px;
}
}
.big-el-button {
margin-right: 15px;
}
}
}
}
</style>

View File

@ -0,0 +1,167 @@
<template>
<div class="big-today-ratio-wrap">
<nav-temp htmlType="t1" :title="title">
<div class="bd-conter" slot="mk-center">
<div class="echarts-list-wrap">
<div v-for="item in rchartsList" :key="item.valueKeys">
<div class="title">{{ item.title }}</div>
<echarts-gauge-wrap
:styles="item.styles"
:colorList="item.colorList"
:eId="item.valueKeys"
:option="tempResult[item.valueKeys]"
></echarts-gauge-wrap>
</div>
</div>
<div class="info-tb-block">
<div>
<div>{{ alarmTB }}%</div>
<div>同比</div>
</div>
<div>
<div>{{ warningTB }}%</div>
<div>同比</div>
</div>
</div>
</div>
</nav-temp>
</div>
</template>
<script>
import EchartsGaugeWrap from "./echartsGauge";
import NavTemp from "./navTemp";
export default {
name: "todayRatio",
components: {
EchartsGaugeWrap,
NavTemp,
},
props: ["result"],
data() {
return {
tempResult: {
q1: 0,
q2: 0,
q3: 0,
q4: 0,
},
alarmTB: 0,
warningTB: 0,
rchartsList: [
{
styles: "width: 100%; height: 100%;",
colorList: ["#27d0ec"],
valueKeys: "q1",
title: "今日报警",
},
{
styles: "width: 100%; height: 100%;",
colorList: ["#fdc46e"],
valueKeys: "q2",
title: "昨日报警 ",
},
{
styles: "width: 100%; height: 100%;",
colorList: ["#27d0ec"],
valueKeys: "q3",
title: "今日预警",
},
{
styles: "width: 100%; height: 100%;",
colorList: ["#fdc46e"],
valueKeys: "q4",
title: "昨日预警",
},
],
title: "最近2天警情同比",
};
},
watch: {
result: {
handler: function (val, oldVal) {
if (val) {
this.tempResult = {};
for (var i = 0; i < val.length; i++) {
if (val[i]["alarmDivide"] === "ALARM") {
this.tempResult["q1"] = val[i]["todayAlarm"];
this.tempResult["q2"] = val[i]["yesterdayAlarm"];
this.alarmTB = val[i]["dayOnDay"];
} else if (val[i]["alarmDivide"] === "WARNING") {
this.tempResult["q3"] = val[i]["todayAlarm"];
this.tempResult["q4"] = val[i]["yesterdayAlarm"];
this.warningTB = val[i]["dayOnDay"];
}
}
}
},
deep: true,
},
},
};
</script>
<style lang="scss">
.big-today-ratio-wrap {
width: 100%;
height: 370px;
display: flex;
flex-wrap: wrap;
.bd-conter {
width: 100%;
height: 310px;
background-size: contain;
padding-top: 10px;
padding: 5px;
display: flex;
padding: 0 20px;
.echarts-list-wrap {
width: 80%;
height: 200px;
height: 100%;
display: flex;
flex-wrap: wrap;
> div {
width: 50%;
height: calc(100% / 2);
display: flex;
flex-wrap: wrap;
justify-content: center;
font-size: 14px;
font-family: "Source Han Sans CN";
font-weight: 400;
> .title {
position: relative;
top: 10px;
width: 100%;
display: flex;
justify-content: center;
height: 30px;
}
}
}
.info-tb-block {
height: 100%;
display: flex;
width: 20%;
flex-wrap: wrap;
align-items: center;
font-size: 16px;
cursor: default;
> div {
width: 100%;
// height: 50%;
display: flex;
flex-wrap: wrap;
align-items: inherit;
justify-content: center;
> div {
width: 100%;
height: 20px;
display: flex;
justify-content: center;
}
}
}
}
}
</style>

View File

@ -0,0 +1,185 @@
<template>
<div class="big-trend-wrap">
<nav-temp htmlType="t1" :title="title">
<div class="trend-conter" slot="mk-center">
<echarts-line-wrap
ref="echartsLineTrend"
:styles="echartsOption.styles"
:colorList="echartsOption.colorList"
:eId="echartsOption.eId"
:option="resultOption"
></echarts-line-wrap>
</div>
</nav-temp>
</div>
</template>
<script>
import echartsLineWrap from "./echartsLineT";
import * as echarts from "echarts";
import NavTemp from "./navTemp";
export default {
name: "typeDistribution",
components: {
echartsLineWrap,
NavTemp,
},
props: ["result"],
data() {
return {
echartsOption: {
styles: "width: 100%; height: 100%;",
colorList: ["#FC6A16", "#1EEEFF"],
eId: "trendEchartsLine",
},
title: "报警预警趋势",
typeName: "alarm",
resultOption: {
color: ["#FC6A16", "#1EEEFF"],
title: {
text: "",
show: false,
},
tooltip: {
trigger: "axis",
},
legend: {
top: 5,
right: 5,
data: ["报警", "预警"],
icon: "circle",
textStyle: {
color: "#fff",
fontSize: 16,
},
},
grid: {
left: "20",
right: "20",
bottom: "5",
top: 30,
containLabel: true,
},
xAxis: {
type: "category",
boundaryGap: false,
show: true,
data: [],
splitLine: {
show: false,
},
axisLabel: {
show: true,
textStyle: {
color: "#fff",
},
},
},
yAxis: {
type: "value",
splitLine: {
show: false,
},
axisLabel: {
show: true,
textStyle: {
color: "#fff",
},
},
},
series: [
{
name: "报警",
type: "line",
smooth: true,
symbolSize: 12,
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "rgba(252,106,22,0.8)",
},
{
offset: 1,
color: "rgba(252,106,22,0.1)",
},
]),
},
label: {
show: false,
formatter: function (params) {
return echarts.format.formatTime("yyyy-MM-dd", params.value);
},
backgroundColor: "#7581BD",
},
data: [],
},
{
name: "预警",
type: "line",
smooth: false,
symbolSize: 12,
data: [],
},
],
},
};
},
watch: {
result: {
handler: function (val, oldVal) {
this.resultOption.xAxis.data = val["name"];
this.resultOption.series[0].data = val["alarm"];
this.resultOption.series[1].data = val["warning"];
this.updateEcharts();
},
deep: true,
},
},
methods: {
//
updateEcharts() {
this.$refs.echartsLineTrend.updateEchart();
},
},
};
</script>
<style lang="scss">
.big-trend-wrap {
width: 100%;
// height: 300px;
display: flex;
flex-wrap: wrap;
// margin-top: 10px;
.trend-conter {
width: 100%;
height: 260px;
display: flex;
flex-wrap: wrap;
justify-content: center;
padding-top: 10px;
background-size: contain;
padding: 25px 0;
.tabs-block {
width: 305px;
height: 38px;
background: #bfbfbf94;
display: flex;
color: #fff;
> div {
width: 50%;
display: flex;
justify-content: center;
align-items: center;
font-size: 18px;
letter-spacing: 7px;
cursor: default;
}
.div-select {
background: #0010ff;
}
}
}
}
</style>

View File

@ -0,0 +1,247 @@
<template>
<div class="big-type-distribution-wrap">
<nav-temp htmlType="t1" :title="title">
<div class="conter-block" slot="mk-center">
<div class="tabs-block">
<div
@click="typeName = 'alarm'"
:class="typeName === 'alarm' ? 'div-select' : ''"
>
报警
</div>
<div
@click="typeName = 'waraing'"
:class="typeName === 'waraing' ? 'div-select' : ''"
>
预警
</div>
</div>
<echarts-pie-wrap
ref="echartsPieType"
:styles="echartsOption.styles"
:colorList="echartsOption.colorList"
:eId="echartsOption.eId"
:option="templist[typeName]"
></echarts-pie-wrap>
<div class="echarts-legend-c">
<div class="legend-for">
<div
class="legend-item"
v-for="(item, idx) in templist[typeName]"
:key="idx"
>
<div
class="color-block"
:style="`background: ${echartsOption.colorList[idx]};`"
></div>
<div class="title-block">
{{
item.name.length > 10
? item.name.substr(0, 10) + "..."
: item.name
}}
</div>
</div>
</div>
</div>
</div>
</nav-temp>
</div>
</template>
<script>
import EchartsPieWrap from "./echartsPie";
import NavTemp from "./navTemp";
export default {
name: "typeDistribution",
components: {
EchartsPieWrap,
NavTemp,
},
props: ["result"],
data() {
return {
resultList: [
{ value: 40, name: "rose 1" },
{ value: 38, name: "rose 2" },
{ value: 32, name: "rose 3" },
{ value: 30, name: "rose 4" },
],
templist: {
alarm: [],
waraing: [],
},
echartsOption: {
styles: "width: 80%; height: 100%;",
colorList: [
"#00deff",
"#ff643e",
"#8882f7",
"#01b3d0",
"#ff9724",
"#168efe",
"#00c279",
"#ffce2a",
"#ff88a7",
"#3785b3",
"#2e966b",
"#8d68d8",
"#c77856",
"#ff4df9",
"#0066ff",
"#788a00",
"#73c0de",
"#91cc75",
"#5470c6",
"#ff69d6",
"#d9815c",
"#00b604",
"#b2942e",
"#b2942e",
"#0656da",
"#ff4e00",
"#387289",
"#5aa1bd",
"#5443f9",
"#708694",
"#cd1fc7",
"#ff00ae",
"#a26f00",
"#277900",
"#00b604",
"#ac29ff",
"#ff3737",
"#eae700",
"#b1af01",
],
eId: "typeEchartsPie",
},
title: "类型分布统计",
typeName: "alarm",
};
},
watch: {
typeName(val, old) {
if (val) {
this.updateEcharts();
}
},
result: {
handler: function (list, oldVal) {
this.templist = {
alarm: [],
waraing: [],
};
if (list) {
for (var i = 0; i < list.length; i++) {
// console.log(list[i]['typeCode'].indexOf('a'))
if (list[i]["typeCode"].indexOf("a") === 0) {
this.templist["alarm"].push({
value: list[i].alarmTotal,
name: list[i].typeName,
});
} else if (list[i]["typeCode"].indexOf("w") === 0) {
this.templist["waraing"].push({
value: list[i].alarmTotal,
name: list[i].typeName,
});
}
}
}
console.log(this.templist);
this.updateEcharts();
},
deep: true,
},
},
methods: {
//
updateEcharts() {
this.$refs.echartsPieType.updateEchart();
},
},
};
</script>
<style lang="scss">
.big-type-distribution-wrap {
width: 100%;
height: 278px;
display: flex;
flex-wrap: wrap;
.conter-block {
width: 100%;
height: 208px;
display: flex;
flex-wrap: wrap;
justify-content: center;
padding-top: 10px;
background-size: contain;
.tabs-block {
width: 305px;
height: 28px;
background: #00029d;
display: flex;
color: #fff;
background: #072d81;
border-radius: 14px;
overflow: hidden;
> div {
width: 50%;
display: flex;
justify-content: center;
align-items: center;
font-size: 16px;
letter-spacing: 7px;
cursor: default;
}
.div-select {
background: #0b79c5;
}
}
.echarts-legend-c {
width: 40%;
height: 100%;
display: flex;
flex-wrap: wrap;
.legend-for {
width: 100%;
width: 100%;
height: calc(100% - 25px);
overflow: auto;
.legend-item {
height: 25px;
width: 100%;
display: flex;
align-items: center;
font-size: 14px;
font-weight: 400;
color: #ffffff;
line-height: 24px;
.color-block {
width: 9px;
height: 8px;
margin-right: 10px;
}
}
}
}
}
.echarts-legend-c .legend-for::-webkit-scrollbar {
/*滚动条整体样式*/
width: 4px; /*高宽分别对应横竖滚动条的尺寸*/
height: 3px;
}
.echarts-legend-c .legend-for::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
border-radius: 10px;
box-shadow: inset 0 0 5px #004eb0;
background: #004eb0;
}
.echarts-legend-c .legend-for::-webkit-scrollbar-track {
/*滚动条里面轨道*/
box-shadow: inset 0 0 5px #042764;
border-radius: 10px;
background: #042764;
}
}
</style>

View File

@ -0,0 +1,183 @@
<template>
<div class="big-wraring-info-wrap">
<nav-temp htmlType="t1" :title="title">
<div class="conter-block" slot="mk-center">
<census-temp-a
v-for="(item, idx) in radarOption2"
:key="idx"
:icolor="item.icolor"
:title="item.title"
:value="result[item.key] || 0"
:icons="item.icons"
></census-temp-a>
</div>
</nav-temp>
</div>
</template>
<script>
import EchartsBarWrap from "./echartsBar";
import NavTemp from "./navTemp";
import CensusTempA from "./censusTempA";
export default {
name: "wraringInfoWrap",
components: {
EchartsBarWrap,
NavTemp,
CensusTempA,
},
props: ["result", 'countResult'],
data() {
return {
title: "运行分析",
radarOption: [],
radarOption2: [
{
icolor: "#00FF48",
icons: "iconfenxi",
title: "总功率(kW)",
value: "456",
key: 'psTotal'
},
{
icolor: "#4FFFFF",
icons: "iconbiandianzhan",
title: "总电量(kWh)",
value: "456",
key: 'pwTotal'
},
{
icolor: "#F1E156",
icons: "iconfugaidq",
title: "覆盖地区(个)",
value: "456",
key: 'projectTotal'
},
{
icolor: "#4FFFFF",
icons: "iconqunchengyuan",
title: "接入用户(家)",
value: "456",
key: 'userTotal'
},
{
icolor: "#F1E156",
icons: "iconjierusb",
title: "接入设备(台)",
value: "456",
key: 'deviceTotal'
},
{
icolor: "#00FF48",
icons: "iconshebei",
title: "设备在线(台)",
value: "456",
key: 'onlineTotal'
},
],
};
},
created() {
this.radarOption = [0, 0, 0];
},
watch: {
result: {
handler: function (obj, oldVal) {
this.radarOption = [];
if (obj) {
this.radarOption.push(obj.alarmTotal);
this.radarOption.push(obj.unProcessed);
this.radarOption.push(obj.processed);
} else {
this.radarOption = [0, 0, 0];
}
},
deep: true,
},
},
};
</script>
<style lang="scss">
.big-wraring-info-wrap {
width: 400px;
height: 350px;
.conter-block {
width: 100%;
height: 290px;
background-size: contain;
padding-top: 10px;
padding: 5px;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
.count-block {
width: calc(100% - 40px);
height: 180px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: flex-start;
margin: 5px 20px;
.info-block-div {
width: 115px;
height: 165px;
border: 0;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
padding: 20px 0;
> div {
width: 100%;
display: flex;
justify-content: center;
font-family: "Source Han Sans SC";
}
> div:nth-child(2) {
font-size: 16px;
color: #ffffff;
font-size: 16px;
font-weight: 400;
color: #00bedb;
line-height: 16px;
}
> div:nth-child(3) {
font-size: 34px;
font-family: "Agency FB";
font-weight: 400;
color: #ffffff;
line-height: 36px;
height: 40px;
}
.big-wraring-svg {
font-size: 40px;
}
}
.alarm-icon-block {
position: relative;
width: 49px;
height: 49px;
z-index: 1;
border: 2px solid #21ffff;
border-radius: 50%;
display: flex;
justify-content: center;
top: -120px;
left: 155px;
background: #042fb4;
box-shadow: 0px 0px 60px 15px #012c9e;
> i {
color: #21ffff;
font-size: 30px;
}
}
}
}
.mk-bottom {
height: 30px;
width: 100%;
background-image: url("../../../../assets/images/big/boxleft-bottom.png");
}
}
</style>

View File

@ -0,0 +1,612 @@
<template>
<div class="app-container">
<el-form
:model="queryParams"
ref="queryForm"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="批次号" prop="batchNumber">
<el-input
v-model="queryParams.batchNumber"
placeholder="请输入批次号"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="区别编码" prop="differentCode">
<el-select
v-model="queryParams.differentCode"
style="width: 100%"
placeholder="请选择区别编码"
>
<el-option
v-for="dict in differentCodeDicts"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="厂商" prop="vendorId">
<el-select
v-model="queryParams.vendorId"
style="width: 100%"
placeholder="请选择区别编码"
>
<el-option
v-for="dict in queryVendorList"
:key="dict.vendorId"
:label="dict.vendorName"
:value="dict.vendorId"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="批次编码" prop="batchCode">
<el-input
v-model="queryParams.batchCode"
placeholder="请输入批次编码"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button
type="primary"
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="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['iot:batch:add']"
>新增</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['iot:batch:remove']"
>删除</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['iot:batch:export']"
>导出</el-button
>
</el-col>
<right-toolbar
:showSearch.sync="showSearch"
@queryTable="getList"
></right-toolbar>
</el-row>
<el-table
v-loading="loading"
:data="batchList"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="50" align="center" />
<el-table-column type="index" label="序号" align="center" :index="indexFormatter" width="80px"></el-table-column>
<!-- <el-table-column label="序号" align="center" prop="index" width="50" /> -->
<el-table-column label="批次号" align="center" prop="batchNumber" />
<el-table-column
label="区别编码"
align="left"
prop="differentCode"
:formatter="statusFormat"
/>
<el-table-column label="厂商" align="left" prop="vendorName" />
<el-table-column label="批次编码" align="left" prop="batchCode" />
<el-table-column
label=" 创建时间"
align="center"
prop="createTime"
width="150px"
/>
<el-table-column
label="操作"
align="center"
width="200"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<!-- <el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['iot:batch:edit']"
>修改</el-button
> -->
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['iot:batch:remove']"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改硬件数据库对话框 -->
<div>
<dialog-template :title="title" :visible="open">
<el-form
ref="form"
:model="form"
:rules="rules"
slot="dialog-center"
label-width="80px"
>
<el-form-item label="批次号" prop="batchNumber">
<el-input v-model="form.batchNumber" placeholder="请输入批次号" />
</el-form-item>
<el-form-item label="区别编码" prop="differentCode">
<el-select
v-model="form.differentCode"
style="width: 100%"
placeholder="请选择区别编码"
>
<el-option
v-for="dict in differentCodeDicts"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="厂商" prop="vendorId">
<el-input
v-model="form.vendorName"
placeholder="点击选择厂商"
@focus="openTableSelectDialog()"
/>
</el-form-item>
</el-form>
<div slot="dialog-footer">
<el-button type="primary" size="mini" @click="submitForm"
> </el-button
>
<el-button size="mini" @click="cancel"> </el-button>
</div>
</dialog-template>
<el-dialog
title="选择"
:visible.sync="selectTableShow"
width="75%"
top="10vh"
class="select-table-dialog"
:close-on-click-modal="false"
>
<select-table-wrap
v-if="selectTableShow"
:tableOption="tableSelectOption.tableOpt"
:queryOption="tableSelectOption.queryOpt"
:tableList="tableSelectOption.tableList"
@parentGetList="childGetList($event)"
:otherOption="tableSelectOption.otherOption"
@returnEvent="returnEvent($event)"
/>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" @click="resuleClick"
> </el-button
>
<el-button
size="mini"
@click="
() => {
selectTableShow = false;
}
"
> </el-button
>
</div>
</el-dialog>
</div>
</div>
</template>
<script>
import {
listBatch,
getBatch,
delBatch,
addBatch,
updateBatch,
exportBatch,
} from "@/api/iot/batch";
import { listVendor } from "@/api/iot/vendor";
import DialogTemplate from "@/components/DialogTemplate";
import SelectTableWrap from "@/components/SelectTable/index";
export default {
name: "Batch",
components: {
DialogTemplate,
SelectTableWrap,
},
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
batchList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
batchNumber: null,
differentCode: null,
vendorId: null,
batchCode: null,
},
//
form: {},
//
rules: {
batchNumber: [
{ required: true, message: "批次号不能为空", trigger: "blur" },
],
differentCode: [
{ required: true, message: "区别编码不能为空", trigger: "blur" },
],
vendorId: [
{ required: true, message: "厂商主键ID不能为空", trigger: "blur" },
],
},
selectResult: {},
tableSelectOption: {},
selectTableShow: false,
differentCodeDicts: null,
queryVendorList: [],
};
},
created() {
this.getDicts("different_code").then((response) => {
this.differentCodeDicts = response.data;
});
this.getVendor();
this.getList();
},
methods: {
indexFormatter(val) {
return val + 1 + ((this.queryParams.pageNum - 1) * this.queryParams.pageSize);
},
getVendor() {
listVendor(
Object.assign({ selected: 1, pageSize: 99999, pageNum: 1 })
).then((response) => {
this.queryVendorList = response.rows;
});
},
//
statusFormat(row, column) {
return this.selectDictLabel(this.differentCodeDicts, row.differentCode);
},
//
openTableSelectDialog() {
this.selectResult = {};
this.tableSelectOption = {
otherOption: {
tableType: "vendor",
},
queryOpt: {
disable: false,
labelWidth: "68px",
params: {
vendorName: "",
vendorAddress: "",
vendorContact: "",
},
page: {
pageSize: 10,
pageNum: 1,
total: 0,
},
inline: true,
queryChilds: [
{
style: "",
placeholder: "厂商名称",
clearable: true,
label: "厂商名称",
type: "input",
key: "vendorName",
size: "small",
value: "",
},
{
style: "",
placeholder: "厂商地址",
clearable: true,
label: "厂商地址",
type: "input",
key: "vendorAddress",
size: "small",
value: "",
},
{
style: "",
placeholder: "联系方式",
clearable: true,
label: "联系方式",
type: "input",
key: "vendorContact",
size: "small",
value: "",
},
],
},
tableOpt: {
loading: false,
rowKey: "deviceId",
selection: false,
maxHeight: "45vh",
childs: [
{
style: "",
label: "厂商名称",
type: "",
prop: "vendorName",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span",
},
{
style: "",
label: " 联系方式",
type: "",
prop: "vendorContact",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span",
},
{
style: "",
label: "厂商地址",
type: "",
prop: "vendorAddress",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span",
},
],
tableList: {
type: Array,
},
},
tableList: [],
};
this.selectTableShow = true;
},
//
childGetList(data) {
if (data.otherOption.tableType === "vendor") {
this.vendorChildList(data);
} else if (data.otherOption.tableType === "product") {
this.productChildList(data);
}
},
productChildList(data) {
listProductList(
Object.assign(data.page, data.param, { selected: 1 })
).then((response) => {
this.tableSelectOption.tableList = response.data;
// this.tableSelectOption.queryOpt.page.total = Number(response.total);
});
},
vendorChildList(data) {
listVendor(Object.assign(data.page, data.param, { selected: 1 })).then(
(response) => {
this.tableSelectOption.tableList = response.rows;
this.tableSelectOption.queryOpt.page.total = Number(response.total);
}
);
},
//
returnEvent(data) {
this.selectResult = {};
if (data.type === "dblclick") {
if (data.otherOption.tableType === "vendor") {
this.form.vendorId = data.value.vendorId;
this.form.vendorName = data.value.vendorName;
} else if (data.otherOption.tableType === "product") {
this.form.prodKey = data.value.prodId;
this.form.prodSecret = data.value.prodSecret;
}
this.selectTableShow = false;
} else if (data.type === "click") {
if (data.otherOption.tableType === "vendor") {
this.selectResult.vendorId = data.value.vendorId;
this.selectResult.vendorName = data.value.vendorName;
} else if (data.otherOption.tableType === "product") {
this.selectResult.prodKey = data.value.prodId;
this.selectResult.prodSecret = data.value.prodSecret;
}
this.selectResult.tableType = data.otherOption.tableType;
}
},
//
resuleClick() {
if (this.selectResult.tableType === "vendor") {
this.form.vendorId = this.selectResult.vendorId;
this.form.vendorName = this.selectResult.vendorName;
} else if (this.selectResult.tableType === "product") {
this.form.prodKey = this.selectResult.prodKey;
this.form.prodSecret = this.selectResult.prodSecret;
}
this.selectTableShow = false;
},
/** 查询设备批次号列表 */
getList() {
this.loading = true;
listBatch(this.queryParams).then((response) => {
this.batchList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
batchId: null,
batchNumber: null,
createId: null,
differentCode: null,
createTime: null,
vendorId: null,
updateId: null,
batchCode: null,
updateTime: null,
remark: null,
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map((item) => item.batchId);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加设备批次号";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const batchId = row.batchId || this.ids;
getBatch(batchId).then((response) => {
this.form = response.data;
this.open = true;
this.title = "修改设备批次号";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate((valid) => {
if (valid) {
if (this.form.batchId != null) {
updateBatch(this.form).then((response) => {
this.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addBatch(this.form).then((response) => {
this.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const batchIds = row.batchId || this.ids;
this.$confirm("是否删除该选项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(function () {
return delBatch(batchIds);
})
.then(() => {
this.getList();
this.msgSuccess("删除成功");
});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$confirm("是否确认导出所有设备批次号数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(function () {
return exportBatch(queryParams);
})
.then((response) => {
this.download(response.msg);
});
},
},
};
</script>

View File

@ -0,0 +1,681 @@
<template>
<div class="app-container">
<el-form
:model="queryParams"
ref="queryForm"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="芯片ID" prop="uId">
<el-input
v-model="queryParams.uId"
placeholder="请输入芯片ID"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="批次编码" prop="batchCode">
<el-input
v-model="queryParams.batchCode"
placeholder="请输入流水号"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="硬件条码" prop="devId">
<el-input
v-model="queryParams.devId"
placeholder="请输入硬件条码"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button
type="primary"
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="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['iot:library:add']"
>新增</el-button
>
</el-col>
<!-- <el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['iot:library:edit']"
>修改</el-button
>
</el-col> -->
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['iot:library:remove']"
>删除</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['iot:library:export']"
>导出</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="info"
plain
icon="el-icon-upload"
size="mini"
@click="handleImport"
>导入</el-button
>
</el-col>
<right-toolbar
:showSearch.sync="showSearch"
@queryTable="getList"
></right-toolbar>
</el-row>
<el-table
v-loading="loading"
:data="libraryList"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="50" align="center" />
<el-table-column
type="index"
label="序号"
align="center"
:index="indexFormatter"
width="80px"
></el-table-column>
<el-table-column label="芯片ID" align="left" prop="uId" />
<el-table-column label="批次编码" align="left" prop="batchCode" />
<el-table-column label="硬件条码" align="left" prop="devId" />
<el-table-column
label=" 创建时间"
align="center"
prop="createTime"
width="150px"
/>
<el-table-column
label="操作"
align="center"
width="200"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<!-- <el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['iot:library:edit']"
>修改</el-button
> -->
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['iot:library:remove']"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改硬件数据库对话框 -->
<div>
<dialog-template :title="title" :visible="open">
<el-form
ref="form"
:model="form"
:rules="rules"
slot="dialog-center"
label-width="80px"
>
<el-form-item label="芯片ID" prop="uId">
<el-input v-model="form.uId" placeholder="请输入芯片ID" />
</el-form-item>
<el-form-item label="批次" prop="batchId">
<el-input
v-model="batchNumber"
placeholder="点击选择批次"
@focus="openTableSelectDialog()"
/>
</el-form-item>
</el-form>
<div slot="dialog-footer">
<el-button type="primary" size="mini" @click="submitForm"
> </el-button
>
<el-button size="mini" @click="cancel"> </el-button>
</div>
</dialog-template>
<el-dialog
title="选择"
:visible.sync="selectTableShow"
width="75%"
top="10vh"
class="select-table-dialog"
:close-on-click-modal="false"
>
<select-table-wrap
v-if="selectTableShow"
:tableOption="tableSelectOption.tableOpt"
:queryOption="tableSelectOption.queryOpt"
:tableList="tableSelectOption.tableList"
@parentGetList="childGetList($event)"
:otherOption="tableSelectOption.otherOption"
@returnEvent="returnEvent($event)"
/>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" @click="resuleClick"
> </el-button
>
<el-button
size="mini"
@click="
() => {
selectTableShow = false;
}
"
> </el-button
>
</div>
</el-dialog>
<!-- 用户导入对话框 -->
<el-dialog
:title="upload.title"
:visible.sync="upload.open"
width="400px"
append-to-body
>
<el-form
ref="form"
:model="form"
:rules="rules"
label-width="80px"
>
<el-form-item label="批次" prop="batchId">
<el-input
v-model="batchNumber"
placeholder="点击选择批次"
@focus="openTableSelectDialog()"
/>
</el-form-item>
</el-form>
<el-upload
ref="upload"
:limit="1"
accept=".xlsx, .xls"
:headers="upload.headers"
:action="upload.url + '?updateSupport=' + upload.updateSupport"
:disabled="upload.isUploading"
:on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess"
:auto-upload="false"
:data="form"
drag
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">
将文件拖到此处
<em>点击上传</em>
</div>
<div class="el-upload__tip" slot="tip">
<!-- <el-checkbox v-model="upload.updateSupport" />是否更新已经存在的硬件数据 -->
<el-link type="info" style="font-size: 12px" @click="importTemplate"
>下载模板</el-link
>
</div>
<div class="el-upload__tip" style="color: red" slot="tip">
提示仅允许导入xlsxlsx格式文件
</div>
</el-upload>
<div slot="footer" class="dialog-footer">
<el-button type="primary" size="mini" @click="submitFileForm"
> </el-button
>
<el-button size="mini" @click="upload.open = false"> </el-button>
</div>
</el-dialog>
</div>
</div>
</template>
<script>
import {
listLibrary,
getLibrary,
delLibrary,
addLibrary,
updateLibrary,
exportLibrary,
importTemplate,
} from "@/api/iot/library";
import { listBatch } from "@/api/iot/batch";
import DialogTemplate from "@/components/DialogTemplate";
import SelectTableWrap from "@/components/SelectTable/index";
import { getToken } from "@/utils/auth";
export default {
name: "Library",
components: {
DialogTemplate,
SelectTableWrap,
},
data() {
return {
importForm: {
batchId: "",
},
//
upload: {
//
open: false,
//
title: "",
//
isUploading: false,
//
updateSupport: 0,
//
headers: { Authorization: "Bearer " + getToken() },
//
url: process.env.VUE_APP_BASE_API + "/iot/library/importData",
},
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
libraryList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
uId: null,
serialNumber: null,
devId: null,
},
batchNumber: "",
//
form: {},
//
rules: {
uId: [
{ required: true, message: "芯片ID不能为空", trigger: "blur" },
{
type: "string",
pattern: /^[A-z 0-9]{16,30}$/,
message: "格式不正确:[A-z 0-9] 16-30字符",
trigger: "blur",
},
],
batchId: [
{ required: true, message: "批次主键不能为空", trigger: "change" },
],
},
selectResult: {},
tableSelectOption: {},
selectTableShow: false,
differentCodeDicts: null,
queryVendorList: [],
};
},
created() {
this.getList();
},
methods: {
//
handleFileUploadProgress(event, file, fileList) {
this.upload.isUploading = true;
},
//
handleFileSuccess(response, file, fileList) {
this.upload.open = false;
this.upload.isUploading = false;
this.$refs.upload.clearFiles();
this.$alert(response.msg, "导入结果", { dangerouslyUseHTMLString: true });
this.getList();
},
//
submitFileForm() {
this.$refs["form"].validate((valid) => {
if (valid) {
this.$refs.upload.submit();
}
});
},
/** 下载模板操作 */
importTemplate() {
importTemplate().then((response) => {
this.download(response.msg);
});
},
/** 导入按钮操作 */
handleImport() {
this.upload.title = "批量导入硬件";
this.form = {
batchId: ''
}
this.batchNumber = ''
this.upload.open = true;
},
indexFormatter(val) {
return (
val + 1 + (this.queryParams.pageNum - 1) * this.queryParams.pageSize
);
},
//
statusFormat(row, column) {
return this.selectDictLabel(this.differentCodeDicts, row.differentCode);
},
//
openTableSelectDialog() {
this.selectResult = {};
this.tableSelectOption = {
otherOption: {
tableType: "batch",
},
queryOpt: {
disable: false,
labelWidth: "68px",
params: {
batchNumber: "",
batchCode: "",
},
page: {
pageSize: 10,
pageNum: 1,
total: 0,
},
inline: true,
queryChilds: [
{
style: "",
placeholder: "批次号",
clearable: true,
label: "批次号",
type: "input",
key: "batchNumber",
size: "small",
value: "",
},
{
style: "",
placeholder: "批次编码",
clearable: true,
label: "批次编码",
type: "input",
key: "batchCode",
size: "small",
value: "",
},
],
},
tableOpt: {
loading: false,
rowKey: "batchId",
selection: false,
maxHeight: "45vh",
childs: [
{
style: "",
label: "批次号",
type: "",
prop: "batchNumber",
align: "center",
width: "",
"show-overflow-tooltip": false,
tempType: "span",
},
{
style: "",
label: " 区别编码",
type: "",
prop: "differentCode",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span",
},
{
style: "",
label: "厂商",
type: "",
prop: "batchNumber",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span",
},
{
style: "",
label: "批次编码",
type: "",
prop: "batchCode",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span",
},
],
tableList: {
type: Array,
},
},
tableList: [],
};
this.selectTableShow = true;
},
//
childGetList(data) {
if (data.otherOption.tableType === "batch") {
this.vendorChildList(data);
}
},
vendorChildList(data) {
listBatch(Object.assign(data.page, data.param, { selected: 1 })).then(
(response) => {
this.tableSelectOption.tableList = response.rows;
this.tableSelectOption.queryOpt.page.total = Number(response.total);
}
);
},
//
returnEvent(data) {
this.selectResult = {};
if (data.type === "dblclick") {
if (data.otherOption.tableType === "batch") {
this.form.batchId = data.value.batchId;
this.batchNumber = data.value.batchNumber;
}
this.selectTableShow = false;
} else if (data.type === "click") {
if (data.otherOption.tableType === "batch") {
this.selectResult.batchId = data.value.batchId;
this.selectResult.batchNumber = data.value.batchNumber;
}
this.selectResult.tableType = data.otherOption.tableType;
}
},
//
resuleClick() {
if (this.selectResult.tableType === "batch") {
this.form.batchId = this.selectResult.batchId;
this.batchNumber = this.selectResult.batchNumber;
}
this.selectTableShow = false;
},
/** 查询硬件数据库列表 */
getList() {
this.loading = true;
listLibrary(this.queryParams).then((response) => {
this.libraryList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
hardwareId: null,
uId: null,
batchId: null,
};
this.batchNumber = ''
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map((item) => item.hardwareId);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加硬件数据库";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const hardwareId = row.hardwareId || this.ids;
getLibrary(hardwareId).then((response) => {
this.form = response.data;
this.open = true;
this.title = "修改硬件数据库";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate((valid) => {
if (valid) {
if (this.form.hardwareId != null) {
updateLibrary(this.form).then((response) => {
this.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addLibrary(this.form).then((response) => {
this.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const hardwareIds = row.hardwareId || this.ids;
this.$confirm("是否删除该选项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(function () {
return delLibrary(hardwareIds);
})
.then(() => {
this.getList();
this.msgSuccess("删除成功");
});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$confirm("是否确认导出所有硬件数据库数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(function () {
return exportLibrary(queryParams);
})
.then((response) => {
this.download(response.msg);
});
},
},
};
</script>

View File

@ -35,8 +35,16 @@
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
<el-button
type="primary"
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>
@ -49,25 +57,56 @@
size="mini"
@click="handleAdd"
v-hasPermi="['iot:vendor:add']"
>新增</el-button>
>新增</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-table
v-loading="loading"
:data="vendorList"
@selection-change="handleSelectionChange"
:default-sort="{prop: 'createTime', order: 'descending'}"
:default-sort="{ prop: 'createTime', order: 'descending' }"
@sort-change="sortChange"
>
<el-table-column type="index" label="序号" align="center" :index="indexFormatter" width="80px"></el-table-column>
<el-table-column label="厂商名称" align="left" width="250" prop="vendorName" />
<el-table-column label="联系方式" align="left" width="250" prop="vendorContact" />
<el-table-column
type="index"
label="序号"
align="center"
:index="indexFormatter"
width="80px"
></el-table-column>
<el-table-column
label="厂商名称"
align="left"
width="250"
prop="vendorName"
/>
<el-table-column
label="联系方式"
align="left"
width="250"
prop="vendorContact"
/>
<el-table-column label="厂商地址" align="left" prop="vendorAddress" />
<el-table-column label="备注" align="left" prop="remark" />
<el-table-column label="创建时间" align="center" sortable="custom" width="160" prop="createTime" />
<el-table-column label="操作" align="center" width="200" class-name="small-padding fixed-width">
<el-table-column
label="创建时间"
align="center"
sortable="custom"
width="160"
prop="createTime"
/>
<el-table-column
label="操作"
align="center"
width="200"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<el-button
size="mini"
@ -75,14 +114,16 @@
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['iot:vendor:edit']"
>修改</el-button>
>修改</el-button
>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['iot:vendor:remove']"
>删除</el-button>
>删除</el-button
>
</template>
</el-table-column>
</el-table>
@ -94,28 +135,51 @@
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<div>
<dialog-template :title="title" :visible="open">
<el-form
ref="form"
slot="dialog-center"
:model="form"
:rules="rules"
label-width="100px"
>
<el-form-item label="厂商名称:" prop="vendorName">
<el-input v-model="form.vendorName" placeholder="请输入厂商名称" />
</el-form-item>
<el-form-item label="联系方式:" prop="vendorContact">
<el-input
v-model="form.vendorContact"
placeholder="请输入厂商联系方式"
/>
</el-form-item>
<el-form-item label="厂商编码:" prop="vendorCode">
<el-input v-model="form.vendorCode" :disabled="form.vendorId !== null && form.vendorId !== undefault" placeholder="请输入厂商编码" />
</el-form-item>
<el-form-item label="厂商地址:" prop="vendorAddress">
<el-input
v-model="form.vendorAddress"
placeholder="请输入厂商地址"
/>
</el-form-item>
<!-- 添加或修改厂商对话框 -->
<el-dialog class="eldialog-wrap" :close-on-click-modal="false" :title="title" :visible.sync="open" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-form-item label="厂商名称:" prop="vendorName">
<el-input v-model="form.vendorName" placeholder="请输入厂商名称" />
</el-form-item>
<el-form-item label="联系方式:" prop="vendorContact">
<el-input v-model="form.vendorContact" placeholder="请输入厂商联系方式" />
</el-form-item>
<el-form-item label="厂商地址:" prop="vendorAddress">
<el-input v-model="form.vendorAddress" placeholder="请输入厂商地址" />
</el-form-item>
<el-form-item label="备注:" prop="remark">
<el-input v-model="form.remark" type="textarea" :rows="2" placeholder="请输入备注" />
</el-form-item>
</el-form>
<div slot="footer" class="form-button-div">
<el-button size="mini" type="primary" @click="submitForm"> </el-button>
<el-button size="mini" @click="cancel"> </el-button>
</div>
</el-dialog>
<el-form-item label="备注:" prop="remark">
<el-input
v-model="form.remark"
type="textarea"
:rows="2"
placeholder="请输入备注"
/>
</el-form-item>
</el-form>
<div slot="dialog-footer">
<el-button type="primary" size="mini" @click="submitForm"
> </el-button
>
<el-button size="mini" @click="cancel"> </el-button>
</div>
</dialog-template>
</div>
</div>
</template>
@ -126,12 +190,15 @@ import {
delVendor,
addVendor,
updateVendor,
exportVendor
exportVendor,
} from "@/api/iot/vendor";
import DialogTemplate from "@/components/DialogTemplate";
export default {
name: "Vendor",
components: {},
components: {
DialogTemplate,
},
data() {
return {
//
@ -160,19 +227,27 @@ export default {
vendorAddress: null,
vendorContact: null,
orderByColumn: "createTime",
isAsc: "desc"
isAsc: "desc",
},
//
form: {},
//
rules: {
vendorName: [
{ required: true, message: "厂商名称不能为空", trigger: "blur" }
{ required: true, message: "厂商名称不能为空", trigger: "blur" },
],
vendorContact: [
{ required: true, message: "联系方式不能为空", trigger: "blur" }
]
}
{ required: true, message: "联系方式不能为空", trigger: "blur" },
],
vendorCode: [
{ required: true, message: "厂商编码不能为空", trigger: "blur" },
{
pattern: /^[0-9]{3}$/,
message: "格式不正确:[0-9] 三个字符",
trigger: "blur",
},
],
},
};
},
created() {
@ -182,7 +257,7 @@ export default {
sortChange(column) {
const sort = {
isAsc: column.order === "descending" ? "desc" : "asc",
orderByColumn: column.prop
orderByColumn: column.prop,
};
this.queryParams = Object.assign(this.queryParams, sort);
this.handleQuery();
@ -195,7 +270,7 @@ export default {
/** 查询厂商列表 */
getList() {
this.loading = true;
listVendor(this.queryParams).then(response => {
listVendor(this.queryParams).then((response) => {
this.vendorList = response.rows;
this.total = response.total;
this.loading = false;
@ -213,12 +288,13 @@ export default {
vendorName: null,
vendorAddress: null,
vendorContact: null,
vendorCode: "",
delFlag: null,
createId: null,
createTime: null,
updateId: null,
updateTime: null,
remark: null
remark: null,
};
this.resetForm("form");
},
@ -234,7 +310,7 @@ export default {
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.vendorId);
this.ids = selection.map((item) => item.vendorId);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
@ -248,7 +324,7 @@ export default {
handleUpdate(row) {
this.reset();
const vendorId = row.vendorId || this.ids;
getVendor(vendorId).then(response => {
getVendor(vendorId).then((response) => {
this.form = response.data;
this.open = true;
this.title = "修改厂商";
@ -256,16 +332,16 @@ export default {
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
this.$refs["form"].validate((valid) => {
if (valid) {
if (this.form.vendorId != null) {
updateVendor(this.form).then(response => {
updateVendor(this.form).then((response) => {
this.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addVendor(this.form).then(response => {
addVendor(this.form).then((response) => {
this.msgSuccess("新增成功");
this.open = false;
this.getList();
@ -280,9 +356,9 @@ export default {
this.$confirm("是否删除该选项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
type: "warning",
})
.then(function() {
.then(function () {
return delVendor(vendorIds);
})
.then(() => {
@ -296,16 +372,16 @@ export default {
this.$confirm("是否确认导出所有厂商数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
type: "warning",
})
.then(function() {
.then(function () {
return exportVendor(queryParams);
})
.then(response => {
.then((response) => {
this.download(response.msg);
});
}
}
},
},
};
</script>
<style lang="scss">

View File

@ -133,6 +133,22 @@
</div>
</div>
<div class="table-row">
<div class="table-row-col">
<div class="title">芯片ID</div>
<div class="content">{{infoData.uId || '--'}}</div>
</div>
<div class="table-row-col">
<div class="title">主板ID</div>
<div class="content">{{infoData.boaId || '--'}}</div>
</div>
<div class="table-row-col">
<div class="title">组装ID</div>
<div class="content">{{infoData.assId || '--'}}</div>
</div>
</div>
<div class="table-row">
<div class="table-row-col" style="flex: 3 1 0%;">
<div class="title">设备图片</div>