Merge branch 'develop' into single-develop
@ -5,7 +5,7 @@
|
|||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||||
<meta name="renderer" content="webkit">
|
<meta name="renderer" content="webkit">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
<link rel="icon" href="<%= BASE_URL %>logo-icon.png">
|
||||||
<title><%= webpackConfig.name %></title>
|
<title><%= webpackConfig.name %></title>
|
||||||
<!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
|
<!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
BIN
public/logo-icon.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
@ -14,7 +14,13 @@ export function getSevenChargeData({siteId,startDate,endDate}) {
|
|||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
// 获取站点包含的设备种类 用来判断单站监控设备监控的菜单栏展示
|
||||||
|
export function getSiteAllDeviceCategory(siteId) {
|
||||||
|
return request({
|
||||||
|
url: `/ems/siteConfig/getSiteAllDeviceCategory?siteId=${siteId}`,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
//获取pcs、实时运行头部的设备信息
|
//获取pcs、实时运行头部的设备信息
|
||||||
export function getRunningHeadInfo(siteId) {
|
export function getRunningHeadInfo(siteId) {
|
||||||
return request({
|
return request({
|
||||||
@ -100,6 +106,14 @@ export function getAlarmDetailList({status,siteId, deviceId, alarmLevel, alarmSt
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 告警生成工单
|
||||||
|
export function createTicketNo(data) {
|
||||||
|
return request({
|
||||||
|
url: `/ems/siteAlarm/createTicketNo`,
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
// 概率统计
|
// 概率统计
|
||||||
//获取概率统计 电量指标接口
|
//获取概率统计 电量指标接口
|
||||||
export function getElectricData({siteId,startDate,endDate}) {
|
export function getElectricData({siteId,startDate,endDate}) {
|
||||||
@ -146,10 +160,10 @@ export function storagePower(siteId) {
|
|||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
//poc平均温度
|
//poc温度
|
||||||
export function stackAveTemp(siteId) {
|
export function pcsMaxTemp(siteId) {
|
||||||
return request({
|
return request({
|
||||||
url: `/ems/siteMonitor/runningGraph/stackAveTemp?siteId=${siteId}`,
|
url: `/ems/siteMonitor/runningGraph/pcsMaxTemp?siteId=${siteId}`,
|
||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -183,9 +197,9 @@ export function getLoadNameList(siteId) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 电表报表
|
// 电表报表
|
||||||
export function getAmmeterData({siteId,deviceId,dateTime}) {
|
export function getAmmeterData({siteId,startTime,endTime, pageSize, pageNum}) {
|
||||||
return request({
|
return request({
|
||||||
url: `/ems/statsReport/getAmmeterData?siteId=${siteId}&deviceId=${deviceId}&dateTime=${dateTime}`,
|
url: `/ems/statsReport/getAmmeterData?siteId=${siteId}&startTime=${startTime}&endTime=${endTime}&pageSize=${pageSize}&pageNum=${pageNum}`,
|
||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
42
src/api/ems/powerTariff.js
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
// 新增
|
||||||
|
export function addPriceConfig(data) {
|
||||||
|
return request({
|
||||||
|
url: '/ems/energyPriceConfig',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//修改
|
||||||
|
export function editPriceConfig(data) {
|
||||||
|
return request({
|
||||||
|
url: '/ems/energyPriceConfig',
|
||||||
|
method: 'put',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//删除
|
||||||
|
export function energyPriceConfig(id) {
|
||||||
|
return request({
|
||||||
|
url: `/ems/energyPriceConfig/${id}`,
|
||||||
|
method: 'DELETE',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//详情
|
||||||
|
export function detailPriceConfig(id) {
|
||||||
|
return request({
|
||||||
|
url: `/ems/energyPriceConfig/${id}`,
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//列表
|
||||||
|
export function listPriceConfig({startTime,endTime,pageSize,pageNum,siteId}) {
|
||||||
|
return request({
|
||||||
|
url: `/ems/energyPriceConfig/list?startTime=${startTime}&endTime=${endTime}&pageNum=${pageNum}&pageSize=${pageSize}&siteId=${siteId}`,
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
@ -54,7 +54,13 @@ export function deleteService(id) {
|
|||||||
method: 'delete',
|
method: 'delete',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
// 获取上级设备id列表
|
||||||
|
export function getParentDeviceId({siteId,deviceCategory}) {
|
||||||
|
return request({
|
||||||
|
url: `/ems/siteConfig/getParentDeviceId?siteId=${siteId}&deviceCategory=${deviceCategory}`,
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
}
|
||||||
//获取所有设备
|
//获取所有设备
|
||||||
export function getDeviceList(siteId) {
|
export function getDeviceList(siteId) {
|
||||||
return request({
|
return request({
|
||||||
@ -64,9 +70,61 @@ export function getDeviceList(siteId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//获取设备点位table
|
//获取设备点位table
|
||||||
export function getDevicePointList({siteId,deviceId,deviceCategory,pageNum,pageSize,dataPointName=''}) {
|
export function getDevicePointList({siteId,deviceId,deviceCategory,parentId,pageNum,pageSize,dataPointName='',sortMethod,sortData,dataPoint,lower,upper}) {
|
||||||
return request({
|
return request({
|
||||||
url: `/ems/siteConfig/getDevicePointList?siteId=${siteId}&deviceId=${deviceId}&pageNum=${pageNum}&pageSize=${pageSize}&deviceCategory=${deviceCategory}&dataPointName=${dataPointName}`,
|
url: `/ems/siteConfig/getDevicePointList?siteId=${siteId}&deviceId=${deviceId}&pageNum=${pageNum}&pageSize=${pageSize}&deviceCategory=${deviceCategory}&dataPointName=${dataPointName}&parentId=${parentId}&dataPoint=${dataPoint}&lower=${lower}&upper=${upper}&pageNum=${pageNum}&sortMethod=${sortMethod}&sortData=${sortData}`,
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//获取设备类型下面的所有设备列表
|
||||||
|
export function getDeviceListBySiteAndCategory({siteId, deviceCategory}) {
|
||||||
|
return request({
|
||||||
|
url: `/ems/siteConfig/getDeviceListBySiteAndCategory?siteId=${siteId}&deviceCategory=${deviceCategory}`,
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//新增设备保护
|
||||||
|
export function addProtectPlan(data) {
|
||||||
|
return request({
|
||||||
|
url: `/ems/protectPlan`,
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//修改设备保护
|
||||||
|
export function updateProtectPlan(data) {
|
||||||
|
return request({
|
||||||
|
url: `/ems/protectPlan`,
|
||||||
|
method: 'put',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//删除设备保护
|
||||||
|
export function deleteProtectPlan(id) {
|
||||||
|
return request({
|
||||||
|
url: `/ems/protectPlan/${id}`,
|
||||||
|
method: 'delete',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//设备保护详情
|
||||||
|
export function getProtectPlan(id) {
|
||||||
|
return request({
|
||||||
|
url: `/ems/protectPlan/${id}`,
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//设备保护详情列表
|
||||||
|
//http://localhost:8089/ems/protectPlan/list?pageSize=10&pageNum=1&faultName=总压&siteId=021_DDS_01
|
||||||
|
export function protectPlanList({siteId, faultName,pageSize,pageNum}) {
|
||||||
|
return request({
|
||||||
|
url: `/ems/protectPlan/list?siteId=${siteId}&faultName=${faultName}&pageSize=${pageSize}&pageNum=${pageNum}`,
|
||||||
method: 'get',
|
method: 'get',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
BIN
src/assets/images/ems/loginBg/1.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
src/assets/images/ems/loginBg/2.png
Normal file
|
After Width: | Height: | Size: 1.7 MiB |
BIN
src/assets/images/ems/loginBg/3.png
Normal file
|
After Width: | Height: | Size: 2.1 MiB |
BIN
src/assets/images/ems/loginBg/4.png
Normal file
|
After Width: | Height: | Size: 1021 KiB |
BIN
src/assets/images/ems/logo-icon.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 134 KiB |
BIN
src/assets/images/ems/logo-small.png
Normal file
|
After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 509 KiB |
@ -54,6 +54,7 @@ export default {
|
|||||||
//重置 设置时间范围为初始化时间段
|
//重置 设置时间范围为初始化时间段
|
||||||
reset(){
|
reset(){
|
||||||
this.resetDate()
|
this.resetDate()
|
||||||
|
this.$emit('reset')
|
||||||
this.$emit('updateDate',this.dateRange)
|
this.$emit('updateDate',this.dateRange)
|
||||||
},
|
},
|
||||||
// 搜索
|
// 搜索
|
||||||
@ -61,15 +62,17 @@ export default {
|
|||||||
this.$emit('updateDate',this.dateRange)
|
this.$emit('updateDate',this.dateRange)
|
||||||
},
|
},
|
||||||
timeLine(type){
|
timeLine(type){
|
||||||
|
if(!this.dateRange || !this.dateRange[0] || !this.dateRange[1]) return
|
||||||
|
const nowStartTimes = new Date(this.dateRange[0]).getTime(),nowEndTimes = new Date(this.dateRange[1]).getTime(),maxTime = new Date(this.defaultDateRange[1]).getTime()
|
||||||
|
const nowDis = nowEndTimes - nowStartTimes//用户当前选择时间差 可能=0
|
||||||
//baseTime,maxTime 毫秒数
|
//baseTime,maxTime 毫秒数
|
||||||
let baseTime = type === 'before' ? new Date(this.dateRange[0]).getTime() - ( 24 * 60 * 60 * 1000) :new Date(this.dateRange[1]).getTime() + ( 24 * 60 * 60 * 1000) ,
|
const baseDis = 24 * 60 * 60 * 1000
|
||||||
maxTime = new Date(this.defaultDateRange[1]).getTime()
|
const calcDis = nowDis === 0 ? baseDis : nowDis
|
||||||
//updateTime 毫秒数
|
let start = type === 'before' ? nowStartTimes - calcDis : nowStartTimes + calcDis
|
||||||
let updateTime = type === 'before' ? baseTime - 7 * 24 * 60 * 60 * 1000 : baseTime + 7 * 24 * 60 * 60 * 1000
|
if(start>maxTime) start=maxTime
|
||||||
if(type === 'next' && updateTime >= maxTime) updateTime = maxTime
|
let end = type === 'before' ? nowEndTimes - calcDis : nowEndTimes + calcDis
|
||||||
const start = formatDate(type === 'before' ? updateTime : baseTime)
|
if(end>maxTime) end=maxTime
|
||||||
const end = formatDate(type === 'before' ? baseTime : updateTime)
|
this.dateRange = [formatDate(start),formatDate(end)]
|
||||||
this.dateRange = [start,end]
|
|
||||||
this.$emit('updateDate',this.dateRange)
|
this.$emit('updateDate',this.dateRange)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -168,6 +168,7 @@ export default {
|
|||||||
.avatar-wrapper {
|
.avatar-wrapper {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
padding-right: 10px;
|
||||||
|
|
||||||
.user-avatar {
|
.user-avatar {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|||||||
@ -1,48 +1,60 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sidebar-logo-container" :class="{'collapse':collapse}" :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }">
|
<div
|
||||||
|
class="sidebar-logo-container"
|
||||||
|
:class="{ collapse: collapse }"
|
||||||
|
:style="{
|
||||||
|
backgroundColor:
|
||||||
|
sideTheme === 'theme-dark'
|
||||||
|
? variables.menuBackground
|
||||||
|
: variables.menuLightBackground,
|
||||||
|
}"
|
||||||
|
>
|
||||||
<transition name="sidebarLogoFade">
|
<transition name="sidebarLogoFade">
|
||||||
<router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
|
<router-link
|
||||||
<img :src="logo" class="sidebar-logo" />
|
v-if="collapse"
|
||||||
<!-- <h1 v-else class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </h1>-->
|
key="collapse"
|
||||||
|
class="sidebar-logo-link"
|
||||||
|
to="/"
|
||||||
|
>
|
||||||
|
<img :src="logoSmall" class="sidebar-logo" />
|
||||||
|
<!-- <h1 v-else class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </h1>-->
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link v-else key="expand" class="sidebar-logo-link" to="/">
|
<router-link v-else key="expand" class="sidebar-logo-link" to="/">
|
||||||
<img :src="logo" class="sidebar-logo" />
|
<img :src="logo" class="sidebar-logo" />
|
||||||
<!-- <h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </h1>-->
|
<!-- <h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </h1>-->
|
||||||
</router-link>
|
</router-link>
|
||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import logoImg from '@/assets/logo/logo.png'
|
import variables from "@/assets/styles/variables.scss";
|
||||||
import variables from '@/assets/styles/variables.scss'
|
import logo from "@/assets/images/ems/logo.png";
|
||||||
import logo from '@/assets/images/ems/logo.png'
|
import logoSmall from "@/assets/images/ems/logo-small.png";
|
||||||
import logoLarge from '@/assets/images/ems/logo-large.png'
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SidebarLogo',
|
name: "SidebarLogo",
|
||||||
props: {
|
props: {
|
||||||
collapse: {
|
collapse: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true
|
required: true,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
variables() {
|
variables() {
|
||||||
return variables
|
return variables;
|
||||||
},
|
},
|
||||||
sideTheme() {
|
sideTheme() {
|
||||||
return this.$store.state.settings.sideTheme
|
return this.$store.state.settings.sideTheme;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
title: process.env.VUE_APP_TITLE,
|
title: process.env.VUE_APP_TITLE,
|
||||||
// logo: logoImg
|
logo: logo,
|
||||||
logo:logo,
|
logoSmall: logoSmall,
|
||||||
logoLarge:logoLarge
|
};
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -55,3 +55,12 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
::v-deep{
|
||||||
|
//,.el-submenu.is-active>.el-submenu__title 选中了二级菜单的以及菜单
|
||||||
|
.el-menu-item.is-active{
|
||||||
|
background-color: rgba(0,0,0,0.1) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -37,49 +37,49 @@ export const dzjk=[
|
|||||||
component: () => import('@/views/ems/dzjk/sbjk/ssyx/index.vue'),
|
component: () => import('@/views/ems/dzjk/sbjk/ssyx/index.vue'),
|
||||||
name: 'DzjkSbjkSsyx',
|
name: 'DzjkSbjkSsyx',
|
||||||
hidden: true,
|
hidden: true,
|
||||||
meta: { title: '实时运行',breadcrumb: false,activeMenu: '/dzjk/sbjk',activeSecondMenuName:'DzjkSbjk'},
|
meta: { title: '实时运行',breadcrumb: false,activeMenu: '/dzjk/sbjk',activeSecondMenuName:'DzjkSbjk',deviceCategory:'SSYX'},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'pcs',
|
path: 'pcs',
|
||||||
component: () => import('@/views/ems/dzjk/sbjk/pcs/index.vue'),
|
component: () => import('@/views/ems/dzjk/sbjk/pcs/index.vue'),
|
||||||
name: 'DzjkSbjkPcs',
|
name: 'DzjkSbjkPcs',
|
||||||
hidden: true,
|
hidden: true,
|
||||||
meta: { title: 'PCS',breadcrumb: false,activeMenu: '/dzjk/sbjk',activeSecondMenuName:'DzjkSbjk'},
|
meta: { title: 'PCS',breadcrumb: false,activeMenu: '/dzjk/sbjk',activeSecondMenuName:'DzjkSbjk',deviceCategory:'PCS'},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'bmszl',
|
path: 'bmszl',
|
||||||
component: () => import('@/views/ems/dzjk/sbjk/bmszl/index.vue'),
|
component: () => import('@/views/ems/dzjk/sbjk/bmszl/index.vue'),
|
||||||
name: 'DzjkSbjkBmszl',
|
name: 'DzjkSbjkBmszl',
|
||||||
hidden: true,
|
hidden: true,
|
||||||
meta: { title: 'BMS总览',breadcrumb: false,activeMenu: '/dzjk/sbjk',activeSecondMenuName:'DzjkSbjk'},
|
meta: { title: 'BMS总览',breadcrumb: false,activeMenu: '/dzjk/sbjk',activeSecondMenuName:'DzjkSbjk', deviceCategory:'STACK'},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'bmsdcc',
|
path: 'bmsdcc',
|
||||||
component: () => import('@/views/ems/dzjk/sbjk/bmsdcc/index.vue'),
|
component: () => import('@/views/ems/dzjk/sbjk/bmsdcc/index.vue'),
|
||||||
name: 'DzjkSbjkBmsdcc',
|
name: 'DzjkSbjkBmsdcc',
|
||||||
hidden: true,
|
hidden: true,
|
||||||
meta: { title: 'BMS电池簇',breadcrumb: false,activeMenu: '/dzjk/sbjk',activeSecondMenuName:'DzjkSbjk'},
|
meta: { title: 'BMS电池簇',breadcrumb: false,activeMenu: '/dzjk/sbjk',activeSecondMenuName:'DzjkSbjk',deviceCategory:'CLUSTER'},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'dtdc',
|
path: 'dtdc',
|
||||||
component: () => import('@/views/ems/dzjk/sbjk/dtdc/index.vue'),
|
component: () => import('@/views/ems/dzjk/sbjk/dtdc/index.vue'),
|
||||||
name: 'DzjkSbjkDtdc',
|
name: 'DzjkSbjkDtdc',
|
||||||
hidden: true,
|
hidden: true,
|
||||||
meta: { title: '单体电池',breadcrumb: false,activeMenu: '/dzjk/sbjk',activeSecondMenuName:'DzjkSbjk'},
|
meta: { title: '单体电池',breadcrumb: false,activeMenu: '/dzjk/sbjk',activeSecondMenuName:'DzjkSbjk',deviceCategory:'BATTERY'},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'db',
|
path: 'db',
|
||||||
component: () => import('@/views/ems/dzjk/sbjk/db/index.vue'),
|
component: () => import('@/views/ems/dzjk/sbjk/db/index.vue'),
|
||||||
name: 'DzjkSbjkDb',
|
name: 'DzjkSbjkDb',
|
||||||
hidden: true,
|
hidden: true,
|
||||||
meta: { title: '电表',breadcrumb: false,activeMenu: '/dzjk/sbjk',activeSecondMenuName:'DzjkSbjk'},
|
meta: { title: '电表',breadcrumb: false,activeMenu: '/dzjk/sbjk',activeSecondMenuName:'DzjkSbjk',deviceCategory:'AMMETER'},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'yl',
|
path: 'yl',
|
||||||
component: () => import('@/views/ems/dzjk/sbjk/yl/index.vue'),
|
component: () => import('@/views/ems/dzjk/sbjk/yl/index.vue'),
|
||||||
name: 'DzjkSbjkYl',
|
name: 'DzjkSbjkYl',
|
||||||
hidden: true,
|
hidden: true,
|
||||||
meta: { title: '液冷',breadcrumb: false,activeMenu: '/dzjk/sbjk',activeSecondMenuName:'DzjkSbjk'},
|
meta: { title: '液冷',breadcrumb: false,activeMenu: '/dzjk/sbjk',activeSecondMenuName:'DzjkSbjk',deviceCategory:'COOLING'},
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@ -7,12 +7,12 @@ module.exports = {
|
|||||||
/**
|
/**
|
||||||
* 侧边栏主题 深色主题theme-dark,浅色主题theme-light
|
* 侧边栏主题 深色主题theme-dark,浅色主题theme-light
|
||||||
*/
|
*/
|
||||||
sideTheme: 'theme-dark',
|
sideTheme: 'theme-light',
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统布局配置
|
* 系统布局配置
|
||||||
*/
|
*/
|
||||||
showSettings: true,
|
showSettings: false,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否显示顶部导航
|
* 是否显示顶部导航
|
||||||
|
|||||||
@ -1,9 +1,12 @@
|
|||||||
import {getAllSites} from '@/api/ems/zddt'
|
import {getAllSites} from '@/api/ems/zddt'
|
||||||
|
import {getAlarmDetailList,getSiteAllDeviceCategory} from'@/api/ems/dzjk'
|
||||||
const ems = {
|
const ems = {
|
||||||
state: {
|
state: {
|
||||||
|
dzjkAlarmLighting:false,//单站监控 告警统计红点标志
|
||||||
zdList:[],
|
zdList:[],
|
||||||
|
zdDeviceCategoryOptions:{},//站点各个站点包含的设备种类 {021_DDS_01:["BATTERY","CLUSTER","STACK", "DH", "AMMETER", "PCS", "XF"],021_DDS_02:[]...}
|
||||||
workStatusOptions:{'0':'正常','1':'异常','2':'停止'},//工作状态
|
workStatusOptions:{'0':'正常','1':'异常','2':'停止'},//工作状态
|
||||||
deviceStatusOptions:{'0':'在线','1':'离线','2':'维修中'},//设备状态
|
deviceStatusOptions:{'0':'离线','1':'待机','2':'运行','3':'故障','4':'停机'},//设备状态
|
||||||
gridStatusOptions:{'0':'并网','1':'未并网'},//并网状态
|
gridStatusOptions:{'0':'并网','1':'未并网'},//并网状态
|
||||||
controlModeOptions:{'0':'远程','1':'本地'},//控制模式
|
controlModeOptions:{'0':'远程','1':'本地'},//控制模式
|
||||||
warnOptions:{0:'正常', 1:'中断', 2:'不在线',3:'异常'},//告警状态
|
warnOptions:{0:'正常', 1:'中断', 2:'不在线',3:'异常'},//告警状态
|
||||||
@ -12,14 +15,22 @@ const ems = {
|
|||||||
alarmLevelOptions:{'A':'提示','B':'一般','C':'严重','D':'紧急'},//告警等级
|
alarmLevelOptions:{'A':'提示','B':'一般','C':'严重','D':'紧急'},//告警等级
|
||||||
alarmStatusOptions:{'0':'待处理','1':'已处理','2':'处理中'},//告警状态
|
alarmStatusOptions:{'0':'待处理','1':'已处理','2':'处理中'},//告警状态
|
||||||
deviceTypeOptions:{'TCP':'TCP','RTU':'RTU'},//设备类型
|
deviceTypeOptions:{'TCP':'TCP','RTU':'RTU'},//设备类型
|
||||||
ticketStatusOptions:{0:'待处理', 1:'已处理', 2:'处理中'},//工单处理状态
|
ticketStatusOptions:{1:'待处理', 2:'处理中', 3:'已处理'},//工单处理状态
|
||||||
strategyStatusOptions:{'0':'未启用', '1':'已运行', '2':'已暂停', '3':'禁用', '4':'删除'},//策略状态
|
strategyStatusOptions:{'0':'未启用', '1':'已运行', '2':'已暂停', '3':'禁用', '4':'删除'},//策略状态
|
||||||
chargeStatusOptions:{'1':'充电','2':'待机'},//冲放状态
|
chargeStatusOptions:{'1':'充电','2':'待机'},//冲放状态
|
||||||
deviceCategoryOptions:{'PCS':'PCS','STACK':'电池堆','CLUSTER':'电池簇','COOLING':'液冷','BATTERY':'单体电池','AMMETER':'电表'},//设备类别
|
deviceCategoryOptions:{'PCS':'PCS','STACK':'电池堆','CLUSTER':'电池簇','COOLING':'液冷','BATTERY':'单体电池','AMMETER':'电表'},//设备类别
|
||||||
|
comparisonOperatorOptions:{'>':'>','<':'<','=':'=','>=':'>=','<=':'<='},
|
||||||
|
relationWithPoint:{'||':'||','&&':'&&'}
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
SET_ZD_LIST(state, list) {
|
SET_ZD_LIST(state, list) {
|
||||||
state.zdList = list || []
|
state.zdList = list || []
|
||||||
|
},
|
||||||
|
SET_DZJK_ALARM_LIGHTING(state, status) {
|
||||||
|
state.dzjkAlarmLighting = status
|
||||||
|
},
|
||||||
|
SET_ZD_DEVICE_CATEGORY_OPTIONS(state,{siteId,data}){
|
||||||
|
state.zdDeviceCategoryOptions = Object.assign({}, state.zdDeviceCategoryOptions, {[siteId]:data})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
@ -31,7 +42,21 @@ const ems = {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
//查询站点的所有待处理0的告警 存在展示红点标志
|
||||||
|
getSiteAlarmNum({state,commit},siteId){
|
||||||
|
getAlarmDetailList({status:0,siteId,pageSize:10,pageNum:1,deviceId:'',alarmLevel:'',alarmStartTime:'',alarmEndTime:''}).then(response=>{
|
||||||
|
commit('SET_DZJK_ALARM_LIGHTING',!!response?.total || false)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getSiteDeviceCategory({state,commit},siteId){
|
||||||
|
getSiteAllDeviceCategory(siteId).then(response=>{
|
||||||
|
let data = response?.data || [];
|
||||||
|
data.unshift('SSYX');
|
||||||
|
commit('SET_ZD_DEVICE_CATEGORY_OPTIONS',{siteId,data})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -33,7 +33,13 @@ const permission = {
|
|||||||
GenerateRoutes({ commit }) {
|
GenerateRoutes({ commit }) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
// 向后端请求路由数据
|
// 向后端请求路由数据
|
||||||
getRouters().then(res => {
|
getRouters().then(res => {
|
||||||
|
let hasDzjk = false
|
||||||
|
if(res?.data){
|
||||||
|
res.data.forEach(i=>{
|
||||||
|
i.children && i.children.find(j=>j.path.indexOf('dzjk')>-1) && (hasDzjk=true)
|
||||||
|
})
|
||||||
|
}
|
||||||
const sdata = JSON.parse(JSON.stringify(res.data))
|
const sdata = JSON.parse(JSON.stringify(res.data))
|
||||||
const rdata = JSON.parse(JSON.stringify(res.data))
|
const rdata = JSON.parse(JSON.stringify(res.data))
|
||||||
const sidebarRoutes = filterAsyncRouter(sdata)
|
const sidebarRoutes = filterAsyncRouter(sdata)
|
||||||
@ -41,6 +47,10 @@ const permission = {
|
|||||||
const asyncRoutes = filterDynamicRoutes(dynamicRoutes)
|
const asyncRoutes = filterDynamicRoutes(dynamicRoutes)
|
||||||
rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
|
rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
|
||||||
router.addRoutes(asyncRoutes)
|
router.addRoutes(asyncRoutes)
|
||||||
|
if(!hasDzjk){
|
||||||
|
const index = constantRoutes.findIndex(i=>i.path.indexOf('dzjk')>-1)
|
||||||
|
constantRoutes.splice(index,1)
|
||||||
|
}
|
||||||
commit('SET_ROUTES', rewriteRoutes)
|
commit('SET_ROUTES', rewriteRoutes)
|
||||||
commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))
|
commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))
|
||||||
commit('SET_DEFAULT_ROUTES', sidebarRoutes)
|
commit('SET_DEFAULT_ROUTES', sidebarRoutes)
|
||||||
|
|||||||
@ -90,7 +90,7 @@
|
|||||||
>
|
>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button type="text" size="mini" v-if="scope.row.ticketNo" @click="toTicket">已生成工单(工单号:{{scope.row.ticketNo}})</el-button>
|
<el-button type="text" size="mini" v-if="scope.row.ticketNo" @click="toTicket">已生成工单(工单号:{{scope.row.ticketNo}})</el-button>
|
||||||
<el-button type="primary" size="mini" v-else @click="toTicket">生成工单</el-button>
|
<el-button type="primary" size="mini" v-else @click="createTicket(scope.row.id)">生成工单</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@ -113,7 +113,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {getAlarmDetailList} from'@/api/ems/dzjk'
|
import {getAlarmDetailList,createTicketNo} from'@/api/ems/dzjk'
|
||||||
import {getDeviceList} from'@/api/ems/site'
|
import {getDeviceList} from'@/api/ems/site'
|
||||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||||
import { formatDate } from '@/filters/ems'
|
import { formatDate } from '@/filters/ems'
|
||||||
@ -149,6 +149,13 @@ export default {
|
|||||||
toTicket(){
|
toTicket(){
|
||||||
this.$router.push({path:'/ticket'})
|
this.$router.push({path:'/ticket'})
|
||||||
},
|
},
|
||||||
|
//生成工单
|
||||||
|
createTicket(id){
|
||||||
|
this.loading = true
|
||||||
|
createTicketNo({id}).then(response=>{
|
||||||
|
response?.data && this.toTicket()
|
||||||
|
}).finally(()=>{this.loading = false})
|
||||||
|
},
|
||||||
// 判断是否是同一天
|
// 判断是否是同一天
|
||||||
isSameDay(day1, day2) {
|
isSameDay(day1, day2) {
|
||||||
const date1 = new Date(day1),date2 = new Date(day2)
|
const date1 = new Date(day1),date2 = new Date(day2)
|
||||||
@ -172,7 +179,6 @@ export default {
|
|||||||
// 搜索
|
// 搜索
|
||||||
onSearch(){
|
onSearch(){
|
||||||
this.pageNum =1//每次搜索从1开始搜索
|
this.pageNum =1//每次搜索从1开始搜索
|
||||||
const [alarmStartTime='',alarmEndTime='']=(this.dateRange || [])
|
|
||||||
this.getData()
|
this.getData()
|
||||||
},
|
},
|
||||||
// 重置
|
// 重置
|
||||||
@ -192,6 +198,7 @@ export default {
|
|||||||
},
|
},
|
||||||
// 获取数据
|
// 获取数据
|
||||||
getData(){
|
getData(){
|
||||||
|
this.$store.dispatch('getSiteAlarmNum',this.siteId)
|
||||||
this.loading=true
|
this.loading=true
|
||||||
const {deviceId,alarmLevel} = this.search
|
const {deviceId,alarmLevel} = this.search
|
||||||
const {siteId,pageNum,pageSize,activeBtn} =this
|
const {siteId,pageNum,pageSize,activeBtn} =this
|
||||||
|
|||||||
@ -14,9 +14,10 @@ import * as echarts from 'echarts'
|
|||||||
import resize from '@/mixins/ems/resize'
|
import resize from '@/mixins/ems/resize'
|
||||||
import DateRangeSelect from '@/components/Ems/DateRangeSelect/index.vue'
|
import DateRangeSelect from '@/components/Ems/DateRangeSelect/index.vue'
|
||||||
import { getPointData } from '@/api/ems/dzjk'
|
import { getPointData } from '@/api/ems/dzjk'
|
||||||
|
import intervalUpdate from "@/mixins/ems/intervalUpdate";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [resize],
|
mixins: [resize,intervalUpdate],
|
||||||
components: {DateRangeSelect},
|
components: {DateRangeSelect},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -59,6 +60,7 @@ export default {
|
|||||||
this.timeRange=[]
|
this.timeRange=[]
|
||||||
this.$refs.dateRangeSelect.init(true)
|
this.$refs.dateRangeSelect.init(true)
|
||||||
this.getGVQXData()
|
this.getGVQXData()
|
||||||
|
this.updateInterval(this.getGVQXData)
|
||||||
},
|
},
|
||||||
initChart() {
|
initChart() {
|
||||||
this.chart = echarts.init(document.querySelector('#activeChart'))
|
this.chart = echarts.init(document.querySelector('#activeChart'))
|
||||||
|
|||||||
@ -78,10 +78,11 @@ import ActiveChart from "./ActiveChart.vue";
|
|||||||
import AlarmTable from "./AlarmTable.vue";
|
import AlarmTable from "./AlarmTable.vue";
|
||||||
import ClInfo from "./ClInfo.vue";
|
import ClInfo from "./ClInfo.vue";
|
||||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||||
|
import intervalUpdate from "@/mixins/ems/intervalUpdate";
|
||||||
export default {
|
export default {
|
||||||
name: "DzjkSbjkHome",
|
name: "DzjkSbjkHome",
|
||||||
components: { WeekChart, ActiveChart, AlarmTable, ClInfo },
|
components: { WeekChart, ActiveChart, AlarmTable, ClInfo },
|
||||||
mixins: [getQuerySiteId],
|
mixins: [getQuerySiteId, intervalUpdate],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
loading: false,
|
loading: false,
|
||||||
@ -113,13 +114,21 @@ export default {
|
|||||||
attr: "dayDisChargedCap",
|
attr: "dayDisChargedCap",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "总充电量(MWh)",
|
title: "总充电量(kWh)",
|
||||||
attr: "totalChargedCap",
|
attr: "totalChargedCap",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "总放电量(MWh)",
|
title: "总放电量(kWh)",
|
||||||
attr: "totalDischargedCap",
|
attr: "totalDischargedCap",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: "总收入(元)",
|
||||||
|
attr: "totalRevenue",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "当日实时收入(元)",
|
||||||
|
attr: "dayRevenue",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
info: {}, //基本信息
|
info: {}, //基本信息
|
||||||
runningInfo: {}, //总累计运行数据+报警表格
|
runningInfo: {}, //总累计运行数据+报警表格
|
||||||
@ -156,6 +165,8 @@ export default {
|
|||||||
Promise.all([this.getBaseInfo(), this.getRunningInfo()]).finally(() => {
|
Promise.all([this.getBaseInfo(), this.getRunningInfo()]).finally(() => {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
});
|
});
|
||||||
|
// 一分钟循环一次总累计运行数据
|
||||||
|
this.updateInterval(this.getRunningInfo);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -172,7 +183,9 @@ export default {
|
|||||||
.sjgl-data {
|
.sjgl-data {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
&:nth-child(1),
|
&:nth-child(1),
|
||||||
&:nth-child(2) {
|
&:nth-child(2),
|
||||||
|
&:nth-child(3),
|
||||||
|
&:nth-child(4) {
|
||||||
margin-bottom: 25px;
|
margin-bottom: 25px;
|
||||||
}
|
}
|
||||||
.sjgl-title {
|
.sjgl-title {
|
||||||
|
|||||||
@ -11,10 +11,10 @@
|
|||||||
active-text-color="#ffffff"
|
active-text-color="#ffffff"
|
||||||
mode="horizontal"
|
mode="horizontal"
|
||||||
>
|
>
|
||||||
<el-menu-item :index="item.name" v-for="(item,index) in childrenRoute" :key="index+'dzjkChildrenRoute'">
|
<el-menu-item :index="item.name" v-for="(item,index) in childrenRoute" :key="index+'dzjkChildrenRoute'" :class="{'lighting':item.path.indexOf('gzgj')>-1 && dzjkAlarmLighting}">
|
||||||
<router-link style="height: 100%;width: 100%;display: block;padding:0 20px;" :to="{path:item.path,query:$route.query}">
|
<router-link style="height: 100%;width: 100%;display: block;padding:0 20px;" :to="{path:item.path,query:$route.query}">
|
||||||
{{item.meta.title}}
|
{{item.meta.title}}
|
||||||
</router-link>
|
</router-link>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
</el-menu>
|
</el-menu>
|
||||||
<div class="ems-content-container ems-content-container-padding dzjk-ems-content-container">
|
<div class="ems-content-container ems-content-container-padding dzjk-ems-content-container">
|
||||||
@ -30,6 +30,7 @@ import { dzjk } from '@/router/ems'
|
|||||||
const childrenRoute = dzjk[0].children[0].children//获取到单站监控下面的字路由
|
const childrenRoute = dzjk[0].children[0].children//获取到单站监控下面的字路由
|
||||||
console.log('childrenRoute',childrenRoute)
|
console.log('childrenRoute',childrenRoute)
|
||||||
import ZdSelect from '@/components/Ems/ZdSelect/index.vue'
|
import ZdSelect from '@/components/Ems/ZdSelect/index.vue'
|
||||||
|
import {mapState} from "vuex";
|
||||||
export default {
|
export default {
|
||||||
components:{ZdSelect},
|
components:{ZdSelect},
|
||||||
data(){
|
data(){
|
||||||
@ -38,14 +39,21 @@ export default {
|
|||||||
activeMenu:''
|
activeMenu:''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed:{
|
||||||
|
...mapState({
|
||||||
|
dzjkAlarmLighting:state=>state.ems.dzjkAlarmLighting
|
||||||
|
})
|
||||||
|
},
|
||||||
methods:{
|
methods:{
|
||||||
submitSite(id){
|
submitSite(id){
|
||||||
if(id != this.$route.query.siteId){
|
if(id !== this.$route.query.siteId){
|
||||||
console.log('单站监控选择了其他的站点id=',id,'并更新页面地址参数')
|
// console.log('单站监控选择了其他的站点id=',id,'并更新页面地址参数')
|
||||||
this.$router.push({query:{...this.$route.query,siteId:id}})
|
this.$router.push({query:{...this.$route.query,siteId:id}})
|
||||||
}else{
|
}else{
|
||||||
console.log('单站监控选择了相同的其他的站点id=',id,'页面地址不发生改变')
|
// console.log('单站监控选择了相同的其他的站点id=',id,'页面地址不发生改变')
|
||||||
}
|
}
|
||||||
|
//获取告警列表数据
|
||||||
|
this.$store.dispatch('getSiteAlarmNum',id)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeRouteLeave(to,from, next){
|
beforeRouteLeave(to,from, next){
|
||||||
@ -54,10 +62,6 @@ export default {
|
|||||||
this.$store.commit('SET_ZD_LIST',[])
|
this.$store.commit('SET_ZD_LIST',[])
|
||||||
next()
|
next()
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
console.log('单站监控一级页面路由',this.$route)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -65,4 +69,19 @@ export default {
|
|||||||
.dzjk-ems-content-container{
|
.dzjk-ems-content-container{
|
||||||
margin-top:0;
|
margin-top:0;
|
||||||
}
|
}
|
||||||
|
.lighting{
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
&::after{
|
||||||
|
content:"";
|
||||||
|
display: block;
|
||||||
|
background-color: red;
|
||||||
|
height: 10px;
|
||||||
|
width: 10px;
|
||||||
|
border-radius: 100%;
|
||||||
|
position: absolute;
|
||||||
|
right: -2px;
|
||||||
|
top: -2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,25 +1,33 @@
|
|||||||
<!--电位展示图表-->
|
<!--电位展示图表-->
|
||||||
<template>
|
<template>
|
||||||
<el-dialog
|
<el-dialog
|
||||||
:visible.sync="show"
|
:visible.sync="show"
|
||||||
:title="pointName"
|
:title="pointName"
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
show-close
|
show-close
|
||||||
destroy-on-close
|
destroy-on-close
|
||||||
lock-scroll
|
lock-scroll
|
||||||
append-to-body
|
append-to-body
|
||||||
width="1000px"
|
width="1000px"
|
||||||
class="ems-dialog"
|
class="ems-dialog"
|
||||||
:before-close="handleColsed"
|
:before-close="handleClosed"
|
||||||
>
|
>
|
||||||
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding time-range-card">
|
<el-card
|
||||||
|
shadow="always"
|
||||||
|
class="common-card-container common-card-container-body-no-padding time-range-card"
|
||||||
|
>
|
||||||
<div slot="header" class="time-range-header">
|
<div slot="header" class="time-range-header">
|
||||||
<el-radio-group class="card-title" v-model="dataUnit">
|
<el-radio-group class="card-title" v-model="dataUnit">
|
||||||
<el-radio :label="1">分钟</el-radio>
|
<el-radio :label="1">分钟</el-radio>
|
||||||
<el-radio :label="2">小时</el-radio>
|
<el-radio :label="2">小时</el-radio>
|
||||||
<el-radio :label="3">天</el-radio>
|
<el-radio :label="3">天</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
<date-time-select ref="dateTimeSelect" :data-unit="dataUnit" @initDate="((e)=>dataRange=e||[])" @updateDate="updateDate"/>
|
<date-time-select
|
||||||
|
ref="dateTimeSelect"
|
||||||
|
:data-unit="dataUnit"
|
||||||
|
@initDate="(e) => (dataRange = e || [])"
|
||||||
|
@updateDate="updateDate"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div style="height: 350px" id="searchChart"></div>
|
<div style="height: 350px" id="searchChart"></div>
|
||||||
</el-card>
|
</el-card>
|
||||||
@ -29,178 +37,240 @@
|
|||||||
import * as echarts from "echarts";
|
import * as echarts from "echarts";
|
||||||
import resize from "@/mixins/ems/resize";
|
import resize from "@/mixins/ems/resize";
|
||||||
import DateTimeSelect from "@/views/ems/search/DateTimeSelect.vue";
|
import DateTimeSelect from "@/views/ems/search/DateTimeSelect.vue";
|
||||||
import {getPointValueList} from "@/api/ems/search";
|
import { getPointValueList } from "@/api/ems/search";
|
||||||
import DateRangeSelect from "@/components/Ems/DateRangeSelect/index.vue";
|
import DateRangeSelect from "@/components/Ems/DateRangeSelect/index.vue";
|
||||||
export default {
|
export default {
|
||||||
components: {DateRangeSelect, DateTimeSelect},
|
components: { DateRangeSelect, DateTimeSelect },
|
||||||
mixins: [resize],
|
mixins: [resize],
|
||||||
props: {
|
props: {
|
||||||
siteId:{
|
siteId: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
isDtdc(){
|
isDtdc() {
|
||||||
return this.categoryName === '单体电池'
|
return this.deviceCategory === "BATTERY";
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
watch:{
|
watch: {
|
||||||
show(val) {
|
show(val) {
|
||||||
if(!val){
|
if (!val) {
|
||||||
this.pointName=''
|
this.pointName = "";
|
||||||
this.categoryName=''
|
this.deviceCategory = "";
|
||||||
this.deviceId=''
|
this.deviceId = "";
|
||||||
this.dataUnit=1
|
this.dataUnit = 1;
|
||||||
|
this.child = "";
|
||||||
if (!this.chart) {
|
if (!this.chart) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
this.hideLoading()
|
this.hideLoading();
|
||||||
this.chart.dispose()
|
this.chart.dispose();
|
||||||
this.chart = null
|
this.chart = null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
dataUnit:{
|
dataUnit: {
|
||||||
handler(newVal,oldVal){
|
handler(newVal, oldVal) {
|
||||||
console.log('wacth到了dataUnit的变化',newVal,oldVal)
|
if (!this.show) return;
|
||||||
this.$nextTick(()=>{
|
console.log("wacth到了dataUnit的变化", newVal, oldVal);
|
||||||
this.$refs.dateTimeSelect.init()
|
this.$nextTick(() => {
|
||||||
this.getDate()
|
this.$refs.dateTimeSelect.init();
|
||||||
})
|
this.getDate();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
data(){
|
data() {
|
||||||
return{
|
return {
|
||||||
show:false,
|
show: false,
|
||||||
chart:null,
|
chart: null,
|
||||||
dataUnit:1,
|
dataUnit: 1,
|
||||||
dataRange:[],
|
dataRange: [],
|
||||||
child:[],//单体电池需要数据 暂不删除
|
child: "", //单体电池需要数据
|
||||||
pointName:'',
|
pointName: "",
|
||||||
categoryName:'',
|
deviceCategory: "",
|
||||||
deviceId:''
|
deviceId: "",
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
methods:{
|
methods: {
|
||||||
showChart({pointName,categoryName,deviceId}){
|
showChart({ pointName, deviceCategory, deviceId, child = "" }) {
|
||||||
//初始化数据
|
//初始化数据
|
||||||
this.pointName=pointName
|
this.pointName = pointName;
|
||||||
this.categoryName=categoryName
|
this.deviceCategory = deviceCategory;
|
||||||
this.deviceId=deviceId
|
this.deviceId = deviceId;
|
||||||
this.show = true
|
child && (this.child = child);
|
||||||
this.$nextTick(()=>{
|
this.show = true;
|
||||||
this.$refs.dateTimeSelect.init()
|
this.$nextTick(() => {
|
||||||
this.initChart()
|
this.$refs.dateTimeSelect.init();
|
||||||
this.getDate()
|
this.initChart();
|
||||||
})
|
this.getDate();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
initChart() {
|
initChart() {
|
||||||
this.chart = echarts.init(document.querySelector('#searchChart'))
|
this.chart = echarts.init(document.querySelector("#searchChart"));
|
||||||
},
|
},
|
||||||
showLoading(){
|
showLoading() {
|
||||||
this.chart && this.chart.showLoading()
|
this.chart && this.chart.showLoading();
|
||||||
},
|
},
|
||||||
hideLoading(){
|
hideLoading() {
|
||||||
this.chart && this.chart.hideLoading()
|
this.chart && this.chart.hideLoading();
|
||||||
},
|
},
|
||||||
getDate(){
|
getDate() {
|
||||||
this.showLoading()
|
this.showLoading();
|
||||||
const{dataUnit,dataRange:[start='',end=''],child}=this
|
const {
|
||||||
let siteDeviceMap={}
|
siteId,
|
||||||
child.forEach(([first,second,third])=>{
|
dataUnit,
|
||||||
if(siteDeviceMap[first]){
|
dataRange: [start = "", end = ""],
|
||||||
siteDeviceMap[first].push(third)
|
child,
|
||||||
}else{
|
deviceId,
|
||||||
siteDeviceMap[first]=[]
|
deviceCategory,
|
||||||
siteDeviceMap[first].push(third)
|
pointName,
|
||||||
}
|
} = this;
|
||||||
})
|
let siteDeviceMap = {};
|
||||||
let startDate,endDate
|
child && (siteDeviceMap[siteId] = child);
|
||||||
if(start && dataUnit===3){
|
let startDate, endDate;
|
||||||
// startDate= start + `${dataUnit === 2 ? ':00' : ' 00:00:00'}`
|
if (start && dataUnit === 3) {
|
||||||
startDate = start + ' 00:00:00'
|
// startDate= start + `${dataUnit === 2 ? ':00' : ' 00:00:00'}`
|
||||||
}else{
|
startDate = start + " 00:00:00";
|
||||||
startDate=start
|
} else {
|
||||||
}
|
startDate = start;
|
||||||
if(end && dataUnit===3){
|
}
|
||||||
// endDate= end + `${dataUnit === 2 ? ':00' : ' 00:00:00'}`
|
if (end && dataUnit === 3) {
|
||||||
endDate = end + ' 00:00:00'
|
// endDate= end + `${dataUnit === 2 ? ':00' : ' 00:00:00'}`
|
||||||
}else{
|
endDate = end + " 00:00:00";
|
||||||
endDate=end
|
} else {
|
||||||
}
|
endDate = end;
|
||||||
|
}
|
||||||
|
|
||||||
getPointValueList({siteIds:[this.siteId],deviceId:this.deviceId,dataUnit,categoryName:this.categoryName,pointName:this.pointName,startDate,endDate,siteDeviceMap:{}}).then(response => {
|
getPointValueList({
|
||||||
this.setOption(response?.data || [])
|
siteIds: [siteId],
|
||||||
}).finally(()=>{
|
deviceId,
|
||||||
this.hideLoading()
|
dataUnit,
|
||||||
|
deviceCategory,
|
||||||
|
pointName,
|
||||||
|
startDate,
|
||||||
|
endDate,
|
||||||
|
siteDeviceMap,
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
this.setOption(response?.data || []);
|
||||||
})
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.hideLoading();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
setOption(data) {
|
setOption(data) {
|
||||||
if(!this.chart) return
|
if (!this.chart) return;
|
||||||
this.chart.clear()
|
this.chart.clear();
|
||||||
console.log('返回的数据',data)
|
console.log("返回的数据", data);
|
||||||
let dataset=[]
|
let dataset = [];
|
||||||
if(data.length>0){
|
if (data.length > 0) {
|
||||||
data.forEach((item,index)=>{
|
data.forEach((item, index) => {
|
||||||
item.deviceList.forEach(inner=>{
|
item.deviceList.forEach((inner) => {
|
||||||
dataset.push({
|
dataset.push({
|
||||||
name:`${this.isDtdc ? `${inner.parentDeviceId ? inner.parentDeviceId+'-' : ''}` : ''}${inner.deviceId}`,
|
name: `${
|
||||||
type:'line',
|
this.isDtdc
|
||||||
xdata:[],
|
? `${inner.parentDeviceId ? inner.parentDeviceId + "-" : ""}${inner.deviceId}`
|
||||||
data:[]
|
: `${inner.deviceId}`
|
||||||
})
|
}`,
|
||||||
const length = dataset.length
|
type: "line",
|
||||||
inner.pointValueList.forEach(value=>{
|
markPoint: {
|
||||||
dataset[length-1].xdata.push(value.valueDate)
|
symbolSize: 30,
|
||||||
dataset[length-1].data.push(value.pointValue)
|
emphasis: {
|
||||||
})
|
disabled:false//打开 鼠标高亮
|
||||||
})
|
},
|
||||||
})
|
data: [//最大值、最小值
|
||||||
}else{
|
{
|
||||||
this.$message.warning('暂无数据')
|
// type: 'max',
|
||||||
|
name: `最大值`,
|
||||||
|
coord:[inner.maxDate,inner.maxValue],
|
||||||
|
relativeTo:'coordinate',
|
||||||
|
label: {
|
||||||
|
position: "top",
|
||||||
|
formatter: item.dataType === 2 ? ([
|
||||||
|
`最大值:${inner.maxValue}`,
|
||||||
|
// `平均值:${inner.avgValue}`,
|
||||||
|
`差值:${inner.diffValue}`,
|
||||||
|
]).join('\n') : ([
|
||||||
|
`最大值:${inner.maxValue}`,
|
||||||
|
// `平均值:${inner.avgValue}`,
|
||||||
|
]).join('\n'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// type: 'min',
|
||||||
|
name: `最小值`,
|
||||||
|
coord:[inner.minDate,inner.minValue],
|
||||||
|
relativeTo:'coordinate',
|
||||||
|
label: {
|
||||||
|
position: "top",
|
||||||
|
formatter: item.dataType === 2 ? ([
|
||||||
|
`最小值:${inner.minValue}`,
|
||||||
|
// `平均值:${inner.avgValue}`,
|
||||||
|
`差值:${inner.diffValue}`,
|
||||||
|
]).join('\n') : ([
|
||||||
|
`最小值:${inner.minValue}`,
|
||||||
|
// `平均值:${inner.avgValue}`,
|
||||||
|
]).join('\n'),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
xdata: [],
|
||||||
|
data: [],
|
||||||
|
});
|
||||||
|
const length = dataset.length;
|
||||||
|
inner.pointValueList.forEach((value) => {
|
||||||
|
dataset[length - 1].xdata.push(value.valueDate);
|
||||||
|
dataset[length - 1].data.push(value.pointValue);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.$message.warning("暂无数据");
|
||||||
}
|
}
|
||||||
console.log('图表数据',dataset)
|
console.log("图表数据", dataset);
|
||||||
this.chart.setOption({
|
this.chart.setOption({
|
||||||
legend: {
|
legend: {
|
||||||
// left: 'center',
|
// left: 'center',
|
||||||
// top: '10',
|
// top: '10',
|
||||||
},
|
},
|
||||||
grid: {
|
grid: {
|
||||||
containLabel: true
|
containLabel: true,
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
trigger: 'axis',
|
trigger: "axis",
|
||||||
axisPointer: { // 坐标轴指示器,坐标轴触发有效
|
axisPointer: {
|
||||||
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
|
// 坐标轴指示器,坐标轴触发有效
|
||||||
}
|
type: "cross", // 默认为直线,可选为:'line' | 'shadow'
|
||||||
|
},
|
||||||
},
|
},
|
||||||
textStyle:{
|
textStyle: {
|
||||||
color:"#333333",
|
color: "#333333",
|
||||||
},
|
},
|
||||||
xAxis: {type:'category',data:dataset?.[0]?.xdata || []},
|
xAxis: { type: "category", data: dataset?.[0]?.xdata || [] },
|
||||||
yAxis: {
|
yAxis: {
|
||||||
type: 'value',
|
type: "value",
|
||||||
},
|
},
|
||||||
dataZoom: [
|
dataZoom: [
|
||||||
{
|
{
|
||||||
type: 'inside',
|
type: "inside",
|
||||||
start: 0,
|
start: 0,
|
||||||
end: 100
|
end: 100,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
start: 0,
|
start: 0,
|
||||||
end: 100
|
end: 100,
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
series: dataset
|
series: dataset,
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
updateDate(val){
|
updateDate(val) {
|
||||||
this.dataRange =val || []
|
this.dataRange = val || [];
|
||||||
this.getDate()
|
this.getDate();
|
||||||
},
|
},
|
||||||
handleColsed(done) {
|
handleClosed(done) {
|
||||||
if (!this.chart) {
|
if (!this.chart) {
|
||||||
return done();
|
return done();
|
||||||
}
|
}
|
||||||
@ -208,14 +278,13 @@ export default {
|
|||||||
this.chart = null;
|
this.chart = null;
|
||||||
done();
|
done();
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
::v-deep {
|
::v-deep {
|
||||||
.card-title .el-radio{
|
.card-title .el-radio {
|
||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
</style>
|
||||||
</style>
|
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
<div class="descriptions-main descriptions-main-bg-color">
|
<div class="descriptions-main descriptions-main-bg-color">
|
||||||
<el-descriptions direction="vertical" :column="3" :colon="false">
|
<el-descriptions direction="vertical" :column="3" :colon="false">
|
||||||
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" v-for="(item,index) in infoData" :key="index+'pcsInfoData'" :span="1" :label="item.label">
|
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" v-for="(item,index) in infoData" :key="index+'pcsInfoData'" :span="1" :label="item.label">
|
||||||
<span class="pointer" @click="showChart(item.pointName || '','电池簇',baseInfo.deviceId)">
|
<span class="pointer" @click="showChart(item.pointName || '',baseInfo.deviceId)">
|
||||||
{{baseInfo[item.attr] | formatNumber}} <span v-if="item.unit" v-html="item.unit"></span>
|
{{baseInfo[item.attr] | formatNumber}} <span v-if="item.unit" v-html="item.unit"></span>
|
||||||
</span>
|
</span>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
@ -30,7 +30,7 @@
|
|||||||
<div class="process-line-bg">
|
<div class="process-line-bg">
|
||||||
<div class="process-line" :style="{height:baseInfo.currentSoc+'%'}"></div>
|
<div class="process-line" :style="{height:baseInfo.currentSoc+'%'}"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="process pointer" @click="showChart( '当前SOC','电池簇',baseInfo.deviceId)">当前SOC : {{baseInfo.currentSoc}}%</div>
|
<div class="process pointer" @click="showChart( '当前SOC',baseInfo.deviceId)">当前SOC : {{baseInfo.currentSoc}}%</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-table
|
<el-table
|
||||||
@ -50,14 +50,14 @@
|
|||||||
label="单体平均值"
|
label="单体平均值"
|
||||||
>
|
>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span class="pointer" @click="showChart( tablePointNameMap[scope.row.dataName+scope.column.label],'电池簇',baseInfo.deviceId)">{{scope.row.avgData}}</span>
|
<span class="pointer" @click="showChart( tablePointNameMap[scope.row.dataName+scope.column.label],baseInfo.deviceId)">{{scope.row.avgData}}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="minData"
|
prop="minData"
|
||||||
label="单体最小值">
|
label="单体最小值">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span class="pointer" @click="showChart( tablePointNameMap[scope.row.dataName+scope.column.label],'电池簇',baseInfo.deviceId)">{{scope.row.minData}}</span>
|
<span class="pointer" @click="showChart( tablePointNameMap[scope.row.dataName+scope.column.label],baseInfo.deviceId)">{{scope.row.minData}}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
@ -68,7 +68,7 @@
|
|||||||
prop="maxData"
|
prop="maxData"
|
||||||
label="单体最大值">
|
label="单体最大值">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span class="pointe " @click="showChart( tablePointNameMap[scope.row.dataName+scope.column.label],'电池簇',baseInfo.deviceId)">{{scope.row.maxData}}</span>
|
<span class="pointer " @click="showChart( tablePointNameMap[scope.row.dataName+scope.column.label],baseInfo.deviceId)">{{scope.row.maxData}}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
@ -106,7 +106,7 @@ export default {
|
|||||||
'电压单体平均值':'电压平均值',
|
'电压单体平均值':'电压平均值',
|
||||||
'电压单体最大值':'最高单体电压',
|
'电压单体最大值':'最高单体电压',
|
||||||
'温度单体最小值':'最低单体温度',
|
'温度单体最小值':'最低单体温度',
|
||||||
'温度单体平均值':'温度平均值',
|
'温度单体平均值':'平均单体温度',
|
||||||
'温度单体最大值':'最高单体温度',
|
'温度单体最大值':'最高单体温度',
|
||||||
'SOC单体最小值':'最低单体SOC',
|
'SOC单体最小值':'最低单体SOC',
|
||||||
'SOC单体平均值':'当前SOC',
|
'SOC单体平均值':'当前SOC',
|
||||||
@ -127,9 +127,8 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods:{
|
methods:{
|
||||||
showChart(pointName,categoryName,deviceId){
|
showChart(pointName,deviceId){
|
||||||
console.log('点击查询图表',pointName,categoryName,deviceId)
|
pointName && this.$refs.pointChart.showChart({pointName,deviceCategory:'CLUSTER',deviceId})
|
||||||
pointName && this.$refs.pointChart.showChart({pointName,categoryName,deviceId})
|
|
||||||
},
|
},
|
||||||
updateData(){
|
updateData(){
|
||||||
this.loading = true
|
this.loading = true
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
<div class="descriptions-main descriptions-main-bg-color">
|
<div class="descriptions-main descriptions-main-bg-color">
|
||||||
<el-descriptions :colon="false" :column="3" direction="vertical">
|
<el-descriptions :colon="false" :column="3" direction="vertical">
|
||||||
<el-descriptions-item v-for="(item,index) in infoData" :key="index+'pcsInfoData'" :label="item.label" :span="1" contentClassName="descriptions-direction" labelClassName="descriptions-label">
|
<el-descriptions-item v-for="(item,index) in infoData" :key="index+'pcsInfoData'" :label="item.label" :span="1" contentClassName="descriptions-direction" labelClassName="descriptions-label">
|
||||||
<span class="pointer" @click="showChart(item.pointName || '','电池堆',baseInfo.deviceId)">
|
<span class="pointer" @click="showChart(item.pointName || '',baseInfo.deviceId)">
|
||||||
{{baseInfo[item.attr] | formatNumber}}<span v-if="item.unit" v-html="item.unit"></span>
|
{{baseInfo[item.attr] | formatNumber}}<span v-if="item.unit" v-html="item.unit"></span>
|
||||||
</span>
|
</span>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
@ -30,7 +30,7 @@
|
|||||||
<div class="process-line-bg">
|
<div class="process-line-bg">
|
||||||
<div :style="{height:baseInfo.stackSoc+'%'}" class="process-line"></div>
|
<div :style="{height:baseInfo.stackSoc+'%'}" class="process-line"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="process pointer" @click="showChart('当前SOC','电池堆',baseInfo.deviceId)">当前SOC : {{baseInfo.stackSoc}}%</div>
|
<div class="process pointer" @click="showChart('当前SOC',baseInfo.deviceId)">当前SOC : {{baseInfo.stackSoc}}%</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-table
|
<el-table
|
||||||
@ -47,26 +47,26 @@
|
|||||||
label="簇电压"
|
label="簇电压"
|
||||||
>
|
>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span class="pointer" @click="showChart('簇电压','电池簇',scope.row.clusterId)">{{scope.row.clusterVoltage}} V</span>
|
<span class="pointer" @click="showChart('簇电压',scope.row.clusterId,'CLUSTER')">{{scope.row.clusterVoltage}} V</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="簇电流">
|
label="簇电流">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span class="pointer" @click="showChart('簇电流','电池簇',scope.row.clusterId)">{{scope.row.clusterCurrent}} A</span>
|
<span class="pointer" @click="showChart('簇电流',scope.row.clusterId,'CLUSTER')">{{scope.row.clusterCurrent}} A</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="簇SOC">
|
label="簇SOC">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span class="pointer" @click="showChart('当前SOC','电池簇',scope.row.clusterId)">{{scope.row.currentSoc}} %</span>
|
<span class="pointer" @click="showChart('当前SOC',scope.row.clusterId,'CLUSTER')">{{scope.row.currentSoc}} %</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="单体最高电压"
|
label="单体最高电压"
|
||||||
prop="maxVoltage">
|
prop="maxVoltage">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span class="pointer" @click="showChart('最高单体电压','电池簇',scope.row.clusterId)">{{scope.row.maxCellVoltage}} V</span>
|
<span class="pointer" @click="showChart('最高单体电压',scope.row.clusterId,'CLUSTER')">{{scope.row.maxCellVoltage}} V</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
@ -77,7 +77,7 @@
|
|||||||
label="单体最低电压"
|
label="单体最低电压"
|
||||||
prop="minVoltage">
|
prop="minVoltage">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span class="pointer" @click="showChart('最低单体电压','电池簇',scope.row.clusterId)">{{scope.row.minCellVoltage}} V</span>
|
<span class="pointer" @click="showChart('最低单体电压',scope.row.clusterId,'CLUSTER')">{{scope.row.minCellVoltage}} V</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
@ -87,7 +87,7 @@
|
|||||||
<el-table-column
|
<el-table-column
|
||||||
label="单体最高温度">
|
label="单体最高温度">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span class="pointer" @click="showChart('最高单体温度','电池簇',scope.row.clusterId)">{{scope.row.maxCellTemp}} ℃</span>
|
<span class="pointer" @click="showChart('最高单体温度',scope.row.clusterId,'CLUSTER')">{{scope.row.maxCellTemp}} ℃</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
@ -98,7 +98,7 @@
|
|||||||
label="单体最低温度"
|
label="单体最低温度"
|
||||||
prop="minTemperature">
|
prop="minTemperature">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span class="pointer" @click="showChart('最低单体温度','电池簇',scope.row.clusterId)">{{scope.row.minCellTemp}} ℃</span>
|
<span class="pointer" @click="showChart('最低单体温度',scope.row.clusterId,'CLUSTER')">{{scope.row.minCellTemp}} ℃</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
@ -141,9 +141,8 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods:{
|
methods:{
|
||||||
showChart(pointName,categoryName,deviceId){
|
showChart(pointName,deviceId,deviceCategory = 'STACK'){
|
||||||
console.log('点击查询图表',pointName,categoryName,deviceId)
|
pointName && this.$refs.pointChart.showChart({pointName,deviceCategory,deviceId})
|
||||||
pointName && this.$refs.pointChart.showChart({pointName,categoryName,deviceId})
|
|
||||||
},
|
},
|
||||||
updateData(){
|
updateData(){
|
||||||
this.loading = true
|
this.loading = true
|
||||||
|
|||||||
@ -1,76 +1,37 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-loading="loading">
|
<div v-loading="loading">
|
||||||
<el-card
|
<el-card
|
||||||
shadow="always"
|
v-for="(item,index) in list"
|
||||||
class="sbjk-card-container"
|
:key="index+'dbList'"
|
||||||
:class="{
|
shadow="always"
|
||||||
'warning-card-container':zbInfo.emsCommunicationStatus && zbInfo.emsCommunicationStatus !== '0',
|
class="sbjk-card-container list"
|
||||||
'running-card-container':zbInfo.emsCommunicationStatus === '0'
|
:class="{
|
||||||
|
'warning-card-container':item.emsCommunicationStatus && item.emsCommunicationStatus !== '0',
|
||||||
|
'running-card-container':item.emsCommunicationStatus === '0'
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div slot="header">
|
<div slot="header">
|
||||||
<span class="large-title">1#{{ zbInfo.deviceName }}</span>
|
<span class="large-title">{{index+1}}#{{ item.deviceName }}</span>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<div>
|
<div>
|
||||||
{{
|
{{
|
||||||
$store.state.ems.communicationStatusOptions[
|
$store.state.ems.communicationStatusOptions[
|
||||||
zbInfo.emsCommunicationStatus
|
item.emsCommunicationStatus
|
||||||
]
|
]
|
||||||
}}
|
}}
|
||||||
</div>
|
</div>
|
||||||
<div>数据更新时间:{{ zbInfo.dataUpdateTime }}</div>
|
<div>数据更新时间:{{ item.dataUpdateTime }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-table
|
<el-row>
|
||||||
class="common-table"
|
<el-col v-for="(tempDataItem,tempDataIndex) in deviceIdTypeMsg[item.deviceId]" :key="tempDataIndex+'dbTempData'" :span="8">
|
||||||
:data="zbInfo.loadDataDetailInfo"
|
<span class="pointer" @click="showChart(tempDataItem.pointName,item.deviceId)">
|
||||||
@cell-click="(row,col)=>{handlerCell(zbInfo.deviceId,row,col)}"
|
{{tempDataItem.name}}:{{item[tempDataItem.attr]}}<span v-html="tempDataItem.unit"></span>
|
||||||
stripe
|
</span>
|
||||||
style="width: 100%"
|
</el-col>
|
||||||
>
|
</el-row>
|
||||||
<el-table-column prop="category" label="类别"> </el-table-column>
|
</el-card>
|
||||||
<el-table-column prop="totalKwh" label="总/kWh"> </el-table-column>
|
<el-empty v-show="list.length<=0" :image-size="200"></el-empty>
|
||||||
<el-table-column prop="peakKwh" label="尖/kWh"> </el-table-column>
|
|
||||||
<el-table-column prop="highKwh" label="峰/kWh"> </el-table-column>
|
|
||||||
<el-table-column prop="flatKwh" label="平/kWh"> </el-table-column>
|
|
||||||
<el-table-column prop="valleyKwh" label="谷/kWh"> </el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</el-card>
|
|
||||||
<el-card
|
|
||||||
shadow="always"
|
|
||||||
class="sbjk-card-container"
|
|
||||||
style="margin-top: 20px"
|
|
||||||
:class="{
|
|
||||||
'warning-card-container':zbInfo.emsCommunicationStatus && zbInfo.emsCommunicationStatus !== '0',
|
|
||||||
'running-card-container':zbInfo.emsCommunicationStatus === '0'
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<div slot="header">
|
|
||||||
<span class="large-title">2#{{ cnbInfo.deviceName }}</span>
|
|
||||||
<div class="info">
|
|
||||||
<div>
|
|
||||||
{{
|
|
||||||
$store.state.ems.communicationStatusOptions[
|
|
||||||
cnbInfo.emsCommunicationStatus
|
|
||||||
]
|
|
||||||
}}
|
|
||||||
</div>
|
|
||||||
<div>数据更新时间:{{ cnbInfo.dataUpdateTime }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<el-table
|
|
||||||
class="common-table"
|
|
||||||
:data="cnbInfo.meteDataDetailInfo"
|
|
||||||
@cell-click="(row,col)=>{handlerCellCN(cnbInfo.deviceId,row,col)}"
|
|
||||||
stripe
|
|
||||||
style="width: 100%"
|
|
||||||
>
|
|
||||||
<el-table-column prop="category" label="类别"> </el-table-column>
|
|
||||||
<el-table-column prop="activePower" label="有功功率"> </el-table-column>
|
|
||||||
<el-table-column prop="reactivePower" label="无功功率">
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</el-card>
|
|
||||||
<point-chart ref="pointChart" :site-id="siteId"/>
|
<point-chart ref="pointChart" :site-id="siteId"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -87,39 +48,106 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
loading: false,
|
loading: false,
|
||||||
zbInfo: {},
|
list:[],
|
||||||
cnbInfo: {},
|
deviceIdTypeMsg:{
|
||||||
|
'LOAD':[
|
||||||
|
{
|
||||||
|
name:'正向有功电能',
|
||||||
|
attr:'forwardActive',
|
||||||
|
pointName:'正向有功电能'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'反向有功电能',
|
||||||
|
attr:'reverseActive',
|
||||||
|
pointName:'反向有功电能'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'正向无功电能',
|
||||||
|
attr:'forwardReactive',
|
||||||
|
pointName:'正向无功电能'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'反向无功电能',
|
||||||
|
attr:'reverseReactive',
|
||||||
|
pointName:'反向无功电能'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'有功功率',
|
||||||
|
attr:'activePower',
|
||||||
|
pointName:'总有功功率'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'无功功率',
|
||||||
|
attr:'reactivePower',
|
||||||
|
pointName:'总无功功率'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'METE':[
|
||||||
|
{
|
||||||
|
name:'正向有功电能',
|
||||||
|
attr:'forwardActive',
|
||||||
|
pointName:'正向有功电能'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'反向有功电能',
|
||||||
|
attr:'reverseActive',
|
||||||
|
pointName:'反向有功电能'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'正向无功电能',
|
||||||
|
attr:'forwardReactive',
|
||||||
|
pointName:'正向无功电能'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'反向无功电能',
|
||||||
|
attr:'reverseReactive',
|
||||||
|
pointName:'反向无功电能'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'有功功率',
|
||||||
|
attr:'activePower',
|
||||||
|
pointName:'总有功功率'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'无功功率',
|
||||||
|
attr:'reactivePower',
|
||||||
|
pointName:'总无功功率'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'METEGF':[
|
||||||
|
{
|
||||||
|
name:'有功电能',
|
||||||
|
attr:'activeEnergy',
|
||||||
|
pointName:'有功电能'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'无功电能',
|
||||||
|
attr:'reactiveEnergy',
|
||||||
|
pointName:'无功电能'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'有功功率',
|
||||||
|
attr:'activePower',
|
||||||
|
pointName:'总有功功率'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'无功功率',
|
||||||
|
attr:'reactivePower',
|
||||||
|
pointName:'总无功功率'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handlerCell(id,row,column){
|
showChart(pointName,deviceId){
|
||||||
if(column.label !== '类别'){
|
pointName && this.$refs.pointChart.showChart({pointName,deviceCategory:'AMMETER',deviceId})
|
||||||
const arr = row.category.split('')
|
|
||||||
arr.splice(6,0,column.label[0])
|
|
||||||
this.showChart(arr.join(''),'电表',id)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
handlerCellCN(id,row,column){
|
|
||||||
if(column.label !== '类别'){
|
|
||||||
const arr = row.category.split('')
|
|
||||||
arr.splice(2,arr.length-2,column.label)
|
|
||||||
this.showChart(arr.join(''),'电表',id)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
showChart(pointName,categoryName,deviceId){
|
|
||||||
console.log('点击查询图表',pointName,categoryName,deviceId)
|
|
||||||
pointName && this.$refs.pointChart.showChart({pointName,categoryName,deviceId})
|
|
||||||
},
|
},
|
||||||
updateData(){
|
updateData(){
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
getAmmeterDataList(this.siteId)
|
getAmmeterDataList(this.siteId)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
this.zbInfo = JSON.parse(
|
this.list = response?.data || []
|
||||||
JSON.stringify(response?.data?.ammeterLoadData || {})
|
|
||||||
);
|
|
||||||
this.cnbInfo = JSON.parse(
|
|
||||||
JSON.stringify(response?.data?.ammeterMeteData || {})
|
|
||||||
);
|
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
@ -136,13 +164,25 @@ export default {
|
|||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.sbjk-card-container {
|
.sbjk-card-container {
|
||||||
::v-deep {
|
&.list:not(:last-child){
|
||||||
.el-table__row td{
|
margin-bottom: 25px;
|
||||||
&:not(:first-child){
|
}
|
||||||
.cell{
|
.el-row{
|
||||||
cursor: pointer;
|
background-color: #ffffff;
|
||||||
}
|
border:1px solid #eeeeee;
|
||||||
}
|
font-size: 14px;
|
||||||
|
line-height: 16px;
|
||||||
|
color: #333333;
|
||||||
|
.el-col{
|
||||||
|
padding:12px 0;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.el-col{
|
||||||
|
border-bottom: 1px solid #eeeeee;
|
||||||
|
}
|
||||||
|
.el-col:not(:nth-child(3n)){
|
||||||
|
border-right: 1px solid #eeeeee;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,13 +10,17 @@
|
|||||||
class="ems-dialog chart-detail-dialog"
|
class="ems-dialog chart-detail-dialog"
|
||||||
:before-close="handleColsed"
|
:before-close="handleColsed"
|
||||||
>
|
>
|
||||||
<el-card shadow="always" class="common-card-container time-range-card" style="margin-top:20px">
|
<el-card
|
||||||
|
shadow="always"
|
||||||
|
class="common-card-container time-range-card"
|
||||||
|
style="margin-top: 20px"
|
||||||
|
>
|
||||||
<div slot="header" class="time-range-header">
|
<div slot="header" class="time-range-header">
|
||||||
<span class="card-title"></span>
|
<span class="card-title"></span>
|
||||||
<date-range-select ref="dateRangeSelect" @updateDate="updateDate"/>
|
<date-range-select ref="dateRangeSelect" @updateDate="updateDate" />
|
||||||
</div>
|
</div>
|
||||||
<div class="card-main" v-loading="loading">
|
<div class="card-main" v-loading="loading">
|
||||||
<div id="lineChart" style="height: 310px;"></div>
|
<div id="lineChart" style="height: 310px"></div>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@ -28,7 +32,7 @@ import resize from "@/mixins/ems/resize";
|
|||||||
import { getSingleBatteryData } from "@/api/ems/dzjk";
|
import { getSingleBatteryData } from "@/api/ems/dzjk";
|
||||||
import DateRangeSelect from "@/components/Ems/DateRangeSelect/index.vue";
|
import DateRangeSelect from "@/components/Ems/DateRangeSelect/index.vue";
|
||||||
export default {
|
export default {
|
||||||
components: {DateRangeSelect},
|
components: { DateRangeSelect },
|
||||||
mixins: [resize],
|
mixins: [resize],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -48,9 +52,9 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 更新时间范围 重置图表
|
// 更新时间范围 重置图表
|
||||||
updateDate(data){
|
updateDate(data) {
|
||||||
this.dateRange=data || []
|
this.dateRange = data || [];
|
||||||
this.getData()
|
this.getData();
|
||||||
},
|
},
|
||||||
handleColsed(done) {
|
handleColsed(done) {
|
||||||
if (!this.chart) {
|
if (!this.chart) {
|
||||||
@ -94,7 +98,7 @@ export default {
|
|||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
!this.chart &&
|
!this.chart &&
|
||||||
(this.chart = echarts.init(document.querySelector("#lineChart")));
|
(this.chart = echarts.init(document.querySelector("#lineChart")));
|
||||||
this.$refs.dateRangeSelect.init()
|
this.$refs.dateRangeSelect.init();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
setOption(data) {
|
setOption(data) {
|
||||||
@ -148,7 +152,6 @@ export default {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
this.chart &&
|
this.chart &&
|
||||||
this.chart.setOption({
|
this.chart.setOption({
|
||||||
color: ["#FFBD00", "#3C81FF", "#05AEA3", "#F86F70"],
|
color: ["#FFBD00", "#3C81FF", "#05AEA3", "#F86F70"],
|
||||||
@ -186,10 +189,10 @@ export default {
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.chart-detail-dialog{
|
.chart-detail-dialog {
|
||||||
::v-deep{
|
::v-deep {
|
||||||
.el-dialog__body{
|
.el-dialog__body {
|
||||||
padding-top:0;
|
padding-top: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,14 +10,17 @@
|
|||||||
v-for="(item, index) in tableData"
|
v-for="(item, index) in tableData"
|
||||||
:key="index + 'dtdcList'"
|
:key="index + 'dtdcList'"
|
||||||
:class="handleListClass(item)"
|
:class="handleListClass(item)"
|
||||||
@click="chartDetail(item)"
|
|
||||||
>
|
>
|
||||||
<div style="font-size: 10px; font-weight: 600">
|
<div style="font-size: 10px; font-weight: 600">
|
||||||
{{ item.clusterDeviceId }}
|
{{ item.clusterDeviceId }}
|
||||||
</div>
|
</div>
|
||||||
<div>#{{ item.deviceId }}</div>
|
<div>#{{ item.deviceId }}</div>
|
||||||
<div class="dy">{{ item.voltage }}V</div>
|
<div class="dy pointer" @click="chartDetail(item, '电压 (V)')">
|
||||||
<div class="wd">{{ item.temperature }}℃</div>
|
{{ item.voltage }}V
|
||||||
|
</div>
|
||||||
|
<div class="wd pointer" @click="chartDetail(item, '温度 (℃)')">
|
||||||
|
{{ item.temperature }}℃
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -101,7 +104,7 @@ export default {
|
|||||||
//查看表格行图表
|
//查看表格行图表
|
||||||
chartDetail(row, dataType = "") {
|
chartDetail(row, dataType = "") {
|
||||||
const { clusterDeviceId, deviceId } = row;
|
const { clusterDeviceId, deviceId } = row;
|
||||||
this.$emit("chart", { clusterDeviceId, deviceId, dataType });
|
this.$emit("chart", { ...row, dataType });
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -123,7 +126,6 @@ export default {
|
|||||||
box-sizing: content-box;
|
box-sizing: content-box;
|
||||||
min-width: 60px;
|
min-width: 60px;
|
||||||
width: auto;
|
width: auto;
|
||||||
cursor: pointer;
|
|
||||||
&::before {
|
&::before {
|
||||||
display: block;
|
display: block;
|
||||||
content: "";
|
content: "";
|
||||||
|
|||||||
@ -8,10 +8,10 @@
|
|||||||
>
|
>
|
||||||
<el-table-column prop="deviceId" label="单体编号"> </el-table-column>
|
<el-table-column prop="deviceId" label="单体编号"> </el-table-column>
|
||||||
<el-table-column prop="clusterDeviceId" label="簇号"> </el-table-column>
|
<el-table-column prop="clusterDeviceId" label="簇号"> </el-table-column>
|
||||||
<el-table-column prop="voltage" label="电压(V)">
|
<el-table-column prop="voltage" label="电压 (V)">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button
|
<el-button
|
||||||
@click="chartDetail(scope.row, 'voltage')"
|
@click="chartDetail(scope.row, '电压 (V)')"
|
||||||
type="text"
|
type="text"
|
||||||
size="small"
|
size="small"
|
||||||
>
|
>
|
||||||
@ -19,10 +19,10 @@
|
|||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="temperature" label="温度(℃)">
|
<el-table-column prop="temperature" label="温度 (℃)">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button
|
<el-button
|
||||||
@click="chartDetail(scope.row, 'temperature')"
|
@click="chartDetail(scope.row, '温度 (℃)')"
|
||||||
type="text"
|
type="text"
|
||||||
size="small"
|
size="small"
|
||||||
>
|
>
|
||||||
@ -30,10 +30,10 @@
|
|||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="soc" label="SOC(%)">
|
<el-table-column prop="soc" label="SOC (%)">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button
|
<el-button
|
||||||
@click="chartDetail(scope.row, 'soc')"
|
@click="chartDetail(scope.row, 'SOC (%)')"
|
||||||
type="text"
|
type="text"
|
||||||
size="small"
|
size="small"
|
||||||
>
|
>
|
||||||
@ -41,10 +41,10 @@
|
|||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="soh" label="SOH(%)">
|
<el-table-column prop="soh" label="SOH (%)">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button
|
<el-button
|
||||||
@click="chartDetail(scope.row, 'soh')"
|
@click="chartDetail(scope.row, 'SOH (%)')"
|
||||||
type="text"
|
type="text"
|
||||||
size="small"
|
size="small"
|
||||||
>
|
>
|
||||||
@ -52,13 +52,13 @@
|
|||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="曲线图">
|
<!-- <el-table-column label="曲线图">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button @click="chartDetail(scope.row)" type="text" size="small">
|
<el-button @click="chartDetail(scope.row)" type="text" size="small">
|
||||||
展示
|
展示
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column> -->
|
||||||
</el-table>
|
</el-table>
|
||||||
<!-- <el-pagination
|
<!-- <el-pagination
|
||||||
v-show="tableData.length > 0"
|
v-show="tableData.length > 0"
|
||||||
@ -116,7 +116,7 @@ export default {
|
|||||||
//查看表格行图表
|
//查看表格行图表
|
||||||
chartDetail(row, dataType = "") {
|
chartDetail(row, dataType = "") {
|
||||||
const { clusterDeviceId, deviceId } = row;
|
const { clusterDeviceId, deviceId } = row;
|
||||||
this.$emit("chart", { clusterDeviceId, deviceId, dataType });
|
this.$emit("chart", { ...row, dataType });
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -103,6 +103,7 @@
|
|||||||
>
|
>
|
||||||
</el-pagination>
|
</el-pagination>
|
||||||
<chart-detail ref="chartDetail" />
|
<chart-detail ref="chartDetail" />
|
||||||
|
<point-chart ref="pointChart" :site-id="siteId" />
|
||||||
</el-card>
|
</el-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -117,10 +118,17 @@ import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
|||||||
import ChartDetail from "./ChartDetail.vue";
|
import ChartDetail from "./ChartDetail.vue";
|
||||||
import Table from "./Table.vue";
|
import Table from "./Table.vue";
|
||||||
import List from "./List.vue";
|
import List from "./List.vue";
|
||||||
|
import pointChart from "./../PointChart.vue";
|
||||||
export default {
|
export default {
|
||||||
name: "DzjkSbjkDtdc",
|
name: "DzjkSbjkDtdc",
|
||||||
mixins: [getQuerySiteId],
|
mixins: [getQuerySiteId],
|
||||||
components: { BarChart, ChartDetail, DtdcTable: Table, DtdcList: List },
|
components: {
|
||||||
|
BarChart,
|
||||||
|
ChartDetail,
|
||||||
|
DtdcTable: Table,
|
||||||
|
DtdcList: List,
|
||||||
|
pointChart,
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
pointIdList() {
|
pointIdList() {
|
||||||
let obj = {};
|
let obj = {};
|
||||||
@ -162,12 +170,14 @@ export default {
|
|||||||
activeBtn !== menu && (this.activeBtn = menu);
|
activeBtn !== menu && (this.activeBtn = menu);
|
||||||
},
|
},
|
||||||
//查看表格行图表
|
//查看表格行图表
|
||||||
chartDetail({ clusterDeviceId, deviceId, dataType = "" }) {
|
chartDetail({ deviceId, clusterDeviceId, dataType = "" }) {
|
||||||
const { siteId } = this;
|
dataType &&
|
||||||
this.$refs.chartDetail.initChart(
|
this.$refs.pointChart.showChart({
|
||||||
{ siteId, clusterDeviceId, deviceId },
|
pointName: dataType,
|
||||||
dataType
|
deviceCategory:'BATTERY',
|
||||||
);
|
deviceId: clusterDeviceId,
|
||||||
|
child: [deviceId],
|
||||||
|
});
|
||||||
},
|
},
|
||||||
// 分页
|
// 分页
|
||||||
handleSizeChange(val) {
|
handleSizeChange(val) {
|
||||||
|
|||||||
@ -1,55 +1,66 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div class="ems-dashboard-editor-container ems-third-menu-container" v-loading="loading">
|
||||||
class="ems-dashboard-editor-container ems-content-container-padding sbjk-ems-dashboard-editor-container ems-third-menu-container"
|
<el-menu
|
||||||
>
|
class="ems-third-menu"
|
||||||
<el-menu
|
:default-active="$route.name"
|
||||||
class="ems-third-menu"
|
background-color="#ffffff"
|
||||||
:default-active="$route.name"
|
text-color="#666666"
|
||||||
background-color="#ffffff"
|
active-text-color="#ffffff"
|
||||||
text-color="#666666"
|
|
||||||
active-text-color="#ffffff"
|
|
||||||
>
|
|
||||||
<el-menu-item
|
|
||||||
:index="item.name"
|
|
||||||
v-for="(item, index) in childrenRoute"
|
|
||||||
:key="index + 'dzjkChildrenRoute'"
|
|
||||||
>
|
>
|
||||||
<router-link
|
<el-menu-item :index="item.name" v-for="(item,index) in categoryRouter" :key="index+'dzjkChildrenRoute'">
|
||||||
style="height: 100%; width: 100%; display: block"
|
<router-link style="height: 100%;width: 100%;display: block" :to="{path:item.path,query:$route.query}">
|
||||||
:to="{ path: item.path, query: $route.query }"
|
{{item.meta.title}}
|
||||||
>
|
</router-link>
|
||||||
{{ item.meta.title }}
|
</el-menu-item>
|
||||||
</router-link>
|
</el-menu>
|
||||||
</el-menu-item>
|
<div class="ems-content-container ems-content-container-padding sbjk-ems-content-container">
|
||||||
</el-menu>
|
<keep-alive>
|
||||||
<div
|
<router-view></router-view>
|
||||||
class="ems-content-container ems-content-container-padding sbjk-ems-content-container"
|
</keep-alive>
|
||||||
>
|
</div>
|
||||||
<keep-alive>
|
|
||||||
<router-view></router-view>
|
|
||||||
</keep-alive>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { dzjk } from "@/router/ems";
|
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||||
const childrenRoute = dzjk[0].children.find(
|
import { dzjk } from '@/router/ems'
|
||||||
(item) => item.name === "DzjkSbjk"
|
import {mapState} from "vuex";
|
||||||
).children; //获取到单站监控-设备监控下面的字路由
|
const childrenRoute = ((dzjk[0]?.children || []).find(item=> item.name==='DzjkSbjk').children) || []//获取到单站监控-设备监控下面的字路由
|
||||||
console.log("设备监控子路由", childrenRoute);
|
|
||||||
export default {
|
export default {
|
||||||
name: "DzjkSbjk",
|
name:'DzjkSbjk',
|
||||||
data() {
|
mixins:[getQuerySiteId],
|
||||||
|
computed:{
|
||||||
|
...mapState({
|
||||||
|
zdDeviceCategoryOptions: state => state.ems.zdDeviceCategoryOptions,
|
||||||
|
}),
|
||||||
|
locationSiteCategory(){
|
||||||
|
return this.zdDeviceCategoryOptions[this.siteId] || []
|
||||||
|
},
|
||||||
|
categoryRouter(){
|
||||||
|
const routeData =this.childrenRoute.filter(item=>this.locationSiteCategory.includes(item.meta.deviceCategory))
|
||||||
|
if(this.siteId && routeData.length > 0 && this.locationSiteCategory && this.locationSiteCategory.length >1){
|
||||||
|
const locationPageDeviceCategory = this.$route.meta?.deviceCategory || ''
|
||||||
|
if(!routeData.some(item=> item.meta.deviceCategory===locationPageDeviceCategory)){
|
||||||
|
this.$router.replace({path:'/dzjk/sbjk/ssyx',query:this.$route.query})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return routeData
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data(){
|
||||||
return {
|
return {
|
||||||
childrenRoute,
|
childrenRoute,
|
||||||
activeMenu: "",
|
activeMenu:'',
|
||||||
};
|
loading:false,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
methods:{
|
||||||
console.log("当前设备监控页面路由", this.$route);
|
init(){
|
||||||
},
|
this.loading=true
|
||||||
};
|
this.$store.dispatch('getSiteDeviceCategory',this.siteId).finally(()=>this.loading=false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@ -1,69 +1,175 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div v-loading="loading" class="pcs-ems-dashboard-editor-container">
|
<div v-loading="loading" class="pcs-ems-dashboard-editor-container">
|
||||||
<!-- 顶部六个方块-->
|
<!-- 顶部六个方块-->
|
||||||
<real-time-base-info :data="runningHeadData"/>
|
<real-time-base-info :data="runningHeadData" />
|
||||||
<div v-for="(pcsItem,pcsIndex) in pcsList" :key="pcsIndex+'PcsHome'" style="margin-bottom:25px;">
|
<div
|
||||||
<el-card :class="{
|
v-for="(pcsItem, pcsIndex) in pcsList"
|
||||||
'warning-card-container':pcsItem.workStatus === '1',
|
:key="pcsIndex + 'PcsHome'"
|
||||||
'timing-card-container':pcsItem.workStatus === '2',
|
style="margin-bottom: 25px"
|
||||||
'running-card-container':!['1','2'].includes(pcsItem.workStatus)
|
>
|
||||||
}" class="sbjk-card-container common-card-container-body-no-padding common-card-container-no-title-bg"
|
<el-card
|
||||||
shadow="always">
|
:class="{
|
||||||
|
'warning-card-container': pcsItem.workStatus === '1',
|
||||||
|
'timing-card-container': pcsItem.workStatus === '2',
|
||||||
|
'running-card-container': !['1', '2'].includes(pcsItem.workStatus),
|
||||||
|
}"
|
||||||
|
class="sbjk-card-container common-card-container-body-no-padding common-card-container-no-title-bg"
|
||||||
|
shadow="always"
|
||||||
|
>
|
||||||
<div slot="header">
|
<div slot="header">
|
||||||
<span class="large-title">{{pcsIndex+1}}#{{pcsItem.deviceName}}</span>
|
<span class="large-title"
|
||||||
|
>{{ pcsIndex + 1 }}#{{ pcsItem.deviceName }}</span
|
||||||
|
>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<div>
|
<div>
|
||||||
{{
|
{{
|
||||||
$store.state.ems.communicationStatusOptions[
|
$store.state.ems.communicationStatusOptions[
|
||||||
pcsItem.communicationStatus
|
pcsItem.communicationStatus
|
||||||
]
|
]
|
||||||
}}
|
}}
|
||||||
</div>
|
</div>
|
||||||
<div>数据更新时间:{{ pcsItem.dataUpdateTime }}</div>
|
<div>数据更新时间:{{ pcsItem.dataUpdateTime }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="alarm">
|
<div class="alarm">
|
||||||
<el-badge :value="pcsItem.alarmNum || 0" class="item">
|
<el-badge :value="pcsItem.alarmNum || 0" class="item">
|
||||||
<i class="el-icon-message-solid" style="font-size: 26px;color: #fff;display: block;"></i>
|
<i
|
||||||
|
class="el-icon-message-solid"
|
||||||
|
style="font-size: 26px; color: #fff; display: block"
|
||||||
|
></i>
|
||||||
</el-badge>
|
</el-badge>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="descriptions-main">
|
<div class="descriptions-main">
|
||||||
<el-descriptions :colon="false" :column="4" direction="vertical">
|
<el-descriptions :colon="false" :column="4" direction="vertical">
|
||||||
<el-descriptions-item :contentClassName="`descriptions-direction ${pcsItem.workStatus === '0' ? 'save' :'danger'}`" :span="1" label="工作状态" labelClassName="descriptions-label">{{$store.state.ems.workStatusOptions[pcsItem.workStatus]}}</el-descriptions-item>
|
<el-descriptions-item
|
||||||
<el-descriptions-item :span="1" contentClassName="descriptions-direction" label="并网状态" labelClassName="descriptions-label">{{$store.state.ems.gridStatusOptions[pcsItem.gridStatus]}}</el-descriptions-item>
|
:contentClassName="`descriptions-direction ${
|
||||||
<el-descriptions-item :contentClassName="`descriptions-direction ${pcsItem.deviceStatus === '0' ? 'save' : 'danger'}`" :span="1" label="设备状态" labelClassName="descriptions-label">{{$store.state.ems.deviceStatusOptions[pcsItem.deviceStatus]}}</el-descriptions-item>
|
pcsItem.workStatus === '0' ? 'save' : 'danger'
|
||||||
<el-descriptions-item :span="1" contentClassName="descriptions-direction" label="控制模式" labelClassName="descriptions-label">{{$store.state.ems.controlModeOptions[pcsItem.controlMode]}}</el-descriptions-item>
|
}`"
|
||||||
</el-descriptions>
|
:span="1"
|
||||||
</div>
|
label="工作状态"
|
||||||
<div class="descriptions-main descriptions-main-bg-color">
|
labelClassName="descriptions-label"
|
||||||
<el-descriptions :colon="false" :column="4" contentClassName="descriptions-direction" direction="vertical" labelClassName="descriptions-label">
|
>{{
|
||||||
<el-descriptions-item v-for="(item,index) in infoData" :key="index+'pcsInfoData'" :label="item.label" :span="1">
|
$store.state.ems.workStatusOptions[pcsItem.workStatus]
|
||||||
<span class="pointer" @click="showChart(item.pointName || '','PCS',pcsItem.deviceId)">
|
}}</el-descriptions-item
|
||||||
{{pcsItem[item.attr] | formatNumber}} <span v-if="item.unit" v-html="item.unit"></span>
|
>
|
||||||
|
<el-descriptions-item
|
||||||
|
:span="1"
|
||||||
|
contentClassName="descriptions-direction"
|
||||||
|
label="并网状态"
|
||||||
|
labelClassName="descriptions-label"
|
||||||
|
>{{
|
||||||
|
$store.state.ems.gridStatusOptions[pcsItem.gridStatus]
|
||||||
|
}}</el-descriptions-item
|
||||||
|
>
|
||||||
|
<el-descriptions-item
|
||||||
|
:contentClassName="`descriptions-direction ${
|
||||||
|
pcsItem.deviceStatus === '2' ? 'save' : 'danger'
|
||||||
|
}`"
|
||||||
|
:span="1"
|
||||||
|
label="设备状态"
|
||||||
|
labelClassName="descriptions-label"
|
||||||
|
>{{
|
||||||
|
$store.state.ems.deviceStatusOptions[pcsItem.deviceStatus]
|
||||||
|
}}</el-descriptions-item
|
||||||
|
>
|
||||||
|
<el-descriptions-item
|
||||||
|
:span="1"
|
||||||
|
contentClassName="descriptions-direction"
|
||||||
|
label="控制模式"
|
||||||
|
labelClassName="descriptions-label"
|
||||||
|
>{{
|
||||||
|
$store.state.ems.controlModeOptions[pcsItem.controlMode]
|
||||||
|
}}</el-descriptions-item
|
||||||
|
>
|
||||||
|
</el-descriptions>
|
||||||
|
</div>
|
||||||
|
<div class="descriptions-main descriptions-main-bg-color">
|
||||||
|
<el-descriptions
|
||||||
|
:colon="false"
|
||||||
|
:column="4"
|
||||||
|
contentClassName="descriptions-direction"
|
||||||
|
direction="vertical"
|
||||||
|
labelClassName="descriptions-label"
|
||||||
|
>
|
||||||
|
<el-descriptions-item
|
||||||
|
v-for="(item, index) in infoData"
|
||||||
|
:key="index + 'pcsInfoData'"
|
||||||
|
:label="item.label"
|
||||||
|
:span="1"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="pointer"
|
||||||
|
@click="
|
||||||
|
showChart(item.pointName || '', pcsItem.deviceId)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ pcsItem[item.attr] | formatNumber }}
|
||||||
|
<span v-if="item.unit" v-html="item.unit"></span>
|
||||||
</span>
|
</span>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</div>
|
</div>
|
||||||
<div v-for="(item,index) in pcsItem.pcsBranchInfoList" :key="index+'pcsBranchInfoList'" class="descriptions-main">
|
<div
|
||||||
<el-descriptions :colon="false" :column="4" contentClassName="descriptions-direction keep" direction="vertical" labelClassName="descriptions-label">
|
v-for="(item, index) in pcsItem.pcsBranchInfoList"
|
||||||
<el-descriptions-item :label="'支路'+(index+1)" :span="4" contentClassName="descriptions-direction keep" labelClassName="descriptions-label">{{item.dischargeStatus}}</el-descriptions-item>
|
:key="index + 'pcsBranchInfoList'"
|
||||||
<el-descriptions-item :span="1" contentClassName="descriptions-direction" label="直流功率" labelClassName="descriptions-label">
|
class="descriptions-main"
|
||||||
<span class="pointer" @click="showChart('直流功率','PCS分支设备',item.deviceId)">{{item.dcPower}}kW</span>
|
>
|
||||||
</el-descriptions-item>
|
<el-descriptions
|
||||||
<el-descriptions-item :span="1" contentClassName="descriptions-direction" label="直流电压" labelClassName="descriptions-label">
|
:colon="false"
|
||||||
<span class="pointer" @click="showChart('直流电压','PCS分支设备',item.deviceId)">{{item.dcVoltage}}V</span>
|
:column="4"
|
||||||
</el-descriptions-item>
|
contentClassName="descriptions-direction keep"
|
||||||
<el-descriptions-item :span="1" contentClassName="descriptions-direction" label="直流电流" labelClassName="descriptions-label">
|
direction="vertical"
|
||||||
<span class="pointer" @click="showChart('直流电流','PCS分支设备',item.deviceId)">{{item.dcCurrent}}A</span>
|
labelClassName="descriptions-label"
|
||||||
</el-descriptions-item>
|
>
|
||||||
</el-descriptions>
|
<el-descriptions-item
|
||||||
</div>
|
:label="'支路' + (index + 1)"
|
||||||
|
:span="4"
|
||||||
|
contentClassName="descriptions-direction keep"
|
||||||
|
labelClassName="descriptions-label"
|
||||||
|
>{{ item.dischargeStatus }}</el-descriptions-item
|
||||||
|
>
|
||||||
|
<el-descriptions-item
|
||||||
|
:span="1"
|
||||||
|
contentClassName="descriptions-direction"
|
||||||
|
label="直流功率"
|
||||||
|
labelClassName="descriptions-label"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="pointer"
|
||||||
|
@click="showChart('直流功率', item.deviceId,true)"
|
||||||
|
>{{ item.dcPower }}kW</span
|
||||||
|
>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item
|
||||||
|
:span="1"
|
||||||
|
contentClassName="descriptions-direction"
|
||||||
|
label="直流电压"
|
||||||
|
labelClassName="descriptions-label"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="pointer"
|
||||||
|
@click="showChart('直流电压', item.deviceId,true)"
|
||||||
|
>{{ item.dcVoltage }}V</span
|
||||||
|
>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item
|
||||||
|
:span="1"
|
||||||
|
contentClassName="descriptions-direction"
|
||||||
|
label="直流电流"
|
||||||
|
labelClassName="descriptions-label"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="pointer"
|
||||||
|
@click="showChart('直流电流', item.deviceId,true)"
|
||||||
|
>{{ item.dcCurrent }}A</span
|
||||||
|
>
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
<el-empty v-show="pcsList.length<=0" :image-size="200"></el-empty>
|
<el-empty v-show="pcsList.length <= 0" :image-size="200"></el-empty>
|
||||||
<!-- 电位图表 showChart({pointName:点位名称,categoryName:设备名称})-->
|
<point-chart ref="pointChart" :site-id="siteId" />
|
||||||
<point-chart ref="pointChart" :site-id="siteId"/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -71,68 +177,127 @@
|
|||||||
import pointChart from "./../PointChart.vue";
|
import pointChart from "./../PointChart.vue";
|
||||||
import RealTimeBaseInfo from "./../RealTimeBaseInfo.vue";
|
import RealTimeBaseInfo from "./../RealTimeBaseInfo.vue";
|
||||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||||
import {getRunningHeadInfo,getPcsDetailInfo} from '@/api/ems/dzjk'
|
import { getRunningHeadInfo, getPcsDetailInfo } from "@/api/ems/dzjk";
|
||||||
import intervalUpdate from "@/mixins/ems/intervalUpdate";
|
import intervalUpdate from "@/mixins/ems/intervalUpdate";
|
||||||
export default {
|
export default {
|
||||||
name:'DzjkSbjkPcs',
|
name: "DzjkSbjkPcs",
|
||||||
components:{RealTimeBaseInfo,pointChart},
|
components: { RealTimeBaseInfo, pointChart },
|
||||||
mixins:[getQuerySiteId,intervalUpdate],
|
mixins: [getQuerySiteId, intervalUpdate],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
loading:false,
|
loading: false,
|
||||||
runningHeadData:{},//运行信息
|
runningHeadData: {}, //运行信息
|
||||||
pcsList:[],
|
pcsList: [],
|
||||||
infoData:[
|
infoData: [
|
||||||
{label:'总交流有功电率',attr:'totalActivePower',unit:'kW',pointName:'总交流有功电率'},
|
{
|
||||||
{label:'当天交流充电量',attr:'dailyAcChargeEnergy',unit:'kWh',pointName:'当天交流充电量 (kWh)'},
|
label: "总交流有功电率",
|
||||||
{label:'A相电压',attr:'aPhaseVoltage',unit:'V',pointName:''},
|
attr: "totalActivePower",
|
||||||
{label:'A相电流',attr:'aPhaseCurrent',unit:'A',pointName:'A相电流'},
|
unit: "kW",
|
||||||
{label:'总交流无功电率',attr:'totalReactivePower',unit:'kVar',pointName:'总交流无功电率'},
|
pointName: "总交流有功电率",
|
||||||
{label:'当天交流放电量',attr:'dailyAcDischargeEnergy',unit:'kWh',pointName:'当天交流放电量 (kWh)'},
|
},
|
||||||
{label:'B相电压',attr:'bPhaseVoltage',unit:'V',pointName:''},
|
{
|
||||||
{label:'B相电流',attr:'bPhaseCurrent',unit:'A',pointName:'B相电流'},
|
label: "当天交流充电量",
|
||||||
{label:'总交流视在功率',attr:'totalApparentPower',unit:'kVA',pointName:'总交流视在功率'},
|
attr: "dailyAcChargeEnergy",
|
||||||
{label:'PCS模块温度',attr:'pcsModuleTemperature',unit:'℃',pointName:''},
|
unit: "kWh",
|
||||||
{label:'C相电压',attr:'cPhaseVoltage',unit:'V',pointName:''},
|
pointName: "当天交流充电量 (kWh)",
|
||||||
{label:'C相电流',attr:'cPhaseCurrent',unit:'A',pointName:'C相电流'},
|
},
|
||||||
{label:'总交流功率因数',attr:'totalPowerFactor',unit:'',pointName:'总交流功率因数'},
|
{ label: "A相电压", attr: "aPhaseVoltage", unit: "V", pointName: "" },
|
||||||
{label:'PCS环境温度',attr:'pcsEnvironmentTemperature',unit:'℃',pointName:''},
|
{
|
||||||
{label:'交流频率',attr:'acFrequency',unit:'Hz',pointName:'交流频率'}
|
label: "A相电流",
|
||||||
|
attr: "aPhaseCurrent",
|
||||||
|
unit: "A",
|
||||||
|
pointName: "A相电流",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "总交流无功电率",
|
||||||
|
attr: "totalReactivePower",
|
||||||
|
unit: "kVar",
|
||||||
|
pointName: "总交流无功电率",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "当天交流放电量",
|
||||||
|
attr: "dailyAcDischargeEnergy",
|
||||||
|
unit: "kWh",
|
||||||
|
pointName: "当天交流放电量 (kWh)",
|
||||||
|
},
|
||||||
|
{ label: "B相电压", attr: "bPhaseVoltage", unit: "V", pointName: "" },
|
||||||
|
{
|
||||||
|
label: "B相电流",
|
||||||
|
attr: "bPhaseCurrent",
|
||||||
|
unit: "A",
|
||||||
|
pointName: "B相电流",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "总交流视在功率",
|
||||||
|
attr: "totalApparentPower",
|
||||||
|
unit: "kVA",
|
||||||
|
pointName: "总交流视在功率",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "PCS模块温度",
|
||||||
|
attr: "pcsModuleTemperature",
|
||||||
|
unit: "℃",
|
||||||
|
pointName: "",
|
||||||
|
},
|
||||||
|
{ label: "C相电压", attr: "cPhaseVoltage", unit: "V", pointName: "" },
|
||||||
|
{
|
||||||
|
label: "C相电流",
|
||||||
|
attr: "cPhaseCurrent",
|
||||||
|
unit: "A",
|
||||||
|
pointName: "C相电流",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "总交流功率因数",
|
||||||
|
attr: "totalPowerFactor",
|
||||||
|
unit: "",
|
||||||
|
pointName: "总交流功率因数",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "PCS环境温度",
|
||||||
|
attr: "pcsEnvironmentTemperature",
|
||||||
|
unit: "℃",
|
||||||
|
pointName: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "交流频率",
|
||||||
|
attr: "acFrequency",
|
||||||
|
unit: "Hz",
|
||||||
|
pointName: "交流频率",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
pcsBranchList:[],//pcs的支路列表
|
pcsBranchList: [], //pcs的支路列表
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
methods:{
|
methods: {
|
||||||
//todo 后续需要新增设备id
|
showChart(pointName, deviceId,isBranch=false) {
|
||||||
showChart(pointName,categoryName,deviceId){
|
pointName &&
|
||||||
console.log('点击查询图表',pointName,categoryName,deviceId)
|
this.$refs.pointChart.showChart({ pointName,deviceCategory:isBranch ? 'BRANCH' : 'PCS', deviceId });
|
||||||
pointName && this.$refs.pointChart.showChart({pointName,categoryName,deviceId})
|
|
||||||
},
|
},
|
||||||
//6个方块数据
|
//6个方块数据
|
||||||
getRunningHeadData(){
|
getRunningHeadData() {
|
||||||
getRunningHeadInfo(this.siteId).then(response => {
|
getRunningHeadInfo(this.siteId).then((response) => {
|
||||||
this.runningHeadData = response?.data || {}
|
this.runningHeadData = response?.data || {};
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
getPcsList(){
|
getPcsList() {
|
||||||
this.loading = true
|
this.loading = true;
|
||||||
getPcsDetailInfo(this.siteId).then(response => {
|
getPcsDetailInfo(this.siteId)
|
||||||
const data = response?.data || {}
|
.then((response) => {
|
||||||
this.pcsList = JSON.parse(JSON.stringify(data))
|
const data = response?.data || {};
|
||||||
}).finally(()=>this.loading = false)
|
this.pcsList = JSON.parse(JSON.stringify(data));
|
||||||
|
})
|
||||||
|
.finally(() => (this.loading = false));
|
||||||
},
|
},
|
||||||
updateData(){
|
updateData() {
|
||||||
this.getRunningHeadData()
|
this.getRunningHeadData();
|
||||||
this.getPcsList()
|
this.getPcsList();
|
||||||
|
},
|
||||||
|
init() {
|
||||||
|
this.updateData();
|
||||||
|
this.updateInterval(this.updateData);
|
||||||
},
|
},
|
||||||
init(){
|
|
||||||
this.updateData()
|
|
||||||
this.updateInterval(this.updateData)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
};
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped></style>
|
||||||
</style>
|
|
||||||
|
|||||||
@ -1,107 +1,125 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding">
|
<el-card
|
||||||
|
shadow="always"
|
||||||
|
class="common-card-container common-card-container-body-no-padding"
|
||||||
|
>
|
||||||
<div slot="header">
|
<div slot="header">
|
||||||
<span class="card-title">储能功率曲线</span>
|
<span class="card-title">PCS有功功率/PCS无功功率</span>
|
||||||
</div>
|
</div>
|
||||||
<div style="height: 360px" id="cnglqxChart"/>
|
<div style="height: 360px" id="cnglqxChart" />
|
||||||
</el-card>
|
</el-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss"></style>
|
<style scoped lang="scss"></style>
|
||||||
<script>
|
<script>
|
||||||
import * as echarts from 'echarts'
|
import * as echarts from "echarts";
|
||||||
import resize from '@/mixins/ems/resize'
|
import resize from "@/mixins/ems/resize";
|
||||||
import {formatDate} from "@/filters/ems";
|
import { formatDate } from "@/filters/ems";
|
||||||
import {storagePower} from '@/api/ems/dzjk'
|
import { storagePower } from "@/api/ems/dzjk";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [resize],
|
mixins: [resize],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
chart: null
|
chart: null,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.chart = echarts.init(document.querySelector('#cnglqxChart'))
|
this.chart = echarts.init(document.querySelector("#cnglqxChart"));
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
if (!this.chart) {
|
if (!this.chart) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
this.chart.dispose()
|
this.chart.dispose();
|
||||||
this.chart = null
|
this.chart = null;
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
init(siteId){
|
init(siteId) {
|
||||||
this.chart.showLoading()
|
this.chart.showLoading();
|
||||||
const x = []
|
const x = [];
|
||||||
const data1 =[],data2 =[]
|
const data1 = [],
|
||||||
storagePower(siteId).then(response => {
|
data2 = [];
|
||||||
const source = response?.data?.energyStoragePowList || []
|
storagePower(siteId)
|
||||||
source.forEach(item=>{
|
.then((response) => {
|
||||||
x.push(formatDate(item.createDate,false,true))
|
this.setOption(response?.data?.pcsPowerList || []);
|
||||||
data1.push(item.pcsTotalActPower)
|
|
||||||
data2.push(item.pcsTotalReactivePower)
|
|
||||||
})
|
})
|
||||||
this.setOption(x,data1,data2)
|
.finally(() => {
|
||||||
}).finally(()=>{
|
this.chart.hideLoading();
|
||||||
this.chart.hideLoading()
|
});
|
||||||
})
|
|
||||||
},
|
},
|
||||||
setOption(x,data1,data2) {
|
setOption(data) {
|
||||||
|
// data=[{deviceId:'pcs1',energyStoragePowList:[{createDate,deviceId,pcsTotalActPower,pcsTotalReactivePower}]}]
|
||||||
|
let xdata = [],
|
||||||
|
series = [];
|
||||||
|
data.forEach((element, index) => {
|
||||||
|
if (index === 0) {
|
||||||
|
xdata = (element.energyStoragePowList || []).map((i) => i.createDate);
|
||||||
|
}
|
||||||
|
series.push(
|
||||||
|
{
|
||||||
|
type: "line",
|
||||||
|
name: `${element.deviceId}有功功率`,
|
||||||
|
areaStyle: {
|
||||||
|
// color:'#FFBD00'
|
||||||
|
},
|
||||||
|
data: (element.energyStoragePowList || []).map(
|
||||||
|
(i) => i.pcsTotalActPower
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "line",
|
||||||
|
name: `${element.deviceId}无功功率`,
|
||||||
|
areaStyle: {
|
||||||
|
// color:'#FFBD00'
|
||||||
|
},
|
||||||
|
data: (element.energyStoragePowList || []).map(
|
||||||
|
(i) => i.pcsTotalReactivePower
|
||||||
|
),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
this.chart.setOption({
|
this.chart.setOption({
|
||||||
color:['#FFBD00','#3C81FF'],
|
|
||||||
legend: {
|
legend: {
|
||||||
left: 'center',
|
left: "center",
|
||||||
top: '10',
|
top: "5",
|
||||||
|
itemWidth: 10,
|
||||||
|
itemHeight: 5,
|
||||||
|
textStyle: {
|
||||||
|
fontSize: 9,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
grid: {
|
grid: {
|
||||||
containLabel: true
|
containLabel: true,
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
trigger: 'axis',
|
trigger: "axis",
|
||||||
axisPointer: { // 坐标轴指示器,坐标轴触发有效
|
axisPointer: {
|
||||||
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
|
// 坐标轴指示器,坐标轴触发有效
|
||||||
}
|
type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
|
||||||
|
},
|
||||||
},
|
},
|
||||||
textStyle:{
|
textStyle: {
|
||||||
color:"#333333",
|
color: "#333333",
|
||||||
},
|
},
|
||||||
xAxis: {type:'category',data:x},
|
xAxis: { type: "category", data: xdata },
|
||||||
yAxis: {
|
yAxis: {
|
||||||
type: 'value',
|
type: "value",
|
||||||
},
|
},
|
||||||
dataZoom: [
|
dataZoom: [
|
||||||
{
|
{
|
||||||
type: 'inside',
|
type: "inside",
|
||||||
start: 0,
|
start: 0,
|
||||||
end: 100
|
end: 100,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
start: 0,
|
start: 0,
|
||||||
end: 100
|
end: 100,
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
series: [
|
series,
|
||||||
{
|
});
|
||||||
name:'PCS实时有功功率',
|
},
|
||||||
type: 'line',
|
},
|
||||||
areaStyle: {
|
};
|
||||||
color:'#FFBD00'
|
|
||||||
},
|
|
||||||
data: data1,
|
|
||||||
},{
|
|
||||||
name:'PCS实时无功功率',
|
|
||||||
type: 'line',
|
|
||||||
areaStyle: {
|
|
||||||
color: '#3C81FF'
|
|
||||||
},
|
|
||||||
data: data2
|
|
||||||
}]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,99 +1,106 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding">
|
<el-card
|
||||||
|
shadow="always"
|
||||||
|
class="common-card-container common-card-container-body-no-padding"
|
||||||
|
>
|
||||||
<div slot="header">
|
<div slot="header">
|
||||||
<span class="card-title">电池平均SOC</span>
|
<span class="card-title">平均SOC</span>
|
||||||
</div>
|
</div>
|
||||||
<div style="height: 360px" id="dcpjsocChart"/>
|
<div style="height: 360px" id="dcpjsocChart" />
|
||||||
</el-card>
|
</el-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss"></style>
|
<style scoped lang="scss"></style>
|
||||||
<script>
|
<script>
|
||||||
import * as echarts from 'echarts'
|
import * as echarts from "echarts";
|
||||||
import resize from '@/mixins/ems/resize'
|
import resize from "@/mixins/ems/resize";
|
||||||
import {formatDate} from "@/filters/ems";
|
import { formatDate } from "@/filters/ems";
|
||||||
import {batteryAveSoc} from '@/api/ems/dzjk'
|
import { batteryAveSoc } from "@/api/ems/dzjk";
|
||||||
export default {
|
export default {
|
||||||
mixins: [resize],
|
mixins: [resize],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
chart: null
|
chart: null,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.chart = echarts.init(document.querySelector('#dcpjsocChart'))
|
this.chart = echarts.init(document.querySelector("#dcpjsocChart"));
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
if (!this.chart) {
|
if (!this.chart) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
this.chart.dispose()
|
this.chart.dispose();
|
||||||
this.chart = null
|
this.chart = null;
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
init(siteId){
|
init(siteId) {
|
||||||
this.chart.showLoading()
|
this.chart.showLoading();
|
||||||
const x = []
|
batteryAveSoc(siteId)
|
||||||
const data =[]
|
.then((response) => {
|
||||||
batteryAveSoc(siteId).then(response => {
|
this.setOption(response?.data?.batteryAveSOCList || []);
|
||||||
const source = response?.data?.batteryAveSOCList || []
|
|
||||||
source.forEach(item=>{
|
|
||||||
x.push(formatDate(item.createDate,false,true))
|
|
||||||
data.push(item.batterySOC)
|
|
||||||
})
|
})
|
||||||
this.setOption(x,data)
|
.finally(() => {
|
||||||
}).finally(()=>{
|
this.chart.hideLoading();
|
||||||
this.chart.hideLoading()
|
});
|
||||||
})
|
|
||||||
},
|
},
|
||||||
setOption(x,data) {
|
setOption(data) {
|
||||||
this.chart.setOption({
|
let xdata = [],
|
||||||
color:['#FFBD00','#3C81FF'],
|
ydata = [];
|
||||||
// legend: {
|
data.forEach((element) => {
|
||||||
// left: 'center',
|
xdata.push(element.createDate);
|
||||||
// bottom: '10',
|
ydata.push(element.batterySOC);
|
||||||
// },
|
});
|
||||||
tooltip: {
|
xdata = this.chart.setOption({
|
||||||
trigger: 'axis',
|
legend: {
|
||||||
axisPointer: { // 坐标轴指示器,坐标轴触发有效
|
left: "center",
|
||||||
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
|
top: "5",
|
||||||
}
|
itemWidth: 10,
|
||||||
|
itemHeight: 5,
|
||||||
|
textStyle: {
|
||||||
|
fontSize: 9,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
grid: {
|
grid: {
|
||||||
containLabel: true
|
containLabel: true,
|
||||||
},
|
},
|
||||||
textStyle:{
|
tooltip: {
|
||||||
color:"#333333",
|
trigger: "axis",
|
||||||
|
axisPointer: {
|
||||||
|
// 坐标轴指示器,坐标轴触发有效
|
||||||
|
type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
|
||||||
|
},
|
||||||
},
|
},
|
||||||
xAxis: {type:'category',data:x},
|
textStyle: {
|
||||||
|
color: "#333333",
|
||||||
|
},
|
||||||
|
xAxis: { type: "category", data: xdata },
|
||||||
yAxis: {
|
yAxis: {
|
||||||
type: 'value',
|
type: "value",
|
||||||
},
|
},
|
||||||
dataZoom: [
|
dataZoom: [
|
||||||
{
|
{
|
||||||
type: 'inside',
|
type: "inside",
|
||||||
start: 0,
|
start: 0,
|
||||||
end: 100
|
end: 100,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
start: 0,
|
start: 0,
|
||||||
end: 100
|
end: 100,
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
name:'电池平均SOC',
|
type: "line",
|
||||||
data: data,
|
name: `平均SOC`,
|
||||||
type: 'line',
|
|
||||||
areaStyle: {
|
areaStyle: {
|
||||||
color:'#FFBD00'
|
// color:'#FFBD00'
|
||||||
}
|
},
|
||||||
|
data: ydata,
|
||||||
}]
|
},
|
||||||
})
|
],
|
||||||
}
|
});
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,99 +1,110 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding">
|
<el-card
|
||||||
|
shadow="always"
|
||||||
|
class="common-card-container common-card-container-body-no-padding"
|
||||||
|
>
|
||||||
<div slot="header">
|
<div slot="header">
|
||||||
<span class="card-title">电池平均温度</span>
|
<span class="card-title">电池平均温度</span>
|
||||||
</div>
|
</div>
|
||||||
<div style="height: 360px" id="dcpjwdChart"/>
|
<div style="height: 360px" id="dcpjwdChart" />
|
||||||
</el-card>
|
</el-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss"></style>
|
<style scoped lang="scss"></style>
|
||||||
<script>
|
<script>
|
||||||
import * as echarts from 'echarts'
|
import * as echarts from "echarts";
|
||||||
import resize from '@/mixins/ems/resize'
|
import resize from "@/mixins/ems/resize";
|
||||||
import {formatDate} from "@/filters/ems";
|
import { formatDate } from "@/filters/ems";
|
||||||
import {batteryAveTemp} from '@/api/ems/dzjk'
|
import { batteryAveTemp } from "@/api/ems/dzjk";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [resize],
|
mixins: [resize],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
chart: null
|
chart: null,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.chart = echarts.init(document.querySelector('#dcpjwdChart'))
|
this.chart = echarts.init(document.querySelector("#dcpjwdChart"));
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
if (!this.chart) {
|
if (!this.chart) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
this.chart.dispose()
|
this.chart.dispose();
|
||||||
this.chart = null
|
this.chart = null;
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
init(siteId){
|
init(siteId) {
|
||||||
this.chart.showLoading()
|
this.chart.showLoading();
|
||||||
const x = []
|
const x = [];
|
||||||
const data1 =[],data2 =[]
|
const data1 = [],
|
||||||
batteryAveTemp(siteId).then(response => {
|
data2 = [];
|
||||||
const source = response?.data?.batteryAveTempList || []
|
batteryAveTemp(siteId)
|
||||||
source.forEach(item=>{
|
.then((response) => {
|
||||||
x.push(formatDate(item.createDate,false,true))
|
this.setOption(response?.data?.batteryAveTempList || []);
|
||||||
data1.push(item.batteryTemp)
|
|
||||||
})
|
})
|
||||||
this.setOption(x,data1,data2)
|
.finally(() => {
|
||||||
}).finally(()=>{
|
this.chart.hideLoading();
|
||||||
this.chart.hideLoading()
|
});
|
||||||
})
|
|
||||||
},
|
},
|
||||||
setOption(x,data) {
|
setOption(data) {
|
||||||
this.chart.setOption({
|
let xdata = [],
|
||||||
color:['#3C81FF'],
|
ydata = [];
|
||||||
// legend: {
|
data.forEach((element) => {
|
||||||
// left: 'center',
|
xdata.push(element.createDate);
|
||||||
// bottom: '10',
|
ydata.push(element.batteryTemp);
|
||||||
// },
|
});
|
||||||
tooltip: {
|
xdata = this.chart.setOption({
|
||||||
trigger: 'axis',
|
legend: {
|
||||||
axisPointer: { // 坐标轴指示器,坐标轴触发有效
|
left: "center",
|
||||||
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
|
top: "5",
|
||||||
}
|
itemWidth: 10,
|
||||||
|
itemHeight: 5,
|
||||||
|
textStyle: {
|
||||||
|
fontSize: 9,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
grid: {
|
grid: {
|
||||||
containLabel: true
|
containLabel: true,
|
||||||
},
|
},
|
||||||
textStyle:{
|
tooltip: {
|
||||||
color:"#333333",
|
trigger: "axis",
|
||||||
|
axisPointer: {
|
||||||
|
// 坐标轴指示器,坐标轴触发有效
|
||||||
|
type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
|
||||||
|
},
|
||||||
},
|
},
|
||||||
xAxis: {type:'category',data:x},
|
textStyle: {
|
||||||
|
color: "#333333",
|
||||||
|
},
|
||||||
|
xAxis: { type: "category", data: xdata },
|
||||||
yAxis: {
|
yAxis: {
|
||||||
type: 'value',
|
type: "value",
|
||||||
},
|
},
|
||||||
dataZoom: [
|
dataZoom: [
|
||||||
{
|
{
|
||||||
type: 'inside',
|
type: "inside",
|
||||||
start: 0,
|
start: 0,
|
||||||
end: 100
|
end: 100,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
start: 0,
|
start: 0,
|
||||||
end: 100
|
end: 100,
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
name:'电池平均温度',
|
type: "line",
|
||||||
data: data,
|
name: `电池平均温度`,
|
||||||
type: 'line',
|
|
||||||
areaStyle: {
|
areaStyle: {
|
||||||
color:'#3C81FF'
|
// color:'#FFBD00'
|
||||||
},
|
},
|
||||||
}]
|
data: ydata,
|
||||||
})
|
},
|
||||||
}
|
],
|
||||||
}
|
});
|
||||||
}
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,96 +1,109 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding">
|
<el-card
|
||||||
|
shadow="always"
|
||||||
|
class="common-card-container common-card-container-body-no-padding"
|
||||||
|
>
|
||||||
<div slot="header">
|
<div slot="header">
|
||||||
<span class="card-title">PCS平均温度</span>
|
<span class="card-title">PCS最高温度</span>
|
||||||
</div>
|
</div>
|
||||||
<div style="height: 360px" id="pocpjwdChart"/>
|
<div style="height: 360px" id="pocpjwdChart" />
|
||||||
</el-card>
|
</el-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss"></style>
|
<style scoped lang="scss"></style>
|
||||||
<script>
|
<script>
|
||||||
import * as echarts from 'echarts'
|
import * as echarts from "echarts";
|
||||||
import resize from '@/mixins/ems/resize'
|
import resize from "@/mixins/ems/resize";
|
||||||
import {formatDate} from "@/filters/ems";
|
import { formatDate } from "@/filters/ems";
|
||||||
import {stackAveTemp} from '@/api/ems/dzjk'
|
import { pcsMaxTemp } from "@/api/ems/dzjk";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [resize],
|
mixins: [resize],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
chart: null
|
chart: null,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.chart = echarts.init(document.querySelector('#pocpjwdChart'))
|
this.chart = echarts.init(document.querySelector("#pocpjwdChart"));
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
if (!this.chart) {
|
if (!this.chart) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
this.chart.dispose()
|
this.chart.dispose();
|
||||||
this.chart = null
|
this.chart = null;
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
init(siteId){
|
init(siteId) {
|
||||||
this.chart.showLoading()
|
this.chart.showLoading();
|
||||||
const x = []
|
const x = [];
|
||||||
const data =[]
|
const data = [];
|
||||||
stackAveTemp(siteId).then(response => {
|
pcsMaxTemp(siteId)
|
||||||
const source = response?.data?.stackAveTempList || []
|
.then((response) => {
|
||||||
source.forEach(item=>{
|
this.setOption(response?.data?.pcsMaxTempList || []);
|
||||||
x.push(formatDate(item.createDate,false,true))
|
|
||||||
data.push(item.temp)
|
|
||||||
})
|
})
|
||||||
this.setOption(x,data)
|
.finally(() => {
|
||||||
}).finally(()=>{
|
this.chart.hideLoading();
|
||||||
this.chart.hideLoading()
|
});
|
||||||
})
|
|
||||||
},
|
},
|
||||||
setOption(x,data) {
|
setOption(data) {
|
||||||
|
let xdata = [],
|
||||||
|
series = [];
|
||||||
|
data.forEach((element, index) => {
|
||||||
|
if (index === 0) {
|
||||||
|
xdata = (element.maxTempVoList || []).map((i) => i.createDate);
|
||||||
|
}
|
||||||
|
series.push({
|
||||||
|
type: "line",
|
||||||
|
name: `${element.deviceId}最高温度`,
|
||||||
|
areaStyle: {
|
||||||
|
// color:'#FFBD00'
|
||||||
|
},
|
||||||
|
data: (element.maxTempVoList || []).map((i) => i.temp),
|
||||||
|
});
|
||||||
|
});
|
||||||
this.chart.setOption({
|
this.chart.setOption({
|
||||||
color:['#FFBD00','#3C81FF'],
|
legend: {
|
||||||
tooltip: {
|
left: "center",
|
||||||
trigger: 'axis',
|
top: "5",
|
||||||
axisPointer: { // 坐标轴指示器,坐标轴触发有效
|
itemWidth: 10,
|
||||||
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
|
itemHeight: 5,
|
||||||
}
|
textStyle: {
|
||||||
|
fontSize: 9,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
grid: {
|
grid: {
|
||||||
containLabel: true
|
containLabel: true,
|
||||||
},
|
},
|
||||||
textStyle:{
|
tooltip: {
|
||||||
color:"#333333",
|
trigger: "axis",
|
||||||
|
axisPointer: {
|
||||||
|
// 坐标轴指示器,坐标轴触发有效
|
||||||
|
type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
|
||||||
|
},
|
||||||
},
|
},
|
||||||
xAxis: {type:'category',data:x},
|
textStyle: {
|
||||||
|
color: "#333333",
|
||||||
|
},
|
||||||
|
xAxis: { type: "category", data: xdata },
|
||||||
yAxis: {
|
yAxis: {
|
||||||
type: 'value',
|
type: "value",
|
||||||
},
|
},
|
||||||
dataZoom: [
|
dataZoom: [
|
||||||
{
|
{
|
||||||
type: 'inside',
|
type: "inside",
|
||||||
start: 0,
|
start: 0,
|
||||||
end: 100
|
end: 100,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
start: 0,
|
start: 0,
|
||||||
end: 100
|
end: 100,
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
series: [
|
series,
|
||||||
{
|
});
|
||||||
name:'PCS平均温度',
|
},
|
||||||
data: data,
|
},
|
||||||
type: 'line',
|
};
|
||||||
areaStyle: {
|
|
||||||
color:'#FFBD00'
|
|
||||||
}
|
|
||||||
|
|
||||||
}]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,19 +1,24 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div v-loading="loading">
|
<div v-loading="loading">
|
||||||
<div class="yl-item-container" :class="{'yl-warn-item-container':item.workMode !== '0','yl-normal-item-container':item.workMode === '0'}" v-for="(item,index) in list" :key="index+'ylLise'">
|
<el-card
|
||||||
<div class="header">
|
v-for="(item,index) in list"
|
||||||
<div class="header-title">{{item.systemName}}</div>
|
:key="index+'ylLise'"
|
||||||
<div>工作模式:<span class="header-values">{{$store.state.ems.workModeOptions[item.workMode]}}</span></div>
|
class="sbjk-card-container running-card-container"
|
||||||
<div>当前温度:<span class="header-values">{{item.currentTemperature}}℃</span></div>
|
shadow="always">
|
||||||
|
<div slot="header">
|
||||||
|
<span class="large-title">{{index+1}}#{{item.deviceName}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<el-row>
|
||||||
<el-row>
|
<el-col v-for="(tempDataItem,tempDataIndex) in tempData" :key="tempDataIndex+'ylTempData'" :span="8">
|
||||||
<el-col v-for="(tempDataItem,tempDataIndex) in tempData" :key="tempDataIndex+'ylTempData'" :span="8">{{tempDataItem.title}}:{{item[tempDataItem.attr]}}℃</el-col>
|
<span class="pointer" @click="showChart(tempDataItem.title,item.deviceId)">
|
||||||
</el-row>
|
{{tempDataItem.title}}:{{item[tempDataItem.attr]}}<span v-html="tempDataItem.unit"></span>
|
||||||
</div>
|
</span>
|
||||||
</div>
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-card>
|
||||||
<el-empty v-show="list.length<=0" :image-size="200"></el-empty>
|
<el-empty v-show="list.length<=0" :image-size="200"></el-empty>
|
||||||
|
<point-chart ref="pointChart" :site-id="siteId"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -22,25 +27,30 @@
|
|||||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||||
import {getCoolingDataList} from '@/api/ems/dzjk'
|
import {getCoolingDataList} from '@/api/ems/dzjk'
|
||||||
import intervalUpdate from "@/mixins/ems/intervalUpdate";
|
import intervalUpdate from "@/mixins/ems/intervalUpdate";
|
||||||
|
import pointChart from "./../PointChart.vue";
|
||||||
export default {
|
export default {
|
||||||
name:'DzjkSbjkYl',
|
name:'DzjkSbjkYl',
|
||||||
mixins:[getQuerySiteId,intervalUpdate],
|
mixins:[getQuerySiteId,intervalUpdate],
|
||||||
|
components:{pointChart},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
loading:false,
|
loading:false,
|
||||||
list:[],
|
list:[],
|
||||||
tempData:[
|
tempData:[
|
||||||
{title:'制热开启点',attr:'heatingStartPoint'},
|
{title:'供水温度',attr:'gsTemp',unit:'℃'},
|
||||||
{title:'制冷开启点',attr:'coolingStartPoint'},
|
{title:'回水温度',attr:'hsTemp',unit:'℃'},
|
||||||
{title:'高温告警点',attr:'highTempAlarmPoint'},
|
{title:'供水压力',attr:'gsPressure',unit:'bar'},
|
||||||
{title:'制热停止点',attr:'heatingStopPoint'},
|
{title:'回水压力',attr:'hsPressure',unit:'bar'},
|
||||||
{title:'制冷停止点',attr:'coolingStopPoint'},
|
{title:'冷源水温度',attr:'lysTemp',unit:'℃'},
|
||||||
{title:'低温告警点',attr:'lowTempAlarmPoint'},
|
{title:'VB01开度',attr:'vb01Kd',unit:'%'},
|
||||||
|
{title:'VB02开度',attr:'vb02Kd',unit:'%'},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods:{
|
methods:{
|
||||||
|
showChart(pointName,deviceId){
|
||||||
|
pointName && this.$refs.pointChart.showChart({pointName,deviceCategory:'COOLING',deviceId})
|
||||||
|
},
|
||||||
updateData(){
|
updateData(){
|
||||||
this.loading = true
|
this.loading = true
|
||||||
getCoolingDataList(this.siteId).then(response => {
|
getCoolingDataList(this.siteId).then(response => {
|
||||||
@ -59,72 +69,27 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.yl-item-container{
|
.sbjk-card-container{
|
||||||
border-radius: 5px;
|
|
||||||
&:not(:last-child){
|
&:not(:last-child){
|
||||||
margin-bottom: 25px;
|
margin-bottom: 25px;
|
||||||
}
|
}
|
||||||
.header{
|
.el-row{
|
||||||
line-height: 40px;
|
background-color: #ffffff;
|
||||||
|
border:1px solid #eeeeee;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
>div{
|
line-height: 16px;
|
||||||
display: inline-block;
|
color: #333333;
|
||||||
margin-right: 40px;
|
.el-col{
|
||||||
}
|
padding:12px 0;
|
||||||
.header-title{
|
|
||||||
border-radius: 5px 0 5px 0;
|
|
||||||
color:#ffffff;
|
|
||||||
width: 120px;
|
|
||||||
height: 40px;
|
|
||||||
font-size: 16px;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
.header-values{
|
.el-col{
|
||||||
font-weight: 500;
|
border-bottom: 1px solid #eeeeee;
|
||||||
}
|
}
|
||||||
}
|
.el-col:not(:nth-child(3n)){
|
||||||
.content{
|
border-right: 1px solid #eeeeee;
|
||||||
padding:25px;
|
|
||||||
.el-row{
|
|
||||||
background-color: #ffffff;
|
|
||||||
border:1px solid #eeeeee;
|
|
||||||
line-height: 14px;
|
|
||||||
color: #333333;
|
|
||||||
font-size: 12px;
|
|
||||||
.el-col{
|
|
||||||
padding:10px 0;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.el-col:nth-child(-n+3){
|
|
||||||
border-bottom: 1px solid #eeeeee;
|
|
||||||
}
|
|
||||||
.el-col:not(:nth-child(3n)){
|
|
||||||
border-right: 1px solid #eeeeee;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.yl-warn-item-container{
|
|
||||||
background-color: #FFF1F0;
|
|
||||||
.header{
|
|
||||||
.header-title{
|
|
||||||
background-color: #FC6B69;
|
|
||||||
}
|
|
||||||
.header-values{
|
|
||||||
color: #FC6B69;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.yl-normal-item-container{
|
|
||||||
background-color: #EBF6F6;
|
|
||||||
.header{
|
|
||||||
.header-title{
|
|
||||||
background-color: #05AEA3;
|
|
||||||
}
|
|
||||||
.header-values{
|
|
||||||
color: #05AEA3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -3,23 +3,18 @@
|
|||||||
<div style="width:100%" v-loading="loading">
|
<div style="width:100%" v-loading="loading">
|
||||||
<!-- 搜索栏-->
|
<!-- 搜索栏-->
|
||||||
<el-form :inline="true" class="select-container">
|
<el-form :inline="true" class="select-container">
|
||||||
<el-form-item label="电表">
|
|
||||||
<el-select v-model="search.deviceId" placeholder="请选择" loading-text="正在加载数据">
|
|
||||||
<el-option :label="item.deviceName" :value="item.id" v-for="(item,index) in deviceOptions" :key="index+'dbOptions'"></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<!-- <el-form-item label="日报">-->
|
|
||||||
<!-- <el-select v-model="search.rb" placeholder="请选择" :loading="loading" loading-text="正在加载数据">-->
|
|
||||||
<!-- <el-option :label="item.name" :value="item.id" v-for="(item,index) in rbOptions" :key="index+'rbOptions'"></el-option>-->
|
|
||||||
<!-- </el-select>-->
|
|
||||||
<!-- </el-form-item>-->
|
|
||||||
<el-form-item label="时间选择">
|
<el-form-item label="时间选择">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="search.date"
|
v-model="dateRange"
|
||||||
type="date"
|
type="daterange"
|
||||||
:picker-options="pickerOptions"
|
range-separator="至"
|
||||||
:default-value="defaultDate">
|
start-placeholder="开始日期"
|
||||||
</el-date-picker>
|
end-placeholder="结束日期"
|
||||||
|
value-format="yyyy-MM-dd"
|
||||||
|
:clearable="false"
|
||||||
|
:picker-options="pickerOptions"
|
||||||
|
:default-value="defaultDateRange"
|
||||||
|
></el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" @click="onSearch" native-type="button">搜索</el-button>
|
<el-button type="primary" @click="onSearch" native-type="button">搜索</el-button>
|
||||||
@ -40,71 +35,92 @@
|
|||||||
prop="dataTime"
|
prop="dataTime"
|
||||||
label="日期"
|
label="日期"
|
||||||
width="120">
|
width="120">
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{scope.row.dataTime}}{{scope.row.dataTime === '汇总' ? '' : ':00'}}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<!--充电量列-->
|
<!--充电量列-->
|
||||||
<el-table-column label="充电量">
|
<el-table-column label="充电量" align="center">
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
align="center"
|
||||||
prop="activePeakKwh"
|
prop="activePeakKwh"
|
||||||
label="尖">
|
label="尖">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
align="center"
|
||||||
prop="activeHighKwh"
|
prop="activeHighKwh"
|
||||||
label="峰">
|
label="峰">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
align="center"
|
||||||
prop="activeFlatKwh"
|
prop="activeFlatKwh"
|
||||||
label="平">
|
label="平">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
align="center"
|
||||||
prop="activeValleyKwh"
|
prop="activeValleyKwh"
|
||||||
label="谷">
|
label="谷">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
align="center"
|
||||||
prop="activeTotalKwh"
|
prop="activeTotalKwh"
|
||||||
label="总">
|
label="总">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<!--充电量列-->
|
<!--充电量列-->
|
||||||
<el-table-column label="放电量">
|
<el-table-column label="放电量" align="center">
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
align="center"
|
||||||
prop="reActivePeakKwh"
|
prop="reActivePeakKwh"
|
||||||
label="尖">
|
label="尖">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
align="center"
|
||||||
prop="reActiveHighKwh"
|
prop="reActiveHighKwh"
|
||||||
label="峰">
|
label="峰">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
align="center"
|
||||||
prop="reActiveFlatKwh"
|
prop="reActiveFlatKwh"
|
||||||
label="平">
|
label="平">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
align="center"
|
||||||
prop="reActiveValleyKwh"
|
prop="reActiveValleyKwh"
|
||||||
label="谷">
|
label="谷">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
align="center"
|
||||||
prop="reActiveTotalKwh"
|
prop="reActiveTotalKwh"
|
||||||
label="总">
|
label="总">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<!-- 效率-->
|
<!-- 效率-->
|
||||||
<el-table-column label="效率(%)">
|
<el-table-column label="效率(%)" align="center">
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
align="center"
|
||||||
prop="effect">
|
prop="effect">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
<el-pagination
|
||||||
|
v-show="tableData.length>0"
|
||||||
|
background
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
:current-page="pageNum"
|
||||||
|
:page-size="pageSize"
|
||||||
|
:page-sizes="[10, 20, 30, 40]"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="totalSize"
|
||||||
|
style="margin-top:15px;text-align: center"
|
||||||
|
>
|
||||||
|
</el-pagination>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||||
import { getAmmeterData, getLoadNameList} from '@/api/ems/dzjk'
|
import { getAmmeterData} from '@/api/ems/dzjk'
|
||||||
import {formatDate} from "@/filters/ems";
|
import {formatDate} from "@/filters/ems";
|
||||||
export default {
|
export default {
|
||||||
name:'DzjkTjbbDbbb',
|
name:'DzjkTjbbDbbb',
|
||||||
@ -117,61 +133,64 @@ export default {
|
|||||||
return time.getTime() > Date.now();
|
return time.getTime() > Date.now();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
defaultDate:'',//默认展示的时间
|
defaultDateRange:[],//默认展示的时间
|
||||||
search:{deviceId:'',date:''},
|
dateRange:[],
|
||||||
deviceOptions:[],
|
tableData:[],
|
||||||
// rbOptions:[
|
pageSize:10,//分页栏当前每个数据总数
|
||||||
// {name:'日报1',id:1},
|
pageNum:1,//分页栏当前页数
|
||||||
// {name:'日报2',id:2},
|
totalSize:0,//table表格数据总数
|
||||||
// ],
|
|
||||||
tableData:[]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods:{
|
methods:{
|
||||||
// 搜索
|
// 搜索
|
||||||
onSearch(){
|
onSearch(){
|
||||||
|
this.pageNum =1//每次搜索从1开始搜索
|
||||||
this.getData()
|
this.getData()
|
||||||
},
|
},
|
||||||
// 重置
|
// 重置
|
||||||
onReset(){
|
onReset(){
|
||||||
this.search.date = ''
|
this.dateRange=this.defaultDateRange
|
||||||
|
this.pageNum =1//每次搜索从1开始搜索
|
||||||
this.getData()
|
this.getData()
|
||||||
},
|
},
|
||||||
|
// 分页
|
||||||
|
handleSizeChange(val) {
|
||||||
|
this.pageSize = val;
|
||||||
|
this.$nextTick(()=>{
|
||||||
|
this.getData()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleCurrentChange(val) {
|
||||||
|
this.pageNum = val
|
||||||
|
this.$nextTick(()=>{
|
||||||
|
this.getData()
|
||||||
|
})
|
||||||
|
},
|
||||||
// 获取数据
|
// 获取数据
|
||||||
getData(){
|
getData(){
|
||||||
if(!this.search.deviceId) return
|
|
||||||
this.loading=true
|
this.loading=true
|
||||||
getAmmeterData({siteId:this.siteId,deviceId:this.search.deviceId,dateTime:formatDate(this.search.date)}).then(response=>{
|
const {siteId,pageNum,pageSize} =this
|
||||||
this.tableData=response?.data || [];
|
const [startTime='',endTime='']=(this.dateRange || [])
|
||||||
|
getAmmeterData({siteId:siteId,startTime,endTime,pageSize,pageNum}).then(response=>{
|
||||||
|
this.tableData=response?.rows || [];
|
||||||
|
this.totalSize = response?.total || 0
|
||||||
}).finally(()=> {
|
}).finally(()=> {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
getDbList(){
|
|
||||||
return getLoadNameList(this.siteId).then(response=>{
|
|
||||||
this.deviceOptions=response?.data || [];
|
|
||||||
this.deviceOptions.length > 0 && (this.search.deviceId = this.deviceOptions[0].id);
|
|
||||||
})
|
|
||||||
},
|
|
||||||
init(){
|
init(){
|
||||||
this.loading = true
|
this.dateRange=[]
|
||||||
this.deviceOptions = []
|
|
||||||
this.search.deviceId=''
|
|
||||||
this.search.date=''
|
|
||||||
this.tableData=[]
|
this.tableData=[]
|
||||||
this.getDbList().then(()=>{
|
this.totalSize=0
|
||||||
if(this.search.deviceId){
|
this.pageSize=10
|
||||||
this.onReset()
|
this.pageNum = 1
|
||||||
}else{
|
const now = new Date().getTime();
|
||||||
this.loading = false
|
const lastMonth = new Date(now-30 * 24 * 60 * 60 * 1000).getTime();
|
||||||
}
|
this.defaultDateRange = [formatDate(lastMonth), formatDate(now)];
|
||||||
})
|
this.dateRange=[formatDate(lastMonth), formatDate(now)];
|
||||||
|
this.getData()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted(){
|
|
||||||
this.defaultDate = new Date()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -1,165 +1,191 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-card shadow="always" class="common-card-container time-range-card" style="margin-top:20px">
|
<el-card
|
||||||
|
shadow="always"
|
||||||
|
class="common-card-container time-range-card"
|
||||||
|
style="margin-top: 20px"
|
||||||
|
>
|
||||||
<div slot="header" class="time-range-header">
|
<div slot="header" class="time-range-header">
|
||||||
<span class="card-title">
|
<span class="card-title"> </span>
|
||||||
<el-button-group class="ems-btns-group">
|
<date-range-select ref="dateRangeSelect" @updateDate="updateDate" />
|
||||||
<el-button v-for="(item,index) in btnList" :key="index+'dcdqxBtns'" size="mini" :class="{'activeBtn' : activeBtn === item.id}" @click="changeDataType(item.id)">{{item.name}}</el-button>
|
|
||||||
</el-button-group>
|
|
||||||
</span>
|
|
||||||
<date-range-select ref="dateRangeSelect" @updateDate="updateDate"/>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card-main" v-loading="loading">
|
<div class="card-main" v-loading="loading">
|
||||||
<div id="dcdEchart" style="height: 310px;"></div>
|
<el-button-group class="ems-btns-group">
|
||||||
|
<el-button
|
||||||
|
v-for="(item, index) in btnList"
|
||||||
|
:key="index + 'dcdqxBtns'"
|
||||||
|
size="mini"
|
||||||
|
:class="{ activeBtn: activeBtn === item.id }"
|
||||||
|
@click="changeDataType(item.id)"
|
||||||
|
>{{ item.name }}</el-button
|
||||||
|
>
|
||||||
|
</el-button-group>
|
||||||
|
<div id="dcdEchart" style="height: 310px"></div>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as echarts from 'echarts'
|
import * as echarts from "echarts";
|
||||||
import resize from "@/mixins/ems/resize";
|
import resize from "@/mixins/ems/resize";
|
||||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||||
import { getStackData, getStackNameList} from '@/api/ems/dzjk'
|
import { getStackData, getStackNameList } from "@/api/ems/dzjk";
|
||||||
import {formatDate} from "@/filters/ems";
|
import { formatDate } from "@/filters/ems";
|
||||||
import DateRangeSelect from "@/components/Ems/DateRangeSelect/index.vue";
|
import DateRangeSelect from "@/components/Ems/DateRangeSelect/index.vue";
|
||||||
export default {
|
export default {
|
||||||
name:'DzjkTjbbDcdqx',
|
name: "DzjkTjbbDcdqx",
|
||||||
components: {DateRangeSelect},
|
components: { DateRangeSelect },
|
||||||
mixins: [resize,getQuerySiteId],
|
mixins: [resize, getQuerySiteId],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
pickerOptions:{
|
pickerOptions: {
|
||||||
disabledDate(time) {
|
disabledDate(time) {
|
||||||
return time.getTime() > Date.now();
|
return time.getTime() > Date.now();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
dateRange:[],
|
dateRange: [],
|
||||||
loading:false,
|
loading: false,
|
||||||
activeBtn:'1',
|
activeBtn: "1",
|
||||||
btnList:[
|
btnList: [
|
||||||
{name:'堆平均维度',id:'1',attr:['temp'],source:['有功功率']},
|
{ name: "堆平均维度", id: "1", attr: ["temp"], source: ["有功功率"] },
|
||||||
{name:'堆电压',id:'2',attr:['voltage'],source:['堆电压']},
|
{ name: "堆电压", id: "2", attr: ["voltage"], source: ["堆电压"] },
|
||||||
{name:'堆电流',id:'3',attr:['current'],source:['堆电流']},
|
{ name: "堆电流", id: "3", attr: ["current"], source: ["堆电流"] },
|
||||||
{name:'堆soc',id:'4',attr:['soc'],source:['堆soc']},
|
{ name: "堆soc", id: "4", attr: ["soc"], source: ["堆soc"] },
|
||||||
],
|
],
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
changeDataType(id){
|
changeDataType(id) {
|
||||||
if(id !== this.activeBtn){
|
if (id !== this.activeBtn) {
|
||||||
this.activeBtn=id;
|
this.activeBtn = id;
|
||||||
this.getData()
|
this.getData();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 更新时间范围 重置图表
|
// 更新时间范围 重置图表
|
||||||
updateDate(data){
|
updateDate(data) {
|
||||||
this.dateRange=data || []
|
this.dateRange = data || [];
|
||||||
this.getData()
|
this.getData();
|
||||||
},
|
},
|
||||||
getData(){
|
getData() {
|
||||||
const {siteId,activeBtn}=this;
|
const { siteId, activeBtn } = this;
|
||||||
const [start='',end='']=(this.dateRange || [])
|
const [start = "", end = ""] = this.dateRange || [];
|
||||||
//接口调用完成之后 设置图表、结束loading
|
//接口调用完成之后 设置图表、结束loading
|
||||||
this.loading=true;
|
this.loading = true;
|
||||||
getStackData({siteId,startTime:formatDate(start),endTime:formatDate(end),dataType:activeBtn}).then(response => {
|
getStackData({
|
||||||
this.setOption(response?.data || [])
|
siteId,
|
||||||
}).finally(()=>{this.loading=false;})
|
startTime: formatDate(start),
|
||||||
|
endTime: formatDate(end),
|
||||||
|
dataType: activeBtn,
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
this.setOption(response?.data || []);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
compareDate(date1,date2){
|
compareDate(date1, date2) {
|
||||||
console.log('比较时间',date1,date2)
|
console.log("比较时间", date1, date2);
|
||||||
// 年2025-09/天2025-09-15/时2025-09-15/10:00
|
// 年2025-09/天2025-09-15/时2025-09-15/10:00
|
||||||
if(date1.indexOf(':') > -1 && date2.indexOf(':') > -1){
|
if (date1.indexOf(":") > -1 && date2.indexOf(":") > -1) {
|
||||||
return parseInt(date1) - parseInt(date2)
|
return parseInt(date1) - parseInt(date2);
|
||||||
}
|
}
|
||||||
const [date1_Y='',date1_M='',date1_D=''] = date1.split('-')//根据空格区分[年月日,小时]
|
const [date1_Y = "", date1_M = "", date1_D = ""] = date1.split("-"); //根据空格区分[年月日,小时]
|
||||||
const [date2_Y='',date2_M='',date2_D=''] = date2.split('-')//根据空格区分[年月日,小时]
|
const [date2_Y = "", date2_M = "", date2_D = ""] = date2.split("-"); //根据空格区分[年月日,小时]
|
||||||
return (date1_Y === date2_Y && date1_M === date2_M && date1_D - date2_D) || (date1_Y === date2_Y && date1_M - date2_M) || date1_Y - date2_Y
|
return (
|
||||||
|
(date1_Y === date2_Y && date1_M === date2_M && date1_D - date2_D) ||
|
||||||
|
(date1_Y === date2_Y && date1_M - date2_M) ||
|
||||||
|
date1_Y - date2_Y
|
||||||
|
);
|
||||||
},
|
},
|
||||||
setOption(data) {
|
setOption(data) {
|
||||||
const ele = this.btnList.find((item)=>{return item.id === this.activeBtn})
|
const ele = this.btnList.find((item) => {
|
||||||
const sourceBase = JSON.parse(JSON.stringify(ele.source))
|
return item.id === this.activeBtn;
|
||||||
|
});
|
||||||
|
const sourceBase = JSON.parse(JSON.stringify(ele.source));
|
||||||
// sourceBase={name:'堆平均维度',id:'1',attr:['temp'],source:['有功功率']},
|
// sourceBase={name:'堆平均维度',id:'1',attr:['temp'],source:['有功功率']},
|
||||||
const source=[]
|
const source = [];
|
||||||
const sourceTop = ['日期']
|
const sourceTop = ["日期"];
|
||||||
let map={},mapArr=[]
|
let map = {},
|
||||||
|
mapArr = [];
|
||||||
// 生成所有{日期:[],日期:[]}格式的对象和所有包含所有日期的[日期1,日期2...]
|
// 生成所有{日期:[],日期:[]}格式的对象和所有包含所有日期的[日期1,日期2...]
|
||||||
data.forEach((item)=>{
|
data.forEach((item) => {
|
||||||
item.dataList.forEach((inner)=>{
|
item.dataList.forEach((inner) => {
|
||||||
// 日期格式
|
// 日期格式
|
||||||
// 年2025-09/天2025-09-15/时2025-09-15/10:00
|
// 年2025-09/天2025-09-15/时2025-09-15/10:00
|
||||||
// 所有数据的日期格式一致
|
// 所有数据的日期格式一致
|
||||||
if(!map[inner.statisDate]) {
|
if (!map[inner.statisDate]) {
|
||||||
map[inner.statisDate] = []
|
map[inner.statisDate] = [];
|
||||||
mapArr.push(inner.statisDate)
|
mapArr.push(inner.statisDate);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
data.forEach((item,itemIndex)=>{
|
data.forEach((item, itemIndex) => {
|
||||||
const dataTimeList = item.dataList.map(i =>i.statisDate)
|
const dataTimeList = item.dataList.map((i) => i.statisDate);
|
||||||
const noDataTime = mapArr.filter(i=>!dataTimeList.includes(i))
|
const noDataTime = mapArr.filter((i) => !dataTimeList.includes(i));
|
||||||
sourceBase.forEach((outer,outerIndex)=>{
|
sourceBase.forEach((outer, outerIndex) => {
|
||||||
sourceTop.push(`${item.deviceId}-${outer}`)
|
sourceTop.push(`${item.deviceId}-${outer}`);
|
||||||
noDataTime.forEach(i=>map[i].push(''))
|
noDataTime.forEach((i) => map[i].push(""));
|
||||||
item.dataList.forEach((inner,innerIndex)=>{
|
item.dataList.forEach((inner, innerIndex) => {
|
||||||
map[inner.statisDate].push(inner[ele.attr[outerIndex]])
|
map[inner.statisDate].push(inner[ele.attr[outerIndex]]);
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
mapArr = mapArr.sort((a,b)=>this.compareDate(a,b))
|
mapArr = mapArr.sort((a, b) => this.compareDate(a, b));
|
||||||
mapArr.forEach(item=>{
|
mapArr.forEach((item) => {
|
||||||
source.push([item,...map[item]])
|
source.push([item, ...map[item]]);
|
||||||
})
|
});
|
||||||
source.unshift(sourceTop)
|
source.unshift(sourceTop);
|
||||||
console.log('map=',map)
|
this.chart.setOption(
|
||||||
console.log('mapArr=',mapArr)
|
{
|
||||||
console.log('========',source)
|
grid: {
|
||||||
this.chart.setOption({
|
containLabel: true,
|
||||||
grid: {
|
},
|
||||||
containLabel: true
|
legend: {
|
||||||
|
left: "center",
|
||||||
|
bottom: "15",
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: "axis",
|
||||||
|
axisPointer: {
|
||||||
|
// 坐标轴指示器,坐标轴触发有效
|
||||||
|
type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
textStyle: {
|
||||||
|
color: "#333333",
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: "category",
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: "value",
|
||||||
|
},
|
||||||
|
dataset: { source },
|
||||||
|
series: source[0].slice(1).map((item) => {
|
||||||
|
return {
|
||||||
|
type: "line",
|
||||||
|
};
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
legend: {
|
true
|
||||||
left: 'center',
|
);
|
||||||
bottom: '15',
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'axis',
|
|
||||||
axisPointer: { // 坐标轴指示器,坐标轴触发有效
|
|
||||||
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
textStyle:{
|
|
||||||
color:"#333333",
|
|
||||||
},
|
|
||||||
xAxis: {
|
|
||||||
type: 'category',
|
|
||||||
},
|
|
||||||
yAxis: {
|
|
||||||
type: 'value',
|
|
||||||
},
|
|
||||||
dataset: {source},
|
|
||||||
series:source[0].slice(1).map(item=>{
|
|
||||||
return {
|
|
||||||
type:ele.type || 'scatter'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},true)
|
|
||||||
},
|
},
|
||||||
initChart() {
|
initChart() {
|
||||||
this.chart = echarts.init(document.querySelector('#dcdEchart'));
|
this.chart = echarts.init(document.querySelector("#dcdEchart"));
|
||||||
|
},
|
||||||
|
init() {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.initChart();
|
||||||
|
this.$refs.dateRangeSelect.init();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
init(){
|
|
||||||
this.$nextTick(()=>{
|
|
||||||
this.initChart()
|
|
||||||
this.$refs.dateRangeSelect.init()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
if (!this.chart) {
|
if (!this.chart) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
this.chart.dispose()
|
this.chart.dispose();
|
||||||
this.chart = null
|
this.chart = null;
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -1,116 +1,151 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<el-card shadow="always" class="common-card-container time-range-card" style="margin-top:20px">
|
<el-card
|
||||||
|
shadow="always"
|
||||||
|
class="common-card-container time-range-card"
|
||||||
|
style="margin-top: 20px"
|
||||||
|
>
|
||||||
<div slot="header" class="time-range-header">
|
<div slot="header" class="time-range-header">
|
||||||
<span class="card-title">功率曲线</span>
|
<span class="card-title">功率曲线</span>
|
||||||
<date-range-select ref="dateRangeSelect" @updateDate="updateDate"/>
|
<date-range-select
|
||||||
|
ref="dateRangeSelect"
|
||||||
|
@reset="resetTime"
|
||||||
|
@updateDate="updateDate"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-main" v-loading="loading">
|
<div class="card-main" v-loading="loading">
|
||||||
<div id="glqxEchart" style="height: 310px;"></div>
|
<div id="glqxEchart" style="height: 310px"></div>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as echarts from 'echarts'
|
import * as echarts from "echarts";
|
||||||
import resize from "@/mixins/ems/resize";
|
import resize from "@/mixins/ems/resize";
|
||||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||||
import {getPcsNameList, getPowerData} from "@/api/ems/dzjk";
|
import { getPcsNameList, getPowerData } from "@/api/ems/dzjk";
|
||||||
import {formatDate} from "@/filters/ems";
|
import { formatDate } from "@/filters/ems";
|
||||||
import DateRangeSelect from "@/components/Ems/DateRangeSelect/index.vue";
|
import DateRangeSelect from "@/components/Ems/DateRangeSelect/index.vue";
|
||||||
export default {
|
export default {
|
||||||
name:'DzjkTjbbGlqx',
|
name: "DzjkTjbbGlqx",
|
||||||
components: {DateRangeSelect},
|
components: { DateRangeSelect },
|
||||||
mixins: [resize,getQuerySiteId],
|
mixins: [resize, getQuerySiteId],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
pickerOptions:{
|
pickerOptions: {
|
||||||
disabledDate(time) {
|
disabledDate(time) {
|
||||||
return time.getTime() > Date.now();
|
return time.getTime() > Date.now();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
dateRange:[],
|
dateRange: [],
|
||||||
loading:false,
|
loading: false,
|
||||||
}
|
dateRangeInit: true,
|
||||||
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 更新时间范围 重置图表
|
// 更新时间范围 重置图表
|
||||||
updateDate(data){
|
updateDate(data) {
|
||||||
this.dateRange=data || []
|
this.dateRange = data || [];
|
||||||
this.getData()
|
this.getData();
|
||||||
},
|
},
|
||||||
getData(){
|
resetTime() {
|
||||||
const {siteId}=this;
|
this.dateRangeInit = true;
|
||||||
const [start='',end='']=(this.dateRange || [])
|
},
|
||||||
|
getData() {
|
||||||
|
const { siteId } = this;
|
||||||
|
let [start = "", end = ""] = this.dateRange || [];
|
||||||
//接口调用完成之后 设置图表、结束loading
|
//接口调用完成之后 设置图表、结束loading
|
||||||
this.loading=true;
|
this.loading = true;
|
||||||
getPowerData({siteId,startDate:formatDate(start),endDate:formatDate(end)}).then(response => {
|
if (this.dateRangeInit) {
|
||||||
this.setOption(response?.data || [])
|
start = "";
|
||||||
}).finally(()=>{this.loading=false;})
|
end = "";
|
||||||
|
this.dateRangeInit = false;
|
||||||
|
}
|
||||||
|
getPowerData({
|
||||||
|
siteId,
|
||||||
|
startDate: formatDate(start),
|
||||||
|
endDate: formatDate(end),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
this.setOption(response?.data || []);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
setOption(data) {
|
setOption(data) {
|
||||||
const source = [['日期','电网功率','负载功率','储能功率','光伏功率']]
|
const source = [["日期", "电网功率", "负载功率", "储能功率", "光伏功率"]];
|
||||||
data.forEach(item=>{
|
data.forEach((item) => {
|
||||||
source.push([item.statisDate,item.gridPower,item.loadPower,item.storagePower,item.pvPower])
|
source.push([
|
||||||
})
|
item.statisDate,
|
||||||
this.chart.setOption({
|
item.gridPower,
|
||||||
grid: {
|
item.loadPower,
|
||||||
containLabel: true
|
item.storagePower,
|
||||||
},
|
item.pvPower,
|
||||||
legend: {
|
]);
|
||||||
left: 'center',
|
});
|
||||||
bottom: '15',
|
this.chart.setOption(
|
||||||
},
|
{
|
||||||
tooltip: {
|
grid: {
|
||||||
trigger: 'axis',
|
containLabel: true,
|
||||||
axisPointer: { // 坐标轴指示器,坐标轴触发有效
|
|
||||||
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
textStyle:{
|
|
||||||
color:"#333333",
|
|
||||||
},
|
|
||||||
xAxis: {
|
|
||||||
type: 'category',
|
|
||||||
},
|
|
||||||
yAxis: {
|
|
||||||
type: 'value',
|
|
||||||
},
|
|
||||||
dataset:{source},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
type: 'scatter',
|
|
||||||
},
|
},
|
||||||
{
|
legend: {
|
||||||
type: 'scatter',
|
left: "center",
|
||||||
|
bottom: "15",
|
||||||
},
|
},
|
||||||
{
|
tooltip: {
|
||||||
type: 'scatter',
|
trigger: "axis",
|
||||||
|
axisPointer: {
|
||||||
|
// 坐标轴指示器,坐标轴触发有效
|
||||||
|
type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
textStyle: {
|
||||||
type: 'scatter',
|
color: "#333333",
|
||||||
}
|
},
|
||||||
]
|
xAxis: {
|
||||||
},true)
|
type: "category",
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: "value",
|
||||||
|
},
|
||||||
|
dataset: { source },
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
type: "line",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "line",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "line",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "line",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
},
|
},
|
||||||
initChart() {
|
initChart() {
|
||||||
this.chart = echarts.init(document.querySelector('#glqxEchart'));
|
if (this.chart) return;
|
||||||
|
this.chart = echarts.init(document.querySelector("#glqxEchart"));
|
||||||
|
},
|
||||||
|
init() {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.dateRangeInit = true;
|
||||||
|
this.initChart();
|
||||||
|
this.$refs.dateRangeSelect.init();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
init(){
|
|
||||||
this.$nextTick(()=>{
|
|
||||||
this.initChart()
|
|
||||||
this.$refs.dateRangeSelect.init()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
if (!this.chart) {
|
if (!this.chart) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
this.chart.dispose()
|
this.chart.dispose();
|
||||||
this.chart = null
|
this.chart = null;
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -1,167 +1,207 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<el-card shadow="always" class="common-card-container time-range-card" style="margin-top:20px">
|
<el-card
|
||||||
|
shadow="always"
|
||||||
|
class="common-card-container time-range-card"
|
||||||
|
style="margin-top: 20px"
|
||||||
|
>
|
||||||
<div slot="header" class="time-range-header">
|
<div slot="header" class="time-range-header">
|
||||||
<span class="card-title">
|
<span class="card-title"> </span>
|
||||||
<el-button-group class="ems-btns-group">
|
<date-range-select ref="dateRangeSelect" @updateDate="updateDate" />
|
||||||
<el-button v-for="(item,index) in btnList" :key="index+'flqxcBtns'" size="mini" :class="{'activeBtn' : activeBtn === item.id}" @click="changeDataType(item.id)">{{item.name}}</el-button>
|
|
||||||
</el-button-group>
|
|
||||||
</span>
|
|
||||||
<date-range-select ref="dateRangeSelect" @updateDate="updateDate"/>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card-main" v-loading="loading">
|
<div class="card-main" v-loading="loading">
|
||||||
<div id="pcsEchart" style="height: 310px;"></div>
|
<el-button-group class="ems-btns-group">
|
||||||
|
<el-button
|
||||||
|
v-for="(item, index) in btnList"
|
||||||
|
:key="index + 'flqxcBtns'"
|
||||||
|
size="mini"
|
||||||
|
:class="{ activeBtn: activeBtn === item.id }"
|
||||||
|
@click="changeDataType(item.id)"
|
||||||
|
>{{ item.name }}</el-button
|
||||||
|
>
|
||||||
|
</el-button-group>
|
||||||
|
<div id="pcsEchart" style="height: 310px"></div>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as echarts from 'echarts'
|
import * as echarts from "echarts";
|
||||||
import resize from "@/mixins/ems/resize";
|
import resize from "@/mixins/ems/resize";
|
||||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||||
import { getPCSData, getPcsNameList} from '@/api/ems/dzjk'
|
import { getPCSData, getPcsNameList } from "@/api/ems/dzjk";
|
||||||
import {formatDate} from "@/filters/ems";
|
import { formatDate } from "@/filters/ems";
|
||||||
import DateRangeSelect from "@/components/Ems/DateRangeSelect/index.vue";
|
import DateRangeSelect from "@/components/Ems/DateRangeSelect/index.vue";
|
||||||
export default {
|
export default {
|
||||||
name:'DzjkTjbbPcsqx',
|
name: "DzjkTjbbPcsqx",
|
||||||
components: {DateRangeSelect},
|
components: { DateRangeSelect },
|
||||||
mixins: [resize,getQuerySiteId],
|
mixins: [resize, getQuerySiteId],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
pickerOptions:{
|
pickerOptions: {
|
||||||
disabledDate(time) {
|
disabledDate(time) {
|
||||||
return time.getTime() > Date.now();
|
return time.getTime() > Date.now();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
dateRange:[],
|
dateRange: [],
|
||||||
loading:false,
|
loading: false,
|
||||||
activeBtn:'1',
|
activeBtn: "1",
|
||||||
btnList:[
|
btnList: [
|
||||||
{name:'有功功率',id:'1',attr:['activePower'],source:['有功功率']},
|
{
|
||||||
{name:'无功功率',id:'2',attr:['reactivePower'],source:['无功功率']},
|
name: "有功功率",
|
||||||
{name:'三相电流',id:'3',attr:['uCurrent','vCurrent','wCurrent'],source:['u电流','v电流','w电流'],type:'bar'},
|
id: "1",
|
||||||
|
attr: ["activePower"],
|
||||||
|
source: ["有功功率"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "无功功率",
|
||||||
|
id: "2",
|
||||||
|
attr: ["reactivePower"],
|
||||||
|
source: ["无功功率"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "三相电流",
|
||||||
|
id: "3",
|
||||||
|
attr: ["uCurrent", "vCurrent", "wCurrent"],
|
||||||
|
source: ["u电流", "v电流", "w电流"],
|
||||||
|
type: "bar",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
|
};
|
||||||
}
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
changeDataType(id){
|
changeDataType(id) {
|
||||||
if(id !== this.activeBtn){
|
if (id !== this.activeBtn) {
|
||||||
console.log('点击了不同的菜单,更新数据')
|
console.log("点击了不同的菜单,更新数据");
|
||||||
this.activeBtn=id;
|
this.activeBtn = id;
|
||||||
this.getData()
|
this.getData();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 更新时间范围 重置图表
|
// 更新时间范围 重置图表
|
||||||
updateDate(data){
|
updateDate(data) {
|
||||||
this.dateRange=data || []
|
this.dateRange = data || [];
|
||||||
this.getData()
|
this.getData();
|
||||||
},
|
},
|
||||||
getData(){
|
getData() {
|
||||||
const {siteId,activeBtn}=this;
|
const { siteId, activeBtn } = this;
|
||||||
const [start='',end='']=(this.dateRange || [])
|
const [start = "", end = ""] = this.dateRange || [];
|
||||||
this.loading=true;
|
this.loading = true;
|
||||||
//接口调用完成之后 设置图表、结束loading
|
//接口调用完成之后 设置图表、结束loading
|
||||||
getPCSData({siteId,startTime:formatDate(start),endTime:formatDate(end),dataType:activeBtn}).then(response => {
|
getPCSData({
|
||||||
this.setOption(response?.data || [])
|
siteId,
|
||||||
}).finally(()=>{this.loading=false;})
|
startTime: formatDate(start),
|
||||||
|
endTime: formatDate(end),
|
||||||
|
dataType: activeBtn,
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
this.setOption(response?.data || []);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
compareDate(date1,date2){
|
compareDate(date1, date2) {
|
||||||
console.log('比较时间',date1,date2)
|
console.log("比较时间", date1, date2);
|
||||||
// 年2025-09/天2025-09-15/时2025-09-15/10:00
|
// 年2025-09/天2025-09-15/时2025-09-15/10:00
|
||||||
if(date1.indexOf(':') > -1 && date2.indexOf(':') > -1){
|
if (date1.indexOf(":") > -1 && date2.indexOf(":") > -1) {
|
||||||
return parseInt(date1) - parseInt(date2)
|
return parseInt(date1) - parseInt(date2);
|
||||||
}
|
}
|
||||||
const [date1_Y='',date1_M='',date1_D=''] = date1.split('-')//根据空格区分[年月日,小时]
|
const [date1_Y = "", date1_M = "", date1_D = ""] = date1.split("-"); //根据空格区分[年月日,小时]
|
||||||
const [date2_Y='',date2_M='',date2_D=''] = date2.split('-')//根据空格区分[年月日,小时]
|
const [date2_Y = "", date2_M = "", date2_D = ""] = date2.split("-"); //根据空格区分[年月日,小时]
|
||||||
return (date1_Y === date2_Y && date1_M === date2_M && date1_D - date2_D) || (date1_Y === date2_Y && date1_M - date2_M) || date1_Y - date2_Y
|
return (
|
||||||
|
(date1_Y === date2_Y && date1_M === date2_M && date1_D - date2_D) ||
|
||||||
|
(date1_Y === date2_Y && date1_M - date2_M) ||
|
||||||
|
date1_Y - date2_Y
|
||||||
|
);
|
||||||
},
|
},
|
||||||
setOption(data) {
|
setOption(data) {
|
||||||
const ele = this.btnList.find((item)=>{return item.id === this.activeBtn})
|
const ele = this.btnList.find((item) => {
|
||||||
const sourceBase = JSON.parse(JSON.stringify(ele.source))
|
return item.id === this.activeBtn;
|
||||||
|
});
|
||||||
|
const sourceBase = JSON.parse(JSON.stringify(ele.source));
|
||||||
// sourceBase={name:'堆平均维度',id:'1',attr:['temp'],source:['有功功率']},
|
// sourceBase={name:'堆平均维度',id:'1',attr:['temp'],source:['有功功率']},
|
||||||
const source=[]
|
const source = [];
|
||||||
const sourceTop = ['日期']
|
const sourceTop = ["日期"];
|
||||||
let map={},mapArr=[]
|
let map = {},
|
||||||
|
mapArr = [];
|
||||||
// 生成所有{日期:[],日期:[]}格式的对象和所有包含所有日期的[日期1,日期2...]
|
// 生成所有{日期:[],日期:[]}格式的对象和所有包含所有日期的[日期1,日期2...]
|
||||||
data.forEach((item)=>{
|
data.forEach((item) => {
|
||||||
item.dataList.forEach((inner)=>{
|
item.dataList.forEach((inner) => {
|
||||||
// 日期格式
|
// 日期格式
|
||||||
// 年2025-09/天2025-09-15/时2025-09-15/10:00
|
// 年2025-09/天2025-09-15/时2025-09-15/10:00
|
||||||
// 所有数据的日期格式一致
|
// 所有数据的日期格式一致
|
||||||
if(!map[inner.statisDate]) {
|
if (!map[inner.statisDate]) {
|
||||||
map[inner.statisDate] = []
|
map[inner.statisDate] = [];
|
||||||
mapArr.push(inner.statisDate)
|
mapArr.push(inner.statisDate);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
data.forEach((item,itemIndex)=>{
|
data.forEach((item, itemIndex) => {
|
||||||
const dataTimeList = item.dataList.map(i =>i.statisDate)
|
const dataTimeList = item.dataList.map((i) => i.statisDate);
|
||||||
const noDataTime = mapArr.filter(i=>!dataTimeList.includes(i))
|
const noDataTime = mapArr.filter((i) => !dataTimeList.includes(i));
|
||||||
sourceBase.forEach((outer,outerIndex)=>{
|
sourceBase.forEach((outer, outerIndex) => {
|
||||||
sourceTop.push(`${item.deviceId}-${outer}`)
|
sourceTop.push(`${item.deviceId}-${outer}`);
|
||||||
noDataTime.forEach(i=>map[i].push(''))
|
noDataTime.forEach((i) => map[i].push(""));
|
||||||
item.dataList.forEach((inner,innerIndex)=>{
|
item.dataList.forEach((inner, innerIndex) => {
|
||||||
map[inner.statisDate].push(inner[ele.attr[outerIndex]])
|
map[inner.statisDate].push(inner[ele.attr[outerIndex]]);
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
mapArr = mapArr.sort((a,b)=>this.compareDate(a,b))
|
mapArr = mapArr.sort((a, b) => this.compareDate(a, b));
|
||||||
mapArr.forEach(item=>{
|
mapArr.forEach((item) => {
|
||||||
source.push([item,...map[item]])
|
source.push([item, ...map[item]]);
|
||||||
})
|
});
|
||||||
source.unshift(sourceTop)
|
source.unshift(sourceTop);
|
||||||
console.log('map=',map)
|
this.chart.setOption(
|
||||||
console.log('mapArr=',mapArr)
|
{
|
||||||
console.log('========',source)
|
grid: {
|
||||||
this.chart.setOption({
|
containLabel: true,
|
||||||
grid: {
|
},
|
||||||
containLabel: true
|
legend: {
|
||||||
|
left: "center",
|
||||||
|
bottom: "15",
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: "axis",
|
||||||
|
axisPointer: {
|
||||||
|
// 坐标轴指示器,坐标轴触发有效
|
||||||
|
type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
textStyle: {
|
||||||
|
color: "#333333",
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: "category",
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: "value",
|
||||||
|
},
|
||||||
|
dataset: { source },
|
||||||
|
series: source[0].slice(1).map((item) => {
|
||||||
|
return {
|
||||||
|
type: "line",
|
||||||
|
};
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
legend: {
|
true
|
||||||
left: 'center',
|
);
|
||||||
bottom: '15',
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'axis',
|
|
||||||
axisPointer: { // 坐标轴指示器,坐标轴触发有效
|
|
||||||
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
textStyle:{
|
|
||||||
color:"#333333",
|
|
||||||
},
|
|
||||||
xAxis: {
|
|
||||||
type: 'category',
|
|
||||||
},
|
|
||||||
yAxis: {
|
|
||||||
type: 'value',
|
|
||||||
},
|
|
||||||
dataset: {source},
|
|
||||||
series:source[0].slice(1).map(item=>{
|
|
||||||
return {
|
|
||||||
type:ele.type || 'scatter'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
},true)
|
|
||||||
},
|
},
|
||||||
initChart() {
|
initChart() {
|
||||||
this.chart = echarts.init(document.querySelector('#pcsEchart'));
|
this.chart = echarts.init(document.querySelector("#pcsEchart"));
|
||||||
|
},
|
||||||
|
init() {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.initChart();
|
||||||
|
this.$refs.dateRangeSelect.init();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
init(){
|
|
||||||
this.$nextTick(()=>{
|
|
||||||
this.initChart()
|
|
||||||
this.$refs.dateRangeSelect.init()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
if (!this.chart) {
|
if (!this.chart) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
this.chart.dispose()
|
this.chart.dispose();
|
||||||
this.chart = null
|
this.chart = null;
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -34,10 +34,10 @@
|
|||||||
<div
|
<div
|
||||||
class="status"
|
class="status"
|
||||||
:class="
|
:class="
|
||||||
item.communicationStatus === '0' ? 'status-running' : ''
|
item.runningStatus === '2' ? 'status-running' : ''
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
{{ communicationStatusOptions[item.communicationStatus] }}
|
{{ deviceStatusOptions[item.runningStatus] }}
|
||||||
</div>
|
</div>
|
||||||
<div class="row-items-img">
|
<div class="row-items-img">
|
||||||
<img
|
<img
|
||||||
@ -68,10 +68,10 @@
|
|||||||
<div
|
<div
|
||||||
class="status"
|
class="status"
|
||||||
:class="
|
:class="
|
||||||
item.communicationStatus === '0' ? 'status-running' : ''
|
item.runningStatus === '2' ? 'status-running' : ''
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
{{ communicationStatusOptions[item.communicationStatus] }}
|
{{ deviceStatusOptions[item.runningStatus] }}
|
||||||
</div>
|
</div>
|
||||||
<div class="row-items-img">
|
<div class="row-items-img">
|
||||||
<img
|
<img
|
||||||
@ -107,10 +107,10 @@
|
|||||||
<div
|
<div
|
||||||
class="status"
|
class="status"
|
||||||
:class="
|
:class="
|
||||||
item.communicationStatus === '0' ? 'status-running' : ''
|
item.runningStatus === '2' ? 'status-running' : ''
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
{{ communicationStatusOptions[item.communicationStatus] }}
|
{{ deviceStatusOptions[item.runningStatus] }}
|
||||||
</div>
|
</div>
|
||||||
<div class="row-items-img row-items-img-bms">
|
<div class="row-items-img row-items-img-bms">
|
||||||
<div style="position:relative;">
|
<div style="position:relative;">
|
||||||
@ -150,10 +150,10 @@
|
|||||||
<div
|
<div
|
||||||
class="status"
|
class="status"
|
||||||
:class="
|
:class="
|
||||||
item.communicationStatus === '0' ? 'status-running' : ''
|
item.runningStatus === '2' ? 'status-running' : ''
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
{{ communicationStatusOptions[item.communicationStatus] }}
|
{{ deviceStatusOptions[item.runningStatus] }}
|
||||||
</div>
|
</div>
|
||||||
<div class="row-items-img">
|
<div class="row-items-img">
|
||||||
<img
|
<img
|
||||||
@ -171,14 +171,14 @@
|
|||||||
<div
|
<div
|
||||||
class="status"
|
class="status"
|
||||||
:class="
|
:class="
|
||||||
item.children[0].communicationStatus === '0'
|
item.children[0].runningStatus === '2'
|
||||||
? 'status-running'
|
? 'status-running'
|
||||||
: ''
|
: ''
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
communicationStatusOptions[
|
deviceStatusOptions[
|
||||||
item.children[0].communicationStatus
|
item.children[0].runningStatus
|
||||||
]
|
]
|
||||||
}}
|
}}
|
||||||
</div>
|
</div>
|
||||||
@ -222,8 +222,8 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
...mapState({
|
||||||
communicationStatusOptions: (state) =>
|
deviceStatusOptions: (state) =>
|
||||||
state.ems.communicationStatusOptions,
|
state.ems.deviceStatusOptions,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
showPcs() {
|
showPcs() {
|
||||||
|
|||||||
@ -32,7 +32,7 @@ export default {
|
|||||||
return this.dataUnit === 3 ? 'daterange' : 'datetimerange'
|
return this.dataUnit === 3 ? 'daterange' : 'datetimerange'
|
||||||
},
|
},
|
||||||
valueFormat(){
|
valueFormat(){
|
||||||
return this.dataUnit === 3 ? 'yyyy-MM-dd' :this.dataUnit === 2 ? 'yyyy-MM-dd HH:mm' : 'yyyy-MM-dd HH:mm:ss'
|
return this.dataUnit === 3 ? 'yyyy-MM-dd' : 'yyyy-MM-dd HH:mm:ss'
|
||||||
},
|
},
|
||||||
disabledNextBtn(){
|
disabledNextBtn(){
|
||||||
if(this.dateRange && this.dateRange.length ===2){
|
if(this.dateRange && this.dateRange.length ===2){
|
||||||
@ -83,31 +83,32 @@ export default {
|
|||||||
if(this.dateRange && this.dateRange.length>0){
|
if(this.dateRange && this.dateRange.length>0){
|
||||||
const {dataUnit} = this
|
const {dataUnit} = this
|
||||||
const [start,end] = this.dateRange
|
const [start,end] = this.dateRange
|
||||||
const startTime = new Date(start),endTime=new Date(end)
|
if([1,2].includes(dataUnit)){
|
||||||
const timeDis= dataUnit === 3? 30 * 24 * 60 * 60 * 1000 :dataUnit === 2 ? 24 * 60 * 60 * 1000 : 60 * 60 * 1000
|
const startTime = new Date(start),endTime=new Date(end)
|
||||||
if(endTime - startTime > timeDis){
|
const timeDis= 7 * 24 * 60 * 60 * 1000
|
||||||
this.$message.error(`时间范围不能超过${dataUnit === 3 ? '30天' : dataUnit === 2 ? '24小时' : '1小时'}`)
|
if(endTime - startTime > timeDis){
|
||||||
}else{
|
this.$message.error(`按分钟或小时查询数据,时间范围不能超过7天`)
|
||||||
this.$emit('updateDate',this.dateRange || [])
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
this.$emit('updateDate',this.dateRange || [])
|
||||||
}else{
|
}else{
|
||||||
this.$emit('updateDate',this.dateRange || [])
|
this.$emit('updateDate',this.dateRange || [])
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
timeLine(type){
|
timeLine(type){
|
||||||
if(!this.dateRange) return
|
if(!this.dateRange || !this.dateRange[0] || !this.dateRange[1]) return
|
||||||
|
const nowStartTimes = new Date(this.dateRange[0]).getTime(),nowEndTimes = new Date(this.dateRange[1]).getTime(),maxTime = new Date(this.defaultDateRange[1]).getTime()
|
||||||
|
const nowDis = nowEndTimes - nowStartTimes//用户当前选择时间差 可能=0
|
||||||
//baseTime,maxTime 毫秒数
|
//baseTime,maxTime 毫秒数
|
||||||
const baseTimes= this.dataUnit === 3 ? 24 * 60 * 60 * 1000 :this.dataUnit === 2 ? 60 * 60 * 1000 : 60 * 1000
|
const baseDis = this.dataUnit === 3 ? 24 * 60 * 60 * 1000 :60 * 60 * 1000
|
||||||
const baseDis = this.dataUnit === 3 ? 30 :this.dataUnit === 2 ? 24 : 60
|
const calcDis = nowDis === 0 ? baseDis : nowDis
|
||||||
let baseTime = type === 'before' ? new Date(this.dateRange[0]).getTime() - baseTimes :new Date(this.dateRange[1]).getTime() + baseTimes ,
|
let start = type === 'before' ? nowStartTimes - calcDis : nowStartTimes + calcDis
|
||||||
maxTime = new Date(this.defaultDateRange[1]).getTime()
|
if(start>maxTime) start=maxTime
|
||||||
//updateTime 毫秒数
|
let end = type === 'before' ? nowEndTimes - calcDis : nowEndTimes + calcDis
|
||||||
let updateTime = type === 'before' ? baseTime - baseDis * baseTimes : baseTime + baseDis * baseTimes
|
if(end>maxTime) end=maxTime
|
||||||
if(type === 'next' && updateTime >= maxTime) updateTime = maxTime
|
this.dateRange = [formatDate(start,this.dataUnit !== 3),formatDate(end,this.dataUnit !== 3)]
|
||||||
const start = formatDate(type === 'before' ? updateTime : baseTime,this.dataUnit !== 3)
|
this.$emit('updateDate',this.dateRange)
|
||||||
const end = formatDate(type === 'before' ? baseTime : updateTime,this.dataUnit !== 3)
|
|
||||||
this.dateRange = [start,end]
|
|
||||||
this.$emit('updateDate',this.dateRange || [])
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,56 +1,79 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-loading="loading" class="ems-dashboard-editor-container" style="background-color: #ffffff">
|
<div
|
||||||
|
v-loading="loading"
|
||||||
|
class="ems-dashboard-editor-container"
|
||||||
|
style="background-color: #ffffff"
|
||||||
|
>
|
||||||
<el-form ref="form" :model="form" label-position="top">
|
<el-form ref="form" :model="form" label-position="top">
|
||||||
<el-form-item
|
<el-form-item
|
||||||
label="站点"
|
label="站点"
|
||||||
prop="siteIds"
|
prop="siteIds"
|
||||||
:rules="[{ required: true, message: '请选择站点' }]"
|
:rules="[{ required: true, message: '请选择站点' }]"
|
||||||
>
|
>
|
||||||
<el-radio-group v-model="form.siteIds" >
|
<el-radio-group v-model="form.siteIds" @input="changeSiteIds">
|
||||||
<el-radio v-for="(item,index) in siteList" :key="index+'zdListSearch'" :label="item.siteId">
|
<el-radio
|
||||||
|
v-for="(item, index) in siteList"
|
||||||
|
:key="index + 'zdListSearch'"
|
||||||
|
:label="item.siteId"
|
||||||
|
>
|
||||||
{{ item.siteName }}
|
{{ item.siteName }}
|
||||||
</el-radio>
|
</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="设备" prop="categoryName" :rules="[{ required: true, message: '请选择设备' }]">
|
<el-form-item
|
||||||
<el-radio-group v-model="form.categoryName" >
|
label="设备"
|
||||||
<el-radio v-for="(key,index) in deviceCategoryList" :key="index+'sbListSearch'" :label="key">
|
prop="deviceCategory"
|
||||||
{{ key }}
|
:rules="[{ required: true, message: '请选择设备' }]"
|
||||||
|
>
|
||||||
|
<el-radio-group v-model="form.deviceCategory" @input="changeSiteIds">
|
||||||
|
<el-radio
|
||||||
|
v-for="(item, index) in deviceCategoryList"
|
||||||
|
:key="index + 'sbListSearch'"
|
||||||
|
:label="item.code"
|
||||||
|
>
|
||||||
|
{{ item.name }}
|
||||||
</el-radio>
|
</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-if="isDtdc" label="单体电池(不超过5个)" prop="child" :rules="[{ required: true, message: '请选择单体电池' }]">
|
<el-form-item
|
||||||
|
v-if="isDtdc"
|
||||||
|
label="单体电池(不超过5个)"
|
||||||
|
prop="child"
|
||||||
|
:rules="[{ required: true, message: '请选择单体电池' }]"
|
||||||
|
>
|
||||||
<el-cascader
|
<el-cascader
|
||||||
v-model="form.child"
|
v-model="form.child"
|
||||||
style="width:400px"
|
style="width: 400px"
|
||||||
:props="{ multiple: true }"
|
:props="{ multiple: true }"
|
||||||
:show-all-levels="false"
|
:show-all-levels="false"
|
||||||
:options="childOptions"
|
:options="childOptions"
|
||||||
@change="handleChildChange"></el-cascader>
|
@change="handleChildChange"
|
||||||
|
></el-cascader>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<div style="display: flex">
|
<div style="display: flex">
|
||||||
<el-form-item label="点位" prop="pointName" :rules="[{ required: true, message: '请输入点位' }]" style="margin-right: 50px">
|
<el-form-item
|
||||||
|
label="点位"
|
||||||
|
prop="pointName"
|
||||||
|
:rules="[{ required: true, message: '请输入点位' }]"
|
||||||
|
style="margin-right: 50px"
|
||||||
|
>
|
||||||
<el-autocomplete
|
<el-autocomplete
|
||||||
v-model="form.pointName"
|
v-model="form.pointName"
|
||||||
placeholder="请输入点位"
|
placeholder="请输入点位"
|
||||||
clearable
|
clearable
|
||||||
:fetch-suggestions="querySearchAsync"
|
:fetch-suggestions="querySearchAsync"
|
||||||
@select="handleSelect"
|
@select="handleSelect"
|
||||||
></el-autocomplete>
|
></el-autocomplete>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- <el-form-item label="横坐标" prop="dataUnit" :rules="[{ required: true, message: '请选择横坐标' }]">-->
|
|
||||||
<!-- <el-radio-group v-model="form.dataUnit">-->
|
|
||||||
<!-- <el-radio :label="1">分钟</el-radio>-->
|
|
||||||
<!-- <el-radio :label="2">小时</el-radio>-->
|
|
||||||
<!-- <el-radio :label="3">天</el-radio>-->
|
|
||||||
<!-- </el-radio-group>-->
|
|
||||||
<!-- </el-form-item>-->
|
|
||||||
</div>
|
</div>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" @click="submitForm">生成图表</el-button>
|
<el-button type="primary" @click="submitForm">生成图表</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding time-range-card">
|
<el-card
|
||||||
|
shadow="always"
|
||||||
|
class="common-card-container common-card-container-body-no-padding time-range-card"
|
||||||
|
>
|
||||||
<div slot="header" class="time-range-header">
|
<div slot="header" class="time-range-header">
|
||||||
<span class="card-title">
|
<span class="card-title">
|
||||||
<el-radio-group v-model="form.dataUnit">
|
<el-radio-group v-model="form.dataUnit">
|
||||||
@ -59,7 +82,12 @@
|
|||||||
<el-radio :label="3">天</el-radio>
|
<el-radio :label="3">天</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</span>
|
</span>
|
||||||
<date-time-select ref="dateTimeSelect" :data-unit="form.dataUnit" @initDate="((e)=>form.dataRange=e||[])" @updateDate="updateDate"/>
|
<date-time-select
|
||||||
|
ref="dateTimeSelect"
|
||||||
|
:data-unit="form.dataUnit"
|
||||||
|
@initDate="(e) => (form.dataRange = e || [])"
|
||||||
|
@updateDate="updateDate"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div style="height: 350px" id="searchChart"></div>
|
<div style="height: 350px" id="searchChart"></div>
|
||||||
</el-card>
|
</el-card>
|
||||||
@ -67,274 +95,356 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as echarts from 'echarts'
|
import * as echarts from "echarts";
|
||||||
import resize from '@/mixins/ems/resize'
|
import resize from "@/mixins/ems/resize";
|
||||||
import {getAllSites} from "@/api/ems/zddt";
|
import { getAllSites } from "@/api/ems/zddt";
|
||||||
import {getAllDeviceCategory,getPointValueList,pointFuzzyQuery,getAllBatteryIdsBySites} from '@/api/ems/search'
|
import {
|
||||||
|
getAllDeviceCategory,
|
||||||
|
getPointValueList,
|
||||||
|
pointFuzzyQuery,
|
||||||
|
getAllBatteryIdsBySites,
|
||||||
|
} from "@/api/ems/search";
|
||||||
import DateTimeSelect from "./DateTimeSelect.vue";
|
import DateTimeSelect from "./DateTimeSelect.vue";
|
||||||
export default {
|
export default {
|
||||||
name: "Search",
|
name: "Search",
|
||||||
mixins: [resize],
|
mixins: [resize],
|
||||||
components:{DateTimeSelect},
|
components: { DateTimeSelect },
|
||||||
computed: {
|
computed: {
|
||||||
isDtdc(){
|
isDtdc() {
|
||||||
return this.form.categoryName === '单体电池'
|
return this.form.deviceCategory === "BATTERY";
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
watch:{
|
watch: {
|
||||||
'form.siteIds':{
|
"form.siteIds": {
|
||||||
handler(newVal){
|
handler(newVal) {
|
||||||
newVal && this.isDtdc && this.getChildList()
|
newVal && this.isDtdc && this.getChildList();
|
||||||
}
|
|
||||||
},
|
|
||||||
isDtdc:{
|
|
||||||
handler(newVal){
|
|
||||||
newVal && this.form.siteIds && this.getChildList()
|
|
||||||
!newVal && (this.form.child = [])
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'form.dataUnit':{
|
|
||||||
handler(newVal,oldVal){
|
|
||||||
console.log('wacth到了dataUnit的变化',newVal,oldVal)
|
|
||||||
this.$nextTick(()=>{
|
|
||||||
this.$refs.dateTimeSelect.init()
|
|
||||||
this.getDate()
|
|
||||||
})
|
|
||||||
// this.submitForm()
|
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
|
isDtdc: {
|
||||||
|
handler(newVal) {
|
||||||
|
newVal && this.form.siteIds && this.getChildList();
|
||||||
|
!newVal && (this.form.child = []);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"form.dataUnit": {
|
||||||
|
handler(newVal, oldVal) {
|
||||||
|
console.log("wacth到了dataUnit的变化", newVal, oldVal);
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.dateTimeSelect.init();
|
||||||
|
this.getDate();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
chart: null,
|
chart: null,
|
||||||
deviceCategoryList:[],//设备列表
|
deviceCategoryList: [], //设备列表
|
||||||
siteList: [],//站点列表
|
siteList: [], //站点列表
|
||||||
childOptions:[],//二级设备列表
|
childOptions: [], //二级设备列表
|
||||||
form: {
|
form: {
|
||||||
dataRange:[],//时间选择范围
|
dataRange: [], //时间选择范围
|
||||||
child:[],
|
child: [],
|
||||||
siteIds: '',//当前选中的站点id 默认选中第一个站点
|
siteIds: "", //当前选中的站点id 默认选中第一个站点
|
||||||
categoryName: '',//设备
|
deviceCategory: "", //设备
|
||||||
pointName: '',//点位
|
pointName: "", //点位
|
||||||
dataUnit: 1,//横坐标
|
dataUnit: 1, //横坐标
|
||||||
},
|
},
|
||||||
loading: false,
|
loading: false,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getChildList(){
|
changeSiteIds(val) {
|
||||||
this.childOptions=[]
|
console.log("切换站点或设备清空点位", val);
|
||||||
this.form.child=[]
|
val && (this.form.pointName = "");
|
||||||
const {siteIds} = this.form
|
},
|
||||||
getAllBatteryIdsBySites([siteIds]).then(response=>{
|
getChildList() {
|
||||||
|
this.childOptions = [];
|
||||||
|
this.form.child = [];
|
||||||
|
const { siteIds } = this.form;
|
||||||
|
getAllBatteryIdsBySites([siteIds]).then((response) => {
|
||||||
const data = response?.data || {};
|
const data = response?.data || {};
|
||||||
const base = 50
|
const base = 50;
|
||||||
let options = []
|
let options = [];
|
||||||
Object.entries(data).forEach(([key,value],index)=>{
|
Object.entries(data).forEach(([key, value], index) => {
|
||||||
if(!value) value =[]
|
if (!value) value = [];
|
||||||
options.push({
|
options.push({
|
||||||
value: key,
|
value: key,
|
||||||
label: this.siteList.find(s=>s.siteId === key)?.siteName || '',
|
label: this.siteList.find((s) => s.siteId === key)?.siteName || "",
|
||||||
children:[]
|
children: [],
|
||||||
})
|
});
|
||||||
const length = value.length
|
const length = value.length;
|
||||||
const num = Math.ceil(length /base )
|
const num = Math.ceil(length / base);
|
||||||
if(num === 0) return
|
if (num === 0) return;
|
||||||
for(let i = 1; i <= num; i++){
|
for (let i = 1; i <= num; i++) {
|
||||||
const start = (i-1)*base+1,end = i*base
|
const start = (i - 1) * base + 1,
|
||||||
|
end = i * base;
|
||||||
options[index].children.push({
|
options[index].children.push({
|
||||||
value:i,
|
value: i,
|
||||||
label: `${start}-${end}`,
|
label: `${start}-${end}`,
|
||||||
children:[]
|
children: [],
|
||||||
})
|
});
|
||||||
for(let s = start;s<=Math.min(length,end);s++){
|
for (let s = start; s <= Math.min(length, end); s++) {
|
||||||
options[index].children[i-1].children.push({
|
options[index].children[i - 1].children.push({
|
||||||
value:value[s-1],
|
value: value[s - 1],
|
||||||
label:value[s-1]
|
label: value[s - 1],
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
console.log('二级设备options',options)
|
console.log("二级设备options", options);
|
||||||
this.childOptions = options;
|
this.childOptions = options;
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
handleChildChange(data){
|
handleChildChange(data) {
|
||||||
console.log('选择二级设备',data)
|
console.log("选择二级设备", data);
|
||||||
this.form.child=data
|
this.form.child = data;
|
||||||
},
|
},
|
||||||
showLoading(){
|
showLoading() {
|
||||||
this.chart && this.chart.showLoading()
|
this.chart && this.chart.showLoading();
|
||||||
},
|
},
|
||||||
hideLoading(){
|
hideLoading() {
|
||||||
this.chart && this.chart.hideLoading()
|
this.chart && this.chart.hideLoading();
|
||||||
},
|
},
|
||||||
initChart() {
|
initChart() {
|
||||||
this.chart = echarts.init(document.querySelector('#searchChart'))
|
this.chart = echarts.init(document.querySelector("#searchChart"));
|
||||||
},
|
},
|
||||||
updateDate(val){
|
updateDate(val) {
|
||||||
this.form.dataRange =val || []
|
this.form.dataRange = val || [];
|
||||||
this.getDate()
|
this.getDate();
|
||||||
},
|
},
|
||||||
setOption(data) {
|
setOption(data) {
|
||||||
if(!this.chart) return
|
if (!this.chart) return;
|
||||||
this.chart.clear()
|
this.chart.clear();
|
||||||
console.log('返回的数据',data)
|
console.log("返回的数据", data);
|
||||||
let dataset=[]
|
let dataset = [];
|
||||||
if(data.length>0){
|
if (data.length > 0) {
|
||||||
data.forEach((item,index)=>{
|
data.forEach((item, index) => {
|
||||||
item.deviceList.forEach(inner=>{
|
item.deviceList.forEach((inner) => {
|
||||||
dataset.push({
|
dataset.push({
|
||||||
name:`${this.isDtdc ? `${inner.parentDeviceId ? inner.parentDeviceId+'-' : ''}` : ''}${inner.deviceId}`,
|
name: `${
|
||||||
type:'line',
|
this.isDtdc
|
||||||
xdata:[],
|
? `${inner.parentDeviceId ? inner.parentDeviceId + "-" : ""}`
|
||||||
data:[]
|
: ""
|
||||||
})
|
}${inner.deviceId}`,
|
||||||
const length = dataset.length
|
type: "line",
|
||||||
inner.pointValueList.forEach(value=>{
|
markPoint: {
|
||||||
dataset[length-1].xdata.push(value.valueDate)
|
symbolSize: 30,
|
||||||
dataset[length-1].data.push(value.pointValue)
|
emphasis: {
|
||||||
})
|
disabled:false//打开 鼠标高亮
|
||||||
})
|
},
|
||||||
})
|
data: [//最大值、最小值
|
||||||
}else{
|
{
|
||||||
this.$message.warning('暂无数据')
|
// type: 'max',
|
||||||
|
name: `最大值`,
|
||||||
|
coord:[inner.maxDate,inner.maxValue],
|
||||||
|
relativeTo:'coordinate',
|
||||||
|
label: {
|
||||||
|
position: "top",
|
||||||
|
formatter: item.dataType === 2 ? ([
|
||||||
|
`最大值:${inner.maxValue}`,
|
||||||
|
// `平均值:${inner.avgValue}`,
|
||||||
|
`差值:${inner.diffValue}`,
|
||||||
|
]).join('\n') : ([
|
||||||
|
`最大值:${inner.maxValue}`,
|
||||||
|
// `平均值:${inner.avgValue}`,
|
||||||
|
]).join('\n'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// type: 'min',
|
||||||
|
name: `最小值`,
|
||||||
|
coord:[inner.minDate,inner.minValue],
|
||||||
|
relativeTo:'coordinate',
|
||||||
|
label: {
|
||||||
|
position: "top",
|
||||||
|
formatter: item.dataType === 2 ? ([
|
||||||
|
`最小值:${inner.minValue}`,
|
||||||
|
// `平均值:${inner.avgValue}`,
|
||||||
|
`差值:${inner.diffValue}`,
|
||||||
|
]).join('\n') : ([
|
||||||
|
`最小值:${inner.minValue}`,
|
||||||
|
// `平均值:${inner.avgValue}`,
|
||||||
|
]).join('\n'),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
xdata: [],
|
||||||
|
data: [],
|
||||||
|
});
|
||||||
|
const length = dataset.length;
|
||||||
|
inner.pointValueList.forEach((value) => {
|
||||||
|
dataset[length - 1].xdata.push(value.valueDate);
|
||||||
|
dataset[length - 1].data.push(value.pointValue);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.$message.warning("暂无数据");
|
||||||
}
|
}
|
||||||
console.log('图表数据',dataset)
|
console.log("图表数据", dataset);
|
||||||
this.chart.setOption({
|
this.chart.setOption({
|
||||||
legend: {
|
legend: {
|
||||||
// left: 'center',
|
// left: 'center',
|
||||||
// top: '10',
|
// top: '10',
|
||||||
},
|
},
|
||||||
grid: {
|
grid: {
|
||||||
containLabel: true
|
containLabel: true,
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
trigger: 'axis',
|
trigger: "axis",
|
||||||
axisPointer: { // 坐标轴指示器,坐标轴触发有效
|
axisPointer: {
|
||||||
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
|
type: 'cross',
|
||||||
}
|
},
|
||||||
|
// axisPointer: {
|
||||||
|
// // 坐标轴指示器,坐标轴触发有效
|
||||||
|
// type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
|
||||||
|
// },
|
||||||
},
|
},
|
||||||
textStyle:{
|
textStyle: {
|
||||||
color:"#333333",
|
color: "#333333",
|
||||||
},
|
},
|
||||||
xAxis: {type:'category',data:dataset?.[0]?.xdata || []},
|
xAxis: { type: "category", data: dataset?.[0]?.xdata || [] },
|
||||||
yAxis: {
|
yAxis: {
|
||||||
type: 'value',
|
type: "value",
|
||||||
},
|
},
|
||||||
dataZoom: [
|
dataZoom: [
|
||||||
{
|
{
|
||||||
type: 'inside',
|
type: "inside",
|
||||||
start: 0,
|
start: 0,
|
||||||
end: 100
|
end: 100,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
start: 0,
|
start: 0,
|
||||||
end: 100
|
end: 100,
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
series: dataset
|
series: dataset,
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
submitForm() {
|
submitForm() {
|
||||||
this.getDate()
|
this.getDate();
|
||||||
},
|
},
|
||||||
handleSelect(data){
|
handleSelect(data) {
|
||||||
this.form.pointName = data.value
|
this.form.pointName = data.value;
|
||||||
},
|
},
|
||||||
querySearchAsync(query,cb){
|
querySearchAsync(query, cb) {
|
||||||
console.log('查询数据',query)
|
console.log("查询数据", query);
|
||||||
if(!this.form.siteIds || !this.form.categoryName){
|
if (!this.form.siteIds || !this.form.deviceCategory) {
|
||||||
this.$message({
|
this.$message({
|
||||||
type: 'warning',
|
type: "warning",
|
||||||
message: '请先选择站点和设备',
|
message: "请先选择站点和设备",
|
||||||
})
|
});
|
||||||
return cb([])
|
return cb([]);
|
||||||
}
|
}
|
||||||
pointFuzzyQuery({
|
pointFuzzyQuery({
|
||||||
siteIds:[this.form.siteIds],
|
siteIds: [this.form.siteIds],
|
||||||
categoryName:this.form.categoryName,
|
deviceCategory: this.form.deviceCategory,
|
||||||
pointName:query,
|
pointName: query,
|
||||||
}).then(response => {
|
}).then((response) => {
|
||||||
const data = response?.data || []
|
const data = response?.data || [];
|
||||||
cb(data.map(item => {
|
cb(
|
||||||
return {name: item, value: item}
|
data.map((item) => {
|
||||||
}))
|
return { name: item, value: item };
|
||||||
})
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
// 获取所有设备
|
// 获取所有设备
|
||||||
getDeviceCategory(){
|
getDeviceCategory() {
|
||||||
return getAllDeviceCategory().then(response => {
|
return getAllDeviceCategory().then((response) => {
|
||||||
this.deviceCategoryList=response?.data || []
|
this.deviceCategoryList = response?.data || [];
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
getZdList() {
|
getZdList() {
|
||||||
return getAllSites().then(response => {
|
return getAllSites()
|
||||||
this.siteList = response.data || []
|
.then((response) => {
|
||||||
}).finally(() => {
|
this.siteList = response.data || [];
|
||||||
})
|
})
|
||||||
|
.finally(() => {});
|
||||||
},
|
},
|
||||||
getDate(){
|
getDate() {
|
||||||
this.$refs.form.validate(valid => {
|
this.$refs.form.validate((valid) => {
|
||||||
if(valid){
|
if (valid) {
|
||||||
if(!this.form.pointName){
|
if (!this.form.pointName) {
|
||||||
return this.$message.error('请输入正确的点位');
|
return this.$message.error("请输入正确的点位");
|
||||||
}
|
}
|
||||||
if(this.isDtdc && (this.form.child.length === 0 || this.form.child.length > 5 )){
|
if (
|
||||||
return this.$message.error('请选择单体电池且不能超过5个');
|
this.isDtdc &&
|
||||||
|
(this.form.child.length === 0 || this.form.child.length > 5)
|
||||||
|
) {
|
||||||
|
return this.$message.error("请选择单体电池且不能超过5个");
|
||||||
}
|
}
|
||||||
this.loading = true
|
const {
|
||||||
const{siteIds,dataUnit,categoryName,pointName,dataRange:[start='',end=''],child}=this.form
|
siteIds,
|
||||||
let siteDeviceMap={}
|
dataUnit,
|
||||||
child.forEach(([first,second,third])=>{
|
deviceCategory,
|
||||||
if(siteDeviceMap[first]){
|
pointName,
|
||||||
siteDeviceMap[first].push(third)
|
dataRange: [start = "", end = ""],
|
||||||
}else{
|
child,
|
||||||
siteDeviceMap[first]=[]
|
} = this.form;
|
||||||
siteDeviceMap[first].push(third)
|
if (!start || !end) return this.$message.error("请选择时间");
|
||||||
}
|
let siteDeviceMap = {};
|
||||||
})
|
child.forEach(([first, second, third]) => {
|
||||||
let startDate,endDate
|
if (siteDeviceMap[first]) {
|
||||||
if(start && dataUnit===3){
|
siteDeviceMap[first].push(third);
|
||||||
|
} else {
|
||||||
|
siteDeviceMap[first] = [];
|
||||||
|
siteDeviceMap[first].push(third);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let startDate, endDate;
|
||||||
|
if (start && dataUnit === 3) {
|
||||||
// startDate= start + `${dataUnit === 2 ? ':00' : ' 00:00:00'}`
|
// startDate= start + `${dataUnit === 2 ? ':00' : ' 00:00:00'}`
|
||||||
startDate = start + ' 00:00:00'
|
startDate = start + " 00:00:00";
|
||||||
}else{
|
} else {
|
||||||
startDate=start
|
startDate = start;
|
||||||
}
|
}
|
||||||
if(end && dataUnit===3){
|
if (end && dataUnit === 3) {
|
||||||
// endDate= end + `${dataUnit === 2 ? ':00' : ' 00:00:00'}`
|
// endDate= end + `${dataUnit === 2 ? ':00' : ' 00:00:00'}`
|
||||||
endDate = end + ' 00:00:00'
|
endDate = end + " 00:00:00";
|
||||||
}else{
|
} else {
|
||||||
endDate=end
|
endDate = end;
|
||||||
}
|
}
|
||||||
|
this.loading = true;
|
||||||
getPointValueList({siteIds:[siteIds],dataUnit,categoryName,pointName,startDate,endDate,siteDeviceMap}).then(response => {
|
getPointValueList({
|
||||||
this.setOption(response?.data || [])
|
siteIds: [siteIds],
|
||||||
}).finally(()=>{
|
dataUnit,
|
||||||
this.loading = false
|
deviceCategory,
|
||||||
|
pointName,
|
||||||
|
startDate,
|
||||||
|
endDate,
|
||||||
|
siteDeviceMap,
|
||||||
})
|
})
|
||||||
|
.then((response) => {
|
||||||
|
this.setOption(response?.data || []);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
if (!this.chart) {
|
if (!this.chart) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
this.chart.dispose()
|
this.chart.dispose();
|
||||||
this.chart = null
|
this.chart = null;
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.loading= true
|
this.loading = true;
|
||||||
this.$nextTick(()=>{
|
this.$nextTick(() => {
|
||||||
this.initChart()
|
this.initChart();
|
||||||
this.$refs.dateTimeSelect.init()
|
this.$refs.dateTimeSelect.init();
|
||||||
Promise.all([this.getDeviceCategory(), this.getZdList()]).finally(()=>this.loading=false)
|
Promise.all([this.getDeviceCategory(), this.getZdList()]).finally(
|
||||||
})
|
() => (this.loading = false)
|
||||||
}
|
);
|
||||||
}
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped></style>
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|||||||
306
src/views/ems/site/powerTariff/AddPowerTariff.vue
Normal file
@ -0,0 +1,306 @@
|
|||||||
|
//选择年月 配置尖峰平谷对应的电价 配置24小时选择对应的尖峰平谷
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-dialog v-loading="loading" width="780px" :visible.sync="dialogTableVisible" class="ems-dialog" title="电价配置" :close-on-click-modal="false" :show-close="false">
|
||||||
|
<div class="items-container">
|
||||||
|
<div class="item-title">站点:</div>
|
||||||
|
<div class="item-content">
|
||||||
|
<el-select v-model="siteId" :disabled="mode === 'edit'" placeholder="请选择站点" :loading="searchLoading" loading-text="正在加载数据">
|
||||||
|
<el-option :label="item.siteName" :value="item.siteId" v-for="(item,index) in siteList" :key="index+'zdxeSelect'"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="items-container">
|
||||||
|
<div class="item-title">时间:</div>
|
||||||
|
<div class="item-content">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="powerDate"
|
||||||
|
format="yyyy-MM"
|
||||||
|
value-format="yyyy-MM"
|
||||||
|
type="month"
|
||||||
|
placeholder="请选择月份"
|
||||||
|
:disabled="mode === 'edit'"
|
||||||
|
>
|
||||||
|
</el-date-picker>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="display: flex">
|
||||||
|
<div class="items-container price-types" v-for="item in priceTypeOptions" :key="item.id">
|
||||||
|
<div class="item-title">{{item.name}}:</div>
|
||||||
|
<div class="item-content">
|
||||||
|
<el-input
|
||||||
|
placeholder="请输入价格"
|
||||||
|
v-model="item.price">
|
||||||
|
</el-input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="items-container">
|
||||||
|
<div class="item-title">
|
||||||
|
<el-button
|
||||||
|
@click.native.prevent="addRow"
|
||||||
|
block
|
||||||
|
type="primary"
|
||||||
|
size="mini">
|
||||||
|
新增时间段配置
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="item-content">
|
||||||
|
<div class="time-lists-container">
|
||||||
|
<div class="time-lists time-lists-title">
|
||||||
|
<div>开始时间</div>
|
||||||
|
<div>结束时间(不包括)</div>
|
||||||
|
<div>电价</div>
|
||||||
|
<div>操作</div>
|
||||||
|
</div>
|
||||||
|
<div class="time-lists" v-for="(item,index) in hoursOptions" :key="'hoursOptions'+index">
|
||||||
|
<div>
|
||||||
|
<el-time-select
|
||||||
|
placeholder="开始时间"
|
||||||
|
v-model="item.startTime"
|
||||||
|
:picker-options="{
|
||||||
|
start: '00:00',
|
||||||
|
step: '01:00',
|
||||||
|
end: '23:00',
|
||||||
|
}">
|
||||||
|
</el-time-select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-time-select
|
||||||
|
placeholder="结束时间"
|
||||||
|
v-model="item.endTime"
|
||||||
|
:picker-options="{
|
||||||
|
start: '00:00',
|
||||||
|
step: '01:00',
|
||||||
|
end: '24:00',
|
||||||
|
minTime: item.startTime
|
||||||
|
}">
|
||||||
|
</el-time-select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-select v-model="item.costType" placeholder="请选择">
|
||||||
|
<el-option v-for="(value,key) in priceTypeOptions" :key="key+'priceTypeOptions'" :label="value.name" :value="value.id"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-button
|
||||||
|
@click.native.prevent="deleteRow(index)"
|
||||||
|
type="warning"
|
||||||
|
size="mini">
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div slot="footer">
|
||||||
|
<el-button @click="closeDialog">取消</el-button>
|
||||||
|
<el-button type="primary" @click="saveDialog">确定</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import {addPriceConfig,editPriceConfig,detailPriceConfig} from '@/api/ems/powerTariff'
|
||||||
|
import {getAllSites} from '@/api/ems/zddt'
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
mode:'',
|
||||||
|
id:'',
|
||||||
|
searchLoading:false,
|
||||||
|
siteId:'',
|
||||||
|
siteList:[],
|
||||||
|
powerDate:'',//时间
|
||||||
|
//尖-peak,峰-high,平-flat,谷=valley
|
||||||
|
priceTypeOptions:[{
|
||||||
|
id:'peak',
|
||||||
|
name:'尖',
|
||||||
|
price:''
|
||||||
|
},{
|
||||||
|
id:'high',
|
||||||
|
name:'峰',
|
||||||
|
price:''
|
||||||
|
},{
|
||||||
|
id:'flat',
|
||||||
|
name:'平',
|
||||||
|
price:''
|
||||||
|
},{
|
||||||
|
id:'valley',
|
||||||
|
name:'谷',
|
||||||
|
price:''
|
||||||
|
}],
|
||||||
|
hoursOptions:[],
|
||||||
|
loading:false,
|
||||||
|
dialogTableVisible:false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
addRow(){
|
||||||
|
this.hoursOptions.push({
|
||||||
|
startTime:'',
|
||||||
|
endTime:'',
|
||||||
|
costType:''
|
||||||
|
})
|
||||||
|
},
|
||||||
|
deleteRow(index){
|
||||||
|
this.hoursOptions.splice(index,1)
|
||||||
|
},
|
||||||
|
//获取站点列表
|
||||||
|
getZdList(){
|
||||||
|
this.searchLoading=true
|
||||||
|
getAllSites().then(response => {
|
||||||
|
this.siteList = response?.data || []
|
||||||
|
}).finally(() => {this.searchLoading=false})
|
||||||
|
},
|
||||||
|
showDialog(id){
|
||||||
|
this.getZdList()
|
||||||
|
this.id = id
|
||||||
|
if(id) {
|
||||||
|
this.mode='edit'
|
||||||
|
//获取详情 初始化hoursOptions
|
||||||
|
this.loading = true
|
||||||
|
detailPriceConfig(id).then(response => {
|
||||||
|
const data = response?.data || {}
|
||||||
|
this.siteId = data?.siteId || ''
|
||||||
|
this.hoursOptions = data?.range || []
|
||||||
|
this.powerDate=data?.year && data?.month ? data.year +'-'+data.month : ''
|
||||||
|
this.priceTypeOptions.forEach(item=>{
|
||||||
|
item.price = data[item.id]
|
||||||
|
})
|
||||||
|
}).finally(()=>this.loading = false)
|
||||||
|
}else {
|
||||||
|
this.mode='add'
|
||||||
|
}
|
||||||
|
this.dialogTableVisible=true
|
||||||
|
},
|
||||||
|
saveDialog() {
|
||||||
|
if(this.siteId === '') return this.$message.error('请选择站点')
|
||||||
|
if(this.powerDate === '') return this.$message.error('请选择时间')
|
||||||
|
let priceArr=[]
|
||||||
|
this.priceTypeOptions.forEach(item=>{
|
||||||
|
!['0',0].includes(item.price) && !item.price && priceArr.push(item.name)
|
||||||
|
})
|
||||||
|
if(priceArr.length>0) return this.$message.error(`请配置${priceArr.join(',')}的电价`)
|
||||||
|
|
||||||
|
if(this.hoursOptions.length<=0) return this.$message.error(`请配置24小时的电价`)
|
||||||
|
let hours=false,hourDis=false
|
||||||
|
this.hoursOptions.forEach(item=>{
|
||||||
|
if(!item.startTime || !item.endTime || !item.costType ) hours=true
|
||||||
|
if(parseInt(item.startTime)>=parseInt(item.endTime)) hourDis=true
|
||||||
|
})
|
||||||
|
if(hours) return this.$message.error(`时间段电价配置错误`)
|
||||||
|
if(hourDis) return this.$message.error(`结束时间要大于开始时间`)
|
||||||
|
let hoursMap={}
|
||||||
|
this.hoursOptions.forEach(item=>{
|
||||||
|
let s = parseInt(item.startTime),e=parseInt(item.endTime)
|
||||||
|
for(s;s<e;s++){
|
||||||
|
if(!hoursMap[s]) hoursMap[s]=1
|
||||||
|
else hoursMap[s]+=1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
console.log('hoursMap======',hoursMap)
|
||||||
|
if(Object.values(hoursMap).length<24 || Object.values(hoursMap).find(i=>i>1)) return this.$message.error(`请配置24小时的电价且时间不能重复`)
|
||||||
|
const {powerDate,priceTypeOptions,hoursOptions,mode,id,siteId} =this
|
||||||
|
this.loading = true
|
||||||
|
let params={
|
||||||
|
year:powerDate.split('-')[0],
|
||||||
|
month:parseInt(powerDate.split('-')[1]),
|
||||||
|
range:hoursOptions,
|
||||||
|
siteId,
|
||||||
|
}
|
||||||
|
priceTypeOptions.forEach(item=>{params[item.id]=item.price})
|
||||||
|
if(mode === 'edit') params.id = id
|
||||||
|
console.log('参数=======',params)
|
||||||
|
//调接口传数据 区分新增还是修改 成功之后关闭弹窗 更新表格
|
||||||
|
if(mode === 'add'){
|
||||||
|
addPriceConfig(params).then(response => {
|
||||||
|
if(response.code === 200){
|
||||||
|
this.$emit('update')
|
||||||
|
this.closeDialog()
|
||||||
|
}else{
|
||||||
|
this.$message.error('新增失败')
|
||||||
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
editPriceConfig(params).then(response => {
|
||||||
|
if(response.code === 200){
|
||||||
|
this.$emit('update')
|
||||||
|
this.closeDialog()
|
||||||
|
}else{
|
||||||
|
this.$message.error('修改失败')
|
||||||
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
closeDialog(){
|
||||||
|
// 清空所有数据
|
||||||
|
this.$emit('clear')
|
||||||
|
this.mode=''
|
||||||
|
this.id=''
|
||||||
|
this.siteId=''
|
||||||
|
this.siteList=[]
|
||||||
|
this.searchLoading=false
|
||||||
|
this.powerDate=''
|
||||||
|
this.hoursOptions=[]
|
||||||
|
this.priceTypeOptions.forEach(item=>{
|
||||||
|
item.price=''
|
||||||
|
})
|
||||||
|
this.dialogTableVisible=false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.items-container{
|
||||||
|
margin-bottom: 20px;
|
||||||
|
.item-title{
|
||||||
|
line-height: 16px;
|
||||||
|
padding: 10px 0;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.price-types{
|
||||||
|
width: 150px;
|
||||||
|
&:not(:last-child){
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.time-lists-container{
|
||||||
|
width: 100%;
|
||||||
|
border:1px solid #eee;
|
||||||
|
.time-lists{
|
||||||
|
&:not(:last-child){
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
}
|
||||||
|
display: flex;
|
||||||
|
&>div{
|
||||||
|
width: 16%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
text-align: center;
|
||||||
|
padding: 10px 15px;
|
||||||
|
&:not(:last-child){
|
||||||
|
width: 28%;
|
||||||
|
border-right: 1px solid #eee;
|
||||||
|
}
|
||||||
|
.el-date-editor.el-input, .el-date-editor.el-input__inner {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.time-lists-title{
|
||||||
|
color: #000;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
208
src/views/ems/site/powerTariff/index.vue
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
<template>
|
||||||
|
<div class="ems-dashboard-editor-container" style="background-color: #ffffff" v-loading="loading">
|
||||||
|
<el-form :inline="true" class="select-container">
|
||||||
|
<el-form-item label="站点选择">
|
||||||
|
<el-select v-model="siteId" placeholder="请选择换电站名称" :loading="searchLoading" loading-text="正在加载数据" @change="onSearch" clearable>
|
||||||
|
<el-option :label="item.siteName" :value="item.siteId" v-for="(item,index) in siteList" :key="index+'zdxeSelect'"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="年份选择">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="defaultYear"
|
||||||
|
type="year"
|
||||||
|
:clearable="false"
|
||||||
|
placeholder="请选择年份"
|
||||||
|
align="center"
|
||||||
|
format="yyyy年"
|
||||||
|
value-format="yyyy"
|
||||||
|
@change="changeDefaultYear"
|
||||||
|
>
|
||||||
|
</el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
<br>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="addPowerConfig('')">新增电价配置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div class="month-lists-container" v-infinite-scroll="getData" infinite-scroll-immediate="false">
|
||||||
|
<el-empty v-show="tableData.length<=0" :image-size="200"></el-empty>
|
||||||
|
<el-card
|
||||||
|
shadow="always"
|
||||||
|
class="common-card-container time-range-card"
|
||||||
|
v-for="item in tableData"
|
||||||
|
:key="item.id"
|
||||||
|
>
|
||||||
|
<div slot="header" class="time-range-header">
|
||||||
|
<span class="card-title">{{siteList.find(i=>i.siteId===item.siteId).siteName || item.siteId || ''}}-{{item.month}}月电价时段划分</span>
|
||||||
|
<div>
|
||||||
|
<el-button type="primary" size="mini" @click="addPowerConfig(item.id)">编辑</el-button>
|
||||||
|
<el-button type="warning" size="mini" @click="deletePowerConfig(item)">删除</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="price-table-container">
|
||||||
|
<div class="price-table">
|
||||||
|
<div class="time-list">
|
||||||
|
<div class="time"> </div>
|
||||||
|
<div class="type">时段</div>
|
||||||
|
<div class="price">电价(元/kWh)</div>
|
||||||
|
</div>
|
||||||
|
<div class="time-list" v-for="(rangeItem,rangeIndex) in item.range" :key="rangeIndex+'price'">
|
||||||
|
<div class="time">{{`${rangeItem.startTime}-${rangeItem.endTime}`}}</div>
|
||||||
|
<div class="type">{{priceTypeOptions[rangeItem.costType]}}</div>
|
||||||
|
<div class="price">{{item[rangeItem.costType]}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
<add-power-tariff ref="addPowerTariff" @update="getData(true)"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {energyPriceConfig,listPriceConfig} from '@/api/ems/powerTariff'
|
||||||
|
import {getAllSites} from '@/api/ems/zddt'
|
||||||
|
import AddPowerTariff from './AddPowerTariff.vue'
|
||||||
|
import DateTimeSelect from "@/views/ems/search/DateTimeSelect.vue";
|
||||||
|
export default {
|
||||||
|
name: "PowerTariff",
|
||||||
|
components: {DateTimeSelect, AddPowerTariff},
|
||||||
|
computed: { },
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading:false,
|
||||||
|
pageNum:1,
|
||||||
|
pageSize:40,
|
||||||
|
searchLoading:false,
|
||||||
|
siteId:'',
|
||||||
|
siteList:[],
|
||||||
|
tableData:[],
|
||||||
|
tableTotal:0,
|
||||||
|
defaultYear:'',
|
||||||
|
pickerOptions:{
|
||||||
|
disabledDate(time) {
|
||||||
|
return time.getFullYear() >= new Date().getFullYear()+1;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
priceTypeOptions:{
|
||||||
|
'peak':'尖',
|
||||||
|
'high':'峰',
|
||||||
|
'flat':'平',
|
||||||
|
'valley':'谷'
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
resetTableData(){
|
||||||
|
this.tableData=[]
|
||||||
|
this.tableTotal=0
|
||||||
|
this.pageNum=1
|
||||||
|
},
|
||||||
|
// 搜索
|
||||||
|
onSearch(){
|
||||||
|
this.getData(true)
|
||||||
|
},
|
||||||
|
//获取站点列表
|
||||||
|
getZdList(){
|
||||||
|
this.searchLoading=true
|
||||||
|
return getAllSites().then(response => {
|
||||||
|
this.siteList = response?.data || []
|
||||||
|
if( this.siteList.length>0 ) this.siteId = this.siteList[0].siteId
|
||||||
|
}).finally(() => {this.searchLoading=false})
|
||||||
|
},
|
||||||
|
changeDefaultYear(){
|
||||||
|
this.getData(true)
|
||||||
|
},
|
||||||
|
getData(reset=false){
|
||||||
|
reset && this.resetTableData()
|
||||||
|
if(!reset && this.tableData.length>=this.tableTotal) return
|
||||||
|
this.loading=true;
|
||||||
|
const date = new Date(this.defaultYear).getFullYear()
|
||||||
|
const startTime = date+'-01',endTime = date+'-12'
|
||||||
|
listPriceConfig({startTime,endTime,pageNum:this.pageNum,pageSize:this.pageSize,siteId:this.siteId}).then(response => {
|
||||||
|
const data = JSON.parse(JSON.stringify(response?.rows || []))
|
||||||
|
data.length > 0 && (this.pageNum += 1)
|
||||||
|
this.tableData.push(...data)
|
||||||
|
this.tableTotal=response?.total || 0
|
||||||
|
}).finally(() => {this.loading=false})
|
||||||
|
},
|
||||||
|
addPowerConfig(id=''){
|
||||||
|
this.$refs.addPowerTariff.showDialog(id);
|
||||||
|
},
|
||||||
|
deletePowerConfig(row){
|
||||||
|
this.$confirm(`确认要删除${row.month}月的电价配置吗?`, {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
showClose:false,
|
||||||
|
closeOnClickModal:false,
|
||||||
|
type: 'warning',
|
||||||
|
beforeClose: (action, instance, done) => {
|
||||||
|
if (action === 'confirm') {
|
||||||
|
instance.confirmButtonLoading = true;
|
||||||
|
energyPriceConfig(row.id).then(response => {
|
||||||
|
response.code === 200 && done();
|
||||||
|
}).finally(() => {
|
||||||
|
instance.confirmButtonLoading = false;
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).then(() => {
|
||||||
|
//只有在废弃成功的情况下会走到这里
|
||||||
|
this.$message({
|
||||||
|
type: 'success',
|
||||||
|
message: '删除成功!'
|
||||||
|
});
|
||||||
|
this.getData(true)
|
||||||
|
//调用接口 更新表格数据
|
||||||
|
}).catch(() => {
|
||||||
|
//取消关机
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.defaultYear = new Date()
|
||||||
|
this.loading=true
|
||||||
|
this.getZdList().then(()=>{
|
||||||
|
this.getData(true)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.month-lists-container{
|
||||||
|
max-height:100vh ;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
.common-card-container{
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.price-table-container{
|
||||||
|
overflow-x: auto;
|
||||||
|
.price-table{
|
||||||
|
border:1px solid #eee;
|
||||||
|
width: fit-content;
|
||||||
|
overflow-x: auto;
|
||||||
|
display: flex;
|
||||||
|
.time-list{
|
||||||
|
&:not(:first-child){
|
||||||
|
border-left:1px solid #eee;
|
||||||
|
}
|
||||||
|
text-align: center;
|
||||||
|
width: 140px;
|
||||||
|
&>div{
|
||||||
|
height: 30px;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 30px;
|
||||||
|
color:#000;
|
||||||
|
&.time,&.type{
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
766
src/views/ems/site/sbbh/AddDevice.vue
Normal file
@ -0,0 +1,766 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
v-loading="loading"
|
||||||
|
width="90%"
|
||||||
|
:visible.sync="dialogTableVisible"
|
||||||
|
class="ems-dialog"
|
||||||
|
title="保护方案"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
:show-close="false"
|
||||||
|
>
|
||||||
|
<el-form
|
||||||
|
v-loading="loading > 0"
|
||||||
|
ref="addTempForm"
|
||||||
|
:model="formData"
|
||||||
|
:rules="rules"
|
||||||
|
size="medium"
|
||||||
|
label-width="140px"
|
||||||
|
>
|
||||||
|
<el-form-item label="站点" prop="siteId">
|
||||||
|
<el-select
|
||||||
|
v-model="formData.siteId"
|
||||||
|
placeholder="请选择"
|
||||||
|
:style="{ width: '50%' }"
|
||||||
|
@change="changeType"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
:label="item.siteName"
|
||||||
|
:value="item.siteId"
|
||||||
|
v-for="(item, index) in siteList"
|
||||||
|
:key="index + 'siteOptions'"
|
||||||
|
></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="设备保护名称" prop="faultName">
|
||||||
|
<el-input
|
||||||
|
v-model="formData.faultName"
|
||||||
|
placeholder="请输入"
|
||||||
|
clearable
|
||||||
|
:style="{ width: '50%' }"
|
||||||
|
>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="处理方案描述" prop="description">
|
||||||
|
<el-input
|
||||||
|
v-model="formData.description"
|
||||||
|
type="textarea"
|
||||||
|
:rows="2"
|
||||||
|
placeholder="请输入"
|
||||||
|
clearable
|
||||||
|
:style="{ width: '50%' }"
|
||||||
|
>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="是否告警" prop="isAlert">
|
||||||
|
<el-checkbox
|
||||||
|
v-model="formData.isAlert"
|
||||||
|
:true-label="1"
|
||||||
|
:false-label="0"
|
||||||
|
></el-checkbox>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="告警等级" prop="faultLevel">
|
||||||
|
<el-radio-group v-model="formData.faultLevel" :style="{ width: '50%' }" :disabled="mode === 'edit'">
|
||||||
|
<el-radio :label="1">等级1</el-radio>
|
||||||
|
<el-radio :label="2">等级2</el-radio>
|
||||||
|
<el-radio :label="3">等级3</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<div class="items-container">
|
||||||
|
<div class="item-title">
|
||||||
|
保护前提:
|
||||||
|
<div style="display: inline-block; margin-left: 20px">
|
||||||
|
<el-form-item label="延时" prop="faultDelaySeconds">
|
||||||
|
<el-input
|
||||||
|
v-model="formData.faultDelaySeconds"
|
||||||
|
placeholder="请输入"
|
||||||
|
clearable
|
||||||
|
:style="{ width: '200px', display: 'inline-block' }"
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-button
|
||||||
|
@click.native.prevent="addRow('protectionSettings')"
|
||||||
|
block
|
||||||
|
type="primary"
|
||||||
|
size="mini"
|
||||||
|
style="margin-bottom: 20px"
|
||||||
|
>
|
||||||
|
新增保护前提
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="item-content">
|
||||||
|
<div class="time-lists-container">
|
||||||
|
<div class="time-lists time-lists-title">
|
||||||
|
<div>设备类型</div>
|
||||||
|
<div>点位</div>
|
||||||
|
<div>故障值比较符号</div>
|
||||||
|
<div>故障值</div>
|
||||||
|
<div>释放值比较符号</div>
|
||||||
|
<div>释放值</div>
|
||||||
|
<div>关系</div>
|
||||||
|
<div>操作</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="time-lists"
|
||||||
|
v-for="(item, index) in protectionSettings"
|
||||||
|
:key="'protectionSettings' + index"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<el-cascader
|
||||||
|
v-model="item.deviceId"
|
||||||
|
:options="childOptions"
|
||||||
|
:show-all-levels="false"
|
||||||
|
@change="(v)=>handleChange(v,'protectionSettings',index)"
|
||||||
|
></el-cascader>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-autocomplete
|
||||||
|
v-model="item.point"
|
||||||
|
placeholder="请输入点位"
|
||||||
|
clearable
|
||||||
|
:fetch-suggestions="
|
||||||
|
(q, c) =>
|
||||||
|
querySearchAsync(q, c, index, 'protectionSettings')
|
||||||
|
"
|
||||||
|
@select="(v) => handleSelect(v, index, 'protectionSettings')"
|
||||||
|
></el-autocomplete>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<el-select v-model="item.faultOperator" placeholder="请选择">
|
||||||
|
<el-option
|
||||||
|
v-for="(value, key) in comparisonOperatorOptions"
|
||||||
|
:key="key + 'faultOperator'"
|
||||||
|
:label="key"
|
||||||
|
:value="value"
|
||||||
|
></el-option>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-input placeholder="请输入故障值" v-model="item.faultValue">
|
||||||
|
</el-input>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-select v-model="item.releaseOperator" placeholder="请选择">
|
||||||
|
<el-option
|
||||||
|
v-for="(value, key) in comparisonOperatorOptions"
|
||||||
|
:key="key + 'releaseOperator'"
|
||||||
|
:label="key"
|
||||||
|
:value="value"
|
||||||
|
></el-option>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-input
|
||||||
|
placeholder="请输入释放值"
|
||||||
|
v-model="item.releaseValue"
|
||||||
|
>
|
||||||
|
</el-input>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-select v-model="item.relationNext" placeholder="请选择">
|
||||||
|
<el-option
|
||||||
|
v-for="(value, key) in relationWithPoint"
|
||||||
|
:key="key + 'relation'"
|
||||||
|
:label="key"
|
||||||
|
:value="value"
|
||||||
|
></el-option>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-button
|
||||||
|
@click.native.prevent="deleteRow(index,'protectionSettings')"
|
||||||
|
type="warning"
|
||||||
|
size="mini"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="items-container">
|
||||||
|
<div class="item-title">
|
||||||
|
保护方案:
|
||||||
|
<div style="display: inline-block; margin-left: 20px">
|
||||||
|
<el-form-item label="延时" prop="releaseDelaySeconds">
|
||||||
|
<el-input
|
||||||
|
v-model="formData.releaseDelaySeconds"
|
||||||
|
placeholder="请输入"
|
||||||
|
clearable
|
||||||
|
:style="{ width: '200px', display: 'inline-block' }"
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-button
|
||||||
|
@click.native.prevent="addRow('protectionPlan')"
|
||||||
|
block
|
||||||
|
type="primary"
|
||||||
|
size="mini"
|
||||||
|
style="margin-bottom: 20px"
|
||||||
|
>
|
||||||
|
新增保护方案
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="item-content">
|
||||||
|
<div class="time-lists-container">
|
||||||
|
<div class="time-lists time-lists-title">
|
||||||
|
<div>设备类型</div>
|
||||||
|
<div>点位</div>
|
||||||
|
<div>故障值比较符号</div>
|
||||||
|
<div>故障值</div>
|
||||||
|
<div>操作</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="time-lists"
|
||||||
|
v-for="(item, index) in protectionPlan"
|
||||||
|
:key="'protectionPlan' + index"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<el-cascader
|
||||||
|
v-model="item.deviceId"
|
||||||
|
:show-all-levels="false"
|
||||||
|
:options="childOptions"
|
||||||
|
@change="(v)=>handleChange(v,'protectionPlan',index)"
|
||||||
|
></el-cascader>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-autocomplete
|
||||||
|
v-model="item.point"
|
||||||
|
placeholder="请输入点位"
|
||||||
|
clearable
|
||||||
|
:fetch-suggestions="
|
||||||
|
(q, c) => querySearchAsync(q, c, index, 'protectionPlan')
|
||||||
|
"
|
||||||
|
@select="(v) => handleSelect(v, index, 'protectionPlan')"
|
||||||
|
></el-autocomplete>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>=</div>
|
||||||
|
<div>
|
||||||
|
<el-input placeholder="请输入故障值" v-model="item.value">
|
||||||
|
</el-input>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-button
|
||||||
|
@click.native.prevent="deleteRow(index,'protectionPlan')"
|
||||||
|
type="warning"
|
||||||
|
size="mini"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer">
|
||||||
|
<el-button @click="closeDialog">取消</el-button>
|
||||||
|
<el-button type="primary" @click="saveDialog">确定</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { mapState } from "vuex";
|
||||||
|
import { getAllSites } from "@/api/ems/zddt";
|
||||||
|
import { validText } from "@/utils/validate";
|
||||||
|
import {
|
||||||
|
updateProtectPlan,
|
||||||
|
addProtectPlan,
|
||||||
|
getProtectPlan,
|
||||||
|
getDeviceListBySiteAndCategory
|
||||||
|
} from "@/api/ems/site";
|
||||||
|
import { getAllDeviceCategory, pointFuzzyQuery } from "@/api/ems/search";
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
const validateText = (rule, value, callback) => {
|
||||||
|
if (value !== "" && !validText(value)) {
|
||||||
|
callback(new Error("只能输入中文、英文、数字和特殊字符!"));
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
mode:'',
|
||||||
|
loading: 0,
|
||||||
|
childOptions:[],
|
||||||
|
protectionSettings: [],
|
||||||
|
protectionPlan: [],
|
||||||
|
dialogTableVisible: false,
|
||||||
|
siteList: [], //站点列表 从接口获取数据
|
||||||
|
formData: {
|
||||||
|
id: "", //设备唯一标识
|
||||||
|
siteId: "", //站点ID
|
||||||
|
faultName: "", //设备保护名称
|
||||||
|
isAlert: 0, //是否告警
|
||||||
|
faultLevel: 1, //告警等级
|
||||||
|
faultDelaySeconds: "", //故障延时
|
||||||
|
releaseDelaySeconds: "", //释放延时
|
||||||
|
description:'',//方案描述
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
siteId: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: "请选择站点",
|
||||||
|
trigger: ["blur", "change"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
faultName: [
|
||||||
|
{ required: true, message: "请输入设备保护名称", trigger: "blur" },
|
||||||
|
],
|
||||||
|
isAlert: [
|
||||||
|
{ required: true, message: "请选择是否告警", trigger: "blur" },
|
||||||
|
],
|
||||||
|
description: [
|
||||||
|
{ required: true, message: "请输入设备描述", trigger: "blur" },
|
||||||
|
{ validator: validateText, trigger: "blur" },
|
||||||
|
],
|
||||||
|
faultDelaySeconds: [
|
||||||
|
{ required: true, message: "请输入保护前提延时", trigger: "blur" },
|
||||||
|
{ validator: validateText, trigger: "blur" },
|
||||||
|
],
|
||||||
|
releaseDelaySeconds: [
|
||||||
|
{ required: true, message: "请输入保护方案延时", trigger: "blur" },
|
||||||
|
{ validator: validateText, trigger: "blur" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState({
|
||||||
|
communicationStatusOptions: (state) =>
|
||||||
|
state?.ems?.communicationStatusOptions || {},
|
||||||
|
deviceTypeOptions: (state) => state?.ems?.deviceTypeOptions || {},
|
||||||
|
comparisonOperatorOptions: (state) =>
|
||||||
|
state?.ems?.comparisonOperatorOptions || {},
|
||||||
|
relationWithPoint: (state) => state?.ems?.relationWithPoint || {},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
open(id,siteId){
|
||||||
|
this.dialogTableVisible=true
|
||||||
|
this.getZdList();
|
||||||
|
this.getDeviceCategoryList().then(()=>{
|
||||||
|
if(id && siteId) {
|
||||||
|
this.getDeviceList('PCS',siteId)
|
||||||
|
this.getDeviceList('STACK',siteId)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if(id){
|
||||||
|
this.formData.id = id
|
||||||
|
this.mode = 'edit'
|
||||||
|
getProtectPlan(id).then(response => {
|
||||||
|
const data = response?.data || {}
|
||||||
|
this.formData = {
|
||||||
|
id,
|
||||||
|
siteId: data?.siteId || '', //站点ID
|
||||||
|
faultName: data?.faultName || '', //设备保护名称
|
||||||
|
isAlert: data?.isAlert || 0, //是否告警
|
||||||
|
faultLevel: data?.faultLevel || 1, //告警等级
|
||||||
|
faultDelaySeconds: data?.faultDelaySeconds || "", //故障延时
|
||||||
|
releaseDelaySeconds: data?.releaseDelaySeconds ||"", //释放延时
|
||||||
|
description: data?.description ||'',//方案描述
|
||||||
|
}
|
||||||
|
const plan =(JSON.parse(data?.protectionPlan || [])).map(item=>{
|
||||||
|
return Object.assign({},item,{
|
||||||
|
deviceId:[item.deviceCategory || '',item.deviceId || ''],
|
||||||
|
})
|
||||||
|
})
|
||||||
|
const settings =(JSON.parse(data?.protectionSettings || [])).map(item=>{
|
||||||
|
return Object.assign({},item,{
|
||||||
|
deviceId:[item.deviceCategory || '',item.deviceId || ''],
|
||||||
|
})
|
||||||
|
})
|
||||||
|
this.$nextTick(()=>{
|
||||||
|
this.protectionPlan.splice(0,0,...plan)
|
||||||
|
this.protectionSettings.splice(0,0,...settings)
|
||||||
|
})
|
||||||
|
console.log('获取设备保护详情并初始化',this.formData,this.protectionPlan,this.protectionSettings)
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
this.mode = 'add'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 新增设备保护前提、设备保护方案
|
||||||
|
addRow(type) {
|
||||||
|
const item = type === 'protectionSettings' ? {
|
||||||
|
deviceId:[],//设备ID
|
||||||
|
deviceCategory: "",//设备类型 英文
|
||||||
|
categoryName:'',//设备类型名称 中文
|
||||||
|
point: "",//点位 英文
|
||||||
|
pointName:"",//点位 中文
|
||||||
|
faultValue: "",//故障值
|
||||||
|
releaseValue: "",//释放值
|
||||||
|
faultOperator: "",//故障值比较关系
|
||||||
|
releaseOperator: "",//释放值比较关系
|
||||||
|
relationNext: "",//与下一个点位的关系
|
||||||
|
} : {
|
||||||
|
deviceId:[],
|
||||||
|
deviceCategory: "",//设备类型 英文
|
||||||
|
categoryName:'',//设备类型名称 中文
|
||||||
|
point: "",
|
||||||
|
pointName:"",
|
||||||
|
value: "",//设置值
|
||||||
|
}
|
||||||
|
// this.$set(this[type], this[type].length, item);
|
||||||
|
this[type].splice(this[type].length,0,item)
|
||||||
|
console.log('新增设备保护前提、方案',type,this[type])
|
||||||
|
},
|
||||||
|
// 删除设备保护前提、设备保护方案
|
||||||
|
deleteRow(index, type) {
|
||||||
|
this[type].splice(index, 1);
|
||||||
|
},
|
||||||
|
|
||||||
|
// 设备保护前提、设备保护方案点位选择
|
||||||
|
querySearchAsync(query, cb, index, type) {
|
||||||
|
console.log("查询数据", query, index);
|
||||||
|
if (!this.formData.siteId || !this[type][index].deviceCategory) {
|
||||||
|
this.$message({
|
||||||
|
type: "warning",
|
||||||
|
message: "请先选择站点和设备",
|
||||||
|
});
|
||||||
|
return cb([]);
|
||||||
|
}
|
||||||
|
pointFuzzyQuery({
|
||||||
|
siteIds: [this.formData.siteId],
|
||||||
|
deviceCategory: this[type][index].deviceCategory,
|
||||||
|
pointName: query,
|
||||||
|
}).then((response) => {
|
||||||
|
const data = response?.data || [];
|
||||||
|
cb(
|
||||||
|
data.map((item) => {
|
||||||
|
return { name: item, value: item };
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 点位选择
|
||||||
|
handleSelect(data, index, type) {
|
||||||
|
console.log('选择点位',data,index,type)
|
||||||
|
// this.$set(this[type], index, Object.assign({},this[type][index],{
|
||||||
|
// point:data.value,
|
||||||
|
// pointName:data.value,
|
||||||
|
// }));
|
||||||
|
let line = Object.assign({},this[type][index],{
|
||||||
|
point:data.value,
|
||||||
|
pointName:data.value,
|
||||||
|
})
|
||||||
|
this[type].splice(index,1,line);
|
||||||
|
console.log('选择点位配置完成',this[type][index])
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取设备类别-不区分站点
|
||||||
|
getDeviceCategoryList() {
|
||||||
|
this.loading += 1;
|
||||||
|
return getAllDeviceCategory()
|
||||||
|
.then((response) => {
|
||||||
|
const data = (response?.data || []).filter(item => ['PCS','STACK'].includes(item.code));
|
||||||
|
// this.childOptions=[]
|
||||||
|
this.$set(this,'childOptions',[])
|
||||||
|
let arr =[]
|
||||||
|
data.forEach((item) => {
|
||||||
|
arr.push({
|
||||||
|
value: item.code,
|
||||||
|
label: item.name,
|
||||||
|
children:[]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
this.childOptions.splice(0,0,...arr)
|
||||||
|
console.log('获取设备类型',data,this.childOptions)
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading -= 1;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
//获取设备列表-区分站点
|
||||||
|
getDeviceList(deviceCategory,siteId){
|
||||||
|
this.$nextTick(()=>{
|
||||||
|
getDeviceListBySiteAndCategory({siteId:siteId || this.formData.siteId,deviceCategory}).then((response) => {
|
||||||
|
const data = (response?.data || []).map(item => {
|
||||||
|
return {
|
||||||
|
label: item.deviceName,
|
||||||
|
value: item.id,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const index = this.childOptions.findIndex(item=>item.value === deviceCategory)
|
||||||
|
if(index>-1){
|
||||||
|
const length = this.childOptions[index].children.length
|
||||||
|
this.childOptions[index].children.splice(0,length,...data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
//更新站点下面的设备列表
|
||||||
|
updateSiteDeviceList(){
|
||||||
|
this.childOptions.forEach(item => {
|
||||||
|
const length = item.children.length
|
||||||
|
item.children.splice(0,length)
|
||||||
|
})
|
||||||
|
this.getDeviceList('PCS')
|
||||||
|
this.getDeviceList('STACK')
|
||||||
|
},
|
||||||
|
//选中设备类型、设备
|
||||||
|
handleChange(data,type,index){
|
||||||
|
const deviceCategory = data[0],deviceId=data[1]
|
||||||
|
console.log('设置选中设备类型、设备',deviceCategory,deviceId,type,index)
|
||||||
|
const item = Object.assign({},this[type][index],{
|
||||||
|
deviceId:data,
|
||||||
|
deviceCategory,
|
||||||
|
categoryName : this.childOptions.find(i=>i.value === deviceCategory).label,
|
||||||
|
pointName:'',
|
||||||
|
point:''
|
||||||
|
})
|
||||||
|
this.$nextTick(()=>{
|
||||||
|
// this.$set(this[type], index, item);
|
||||||
|
this[type].splice(index,1,item);
|
||||||
|
})
|
||||||
|
console.log('设置选中设备类型、设备配置完成',this[type][index])
|
||||||
|
},
|
||||||
|
|
||||||
|
//获取站点列表
|
||||||
|
getZdList() {
|
||||||
|
this.loading += 1;
|
||||||
|
getAllSites()
|
||||||
|
.then((response) => {
|
||||||
|
this.siteList = response?.data || [];
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading -= 1;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 切换站点
|
||||||
|
// 重新获取设备列表
|
||||||
|
// 清空选中的设备、点位信息
|
||||||
|
changeType() {
|
||||||
|
//获取当前站点下的pcs和bms
|
||||||
|
this.updateSiteDeviceList()
|
||||||
|
if(this.protectionSettings.length>0){
|
||||||
|
const list =this.protectionSettings
|
||||||
|
list.forEach((item) => {
|
||||||
|
item.point = ""
|
||||||
|
item.pointName = ""
|
||||||
|
item.deviceId=[]
|
||||||
|
item.categoryName=''
|
||||||
|
item.deviceCategory=''
|
||||||
|
});
|
||||||
|
// this.$set(this,'protectionSettings',list)
|
||||||
|
this.$nextTick(()=>{
|
||||||
|
this.protectionSettings.splice(0,this.protectionSettings.length,...list)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if(this.protectionPlan.length>0){
|
||||||
|
const list =this.protectionPlan
|
||||||
|
list.forEach((item) => {
|
||||||
|
item.point = ""
|
||||||
|
item.pointName = ""
|
||||||
|
item.deviceId=[]
|
||||||
|
item.categoryName=''
|
||||||
|
item.deviceCategory=''
|
||||||
|
});
|
||||||
|
// this.$set(this,'protectionPlan',list)
|
||||||
|
this.$nextTick(()=>{
|
||||||
|
this.protectionPlan.splice(0,this.protectionPlan.length,...list)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
saveDialog() {
|
||||||
|
function getToastMsg(name,type,index){
|
||||||
|
return {
|
||||||
|
protectionSettings:{
|
||||||
|
deviceId:`请选择保护前提第${index}行的设备`,//设备ID
|
||||||
|
deviceCategory: `请选择保护前提第${index}行的设备类型`,//设备类型 英文
|
||||||
|
categoryName:`请选择保护前提第${index}行的设备类型`,//设备类型名称 中文
|
||||||
|
point: `请选择保护前提第${index}行的点位`,//点位 英文
|
||||||
|
pointName:`请选择保护前提第${index}行的点位`,//点位 中文
|
||||||
|
faultValue: `请输入保护前提第${index}行的故障值`,//故障值
|
||||||
|
releaseValue: `请输入保护前提第${index}行的释放值`,//释放值
|
||||||
|
faultOperator: `请选择保护前提第${index}行的故障值比较关系`,//故障值比较关系
|
||||||
|
releaseOperator: `请选择保护前提第${index}行的释放值比较关系`,//释放值比较关系
|
||||||
|
relationNext: `请选择保护前提第${index}行与下一个点位的关系`,//与下一个点位的关系
|
||||||
|
},
|
||||||
|
protectionPlan :{
|
||||||
|
deviceId:`请选择保护方案第${index}行的设备`,
|
||||||
|
deviceCategory: `请选择保护方案第${index}行的设备类型`,//设备类型 英文
|
||||||
|
categoryName:`请选择保护方案第${index}行的设备类型`,//设备类型名称 中文
|
||||||
|
point: `请选择保护方案第${index}行的点位`,
|
||||||
|
pointName:`请选择保护方案第${index}行的点位`,
|
||||||
|
value: `请输入保护方案第${index}行的故障值`,//设置值
|
||||||
|
}
|
||||||
|
}[type][name]
|
||||||
|
}
|
||||||
|
this.$refs.addTempForm.validate((valid) => {
|
||||||
|
if (!valid) return;
|
||||||
|
const {
|
||||||
|
id = "", //设备唯一标识
|
||||||
|
siteId = "", //站点ID
|
||||||
|
faultName = "", //设备保护名称
|
||||||
|
isAlert = 0, //是否告警
|
||||||
|
faultLevel = 1, //告警等级
|
||||||
|
faultDelaySeconds = "", //故障延时
|
||||||
|
releaseDelaySeconds = "", //释放延时
|
||||||
|
description="",//方案描述
|
||||||
|
} = this.formData;
|
||||||
|
const {protectionSettings,protectionPlan} = this
|
||||||
|
let protectionSettingsValidateStatus= true , protectionPlanValidateStatus= true
|
||||||
|
for(let i = 0;i<protectionSettings.length;i++){
|
||||||
|
let valueMap = Object.entries(protectionSettings[i]);
|
||||||
|
for(let inner = 0;inner < valueMap.length;inner++){
|
||||||
|
const key =valueMap[inner][0],value =valueMap[inner][1]
|
||||||
|
if(key === 'relationNext'){
|
||||||
|
if(protectionSettings[i+1] && !value){//有下一个点位
|
||||||
|
this.$message.error(getToastMsg(key,'protectionSettings',i+1))
|
||||||
|
protectionSettingsValidateStatus=false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if(![0,'0'].includes(value) && !value){
|
||||||
|
this.$message.error(getToastMsg(key,'protectionSettings',i+1))
|
||||||
|
protectionSettingsValidateStatus=false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!protectionSettingsValidateStatus) break
|
||||||
|
}
|
||||||
|
|
||||||
|
for(let i = 0;i<protectionPlan.length;i++){
|
||||||
|
let valueMap = Object.entries(protectionPlan[i]);
|
||||||
|
for(let inner = 0;inner < valueMap.length;inner++){
|
||||||
|
const key =valueMap[inner][0],value =valueMap[inner][1]
|
||||||
|
if(key === 'relationNext'){
|
||||||
|
if(protectionPlan[i+1] && !value){//有下一个点位
|
||||||
|
this.$message.error(getToastMsg(key,'protectionPlan',i+1))
|
||||||
|
protectionPlanValidateStatus=false
|
||||||
|
break
|
||||||
|
}else{
|
||||||
|
// protectionPlan[i][key] = ''//清空选择的关系
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if(![0,'0'].includes(value) && !value){
|
||||||
|
this.$message.error(getToastMsg(key,'protectionPlan',i+1))
|
||||||
|
protectionPlanValidateStatus=false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!protectionPlanValidateStatus) break
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!protectionSettingsValidateStatus || !protectionPlanValidateStatus) return
|
||||||
|
const settings = protectionSettings.map(item=>{
|
||||||
|
return Object.assign({},item,{
|
||||||
|
deviceId:item.deviceId[1],
|
||||||
|
})
|
||||||
|
})
|
||||||
|
const plan = protectionPlan.map(item=>{
|
||||||
|
return Object.assign({},item,{
|
||||||
|
deviceId:item.deviceId[1],
|
||||||
|
})
|
||||||
|
})
|
||||||
|
this.loading += 1;
|
||||||
|
const params= {
|
||||||
|
siteId,
|
||||||
|
faultName,
|
||||||
|
isAlert,
|
||||||
|
faultLevel,
|
||||||
|
faultDelaySeconds,
|
||||||
|
releaseDelaySeconds,
|
||||||
|
description,
|
||||||
|
protectionSettings:JSON.stringify(settings),
|
||||||
|
protectionPlan:JSON.stringify(plan),
|
||||||
|
}
|
||||||
|
if (this.mode === "add") {
|
||||||
|
addProtectPlan(params)
|
||||||
|
.then((response) => {
|
||||||
|
if (response.code === 200) {
|
||||||
|
//新增成功
|
||||||
|
// 关闭弹窗 更新表格
|
||||||
|
this.$emit("update");
|
||||||
|
this.closeDialog();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading -= 1;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
params.id = id
|
||||||
|
updateProtectPlan(params)
|
||||||
|
.then((response) => {
|
||||||
|
if (response.code === 200) {
|
||||||
|
//新增成功
|
||||||
|
// 关闭弹窗 更新表格
|
||||||
|
this.$emit("update");
|
||||||
|
this.closeDialog();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading -= 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
closeDialog() {
|
||||||
|
this.$emit("clear");
|
||||||
|
// 清空所有数据
|
||||||
|
for(let key in this.formData) {
|
||||||
|
this.formData[key] = key === 'isAlert' ? 0 : key === 'faultLevel' ? 1 : ''
|
||||||
|
}
|
||||||
|
this.$refs.addTempForm.resetFields();
|
||||||
|
this.$set(this,'protectionSettings',[])
|
||||||
|
this.$set(this,'protectionPlan',[])
|
||||||
|
this.$set(this,'childOptions',[])
|
||||||
|
this.dialogTableVisible = false;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.items-container {
|
||||||
|
margin-top: 40px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
.item-title {
|
||||||
|
line-height: 16px;
|
||||||
|
padding: 10px 0;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.time-lists-container {
|
||||||
|
width: 100%;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
.time-lists {
|
||||||
|
&:not(:last-child) {
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
}
|
||||||
|
display: flex;
|
||||||
|
& > div {
|
||||||
|
width: 16%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
text-align: center;
|
||||||
|
padding: 10px 15px;
|
||||||
|
&:not(:last-child) {
|
||||||
|
width: 28%;
|
||||||
|
border-right: 1px solid #eee;
|
||||||
|
}
|
||||||
|
.el-date-editor.el-input,
|
||||||
|
.el-date-editor.el-input__inner {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.time-lists-title {
|
||||||
|
color: #000;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
259
src/views/ems/site/sbbh/index.vue
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="ems-dashboard-editor-container"
|
||||||
|
style="background-color: #ffffff"
|
||||||
|
v-loading="loading"
|
||||||
|
>
|
||||||
|
<el-form :inline="true" class="select-container">
|
||||||
|
<el-form-item label="站点选择">
|
||||||
|
<el-select
|
||||||
|
v-model="form.siteId"
|
||||||
|
placeholder="请选择换电站名称"
|
||||||
|
:loading="searchLoading"
|
||||||
|
loading-text="正在加载数据"
|
||||||
|
clearable
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
:label="item.siteName"
|
||||||
|
:value="item.siteId"
|
||||||
|
v-for="(item, index) in siteList"
|
||||||
|
:key="index + 'zdxeSelect'"
|
||||||
|
></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="故障名称">
|
||||||
|
<el-input
|
||||||
|
v-model="form.faultName"
|
||||||
|
clearable
|
||||||
|
placeholder="请输入故障名称"
|
||||||
|
style="width: 150px"
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="onSearch" native-type="button">搜索</el-button>
|
||||||
|
<el-button @click="onReset" native-type="button">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<el-button type="primary" @click="addDevice" native-type="button"
|
||||||
|
>新增设备</el-button
|
||||||
|
>
|
||||||
|
<el-table
|
||||||
|
class="common-table"
|
||||||
|
:data="tableData"
|
||||||
|
stripe
|
||||||
|
max-height="600px"
|
||||||
|
style="width: 100%; margin-top: 25px"
|
||||||
|
>
|
||||||
|
<el-table-column prop="siteId" label="站点" width="100"> </el-table-column>
|
||||||
|
<el-table-column prop="faultName" label="设备保护名称" width="100"> </el-table-column>
|
||||||
|
<el-table-column prop="faultLevel" label="故障等级" width="100">
|
||||||
|
<template slot-scope="scope">等级{{scope.row.faultLevel}}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="isAlert" label="是否告警" width="100">
|
||||||
|
<template slot-scope="scope">{{scope.row.isAlert === 1 ? '是' : '否'}}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="description" label="处理方案描述" width="200" show-overflow-tooltip>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="protectionSettings" label="保护前提" show-overflow-tooltip width="400">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<div v-html="handleProtectionSettings(scope.row.protectionSettings)"></div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="faultDelaySeconds" label="保护前提延时(s)" width="120">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="protectionPlan" label="保护方案" show-overflow-tooltip width="200">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<div v-html="handleProtectionPlan(scope.row.protectionPlan)"></div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="releaseDelaySeconds" label="保护方案延时(s)" width="120">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column fixed="right" label="操作" width="150">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button @click="editDevice(scope.row)" type="warning" size="mini">
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-button type="danger" @click="deleteDevice(scope.row)" size="mini">
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<el-pagination
|
||||||
|
v-show="tableData.length > 0"
|
||||||
|
background
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
:current-page="pageNum"
|
||||||
|
:page-size="pageSize"
|
||||||
|
:page-sizes="[10, 20, 30, 40]"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="totalSize"
|
||||||
|
style="margin-top: 15px; text-align: center"
|
||||||
|
>
|
||||||
|
</el-pagination>
|
||||||
|
<add-device
|
||||||
|
ref="addDevice"
|
||||||
|
@update="getData"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
protectPlanList,
|
||||||
|
deleteProtectPlan,
|
||||||
|
} from "@/api/ems/site";
|
||||||
|
import { getAllSites } from "@/api/ems/zddt";
|
||||||
|
import AddDevice from "./AddDevice.vue";
|
||||||
|
export default {
|
||||||
|
name: "SBBH",
|
||||||
|
components: { AddDevice },
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
form:{
|
||||||
|
siteId:'',
|
||||||
|
faultName:''
|
||||||
|
},
|
||||||
|
loading: false,
|
||||||
|
searchLoading: false,
|
||||||
|
siteList: [],
|
||||||
|
tableData: [],
|
||||||
|
pageSize: 10, //分页栏当前每个数据总数
|
||||||
|
pageNum: 1, //分页栏当前页数
|
||||||
|
totalSize: 0, //table表格数据总数
|
||||||
|
dialogTableVisible: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleProtectionSettings(data){
|
||||||
|
if(!data || !JSON.parse(data)) return
|
||||||
|
const arr = JSON.parse(data),
|
||||||
|
str= arr.map((item,index)=>{
|
||||||
|
const {categoryName='',deviceId='',point='',faultOperator='',faultValue='',releaseOperator='',releaseValue='',relationNext=''} = item
|
||||||
|
return `<div>${index+1}、 <span>${categoryName ? categoryName + '-' : ''}${deviceId ? deviceId + '-' : ''}${ point || ''}</span> <span>故障:${faultOperator || ''}${ faultValue || ''}</span> <span>释放:${releaseOperator || ''}${releaseValue || ''}</span> ${arr[index+1] ? '<span>关系:'+(relationNext || '')+'</span>' : ''}</div>`
|
||||||
|
})
|
||||||
|
return str.join('')
|
||||||
|
},
|
||||||
|
handleProtectionPlan(data){
|
||||||
|
if(!data || !JSON.parse(data)) return
|
||||||
|
const arr = JSON.parse(data),
|
||||||
|
str= arr.map((item,index)=>{
|
||||||
|
const {categoryName='',deviceId='',point='',value=''} = item
|
||||||
|
return `<div>${index+1}、 <span>${categoryName ? categoryName + '-' : ''}${deviceId ? deviceId + '-' : ''}${ point || ''}</span> <span>故障:=${ value || ''}</span> </div>`
|
||||||
|
})
|
||||||
|
return str.join('')
|
||||||
|
},
|
||||||
|
// 新增设备 展示弹窗
|
||||||
|
addDevice() {
|
||||||
|
this.$refs.addDevice.open()
|
||||||
|
},
|
||||||
|
// 编辑设备
|
||||||
|
editDevice(row) {
|
||||||
|
this.$refs.addDevice.open(row.id,row.siteId)
|
||||||
|
},
|
||||||
|
//删除设备
|
||||||
|
deleteDevice(row) {
|
||||||
|
console.log('删除')
|
||||||
|
this.$confirm(`确认要设备保护${row.faultName}吗?`, {
|
||||||
|
confirmButtonText: "确定",
|
||||||
|
cancelButtonText: "取消",
|
||||||
|
showClose: false,
|
||||||
|
closeOnClickModal: false,
|
||||||
|
type: "warning",
|
||||||
|
beforeClose: (action, instance, done) => {
|
||||||
|
if (action === "confirm") {
|
||||||
|
instance.confirmButtonLoading = true;
|
||||||
|
deleteProtectPlan(row.id)
|
||||||
|
.then((response) => {
|
||||||
|
response.code === 200 && done();
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
instance.confirmButtonLoading = false;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
//只有在废弃成功的情况下会走到这里
|
||||||
|
this.$message({
|
||||||
|
type: "success",
|
||||||
|
message: "删除成功!",
|
||||||
|
});
|
||||||
|
this.getData();
|
||||||
|
//调用接口 更新表格数据
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
//取消关机
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 分页
|
||||||
|
handleSizeChange(val) {
|
||||||
|
this.pageSize = val;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.getData();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleCurrentChange(val) {
|
||||||
|
this.pageNum = val;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.getData();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 搜索
|
||||||
|
onSearch() {
|
||||||
|
this.pageNum = 1; //每次搜索从1开始搜索
|
||||||
|
this.getData();
|
||||||
|
},
|
||||||
|
// 重置
|
||||||
|
onReset() {
|
||||||
|
this.form={
|
||||||
|
siteId: "",
|
||||||
|
faultName: "",
|
||||||
|
}
|
||||||
|
this.pageNum = 1; //每次搜索从1开始搜索
|
||||||
|
this.getData();
|
||||||
|
},
|
||||||
|
// 获取数据
|
||||||
|
getData() {
|
||||||
|
this.loading = true;
|
||||||
|
const { pageNum, pageSize } = this,{siteId,faultName=''}=this.form;
|
||||||
|
protectPlanList({ siteId, faultName,pageNum, pageSize })
|
||||||
|
.then((response) => {
|
||||||
|
this.tableData = response?.rows || [];
|
||||||
|
this.totalSize = response?.total || 0;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
//获取站点列表
|
||||||
|
getZdList() {
|
||||||
|
this.searchLoading = true;
|
||||||
|
return getAllSites()
|
||||||
|
.then((response) => {
|
||||||
|
this.siteList = response?.data || [];
|
||||||
|
if (this.siteList.length > 0) this.form.siteId = this.siteList[0].siteId;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.searchLoading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.loading = true;
|
||||||
|
this.form = {
|
||||||
|
siteId: "",
|
||||||
|
faultName: "",
|
||||||
|
};
|
||||||
|
this.pageNum = 1; //每次搜索从1开始搜索
|
||||||
|
this.getZdList().then(() => {
|
||||||
|
this.getData();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
||||||
@ -1,13 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog :visible.sync="dialogTableVisible" :close-on-click-modal="false" :show-close="false" destroy-on-close lock-scroll append-to-body width="600px" class="ems-dialog" :title="mode === 'add'?'新增设备':`编辑设备` " >
|
<el-dialog :visible.sync="dialogTableVisible" :close-on-press-escape="false" :close-on-click-modal="false" :show-close="false" destroy-on-close lock-scroll append-to-body width="600px" class="ems-dialog" :title="mode === 'add'?'新增设备':`编辑设备` " >
|
||||||
<el-form v-loading="loading>0" ref="addTempForm" :model="formData" :rules="rules" size="medium" label-width="100px">
|
<el-form v-loading="loading>0" ref="addTempForm" :model="formData" :rules="rules" size="medium" label-width="140px">
|
||||||
<el-form-item label="站点" prop="siteId">
|
<el-form-item label="站点" prop="siteId">
|
||||||
<el-select v-model="formData.siteId" placeholder="请选择" :style="{width: '100%'}">
|
<el-select v-model="formData.siteId" placeholder="请选择" :style="{width: '100%'}" @change="changeType">
|
||||||
<el-option :label="item.siteName" :value="item.siteId" v-for="(item,index) in siteList" :key="index+'siteOptions'"></el-option>
|
<el-option :label="item.siteName" :value="item.siteId" v-for="(item,index) in siteList" :key="index+'siteOptions'"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="设备id" prop="deviceId" >
|
<el-form-item label="设备id" prop="deviceId" >
|
||||||
<el-input v-model="formData.deviceId" maxlength="60" clearable :style="{width: '100%'}">
|
<el-input v-model="formData.deviceId" placeholder="请输入" maxlength="60" clearable :style="{width: '100%'}">
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="设备名称" prop="deviceName">
|
<el-form-item label="设备名称" prop="deviceName">
|
||||||
@ -29,11 +29,11 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="设备类别" prop="deviceCategory">
|
<el-form-item label="设备类别" prop="deviceCategory">
|
||||||
<el-select v-model="formData.deviceCategory" placeholder="请选择" :style="{width: '100%'}">
|
<el-select v-model="formData.deviceCategory" placeholder="请选择" :style="{width: '100%'}" @change="changeType">
|
||||||
<el-option :label="item" :value="item" v-for="(item,index) in deviceCategoryList" :key="index+'deviceCategoryList'"></el-option>
|
<el-option :label="item.name" :value="item.code" v-for="(item,index) in deviceCategoryList" :key="index+'deviceCategoryList'"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="上级设备" prop="parentId" v-if="formData.deviceCategory === dccDeviceCategory">
|
<el-form-item label="上级设备" prop="parentId" v-if="dccDeviceCategoryList.includes(formData.deviceCategory)">
|
||||||
<el-select v-model="formData.parentId" :placeholder="parentDeviceList.length === 0 && !formData.siteId ? '请先选择站点' : '请选择'" :style="{width: '100%'}">
|
<el-select v-model="formData.parentId" :placeholder="parentDeviceList.length === 0 && !formData.siteId ? '请先选择站点' : '请选择'" :style="{width: '100%'}">
|
||||||
<el-option :label="item.deviceName" :value="item.id" v-for="(item,index) in parentDeviceList" :key="index+'parentDeviceList'" ></el-option>
|
<el-option :label="item.deviceName" :value="item.id" v-for="(item,index) in parentDeviceList" :key="index+'parentDeviceList'" ></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
@ -80,10 +80,10 @@
|
|||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import {mapState} from "vuex";
|
import {mapState} from "vuex";
|
||||||
import {getStackNameList} from '@/api/ems/dzjk'
|
|
||||||
import {getAllSites} from '@/api/ems/zddt'
|
import {getAllSites} from '@/api/ems/zddt'
|
||||||
import {validText} from '@/utils/validate'
|
import {validText} from '@/utils/validate'
|
||||||
import {getDeviceDetailInfo,getDeviceCategory,updateDevice,addDevice} from "@/api/ems/site";
|
import {getDeviceDetailInfo,updateDevice,addDevice,getParentDeviceId} from "@/api/ems/site";
|
||||||
|
import {getAllDeviceCategory} from '@/api/ems/search'
|
||||||
export default {
|
export default {
|
||||||
props:{
|
props:{
|
||||||
mode:{
|
mode:{
|
||||||
@ -112,7 +112,7 @@ export default {
|
|||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
loading:0,
|
loading:0,
|
||||||
dccDeviceCategory:'CLUSTER',
|
dccDeviceCategoryList:['CLUSTER','BATTERY'],//需要展示上级设备的设备类型
|
||||||
dialogTableVisible:false,
|
dialogTableVisible:false,
|
||||||
parentDeviceList:[],//上级设备列表 从接口获取数据
|
parentDeviceList:[],//上级设备列表 从接口获取数据
|
||||||
siteList:[],//站点列表 从接口获取数据
|
siteList:[],//站点列表 从接口获取数据
|
||||||
@ -195,24 +195,6 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
watch:{
|
watch:{
|
||||||
'formData.deviceCategory':{
|
|
||||||
handler(newVal){
|
|
||||||
// 只有电池簇需要选择上级设备 调用接口获取电池堆列表
|
|
||||||
if(newVal && newVal === this.dccDeviceCategory){
|
|
||||||
this.getParentDeviceList()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
immediate:true
|
|
||||||
},
|
|
||||||
'formData.siteId':{
|
|
||||||
handler(newVal,oldVal){
|
|
||||||
// 只有电池簇需要选择上级设备 调用接口获取电池堆列表
|
|
||||||
if(newVal && oldVal!== newVal && this.formData.deviceCategory === this.dccDeviceCategory){
|
|
||||||
this.getParentDeviceList()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
immediate:true
|
|
||||||
},
|
|
||||||
dialogTableVisible:{
|
dialogTableVisible:{
|
||||||
handler(newVal){
|
handler(newVal){
|
||||||
//打开弹窗
|
//打开弹窗
|
||||||
@ -229,6 +211,9 @@ export default {
|
|||||||
this.loading+=1
|
this.loading+=1
|
||||||
getDeviceDetailInfo(newVal).then(response => {
|
getDeviceDetailInfo(newVal).then(response => {
|
||||||
this.formData = JSON.parse(JSON.stringify(response?.data || {}));
|
this.formData = JSON.parse(JSON.stringify(response?.data || {}));
|
||||||
|
if(this.dccDeviceCategoryList.includes(this.formData.deviceCategory)){
|
||||||
|
this.getParentDeviceList(true)
|
||||||
|
}
|
||||||
}).finally(() => {this.loading-=1})
|
}).finally(() => {this.loading-=1})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -236,6 +221,11 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
changeType(){
|
||||||
|
if(this.dccDeviceCategoryList.includes(this.formData.deviceCategory)){
|
||||||
|
this.getParentDeviceList()
|
||||||
|
}
|
||||||
|
},
|
||||||
uploadImage(data){
|
uploadImage(data){
|
||||||
this.formData.pictureUrl = data
|
this.formData.pictureUrl = data
|
||||||
},
|
},
|
||||||
@ -249,18 +239,18 @@ export default {
|
|||||||
// 获取设备类别
|
// 获取设备类别
|
||||||
getDeviceCategoryList(){
|
getDeviceCategoryList(){
|
||||||
this.loading+=1
|
this.loading+=1
|
||||||
getDeviceCategory().then(response => {
|
getAllDeviceCategory().then(response => {
|
||||||
this.deviceCategoryList = response?.data || []
|
this.deviceCategoryList = response?.data || []
|
||||||
}).finally(() => {this.loading-=1})
|
}).finally(() => {this.loading-=1})
|
||||||
},
|
},
|
||||||
//获取上级id列表
|
//获取上级id列表
|
||||||
getParentDeviceList(){
|
getParentDeviceList(init=false){
|
||||||
if(!this.formData.siteId){
|
if(!this.formData.siteId){
|
||||||
return console.log('请先选择站点')
|
return console.log('请先选择站点')
|
||||||
}
|
}
|
||||||
this.formData.parentId=''
|
!init && (this.formData.parentId='')
|
||||||
this.loading= this.loading+1
|
this.loading= this.loading+1
|
||||||
getStackNameList(this.formData.siteId).then(response => {
|
getParentDeviceId({siteId:this.formData.siteId,deviceCategory:this.formData.deviceCategory}).then(response => {
|
||||||
this.parentDeviceList = JSON.parse(JSON.stringify(response?.data || []));
|
this.parentDeviceList = JSON.parse(JSON.stringify(response?.data || []));
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
this.loading=this.loading -1
|
this.loading=this.loading -1
|
||||||
@ -318,26 +308,26 @@ export default {
|
|||||||
closeDialog(){
|
closeDialog(){
|
||||||
this.$emit('clear')
|
this.$emit('clear')
|
||||||
// 清空所有数据
|
// 清空所有数据
|
||||||
this.$refs.addTempForm.resetFields()
|
|
||||||
this.formData= {
|
this.formData= {
|
||||||
id:'',//设备唯一标识
|
id:'',//设备唯一标识
|
||||||
siteId:'',//站点ID
|
siteId:'',//站点ID
|
||||||
deviceId:'',//设备id
|
deviceId:'',//设备id
|
||||||
deviceName:'',//设备名称
|
deviceName:'',//设备名称
|
||||||
description:'',//设备描述
|
description:'',//设备描述
|
||||||
communicationStatus:'',//工作状态
|
communicationStatus:'',//工作状态
|
||||||
deviceType:'',//设备类型
|
deviceType:'',//设备类型
|
||||||
deviceCategory:'',//设备类别
|
deviceCategory:'',//设备类别
|
||||||
parentId:'',//上级设备id
|
parentId:'',//上级设备id
|
||||||
ipAddress:'',//TCP设备的ip地址
|
ipAddress:'',//TCP设备的ip地址
|
||||||
ipPort:"",//TCP端口号
|
ipPort:"",//TCP端口号
|
||||||
serialPort:'',//串口路径
|
serialPort:'',//串口路径
|
||||||
baudRate:'',//波特率
|
baudRate:'',//波特率
|
||||||
dataBits:'',//数据位
|
dataBits:'',//数据位
|
||||||
stopBits:'',//停止位
|
stopBits:'',//停止位
|
||||||
parity:'',//校验位
|
parity:'',//校验位
|
||||||
pictureUrl:'',//设备图片
|
pictureUrl:'',//设备图片
|
||||||
}
|
}
|
||||||
|
this.$refs.addTempForm.resetFields()
|
||||||
this.dialogTableVisible=false
|
this.dialogTableVisible=false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
<!--电位展示图表-->
|
<!--电位展示图表-->
|
||||||
<template>
|
<template>
|
||||||
<el-dialog
|
<div>
|
||||||
|
<el-dialog
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
:visible.sync="show"
|
:visible.sync="show"
|
||||||
@ -9,46 +10,84 @@
|
|||||||
destroy-on-close
|
destroy-on-close
|
||||||
lock-scroll
|
lock-scroll
|
||||||
show-close
|
show-close
|
||||||
title="点位列表"
|
title="点位清单"
|
||||||
width="800px"
|
width="800px"
|
||||||
>
|
>
|
||||||
<div style="margin-bottom: 20px">
|
<el-form :inline="true" label-width="85px">
|
||||||
<el-input v-model="pointName" placeholder="请输入点位" clearable style="width: 200px"></el-input>
|
<el-form-item label="点位名称">
|
||||||
<!-- <el-autocomplete-->
|
<el-input
|
||||||
<!-- v-model="pointName"-->
|
v-model="form.dataPointName"
|
||||||
<!-- placeholder="请输入点位"-->
|
clearable
|
||||||
<!-- clearable-->
|
placeholder="请输入点位名称"
|
||||||
<!-- :fetch-suggestions="querySearchAsync"-->
|
style="width: 150px"
|
||||||
<!-- @select="handleSelect"-->
|
></el-input>
|
||||||
<!-- ></el-autocomplete>-->
|
</el-form-item>
|
||||||
|
<el-form-item label="点位">
|
||||||
|
<el-input
|
||||||
|
v-model="form.dataPoint"
|
||||||
|
clearable
|
||||||
|
placeholder="请输入点位"
|
||||||
|
style="width: 150px"
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<br />
|
||||||
|
<el-form-item label="最小值">
|
||||||
|
<el-input
|
||||||
|
v-model="form.lower"
|
||||||
|
clearable
|
||||||
|
placeholder="请输入最小值"
|
||||||
|
style="width: 150px"
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="最大值">
|
||||||
|
<el-input
|
||||||
|
v-model="form.upper"
|
||||||
|
clearable
|
||||||
|
placeholder="请输入最大值"
|
||||||
|
style="width: 150px"
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item style="margin-left: 20px">
|
||||||
|
<el-button type="primary" @click="search">搜索</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
<el-button type="primary" style="margin-left: 20px" @click="pointNameSearch">搜索</el-button>
|
<el-table
|
||||||
</div>
|
|
||||||
<el-table
|
|
||||||
:data="tableData"
|
:data="tableData"
|
||||||
class="common-table"
|
class="common-table"
|
||||||
max-height="400px"
|
max-height="400px"
|
||||||
stripe
|
stripe
|
||||||
style="width: 100%;">
|
style="width: 100%"
|
||||||
<el-table-column
|
:default-sort="defaultSort"
|
||||||
label="数据点位"
|
@sort-change="handleSortChange"
|
||||||
prop="dataPoint">
|
>
|
||||||
</el-table-column>
|
<el-table-column label="数据点位" prop="dataPoint"> </el-table-column>
|
||||||
<el-table-column
|
<el-table-column label="数据点位名称" prop="pointName">
|
||||||
label="数据点位名称"
|
</el-table-column>
|
||||||
prop="dataPointName">
|
<el-table-column
|
||||||
</el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
label="最新值"
|
label="最新值"
|
||||||
prop="pointValue">
|
prop="pointValue"
|
||||||
</el-table-column>
|
align="right"
|
||||||
<el-table-column
|
sortable="custom"
|
||||||
label="更新时间"
|
>
|
||||||
prop="updateTime">
|
<template slot-scope="scope">
|
||||||
</el-table-column>
|
<span
|
||||||
</el-table>
|
class="pointer"
|
||||||
<el-pagination
|
@click="
|
||||||
v-show="tableData.length>0"
|
showChart(
|
||||||
|
scope.row
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>{{ scope.row.pointValue }}</span
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="单位" prop="dataUnit"></el-table-column>
|
||||||
|
<el-table-column label="更新时间" prop="updateTime" sortable="custom">
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<el-pagination
|
||||||
|
v-show="tableData.length > 0"
|
||||||
:current-page="pageNum"
|
:current-page="pageNum"
|
||||||
:page-size="pageSize"
|
:page-size="pageSize"
|
||||||
:page-sizes="[10, 20, 30, 40]"
|
:page-sizes="[10, 20, 30, 40]"
|
||||||
@ -57,107 +96,158 @@
|
|||||||
background
|
background
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
small
|
small
|
||||||
style="margin-top:15px;text-align: center"
|
style="margin-top: 15px; text-align: center"
|
||||||
@size-change="handleSizeChange"
|
@size-change="handleSizeChange"
|
||||||
@current-change="handleCurrentChange"
|
@current-change="handleCurrentChange"
|
||||||
>
|
>
|
||||||
</el-pagination>
|
</el-pagination>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
<point-chart ref="pointChart" :site-id="siteId" />
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import {getDevicePointList} from "@/api/ems/site";
|
import { getDevicePointList } from "@/api/ems/site";
|
||||||
import {pointFuzzyQuery} from "@/api/ems/search";
|
import pointChart from "@/views/ems/dzjk/sbjk/PointChart.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
watch:{
|
components: { pointChart },
|
||||||
|
watch: {
|
||||||
show(val) {
|
show(val) {
|
||||||
if(!val){
|
if (!val) {
|
||||||
this.tableData=[]
|
this.tableData = [];
|
||||||
this.deviceId=''
|
this.deviceId = "";
|
||||||
this.deviceName=''
|
this.parentId='';
|
||||||
this.siteId=''
|
this.siteId = "";
|
||||||
this.pageSize=10
|
this.pageSize = 10;
|
||||||
this.pageNum=1
|
this.pageNum = 1;
|
||||||
this.totalSize=0
|
this.totalSize = 0;
|
||||||
this.pointName=''
|
this.form = {
|
||||||
this.loading =false
|
sortMethod: "desc", //升序不传或者asc、降序desc)
|
||||||
|
sortData:this.defaultSort.prop,
|
||||||
|
dataPointName: "", //点位名称
|
||||||
|
dataPoint: "", //点位名称
|
||||||
|
lower: "", //
|
||||||
|
upper: "", //
|
||||||
|
};
|
||||||
|
this.loading = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data(){
|
computed:{
|
||||||
return{
|
isDtdc(){
|
||||||
show:false,
|
return this.deviceCategory === 'BATTERY'
|
||||||
loading:false,
|
|
||||||
pointName:'',//点位名称
|
|
||||||
deviceCategory:'',
|
|
||||||
deviceName:'',
|
|
||||||
deviceId:'',
|
|
||||||
siteId:'',
|
|
||||||
tableData:[],
|
|
||||||
pageSize:10,//分页栏当前每个数据总数
|
|
||||||
pageNum:1,//分页栏当前页数
|
|
||||||
totalSize:0,//table表格数据总数
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods:{
|
data() {
|
||||||
pointNameSearch(){
|
return {
|
||||||
this.pageNum=1
|
// 默认排序
|
||||||
this.getData()
|
defaultSort: { prop: "updateTime", order: "descending" },
|
||||||
|
show: false,
|
||||||
|
loading: false,
|
||||||
|
form: {
|
||||||
|
sortData: "updateTime", //最新值升序不传或者asc、降序desc)
|
||||||
|
sortMethod: "desc", //升序不传或者asc、降序desc)
|
||||||
|
dataPointName: "", //点位名称
|
||||||
|
dataPoint: "", //点位名称
|
||||||
|
lower: "", //
|
||||||
|
upper: "", //
|
||||||
|
},
|
||||||
|
deviceCategory: "",
|
||||||
|
deviceId: "",
|
||||||
|
parentId:'',
|
||||||
|
siteId: "",
|
||||||
|
tableData: [],
|
||||||
|
pageSize: 10, //分页栏当前每个数据总数
|
||||||
|
pageNum: 1, //分页栏当前页数
|
||||||
|
totalSize: 0, //table表格数据总数
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
showChart({pointName}) {
|
||||||
|
if(pointName){
|
||||||
|
const {deviceCategory,deviceId}=this
|
||||||
|
if(this.isDtdc) this.$refs.pointChart.showChart({ pointName, deviceCategory, deviceId:this.parentId,child:[deviceId] });
|
||||||
|
else this.$refs.pointChart.showChart({ pointName, deviceCategory, deviceId });
|
||||||
|
}
|
||||||
},
|
},
|
||||||
showTable({deviceCategory,siteId,deviceId,deviceName}){
|
handleSortChange(column) {
|
||||||
this.deviceCategory =deviceCategory
|
this.form.sortData = column.prop
|
||||||
this.siteId=siteId
|
this.form.sortMethod = column.order === "descending" ? "desc" : "asc";
|
||||||
this.deviceId=deviceId
|
console.log("切换排序方式", column, this.form);
|
||||||
this.deviceName=deviceName
|
this.getData();
|
||||||
this.show=true
|
|
||||||
this.getData()
|
|
||||||
},
|
},
|
||||||
getData(){
|
search() {
|
||||||
this.loading=true
|
this.pageNum = 1;
|
||||||
const {siteId,deviceId,deviceCategory,pageNum,pageSize,pointName} =this
|
this.getData();
|
||||||
getDevicePointList({siteId,deviceId,deviceCategory,pageNum,pageSize,dataPointName:pointName}).then(response => {
|
},
|
||||||
this.tableData=response?.rows || [];
|
showTable({ deviceCategory, siteId, deviceId ,parentId=''}) {
|
||||||
this.totalSize = response?.total || 0
|
this.deviceCategory = deviceCategory;
|
||||||
}).finally(() => {this.loading=false})
|
this.siteId = siteId;
|
||||||
|
this.deviceId = deviceId;
|
||||||
|
this.parentId=deviceCategory === 'BATTERY' ? parentId : ''//只有单体电池需要这个值
|
||||||
|
this.show = true;
|
||||||
|
this.getData();
|
||||||
|
},
|
||||||
|
getData() {
|
||||||
|
this.loading = true;
|
||||||
|
const {
|
||||||
|
siteId,
|
||||||
|
deviceId,
|
||||||
|
deviceCategory,
|
||||||
|
parentId,
|
||||||
|
pageNum,
|
||||||
|
pageSize,
|
||||||
|
form: {
|
||||||
|
sortData,
|
||||||
|
sortMethod,
|
||||||
|
dataPointName,
|
||||||
|
dataPoint,
|
||||||
|
lower,
|
||||||
|
upper,
|
||||||
|
},
|
||||||
|
} = this;
|
||||||
|
getDevicePointList({
|
||||||
|
siteId,
|
||||||
|
deviceId,
|
||||||
|
deviceCategory,
|
||||||
|
parentId,
|
||||||
|
pageNum,
|
||||||
|
pageSize,
|
||||||
|
sortData,
|
||||||
|
sortMethod,
|
||||||
|
dataPointName,
|
||||||
|
dataPoint,
|
||||||
|
lower,
|
||||||
|
upper,
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
this.tableData = response?.rows || [];
|
||||||
|
this.totalSize = response?.total || 0;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
// 分页
|
// 分页
|
||||||
handleSizeChange(val) {
|
handleSizeChange(val) {
|
||||||
this.pageSize = val;
|
this.pageSize = val;
|
||||||
this.$nextTick(()=>{
|
this.$nextTick(() => {
|
||||||
this.getData()
|
this.getData();
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
handleCurrentChange(val) {
|
handleCurrentChange(val) {
|
||||||
this.pageNum = val
|
this.pageNum = val;
|
||||||
this.$nextTick(()=>{
|
this.$nextTick(() => {
|
||||||
this.getData()
|
this.getData();
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
//点位
|
},
|
||||||
handleSelect(data){
|
};
|
||||||
this.pointName = data.value
|
|
||||||
},
|
|
||||||
querySearchAsync(query,cb){
|
|
||||||
console.log('查询数据',query)
|
|
||||||
pointFuzzyQuery({
|
|
||||||
siteIds:[this.siteId],
|
|
||||||
categoryName:this.deviceName,
|
|
||||||
pointName:query,
|
|
||||||
}).then(response => {
|
|
||||||
const data = response?.data || []
|
|
||||||
cb(data.map(item => {
|
|
||||||
return {name: item, value: item}
|
|
||||||
}))
|
|
||||||
})
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
::v-deep {
|
::v-deep {
|
||||||
.card-title .el-radio{
|
.card-title .el-radio {
|
||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
</style>
|
||||||
</style>
|
|
||||||
|
|||||||
@ -3,13 +3,13 @@
|
|||||||
<div class="ems-dashboard-editor-container" style="background-color: #ffffff" v-loading="loading">
|
<div class="ems-dashboard-editor-container" style="background-color: #ffffff" v-loading="loading">
|
||||||
<el-form :inline="true" class="select-container">
|
<el-form :inline="true" class="select-container">
|
||||||
<el-form-item label="站点选择">
|
<el-form-item label="站点选择">
|
||||||
<el-select v-model="siteId" placeholder="请选择换电站名称" :loading="loading" loading-text="正在加载数据" @change="onSearch">
|
<el-select v-model="siteId" placeholder="请选择换电站名称" :loading="searchLoading" loading-text="正在加载数据" @change="onSearch" clearable>
|
||||||
<el-option :label="item.siteName" :value="item.siteId" v-for="(item,index) in siteList" :key="index+'zdxeSelect'"></el-option>
|
<el-option :label="item.siteName" :value="item.siteId" v-for="(item,index) in siteList" :key="index+'zdxeSelect'"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<!-- <el-button type="primary" @click="onSearch" native-type="button">搜索</el-button>-->
|
<!-- <el-button type="primary" @click="onSearch" native-type="button">搜索</el-button>-->
|
||||||
<el-button @click="onReset" native-type="button">重置</el-button>
|
<!-- <el-button @click="onReset" native-type="button">重置</el-button>-->
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<el-button type="primary" @click="addDevice" native-type="button">新增设备</el-button>
|
<el-button type="primary" @click="addDevice" native-type="button">新增设备</el-button>
|
||||||
@ -37,14 +37,14 @@
|
|||||||
label="设备名称">
|
label="设备名称">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="deviceType"
|
prop="categoryName"
|
||||||
label="设备类型">
|
label="设备类别">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="communicationStatus"
|
prop="runningStatus"
|
||||||
label="通信状态">
|
label="在线状态">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span>{{$store.state.ems.communicationStatusOptions[scope.row.communicationStatus]}}</span>
|
<span>{{$store.state.ems.deviceStatusOptions[scope.row.runningStatus]}}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
@ -52,17 +52,11 @@
|
|||||||
label="操作"
|
label="操作"
|
||||||
width="260">
|
width="260">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<!-- <el-button-->
|
|
||||||
<!-- @click="toDetail(scope.row.id)"-->
|
|
||||||
<!-- type="primary"-->
|
|
||||||
<!-- size="mini">-->
|
|
||||||
<!-- 查看详情-->
|
|
||||||
<!-- </el-button>-->
|
|
||||||
<el-button
|
<el-button
|
||||||
@click="pointDetail(scope.row)"
|
@click="pointDetail(scope.row)"
|
||||||
type="primary"
|
type="primary"
|
||||||
size="mini">
|
size="mini">
|
||||||
点位列表
|
点位清单
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
@click="editDevice(scope.row)"
|
@click="editDevice(scope.row)"
|
||||||
@ -257,14 +251,19 @@ export default {
|
|||||||
//获取站点列表
|
//获取站点列表
|
||||||
getZdList(){
|
getZdList(){
|
||||||
this.searchLoading=true
|
this.searchLoading=true
|
||||||
getAllSites().then(response => {
|
return getAllSites().then(response => {
|
||||||
this.siteList = response?.data || []
|
this.siteList = response?.data || []
|
||||||
|
if(this.siteList.length>0) this.siteId = this.siteList[0].siteId
|
||||||
}).finally(() => {this.searchLoading=false})
|
}).finally(() => {this.searchLoading=false})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.onReset()
|
this.loading=true
|
||||||
this.getZdList()
|
this.siteId=''
|
||||||
|
this.pageNum =1//每次搜索从1开始搜索
|
||||||
|
this.getZdList().then(()=>{
|
||||||
|
this.getData()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog v-loading="loading>0" :visible.sync="dialogTableVisible" class="ems-dialog" :title="mode === 'add'?'新增工单':`编辑工单` " :close-on-click-modal="false" :show-close="false">
|
<el-dialog v-loading="loading>0" :visible.sync="dialogTableVisible" class="ems-dialog" :title="mode === 'add'?'新增工单':`编辑工单`" :close-on-press-escape="false" :close-on-click-modal="false" :show-close="false">
|
||||||
<el-form ref="addTempForm" :model="formData" :rules="rules" size="medium" label-width="120px">
|
<el-form ref="addTempForm" :model="formData" :rules="rules" size="medium" label-width="120px">
|
||||||
<el-form-item label="工单号" prop="ticketNo" v-if="mode !== 'add'">
|
<el-form-item label="工单号" prop="ticketNo" v-if="mode !== 'add'">
|
||||||
<el-input disabled v-model="formData.ticketNo" clearable :style="{width: '100%'}">
|
<el-input disabled v-model="formData.ticketNo" clearable :style="{width: '100%'}">
|
||||||
@ -159,7 +159,7 @@ export default {
|
|||||||
this.$refs.addTempForm.validate(valid => {
|
this.$refs.addTempForm.validate(valid => {
|
||||||
if (!valid) return
|
if (!valid) return
|
||||||
this.loading+=1
|
this.loading+=1
|
||||||
const {title='',content='',status='',userId='',workUserId='',id='',expectedCompleteTime=''} = this.formData;
|
const {title='',content='',status='',userId='',workUserId='',id='',expectedCompleteTime='',ticketNo=''} = this.formData;
|
||||||
if(this.mode === 'add'){
|
if(this.mode === 'add'){
|
||||||
addTicket({title,content,status,userId,workUserId,expectedCompleteTime}).then(response => {
|
addTicket({title,content,status,userId,workUserId,expectedCompleteTime}).then(response => {
|
||||||
if(response.code === 200){
|
if(response.code === 200){
|
||||||
@ -172,7 +172,7 @@ export default {
|
|||||||
this.loading-=1
|
this.loading-=1
|
||||||
})
|
})
|
||||||
}else{
|
}else{
|
||||||
updateTicket({title,content,status,userId,workUserId,id,expectedCompleteTime}).then(response => {
|
updateTicket({title,content,status,userId,workUserId,id,expectedCompleteTime,ticketNo}).then(response => {
|
||||||
if(response.code === 200){
|
if(response.code === 200){
|
||||||
//新增成功
|
//新增成功
|
||||||
// 关闭弹窗 更新表格
|
// 关闭弹窗 更新表格
|
||||||
|
|||||||
@ -1,7 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="login">
|
<div class="login">
|
||||||
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
|
<img :src="loginBg" alt="" srcset="" class="login-bg" />
|
||||||
<h3 class="title">{{title}}</h3>
|
<el-form
|
||||||
|
ref="loginForm"
|
||||||
|
:model="loginForm"
|
||||||
|
:rules="loginRules"
|
||||||
|
class="login-form"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="./../assets/images/ems/logo.png"
|
||||||
|
alt=""
|
||||||
|
srcset=""
|
||||||
|
class="login-logo"
|
||||||
|
/>
|
||||||
<el-form-item prop="username">
|
<el-form-item prop="username">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="loginForm.username"
|
v-model="loginForm.username"
|
||||||
@ -9,7 +20,11 @@
|
|||||||
auto-complete="off"
|
auto-complete="off"
|
||||||
placeholder="账号"
|
placeholder="账号"
|
||||||
>
|
>
|
||||||
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
|
<svg-icon
|
||||||
|
slot="prefix"
|
||||||
|
icon-class="user"
|
||||||
|
class="el-input__icon input-icon"
|
||||||
|
/>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="password">
|
<el-form-item prop="password">
|
||||||
@ -20,7 +35,11 @@
|
|||||||
placeholder="密码"
|
placeholder="密码"
|
||||||
@keyup.enter.native="handleLogin"
|
@keyup.enter.native="handleLogin"
|
||||||
>
|
>
|
||||||
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
|
<svg-icon
|
||||||
|
slot="prefix"
|
||||||
|
icon-class="password"
|
||||||
|
class="el-input__icon input-icon"
|
||||||
|
/>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="code" v-if="captchaEnabled">
|
<el-form-item prop="code" v-if="captchaEnabled">
|
||||||
@ -31,152 +50,194 @@
|
|||||||
style="width: 63%"
|
style="width: 63%"
|
||||||
@keyup.enter.native="handleLogin"
|
@keyup.enter.native="handleLogin"
|
||||||
>
|
>
|
||||||
<svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" />
|
<svg-icon
|
||||||
|
slot="prefix"
|
||||||
|
icon-class="validCode"
|
||||||
|
class="el-input__icon input-icon"
|
||||||
|
/>
|
||||||
</el-input>
|
</el-input>
|
||||||
<div class="login-code">
|
<div class="login-code">
|
||||||
<img :src="codeUrl" @click="getCode" class="login-code-img"/>
|
<img :src="codeUrl" @click="getCode" class="login-code-img" />
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox>
|
<el-checkbox
|
||||||
<el-form-item style="width:100%;">
|
v-model="loginForm.rememberMe"
|
||||||
|
style="margin: 0px 0px 25px 0px"
|
||||||
|
>记住密码</el-checkbox
|
||||||
|
>
|
||||||
|
<el-form-item style="width: 100%">
|
||||||
<el-button
|
<el-button
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
size="medium"
|
size="medium"
|
||||||
type="primary"
|
type="primary"
|
||||||
style="width:100%;"
|
style="width: 100%"
|
||||||
@click.native.prevent="handleLogin"
|
@click.native.prevent="handleLogin"
|
||||||
>
|
>
|
||||||
<span v-if="!loading">登 录</span>
|
<span v-if="!loading">登 录</span>
|
||||||
<span v-else>登 录 中...</span>
|
<span v-else>登 录 中...</span>
|
||||||
</el-button>
|
</el-button>
|
||||||
<div style="float: right;" v-if="register">
|
<div style="float: right" v-if="register">
|
||||||
<router-link class="link-type" :to="'/register'">立即注册</router-link>
|
<router-link class="link-type" :to="'/register'"
|
||||||
|
>立即注册</router-link
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<!-- 底部 -->
|
<!-- 底部 -->
|
||||||
<div class="el-login-footer">
|
<div class="el-login-footer">
|
||||||
<span>Copyright © 2025 上海电动工具研究所(集团)有限公司.</span>
|
<span>Copyright © 2025 上动新能源 版权所有</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getCodeImg } from "@/api/login"
|
import { getCodeImg } from "@/api/login";
|
||||||
import Cookies from "js-cookie"
|
import Cookies from "js-cookie";
|
||||||
import { encrypt, decrypt } from '@/utils/jsencrypt'
|
import { encrypt, decrypt } from "@/utils/jsencrypt";
|
||||||
|
import intervalUpdate from "@/mixins/ems/intervalUpdate";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Login",
|
name: "Login",
|
||||||
|
mixins: [intervalUpdate],
|
||||||
|
computed: {
|
||||||
|
loginBg() {
|
||||||
|
return require(`./../assets/images/ems/loginBg/${this.bgNum}.png`);
|
||||||
|
},
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
title: process.env.VUE_APP_TITLE,
|
bgNum: 1,
|
||||||
codeUrl: "",
|
codeUrl: "",
|
||||||
loginForm: {
|
loginForm: {
|
||||||
username: "admin",
|
username: "admin",
|
||||||
password: "admin123",
|
password: "admin123",
|
||||||
rememberMe: false,
|
rememberMe: false,
|
||||||
code: "",
|
code: "",
|
||||||
uuid: ""
|
uuid: "",
|
||||||
},
|
},
|
||||||
loginRules: {
|
loginRules: {
|
||||||
username: [
|
username: [
|
||||||
{ required: true, trigger: "blur", message: "请输入您的账号" }
|
{ required: true, trigger: "blur", message: "请输入您的账号" },
|
||||||
],
|
],
|
||||||
password: [
|
password: [
|
||||||
{ required: true, trigger: "blur", message: "请输入您的密码" }
|
{ required: true, trigger: "blur", message: "请输入您的密码" },
|
||||||
],
|
],
|
||||||
code: [{ required: true, trigger: "change", message: "请输入验证码" }]
|
code: [{ required: true, trigger: "change", message: "请输入验证码" }],
|
||||||
},
|
},
|
||||||
loading: false,
|
loading: false,
|
||||||
// 验证码开关
|
// 验证码开关
|
||||||
captchaEnabled: true,
|
captchaEnabled: true,
|
||||||
// 注册开关
|
// 注册开关
|
||||||
register: false,
|
register: false,
|
||||||
redirect: undefined
|
redirect: undefined,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
$route: {
|
$route: {
|
||||||
handler: function(route) {
|
handler: function (route) {
|
||||||
this.redirect = route.query && route.query.redirect
|
this.redirect = route.query && route.query.redirect;
|
||||||
},
|
},
|
||||||
immediate: true
|
immediate: true,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.getCode()
|
this.getCode();
|
||||||
this.getCookie()
|
this.getCookie();
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.updateInterval(this.updateBgNum, 5000);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
updateBgNum() {
|
||||||
|
if (this.bgNum >= 4) this.bgNum = 0;
|
||||||
|
this.bgNum += 1;
|
||||||
|
},
|
||||||
getCode() {
|
getCode() {
|
||||||
getCodeImg().then(res => {
|
getCodeImg().then((res) => {
|
||||||
this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled
|
this.captchaEnabled =
|
||||||
|
res.captchaEnabled === undefined ? true : res.captchaEnabled;
|
||||||
if (this.captchaEnabled) {
|
if (this.captchaEnabled) {
|
||||||
this.codeUrl = "data:image/gif;base64," + res.img
|
this.codeUrl = "data:image/gif;base64," + res.img;
|
||||||
this.loginForm.uuid = res.uuid
|
this.loginForm.uuid = res.uuid;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
getCookie() {
|
getCookie() {
|
||||||
const username = Cookies.get("username")
|
const username = Cookies.get("username");
|
||||||
const password = Cookies.get("password")
|
const password = Cookies.get("password");
|
||||||
const rememberMe = Cookies.get('rememberMe')
|
const rememberMe = Cookies.get("rememberMe");
|
||||||
this.loginForm = {
|
this.loginForm = {
|
||||||
username: username === undefined ? this.loginForm.username : username,
|
username: username === undefined ? this.loginForm.username : username,
|
||||||
password: password === undefined ? this.loginForm.password : decrypt(password),
|
password:
|
||||||
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
|
password === undefined ? this.loginForm.password : decrypt(password),
|
||||||
}
|
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe),
|
||||||
|
};
|
||||||
},
|
},
|
||||||
handleLogin() {
|
handleLogin() {
|
||||||
this.$refs.loginForm.validate(valid => {
|
this.$refs.loginForm.validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
this.loading = true
|
this.loading = true;
|
||||||
if (this.loginForm.rememberMe) {
|
if (this.loginForm.rememberMe) {
|
||||||
Cookies.set("username", this.loginForm.username, { expires: 30 })
|
Cookies.set("username", this.loginForm.username, { expires: 30 });
|
||||||
Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 })
|
Cookies.set("password", encrypt(this.loginForm.password), {
|
||||||
Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 })
|
expires: 30,
|
||||||
|
});
|
||||||
|
Cookies.set("rememberMe", this.loginForm.rememberMe, {
|
||||||
|
expires: 30,
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
Cookies.remove("username")
|
Cookies.remove("username");
|
||||||
Cookies.remove("password")
|
Cookies.remove("password");
|
||||||
Cookies.remove('rememberMe')
|
Cookies.remove("rememberMe");
|
||||||
}
|
}
|
||||||
this.$store.dispatch("Login", this.loginForm).then(() => {
|
this.$store
|
||||||
this.$router.push({ path: this.redirect || "/" }).catch(()=>{})
|
.dispatch("Login", this.loginForm)
|
||||||
}).catch(() => {
|
.then(() => {
|
||||||
this.loading = false
|
this.$router.push({ path: this.redirect || "/" }).catch(() => {});
|
||||||
if (this.captchaEnabled) {
|
})
|
||||||
this.getCode()
|
.catch(() => {
|
||||||
}
|
this.loading = false;
|
||||||
})
|
if (this.captchaEnabled) {
|
||||||
|
this.getCode();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style rel="stylesheet/scss" lang="scss">
|
<style rel="stylesheet/scss" lang="scss">
|
||||||
.login {
|
.login {
|
||||||
|
padding-left: 180px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: left;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-image: url("../assets/images/ems/login-background.png");
|
|
||||||
background-size: cover;
|
|
||||||
}
|
}
|
||||||
.title {
|
.login-bg {
|
||||||
margin: 0px auto 30px auto;
|
position: absolute;
|
||||||
text-align: center;
|
top: 0;
|
||||||
color: #707070;
|
left: 0;
|
||||||
|
z-index: 1;
|
||||||
|
display: block;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.login-logo {
|
||||||
|
display: block;
|
||||||
|
width: 70%;
|
||||||
|
height: auto;
|
||||||
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-form {
|
.login-form {
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
width: 400px;
|
width: 400px;
|
||||||
padding: 25px 25px 5px 25px;
|
padding: 0 25px 5px 25px;
|
||||||
z-index: 1;
|
z-index: 2;
|
||||||
.el-input {
|
.el-input {
|
||||||
height: 38px;
|
height: 38px;
|
||||||
input {
|
input {
|
||||||
@ -204,6 +265,8 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.el-login-footer {
|
.el-login-footer {
|
||||||
|
margin-left: -180px;
|
||||||
|
z-index:2;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
|||||||
@ -1,10 +1,30 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="register">
|
<div class="register">
|
||||||
<el-form ref="registerForm" :model="registerForm" :rules="registerRules" class="register-form">
|
<img :src="loginBg" alt="" srcset="" class="login-bg" />
|
||||||
<h3 class="title">{{title}}</h3>
|
<el-form
|
||||||
|
ref="registerForm"
|
||||||
|
:model="registerForm"
|
||||||
|
:rules="registerRules"
|
||||||
|
class="register-form"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="./../assets/images/ems/logo.png"
|
||||||
|
alt=""
|
||||||
|
srcset=""
|
||||||
|
class="login-logo"
|
||||||
|
/>
|
||||||
<el-form-item prop="username">
|
<el-form-item prop="username">
|
||||||
<el-input v-model="registerForm.username" type="text" auto-complete="off" placeholder="账号">
|
<el-input
|
||||||
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
|
v-model="registerForm.username"
|
||||||
|
type="text"
|
||||||
|
auto-complete="off"
|
||||||
|
placeholder="账号"
|
||||||
|
>
|
||||||
|
<svg-icon
|
||||||
|
slot="prefix"
|
||||||
|
icon-class="user"
|
||||||
|
class="el-input__icon input-icon"
|
||||||
|
/>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="password">
|
<el-form-item prop="password">
|
||||||
@ -15,7 +35,11 @@
|
|||||||
placeholder="密码"
|
placeholder="密码"
|
||||||
@keyup.enter.native="handleRegister"
|
@keyup.enter.native="handleRegister"
|
||||||
>
|
>
|
||||||
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
|
<svg-icon
|
||||||
|
slot="prefix"
|
||||||
|
icon-class="password"
|
||||||
|
class="el-input__icon input-icon"
|
||||||
|
/>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="confirmPassword">
|
<el-form-item prop="confirmPassword">
|
||||||
@ -26,7 +50,11 @@
|
|||||||
placeholder="确认密码"
|
placeholder="确认密码"
|
||||||
@keyup.enter.native="handleRegister"
|
@keyup.enter.native="handleRegister"
|
||||||
>
|
>
|
||||||
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
|
<svg-icon
|
||||||
|
slot="prefix"
|
||||||
|
icon-class="password"
|
||||||
|
class="el-input__icon input-icon"
|
||||||
|
/>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="code" v-if="captchaEnabled">
|
<el-form-item prop="code" v-if="captchaEnabled">
|
||||||
@ -37,136 +65,190 @@
|
|||||||
style="width: 63%"
|
style="width: 63%"
|
||||||
@keyup.enter.native="handleRegister"
|
@keyup.enter.native="handleRegister"
|
||||||
>
|
>
|
||||||
<svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" />
|
<svg-icon
|
||||||
|
slot="prefix"
|
||||||
|
icon-class="validCode"
|
||||||
|
class="el-input__icon input-icon"
|
||||||
|
/>
|
||||||
</el-input>
|
</el-input>
|
||||||
<div class="register-code">
|
<div class="register-code">
|
||||||
<img :src="codeUrl" @click="getCode" class="register-code-img"/>
|
<img :src="codeUrl" @click="getCode" class="register-code-img" />
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item style="width:100%;">
|
<el-form-item style="width: 100%">
|
||||||
<el-button
|
<el-button
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
size="medium"
|
size="medium"
|
||||||
type="primary"
|
type="primary"
|
||||||
style="width:100%;"
|
style="width: 100%"
|
||||||
@click.native.prevent="handleRegister"
|
@click.native.prevent="handleRegister"
|
||||||
>
|
>
|
||||||
<span v-if="!loading">注 册</span>
|
<span v-if="!loading">注 册</span>
|
||||||
<span v-else>注 册 中...</span>
|
<span v-else>注 册 中...</span>
|
||||||
</el-button>
|
</el-button>
|
||||||
<div style="float: right;">
|
<div style="float: right">
|
||||||
<router-link class="link-type" :to="'/login'">使用已有账户登录</router-link>
|
<router-link class="link-type" :to="'/login'"
|
||||||
|
>使用已有账户登录</router-link
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<!-- 底部 -->
|
<!-- 底部 -->
|
||||||
<div class="el-register-footer">
|
<div class="el-register-footer">
|
||||||
<span>Copyright © 2018-2025 上海电动工具研究所(集团)有限公司.</span>
|
<span>Copyright © 2025 上动新能源 版权所有</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getCodeImg, register } from "@/api/login"
|
import { getCodeImg, register } from "@/api/login";
|
||||||
|
import intervalUpdate from "@/mixins/ems/intervalUpdate";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Register",
|
name: "Register",
|
||||||
|
mixins: [intervalUpdate],
|
||||||
|
computed: {
|
||||||
|
loginBg() {
|
||||||
|
return require(`./../assets/images/ems/loginBg/${this.bgNum}.png`);
|
||||||
|
},
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
const equalToPassword = (rule, value, callback) => {
|
const equalToPassword = (rule, value, callback) => {
|
||||||
if (this.registerForm.password !== value) {
|
if (this.registerForm.password !== value) {
|
||||||
callback(new Error("两次输入的密码不一致"))
|
callback(new Error("两次输入的密码不一致"));
|
||||||
} else {
|
} else {
|
||||||
callback()
|
callback();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
return {
|
return {
|
||||||
title: process.env.VUE_APP_TITLE,
|
bgNum: 1,
|
||||||
codeUrl: "",
|
codeUrl: "",
|
||||||
registerForm: {
|
registerForm: {
|
||||||
username: "",
|
username: "",
|
||||||
password: "",
|
password: "",
|
||||||
confirmPassword: "",
|
confirmPassword: "",
|
||||||
code: "",
|
code: "",
|
||||||
uuid: ""
|
uuid: "",
|
||||||
},
|
},
|
||||||
registerRules: {
|
registerRules: {
|
||||||
username: [
|
username: [
|
||||||
{ required: true, trigger: "blur", message: "请输入您的账号" },
|
{ required: true, trigger: "blur", message: "请输入您的账号" },
|
||||||
{ min: 2, max: 20, message: '用户账号长度必须介于 2 和 20 之间', trigger: 'blur' }
|
{
|
||||||
|
min: 2,
|
||||||
|
max: 20,
|
||||||
|
message: "用户账号长度必须介于 2 和 20 之间",
|
||||||
|
trigger: "blur",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
password: [
|
password: [
|
||||||
{ required: true, trigger: "blur", message: "请输入您的密码" },
|
{ required: true, trigger: "blur", message: "请输入您的密码" },
|
||||||
{ min: 5, max: 20, message: "用户密码长度必须介于 5 和 20 之间", trigger: "blur" },
|
{
|
||||||
{ pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\\ |", trigger: "blur" }
|
min: 5,
|
||||||
|
max: 20,
|
||||||
|
message: "用户密码长度必须介于 5 和 20 之间",
|
||||||
|
trigger: "blur",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: /^[^<>"'|\\]+$/,
|
||||||
|
message: "不能包含非法字符:< > \" ' \\\ |",
|
||||||
|
trigger: "blur",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
confirmPassword: [
|
confirmPassword: [
|
||||||
{ required: true, trigger: "blur", message: "请再次输入您的密码" },
|
{ required: true, trigger: "blur", message: "请再次输入您的密码" },
|
||||||
{ required: true, validator: equalToPassword, trigger: "blur" }
|
{ required: true, validator: equalToPassword, trigger: "blur" },
|
||||||
],
|
],
|
||||||
code: [{ required: true, trigger: "change", message: "请输入验证码" }]
|
code: [{ required: true, trigger: "change", message: "请输入验证码" }],
|
||||||
},
|
},
|
||||||
loading: false,
|
loading: false,
|
||||||
captchaEnabled: true
|
captchaEnabled: true,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.getCode()
|
this.getCode();
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.updateInterval(this.updateBgNum, 5000);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
updateBgNum() {
|
||||||
|
if (this.bgNum >= 4) this.bgNum = 0;
|
||||||
|
this.bgNum += 1;
|
||||||
|
},
|
||||||
getCode() {
|
getCode() {
|
||||||
getCodeImg().then(res => {
|
getCodeImg().then((res) => {
|
||||||
this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled
|
this.captchaEnabled =
|
||||||
|
res.captchaEnabled === undefined ? true : res.captchaEnabled;
|
||||||
if (this.captchaEnabled) {
|
if (this.captchaEnabled) {
|
||||||
this.codeUrl = "data:image/gif;base64," + res.img
|
this.codeUrl = "data:image/gif;base64," + res.img;
|
||||||
this.registerForm.uuid = res.uuid
|
this.registerForm.uuid = res.uuid;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
handleRegister() {
|
handleRegister() {
|
||||||
this.$refs.registerForm.validate(valid => {
|
this.$refs.registerForm.validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
this.loading = true
|
this.loading = true;
|
||||||
register(this.registerForm).then(res => {
|
register(this.registerForm)
|
||||||
const username = this.registerForm.username
|
.then((res) => {
|
||||||
this.$alert("<font color='red'>恭喜你,您的账号 " + username + " 注册成功!</font>", '系统提示', {
|
const username = this.registerForm.username;
|
||||||
dangerouslyUseHTMLString: true,
|
this.$alert(
|
||||||
type: 'success'
|
"<font color='red'>恭喜你,您的账号 " +
|
||||||
}).then(() => {
|
username +
|
||||||
this.$router.push("/login")
|
" 注册成功!</font>",
|
||||||
}).catch(() => {})
|
"系统提示",
|
||||||
}).catch(() => {
|
{
|
||||||
this.loading = false
|
dangerouslyUseHTMLString: true,
|
||||||
if (this.captchaEnabled) {
|
type: "success",
|
||||||
this.getCode()
|
}
|
||||||
}
|
)
|
||||||
})
|
.then(() => {
|
||||||
|
this.$router.push("/login");
|
||||||
|
})
|
||||||
|
.catch(() => {});
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.loading = false;
|
||||||
|
if (this.captchaEnabled) {
|
||||||
|
this.getCode();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style rel="stylesheet/scss" lang="scss">
|
<style rel="stylesheet/scss" lang="scss">
|
||||||
.register {
|
.register {
|
||||||
|
padding-left: 180px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: left;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-image: url("../assets/images/ems/login-background.png");
|
|
||||||
background-size: cover;
|
|
||||||
}
|
}
|
||||||
.title {
|
.login-bg {
|
||||||
margin: 0px auto 30px auto;
|
position: absolute;
|
||||||
text-align: center;
|
top: 0;
|
||||||
color: #707070;
|
left: 0;
|
||||||
|
z-index: 1;
|
||||||
|
display: block;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.login-logo {
|
||||||
|
display: block;
|
||||||
|
width: 70%;
|
||||||
|
height: auto;
|
||||||
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.register-form {
|
.register-form {
|
||||||
|
z-index: 2;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
width: 400px;
|
width: 400px;
|
||||||
padding: 25px 25px 5px 25px;
|
padding: 0 25px 5px 25px;
|
||||||
.el-input {
|
.el-input {
|
||||||
height: 38px;
|
height: 38px;
|
||||||
input {
|
input {
|
||||||
@ -194,6 +276,8 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.el-register-footer {
|
.el-register-footer {
|
||||||
|
margin-left: -180px;
|
||||||
|
z-index:2;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
|||||||
@ -2,9 +2,7 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="left-board">
|
<div class="left-board">
|
||||||
<div class="logo-wrapper">
|
<div class="logo-wrapper">
|
||||||
<div class="logo">
|
<div class="logo"><img :src="logo" alt="logo" /> Form Generator</div>
|
||||||
<img :src="logo" alt="logo"> Form Generator
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<el-scrollbar class="left-scrollbar">
|
<el-scrollbar class="left-scrollbar">
|
||||||
<div class="components-list">
|
<div class="components-list">
|
||||||
@ -21,7 +19,9 @@
|
|||||||
@end="onEnd"
|
@end="onEnd"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-for="(element, index) in inputComponents" :key="index" class="components-item"
|
v-for="(element, index) in inputComponents"
|
||||||
|
:key="index"
|
||||||
|
class="components-item"
|
||||||
@click="addComponent(element)"
|
@click="addComponent(element)"
|
||||||
>
|
>
|
||||||
<div class="components-body">
|
<div class="components-body">
|
||||||
@ -58,12 +58,18 @@
|
|||||||
<svg-icon icon-class="component" /> 布局型组件
|
<svg-icon icon-class="component" /> 布局型组件
|
||||||
</div>
|
</div>
|
||||||
<draggable
|
<draggable
|
||||||
class="components-draggable" :list="layoutComponents"
|
class="components-draggable"
|
||||||
:group="{ name: 'componentsGroup', pull: 'clone', put: false }" :clone="cloneComponent"
|
:list="layoutComponents"
|
||||||
draggable=".components-item" :sort="false" @end="onEnd"
|
:group="{ name: 'componentsGroup', pull: 'clone', put: false }"
|
||||||
|
:clone="cloneComponent"
|
||||||
|
draggable=".components-item"
|
||||||
|
:sort="false"
|
||||||
|
@end="onEnd"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-for="(element, index) in layoutComponents" :key="index" class="components-item"
|
v-for="(element, index) in layoutComponents"
|
||||||
|
:key="index"
|
||||||
|
class="components-item"
|
||||||
@click="addComponent(element)"
|
@click="addComponent(element)"
|
||||||
>
|
>
|
||||||
<div class="components-body">
|
<div class="components-body">
|
||||||
@ -81,10 +87,20 @@
|
|||||||
<el-button icon="el-icon-download" type="text" @click="download">
|
<el-button icon="el-icon-download" type="text" @click="download">
|
||||||
导出vue文件
|
导出vue文件
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button class="copy-btn-main" icon="el-icon-document-copy" type="text" @click="copy">
|
<el-button
|
||||||
|
class="copy-btn-main"
|
||||||
|
icon="el-icon-document-copy"
|
||||||
|
type="text"
|
||||||
|
@click="copy"
|
||||||
|
>
|
||||||
复制代码
|
复制代码
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button class="delete-btn" icon="el-icon-delete" type="text" @click="empty">
|
<el-button
|
||||||
|
class="delete-btn"
|
||||||
|
icon="el-icon-delete"
|
||||||
|
type="text"
|
||||||
|
@click="empty"
|
||||||
|
>
|
||||||
清空
|
清空
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
@ -96,7 +112,12 @@
|
|||||||
:disabled="formConf.disabled"
|
:disabled="formConf.disabled"
|
||||||
:label-width="formConf.labelWidth + 'px'"
|
:label-width="formConf.labelWidth + 'px'"
|
||||||
>
|
>
|
||||||
<draggable class="drawing-board" :list="drawingList" :animation="340" group="componentsGroup">
|
<draggable
|
||||||
|
class="drawing-board"
|
||||||
|
:list="drawingList"
|
||||||
|
:animation="340"
|
||||||
|
group="componentsGroup"
|
||||||
|
>
|
||||||
<draggable-item
|
<draggable-item
|
||||||
v-for="(element, index) in drawingList"
|
v-for="(element, index) in drawingList"
|
||||||
:key="element.renderKey"
|
:key="element.renderKey"
|
||||||
@ -131,28 +152,38 @@
|
|||||||
:show-file-name="showFileName"
|
:show-file-name="showFileName"
|
||||||
@confirm="generate"
|
@confirm="generate"
|
||||||
/>
|
/>
|
||||||
<input id="copyNode" type="hidden">
|
<input id="copyNode" type="hidden" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import draggable from 'vuedraggable'
|
import draggable from "vuedraggable";
|
||||||
import beautifier from 'js-beautify'
|
import beautifier from "js-beautify";
|
||||||
import ClipboardJS from 'clipboard'
|
import ClipboardJS from "clipboard";
|
||||||
import render from '@/utils/generator/render'
|
import render from "@/utils/generator/render";
|
||||||
import RightPanel from './RightPanel'
|
import RightPanel from "./RightPanel";
|
||||||
import { inputComponents, selectComponents, layoutComponents, formConf } from '@/utils/generator/config'
|
import {
|
||||||
import { beautifierConf, titleCase } from '@/utils/index'
|
inputComponents,
|
||||||
import { makeUpHtml, vueTemplate, vueScript, cssStyle } from '@/utils/generator/html'
|
selectComponents,
|
||||||
import { makeUpJs } from '@/utils/generator/js'
|
layoutComponents,
|
||||||
import { makeUpCss } from '@/utils/generator/css'
|
formConf,
|
||||||
import drawingDefault from '@/utils/generator/drawingDefault'
|
} from "@/utils/generator/config";
|
||||||
import logo from '@/assets/logo/logo.png'
|
import { beautifierConf, titleCase } from "@/utils/index";
|
||||||
import CodeTypeDialog from './CodeTypeDialog'
|
import {
|
||||||
import DraggableItem from './DraggableItem'
|
makeUpHtml,
|
||||||
|
vueTemplate,
|
||||||
|
vueScript,
|
||||||
|
cssStyle,
|
||||||
|
} from "@/utils/generator/html";
|
||||||
|
import { makeUpJs } from "@/utils/generator/js";
|
||||||
|
import { makeUpCss } from "@/utils/generator/css";
|
||||||
|
import drawingDefault from "@/utils/generator/drawingDefault";
|
||||||
|
import logo from "@/assets/images/ems/logo-icon.png";
|
||||||
|
import CodeTypeDialog from "./CodeTypeDialog";
|
||||||
|
import DraggableItem from "./DraggableItem";
|
||||||
|
|
||||||
let oldActiveId
|
let oldActiveId;
|
||||||
let tempActiveData
|
let tempActiveData;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@ -160,7 +191,7 @@ export default {
|
|||||||
render,
|
render,
|
||||||
RightPanel,
|
RightPanel,
|
||||||
CodeTypeDialog,
|
CodeTypeDialog,
|
||||||
DraggableItem
|
DraggableItem,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -179,207 +210,213 @@ export default {
|
|||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
generateConf: null,
|
generateConf: null,
|
||||||
showFileName: false,
|
showFileName: false,
|
||||||
activeData: drawingDefault[0]
|
activeData: drawingDefault[0],
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
// 防止 firefox 下 拖拽 会新打卡一个选项卡
|
// 防止 firefox 下 拖拽 会新打卡一个选项卡
|
||||||
document.body.ondrop = event => {
|
document.body.ondrop = (event) => {
|
||||||
event.preventDefault()
|
event.preventDefault();
|
||||||
event.stopPropagation()
|
event.stopPropagation();
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'activeData.label': function (val, oldVal) {
|
"activeData.label": function (val, oldVal) {
|
||||||
if (
|
if (
|
||||||
this.activeData.placeholder === undefined
|
this.activeData.placeholder === undefined ||
|
||||||
|| !this.activeData.tag
|
!this.activeData.tag ||
|
||||||
|| oldActiveId !== this.activeId
|
oldActiveId !== this.activeId
|
||||||
) {
|
) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
this.activeData.placeholder = this.activeData.placeholder.replace(oldVal, '') + val
|
this.activeData.placeholder =
|
||||||
|
this.activeData.placeholder.replace(oldVal, "") + val;
|
||||||
},
|
},
|
||||||
activeId: {
|
activeId: {
|
||||||
handler(val) {
|
handler(val) {
|
||||||
oldActiveId = val
|
oldActiveId = val;
|
||||||
},
|
},
|
||||||
immediate: true
|
immediate: true,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
const clipboard = new ClipboardJS('#copyNode', {
|
const clipboard = new ClipboardJS("#copyNode", {
|
||||||
text: trigger => {
|
text: (trigger) => {
|
||||||
const codeStr = this.generateCode()
|
const codeStr = this.generateCode();
|
||||||
this.$notify({
|
this.$notify({
|
||||||
title: '成功',
|
title: "成功",
|
||||||
message: '代码已复制到剪切板,可粘贴。',
|
message: "代码已复制到剪切板,可粘贴。",
|
||||||
type: 'success'
|
type: "success",
|
||||||
})
|
});
|
||||||
return codeStr
|
return codeStr;
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
clipboard.on('error', e => {
|
clipboard.on("error", (e) => {
|
||||||
this.$message.error('代码复制失败')
|
this.$message.error("代码复制失败");
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
activeFormItem(element) {
|
activeFormItem(element) {
|
||||||
this.activeData = element
|
this.activeData = element;
|
||||||
this.activeId = element.formId
|
this.activeId = element.formId;
|
||||||
},
|
},
|
||||||
onEnd(obj, a) {
|
onEnd(obj, a) {
|
||||||
if (obj.from !== obj.to) {
|
if (obj.from !== obj.to) {
|
||||||
this.activeData = tempActiveData
|
this.activeData = tempActiveData;
|
||||||
this.activeId = this.idGlobal
|
this.activeId = this.idGlobal;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
addComponent(item) {
|
addComponent(item) {
|
||||||
const clone = this.cloneComponent(item)
|
const clone = this.cloneComponent(item);
|
||||||
this.drawingList.push(clone)
|
this.drawingList.push(clone);
|
||||||
this.activeFormItem(clone)
|
this.activeFormItem(clone);
|
||||||
},
|
},
|
||||||
cloneComponent(origin) {
|
cloneComponent(origin) {
|
||||||
const clone = JSON.parse(JSON.stringify(origin))
|
const clone = JSON.parse(JSON.stringify(origin));
|
||||||
clone.formId = ++this.idGlobal
|
clone.formId = ++this.idGlobal;
|
||||||
clone.span = formConf.span
|
clone.span = formConf.span;
|
||||||
clone.renderKey = +new Date() // 改变renderKey后可以实现强制更新组件
|
clone.renderKey = +new Date(); // 改变renderKey后可以实现强制更新组件
|
||||||
if (!clone.layout) clone.layout = 'colFormItem'
|
if (!clone.layout) clone.layout = "colFormItem";
|
||||||
if (clone.layout === 'colFormItem') {
|
if (clone.layout === "colFormItem") {
|
||||||
clone.vModel = `field${this.idGlobal}`
|
clone.vModel = `field${this.idGlobal}`;
|
||||||
clone.placeholder !== undefined && (clone.placeholder += clone.label)
|
clone.placeholder !== undefined && (clone.placeholder += clone.label);
|
||||||
tempActiveData = clone
|
tempActiveData = clone;
|
||||||
} else if (clone.layout === 'rowFormItem') {
|
} else if (clone.layout === "rowFormItem") {
|
||||||
delete clone.label
|
delete clone.label;
|
||||||
clone.componentName = `row${this.idGlobal}`
|
clone.componentName = `row${this.idGlobal}`;
|
||||||
clone.gutter = this.formConf.gutter
|
clone.gutter = this.formConf.gutter;
|
||||||
tempActiveData = clone
|
tempActiveData = clone;
|
||||||
}
|
}
|
||||||
return tempActiveData
|
return tempActiveData;
|
||||||
},
|
},
|
||||||
AssembleFormData() {
|
AssembleFormData() {
|
||||||
this.formData = {
|
this.formData = {
|
||||||
fields: JSON.parse(JSON.stringify(this.drawingList)),
|
fields: JSON.parse(JSON.stringify(this.drawingList)),
|
||||||
...this.formConf
|
...this.formConf,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
generate(data) {
|
generate(data) {
|
||||||
const func = this[`exec${titleCase(this.operationType)}`]
|
const func = this[`exec${titleCase(this.operationType)}`];
|
||||||
this.generateConf = data
|
this.generateConf = data;
|
||||||
func && func(data)
|
func && func(data);
|
||||||
},
|
},
|
||||||
execRun(data) {
|
execRun(data) {
|
||||||
this.AssembleFormData()
|
this.AssembleFormData();
|
||||||
this.drawerVisible = true
|
this.drawerVisible = true;
|
||||||
},
|
},
|
||||||
execDownload(data) {
|
execDownload(data) {
|
||||||
const codeStr = this.generateCode()
|
const codeStr = this.generateCode();
|
||||||
const blob = new Blob([codeStr], { type: 'text/plain;charset=utf-8' })
|
const blob = new Blob([codeStr], { type: "text/plain;charset=utf-8" });
|
||||||
this.$download.saveAs(blob, data.fileName)
|
this.$download.saveAs(blob, data.fileName);
|
||||||
},
|
},
|
||||||
execCopy(data) {
|
execCopy(data) {
|
||||||
document.getElementById('copyNode').click()
|
document.getElementById("copyNode").click();
|
||||||
},
|
},
|
||||||
empty() {
|
empty() {
|
||||||
this.$confirm('确定要清空所有组件吗?', '提示', { type: 'warning' }).then(
|
this.$confirm("确定要清空所有组件吗?", "提示", { type: "warning" }).then(
|
||||||
() => {
|
() => {
|
||||||
this.drawingList = []
|
this.drawingList = [];
|
||||||
}
|
}
|
||||||
)
|
);
|
||||||
},
|
},
|
||||||
drawingItemCopy(item, parent) {
|
drawingItemCopy(item, parent) {
|
||||||
let clone = JSON.parse(JSON.stringify(item))
|
let clone = JSON.parse(JSON.stringify(item));
|
||||||
clone = this.createIdAndKey(clone)
|
clone = this.createIdAndKey(clone);
|
||||||
parent.push(clone)
|
parent.push(clone);
|
||||||
this.activeFormItem(clone)
|
this.activeFormItem(clone);
|
||||||
},
|
},
|
||||||
createIdAndKey(item) {
|
createIdAndKey(item) {
|
||||||
item.formId = ++this.idGlobal
|
item.formId = ++this.idGlobal;
|
||||||
item.renderKey = +new Date()
|
item.renderKey = +new Date();
|
||||||
if (item.layout === 'colFormItem') {
|
if (item.layout === "colFormItem") {
|
||||||
item.vModel = `field${this.idGlobal}`
|
item.vModel = `field${this.idGlobal}`;
|
||||||
} else if (item.layout === 'rowFormItem') {
|
} else if (item.layout === "rowFormItem") {
|
||||||
item.componentName = `row${this.idGlobal}`
|
item.componentName = `row${this.idGlobal}`;
|
||||||
}
|
}
|
||||||
if (Array.isArray(item.children)) {
|
if (Array.isArray(item.children)) {
|
||||||
item.children = item.children.map(childItem => this.createIdAndKey(childItem))
|
item.children = item.children.map((childItem) =>
|
||||||
|
this.createIdAndKey(childItem)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return item
|
return item;
|
||||||
},
|
},
|
||||||
drawingItemDelete(index, parent) {
|
drawingItemDelete(index, parent) {
|
||||||
parent.splice(index, 1)
|
parent.splice(index, 1);
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
const len = this.drawingList.length
|
const len = this.drawingList.length;
|
||||||
if (len) {
|
if (len) {
|
||||||
this.activeFormItem(this.drawingList[len - 1])
|
this.activeFormItem(this.drawingList[len - 1]);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
generateCode() {
|
generateCode() {
|
||||||
const { type } = this.generateConf
|
const { type } = this.generateConf;
|
||||||
this.AssembleFormData()
|
this.AssembleFormData();
|
||||||
const script = vueScript(makeUpJs(this.formData, type))
|
const script = vueScript(makeUpJs(this.formData, type));
|
||||||
const html = vueTemplate(makeUpHtml(this.formData, type))
|
const html = vueTemplate(makeUpHtml(this.formData, type));
|
||||||
const css = cssStyle(makeUpCss(this.formData))
|
const css = cssStyle(makeUpCss(this.formData));
|
||||||
return beautifier.html(html + script + css, beautifierConf.html)
|
return beautifier.html(html + script + css, beautifierConf.html);
|
||||||
},
|
},
|
||||||
download() {
|
download() {
|
||||||
this.dialogVisible = true
|
this.dialogVisible = true;
|
||||||
this.showFileName = true
|
this.showFileName = true;
|
||||||
this.operationType = 'download'
|
this.operationType = "download";
|
||||||
},
|
},
|
||||||
run() {
|
run() {
|
||||||
this.dialogVisible = true
|
this.dialogVisible = true;
|
||||||
this.showFileName = false
|
this.showFileName = false;
|
||||||
this.operationType = 'run'
|
this.operationType = "run";
|
||||||
},
|
},
|
||||||
copy() {
|
copy() {
|
||||||
this.dialogVisible = true
|
this.dialogVisible = true;
|
||||||
this.showFileName = false
|
this.showFileName = false;
|
||||||
this.operationType = 'copy'
|
this.operationType = "copy";
|
||||||
},
|
},
|
||||||
tagChange(newTag) {
|
tagChange(newTag) {
|
||||||
newTag = this.cloneComponent(newTag)
|
newTag = this.cloneComponent(newTag);
|
||||||
newTag.vModel = this.activeData.vModel
|
newTag.vModel = this.activeData.vModel;
|
||||||
newTag.formId = this.activeId
|
newTag.formId = this.activeId;
|
||||||
newTag.span = this.activeData.span
|
newTag.span = this.activeData.span;
|
||||||
delete this.activeData.tag
|
delete this.activeData.tag;
|
||||||
delete this.activeData.tagIcon
|
delete this.activeData.tagIcon;
|
||||||
delete this.activeData.document
|
delete this.activeData.document;
|
||||||
Object.keys(newTag).forEach(key => {
|
Object.keys(newTag).forEach((key) => {
|
||||||
if (this.activeData[key] !== undefined
|
if (
|
||||||
&& typeof this.activeData[key] === typeof newTag[key]) {
|
this.activeData[key] !== undefined &&
|
||||||
newTag[key] = this.activeData[key]
|
typeof this.activeData[key] === typeof newTag[key]
|
||||||
|
) {
|
||||||
|
newTag[key] = this.activeData[key];
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
this.activeData = newTag
|
this.activeData = newTag;
|
||||||
this.updateDrawingList(newTag, this.drawingList)
|
this.updateDrawingList(newTag, this.drawingList);
|
||||||
},
|
},
|
||||||
updateDrawingList(newTag, list) {
|
updateDrawingList(newTag, list) {
|
||||||
const index = list.findIndex(item => item.formId === this.activeId)
|
const index = list.findIndex((item) => item.formId === this.activeId);
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
list.splice(index, 1, newTag)
|
list.splice(index, 1, newTag);
|
||||||
} else {
|
} else {
|
||||||
list.forEach(item => {
|
list.forEach((item) => {
|
||||||
if (Array.isArray(item.children)) this.updateDrawingList(newTag, item.children)
|
if (Array.isArray(item.children))
|
||||||
})
|
this.updateDrawingList(newTag, item.children);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang='scss'>
|
<style lang="scss">
|
||||||
.editor-tabs{
|
.editor-tabs {
|
||||||
background: #121315;
|
background: #121315;
|
||||||
.el-tabs__header{
|
.el-tabs__header {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
border-bottom-color: #121315;
|
border-bottom-color: #121315;
|
||||||
.el-tabs__nav{
|
.el-tabs__nav {
|
||||||
border-color: #121315;
|
border-color: #121315;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.el-tabs__item{
|
.el-tabs__item {
|
||||||
height: 32px;
|
height: 32px;
|
||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
color: #888a8e;
|
color: #888a8e;
|
||||||
@ -388,15 +425,15 @@ export default {
|
|||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
.el-tabs__item.is-active{
|
.el-tabs__item.is-active {
|
||||||
background: #1e1e1e;
|
background: #1e1e1e;
|
||||||
border-bottom-color: #1e1e1e!important;
|
border-bottom-color: #1e1e1e !important;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
.el-icon-edit{
|
.el-icon-edit {
|
||||||
color: #f1fa8c;
|
color: #f1fa8c;
|
||||||
}
|
}
|
||||||
.el-icon-document{
|
.el-icon-document {
|
||||||
color: #a95812;
|
color: #a95812;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -412,24 +449,24 @@ export default {
|
|||||||
overflow-x: hidden !important;
|
overflow-x: hidden !important;
|
||||||
margin-bottom: 0 !important;
|
margin-bottom: 0 !important;
|
||||||
}
|
}
|
||||||
.center-tabs{
|
.center-tabs {
|
||||||
.el-tabs__header{
|
.el-tabs__header {
|
||||||
margin-bottom: 0!important;
|
margin-bottom: 0 !important;
|
||||||
}
|
}
|
||||||
.el-tabs__item{
|
.el-tabs__item {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.el-tabs__nav{
|
.el-tabs__nav {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.reg-item{
|
.reg-item {
|
||||||
padding: 12px 6px;
|
padding: 12px 6px;
|
||||||
background: #f8f8f8;
|
background: #f8f8f8;
|
||||||
position: relative;
|
position: relative;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
.close-btn{
|
.close-btn {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: -6px;
|
right: -6px;
|
||||||
top: -6px;
|
top: -6px;
|
||||||
@ -444,16 +481,16 @@ export default {
|
|||||||
z-index: 1;
|
z-index: 1;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
&:hover{
|
&:hover {
|
||||||
background: rgba(210, 23, 23, 0.5)
|
background: rgba(210, 23, 23, 0.5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
& + .reg-item{
|
& + .reg-item {
|
||||||
margin-top: 18px;
|
margin-top: 18px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.action-bar{
|
.action-bar {
|
||||||
& .el-button+.el-button {
|
& .el-button + .el-button {
|
||||||
margin-left: 15px;
|
margin-left: 15px;
|
||||||
}
|
}
|
||||||
& i {
|
& i {
|
||||||
@ -464,37 +501,37 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-tree-node{
|
.custom-tree-node {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
.node-operation{
|
.node-operation {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
i[class*="el-icon"] + i[class*="el-icon"]{
|
i[class*="el-icon"] + i[class*="el-icon"] {
|
||||||
margin-left: 6px;
|
margin-left: 6px;
|
||||||
}
|
}
|
||||||
.el-icon-plus{
|
.el-icon-plus {
|
||||||
color: #409EFF;
|
color: #409eff;
|
||||||
}
|
}
|
||||||
.el-icon-delete{
|
.el-icon-delete {
|
||||||
color: #157a0c;
|
color: #157a0c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.left-scrollbar .el-scrollbar__view{
|
.left-scrollbar .el-scrollbar__view {
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-rate{
|
.el-rate {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: text-top;
|
vertical-align: text-top;
|
||||||
}
|
}
|
||||||
.el-upload__tip{
|
.el-upload__tip {
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
$selectedColor: #f6f7ff;
|
$selectedColor: #f6f7ff;
|
||||||
$lighterBlue: #409EFF;
|
$lighterBlue: #409eff;
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -513,14 +550,14 @@ $lighterBlue: #409EFF;
|
|||||||
transition: transform 0ms !important;
|
transition: transform 0ms !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.components-draggable{
|
.components-draggable {
|
||||||
padding-bottom: 20px;
|
padding-bottom: 20px;
|
||||||
}
|
}
|
||||||
.components-title{
|
.components-title {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #222;
|
color: #222;
|
||||||
margin: 6px 2px;
|
margin: 6px 2px;
|
||||||
.svg-icon{
|
.svg-icon {
|
||||||
color: #666;
|
color: #666;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
}
|
}
|
||||||
@ -533,7 +570,7 @@ $lighterBlue: #409EFF;
|
|||||||
cursor: move;
|
cursor: move;
|
||||||
border: 1px dashed $selectedColor;
|
border: 1px dashed $selectedColor;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
.svg-icon{
|
.svg-icon {
|
||||||
color: #777;
|
color: #777;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
}
|
}
|
||||||
@ -553,7 +590,7 @@ $lighterBlue: #409EFF;
|
|||||||
top: 0;
|
top: 0;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
}
|
}
|
||||||
.left-scrollbar{
|
.left-scrollbar {
|
||||||
height: calc(100vh - 42px);
|
height: calc(100vh - 42px);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
@ -570,7 +607,7 @@ $lighterBlue: #409EFF;
|
|||||||
margin: 0 350px 0 260px;
|
margin: 0 350px 0 260px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
.empty-info{
|
.empty-info {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 46%;
|
top: 46%;
|
||||||
left: 0;
|
left: 0;
|
||||||
@ -580,27 +617,27 @@ $lighterBlue: #409EFF;
|
|||||||
color: #ccb1ea;
|
color: #ccb1ea;
|
||||||
letter-spacing: 4px;
|
letter-spacing: 4px;
|
||||||
}
|
}
|
||||||
.action-bar{
|
.action-bar {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 42px;
|
height: 42px;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
padding: 0 15px;
|
padding: 0 15px;
|
||||||
box-sizing: border-box;;
|
box-sizing: border-box;
|
||||||
border: 1px solid #f1e8e8;
|
border: 1px solid #f1e8e8;
|
||||||
border-top: none;
|
border-top: none;
|
||||||
border-left: none;
|
border-left: none;
|
||||||
.delete-btn{
|
.delete-btn {
|
||||||
color: #F56C6C;
|
color: #f56c6c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.logo-wrapper{
|
.logo-wrapper {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 42px;
|
height: 42px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border-bottom: 1px solid #f1e8e8;
|
border-bottom: 1px solid #f1e8e8;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
.logo{
|
.logo {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 12px;
|
left: 12px;
|
||||||
top: 6px;
|
top: 6px;
|
||||||
@ -609,16 +646,16 @@ $lighterBlue: #409EFF;
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 17px;
|
font-size: 17px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
> img{
|
> img {
|
||||||
width: 30px;
|
width: 30px;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
.github{
|
.github {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: sub;
|
vertical-align: sub;
|
||||||
margin-left: 15px;
|
margin-left: 15px;
|
||||||
> img{
|
> img {
|
||||||
height: 22px;
|
height: 22px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -661,32 +698,33 @@ $lighterBlue: #409EFF;
|
|||||||
background-color: $selectedColor;
|
background-color: $selectedColor;
|
||||||
}
|
}
|
||||||
.active-from-item {
|
.active-from-item {
|
||||||
& > .el-form-item{
|
& > .el-form-item {
|
||||||
background: $selectedColor;
|
background: $selectedColor;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
}
|
}
|
||||||
& > .drawing-item-copy, & > .drawing-item-delete{
|
& > .drawing-item-copy,
|
||||||
|
& > .drawing-item-delete {
|
||||||
display: initial;
|
display: initial;
|
||||||
}
|
}
|
||||||
& > .component-name{
|
& > .component-name {
|
||||||
color: $lighterBlue;
|
color: $lighterBlue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.el-form-item{
|
.el-form-item {
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.drawing-item{
|
.drawing-item {
|
||||||
position: relative;
|
position: relative;
|
||||||
cursor: move;
|
cursor: move;
|
||||||
&.unfocus-bordered:not(.activeFromItem) > div:first-child {
|
&.unfocus-bordered:not(.activeFromItem) > div:first-child {
|
||||||
border: 1px dashed #ccc;
|
border: 1px dashed #ccc;
|
||||||
}
|
}
|
||||||
.el-form-item{
|
.el-form-item {
|
||||||
padding: 12px 10px;
|
padding: 12px 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.drawing-row-item{
|
.drawing-row-item {
|
||||||
position: relative;
|
position: relative;
|
||||||
cursor: move;
|
cursor: move;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@ -697,19 +735,19 @@ $lighterBlue: #409EFF;
|
|||||||
.drawing-row-item {
|
.drawing-row-item {
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
}
|
}
|
||||||
.el-col{
|
.el-col {
|
||||||
margin-top: 22px;
|
margin-top: 22px;
|
||||||
}
|
}
|
||||||
.el-form-item{
|
.el-form-item {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
.drag-wrapper{
|
.drag-wrapper {
|
||||||
min-height: 80px;
|
min-height: 80px;
|
||||||
}
|
}
|
||||||
&.active-from-item{
|
&.active-from-item {
|
||||||
border: 1px dashed $lighterBlue;
|
border: 1px dashed $lighterBlue;
|
||||||
}
|
}
|
||||||
.component-name{
|
.component-name {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
@ -719,17 +757,20 @@ $lighterBlue: #409EFF;
|
|||||||
padding: 0 6px;
|
padding: 0 6px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.drawing-item, .drawing-row-item{
|
.drawing-item,
|
||||||
|
.drawing-row-item {
|
||||||
&:hover {
|
&:hover {
|
||||||
& > .el-form-item{
|
& > .el-form-item {
|
||||||
background: $selectedColor;
|
background: $selectedColor;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
}
|
}
|
||||||
& > .drawing-item-copy, & > .drawing-item-delete{
|
& > .drawing-item-copy,
|
||||||
|
& > .drawing-item-delete {
|
||||||
display: initial;
|
display: initial;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
& > .drawing-item-copy, & > .drawing-item-delete{
|
& > .drawing-item-copy,
|
||||||
|
& > .drawing-item-delete {
|
||||||
display: none;
|
display: none;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: -10px;
|
top: -10px;
|
||||||
@ -743,23 +784,23 @@ $lighterBlue: #409EFF;
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
& > .drawing-item-copy{
|
& > .drawing-item-copy {
|
||||||
right: 56px;
|
right: 56px;
|
||||||
border-color: $lighterBlue;
|
border-color: $lighterBlue;
|
||||||
color: $lighterBlue;
|
color: $lighterBlue;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
&:hover{
|
&:hover {
|
||||||
background: $lighterBlue;
|
background: $lighterBlue;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
& > .drawing-item-delete{
|
& > .drawing-item-delete {
|
||||||
right: 24px;
|
right: 24px;
|
||||||
border-color: #F56C6C;
|
border-color: #f56c6c;
|
||||||
color: #F56C6C;
|
color: #f56c6c;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
&:hover{
|
&:hover {
|
||||||
background: #F56C6C;
|
background: #f56c6c;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||